diff options
Diffstat (limited to 'target/linux/bcm27xx/patches-5.10/950-0448-spi-bcm2835-Workaround-fix-for-zero-length-transfers.patch')
-rw-r--r-- | target/linux/bcm27xx/patches-5.10/950-0448-spi-bcm2835-Workaround-fix-for-zero-length-transfers.patch | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/target/linux/bcm27xx/patches-5.10/950-0448-spi-bcm2835-Workaround-fix-for-zero-length-transfers.patch b/target/linux/bcm27xx/patches-5.10/950-0448-spi-bcm2835-Workaround-fix-for-zero-length-transfers.patch new file mode 100644 index 0000000000..2b9d30ff18 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.10/950-0448-spi-bcm2835-Workaround-fix-for-zero-length-transfers.patch @@ -0,0 +1,50 @@ +From 54545710d40fd00e3c727603a446500b1b9b3d88 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Thu, 28 Jan 2021 11:30:04 +0000 +Subject: [PATCH] spi: bcm2835: Workaround/fix for zero-length + transfers + +A relatively recent commit ([1]) contained optimisation for the PIO +SPI FIFO-filling functions. The commit message includes the phrase +"[t]he blind and counted loops are always called with nonzero count". +This is technically true, but it is still possible for count to become +zero before the loop is entered - if tfr->len is zero. Moving the loop +exit condition to the end of the loop saves a few cycles, but results +in a near-infinite loop should the revised count be zero on entry. + +Strangely, zero-lengthed transfers aren't filtered by the SPI framework +and, even more strangely, the Python3 spidev library is triggering them +for no obvious reason. + +Avoid the problem completely by bailing out of the main transfer +function early if trf->len is zero, although there may be a case for +moving the mitigation into the framework. + +See: https://github.com/raspberrypi/linux/issues/4100 + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> + +[1] 26751de25d25 ("spi: bcm2835: Micro-optimise FIFO loops") +--- + drivers/spi/spi-bcm2835.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/drivers/spi/spi-bcm2835.c ++++ b/drivers/spi/spi-bcm2835.c +@@ -1092,6 +1092,16 @@ static int bcm2835_spi_transfer_one(stru + unsigned long hz_per_byte, byte_limit; + u32 cs = bs->prepare_cs[spi->chip_select]; + ++ if (unlikely(!tfr->len)) { ++ static int warned; ++ ++ if (!warned) ++ dev_warn(&spi->dev, ++ "zero-length SPI transfer ignored\n"); ++ warned = 1; ++ return 0; ++ } ++ + /* set clock */ + spi_hz = tfr->speed_hz; + |