]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
spi: lantiq: fix: Rx overflow error in full duplex mode
authorDilip Kota <eswara.kota@linux.intel.com>
Fri, 17 Jul 2020 06:27:50 +0000 (14:27 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 21 Aug 2020 07:48:04 +0000 (09:48 +0200)
[ Upstream commit 661ccf2b3f1360be50242726f7c26ced6a9e7d52 ]

In full duplex mode, rx overflow error is observed. To overcome the error,
wait until the complete data got received and proceed further.

Fixes: 17f84b793c01 ("spi: lantiq-ssc: add support for Lantiq SSC SPI controller")
Signed-off-by: Dilip Kota <eswara.kota@linux.intel.com>
Link: https://lore.kernel.org/r/efb650b0faa49a00788c4e0ca8ef7196bdba851d.1594957019.git.eswara.kota@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/spi/spi-lantiq-ssc.c

index d5976615d924b7b1d5c4a930aeca4765cf01ea47..dc740b5f720ba0cbc1919a55f361ecb0c499b8ea 100644 (file)
@@ -187,6 +187,7 @@ struct lantiq_ssc_spi {
        unsigned int                    tx_fifo_size;
        unsigned int                    rx_fifo_size;
        unsigned int                    base_cs;
+       unsigned int                    fdx_tx_level;
 };
 
 static u32 lantiq_ssc_readl(const struct lantiq_ssc_spi *spi, u32 reg)
@@ -484,6 +485,7 @@ static void tx_fifo_write(struct lantiq_ssc_spi *spi)
        u32 data;
        unsigned int tx_free = tx_fifo_free(spi);
 
+       spi->fdx_tx_level = 0;
        while (spi->tx_todo && tx_free) {
                switch (spi->bits_per_word) {
                case 2 ... 8:
@@ -512,6 +514,7 @@ static void tx_fifo_write(struct lantiq_ssc_spi *spi)
 
                lantiq_ssc_writel(spi, data, LTQ_SPI_TB);
                tx_free--;
+               spi->fdx_tx_level++;
        }
 }
 
@@ -523,6 +526,13 @@ static void rx_fifo_read_full_duplex(struct lantiq_ssc_spi *spi)
        u32 data;
        unsigned int rx_fill = rx_fifo_level(spi);
 
+       /*
+        * Wait until all expected data to be shifted in.
+        * Otherwise, rx overrun may occur.
+        */
+       while (rx_fill != spi->fdx_tx_level)
+               rx_fill = rx_fifo_level(spi);
+
        while (rx_fill) {
                data = lantiq_ssc_readl(spi, LTQ_SPI_RB);