From: Mirko Vogt mirko-dev|linux@nanl.de
stable inclusion from stable-5.10.50 commit c43082d284fa15079c3ca22583fd76f50fe4e5d4 bugzilla: 174522 https://gitee.com/openeuler/kernel/issues/I4DNFY
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=...
--------------------------------
[ Upstream commit 0d7993b234c9fad8cb6bec6adfaa74694ba85ecb ]
The current sun6i SPI implementation initializes the transfer too early, resulting in SCK going high before the transfer. When using an additional (gpio) chipselect with sun6i, the chipselect is asserted at a time when clock is high, making the SPI transfer fail.
This is due to SUN6I_GBL_CTL_BUS_ENABLE being written into SUN6I_GBL_CTL_REG at an early stage. Moving that to the transfer function, hence, right before the transfer starts, mitigates that problem.
Fixes: 3558fe900e8af (spi: sunxi: Add Allwinner A31 SPI controller driver) Signed-off-by: Mirko Vogt mirko-dev|linux@nanl.de Signed-off-by: Ralf Schlatterbeck rsc@runtux.com Link: https://lore.kernel.org/r/20210614144507.y3udezjfbko7eavv@runtux.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Chen Jun chenjun102@huawei.com Acked-by: Weilong Chen chenweilong@huawei.com Signed-off-by: Chen Jun chenjun102@huawei.com --- drivers/spi/spi-sun6i.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/spi/spi-sun6i.c b/drivers/spi/spi-sun6i.c index 19238e1b76b4..803d92f8d031 100644 --- a/drivers/spi/spi-sun6i.c +++ b/drivers/spi/spi-sun6i.c @@ -290,6 +290,10 @@ static int sun6i_spi_transfer_one(struct spi_master *master, }
sun6i_spi_write(sspi, SUN6I_CLK_CTL_REG, reg); + /* Finally enable the bus - doing so before might raise SCK to HIGH */ + reg = sun6i_spi_read(sspi, SUN6I_GBL_CTL_REG); + reg |= SUN6I_GBL_CTL_BUS_ENABLE; + sun6i_spi_write(sspi, SUN6I_GBL_CTL_REG, reg);
/* Setup the transfer now... */ if (sspi->tx_buf) @@ -398,7 +402,7 @@ static int sun6i_spi_runtime_resume(struct device *dev) }
sun6i_spi_write(sspi, SUN6I_GBL_CTL_REG, - SUN6I_GBL_CTL_BUS_ENABLE | SUN6I_GBL_CTL_MASTER | SUN6I_GBL_CTL_TP); + SUN6I_GBL_CTL_MASTER | SUN6I_GBL_CTL_TP);
return 0;