spi: spi-cadence: Reverse the order of interleaved write and read operations
authorAmit Kumar Mahapatra <amit.kumar-mahapatra@amd.com>
Mon, 18 Dec 2023 09:06:52 +0000 (14:36 +0530)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 1 Feb 2024 00:19:13 +0000 (16:19 -0800)
[ Upstream commit 633cd6fe6e1993ba80e0954c2db127a0b1a3e66f ]

In the existing implementation, when executing interleaved write and read
operations in the ISR for a transfer length greater than the FIFO size,
the TXFIFO write precedes the RXFIFO read. Consequently, the initially
received data in the RXFIFO is pushed out and lost, leading to a failure
in data integrity. To address this issue, reverse the order of interleaved
operations and conduct the RXFIFO read followed by the TXFIFO write.

Fixes: 6afe2ae8dc48 ("spi: spi-cadence: Interleave write of TX and read of RX FIFO")
Signed-off-by: Amit Kumar Mahapatra <amit.kumar-mahapatra@amd.com>
Link: https://msgid.link/r/20231218090652.18403-1-amit.kumar-mahapatra@amd.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/spi/spi-cadence.c

index bd96d8b..5cab7ca 100644 (file)
@@ -317,6 +317,15 @@ static void cdns_spi_process_fifo(struct cdns_spi *xspi, int ntx, int nrx)
        xspi->rx_bytes -= nrx;
 
        while (ntx || nrx) {
+               if (nrx) {
+                       u8 data = cdns_spi_read(xspi, CDNS_SPI_RXD);
+
+                       if (xspi->rxbuf)
+                               *xspi->rxbuf++ = data;
+
+                       nrx--;
+               }
+
                if (ntx) {
                        if (xspi->txbuf)
                                cdns_spi_write(xspi, CDNS_SPI_TXD, *xspi->txbuf++);
@@ -326,14 +335,6 @@ static void cdns_spi_process_fifo(struct cdns_spi *xspi, int ntx, int nrx)
                        ntx--;
                }
 
-               if (nrx) {
-                       u8 data = cdns_spi_read(xspi, CDNS_SPI_RXD);
-
-                       if (xspi->rxbuf)
-                               *xspi->rxbuf++ = data;
-
-                       nrx--;
-               }
        }
 }