3b4946f24191dfd8bc8ab5d6f16512c5ef51ca85
[openwrt/staging/blogic.git] /
1 From 72742fb9d06e6c931738de020bc6bbd98c6829f7 Mon Sep 17 00:00:00 2001
2 From: Phil Elwell <phil@raspberrypi.com>
3 Date: Thu, 28 Jan 2021 11:30:04 +0000
4 Subject: [PATCH] spi: bcm2835: Workaround/fix for zero-length
5 transfers
6
7 A relatively recent commit ([1]) contained optimisation for the PIO
8 SPI FIFO-filling functions. The commit message includes the phrase
9 "[t]he blind and counted loops are always called with nonzero count".
10 This is technically true, but it is still possible for count to become
11 zero before the loop is entered - if tfr->len is zero. Moving the loop
12 exit condition to the end of the loop saves a few cycles, but results
13 in a near-infinite loop should the revised count be zero on entry.
14
15 Strangely, zero-lengthed transfers aren't filtered by the SPI framework
16 and, even more strangely, the Python3 spidev library is triggering them
17 for no obvious reason.
18
19 Avoid the problem completely by bailing out of the main transfer
20 function early if trf->len is zero, although there may be a case for
21 moving the mitigation into the framework.
22
23 See: https://github.com/raspberrypi/linux/issues/4100
24
25 Signed-off-by: Phil Elwell <phil@raspberrypi.com>
26
27 [1] 26751de25d25 ("spi: bcm2835: Micro-optimise FIFO loops")
28 ---
29 drivers/spi/spi-bcm2835.c | 10 ++++++++++
30 1 file changed, 10 insertions(+)
31
32 --- a/drivers/spi/spi-bcm2835.c
33 +++ b/drivers/spi/spi-bcm2835.c
34 @@ -1055,6 +1055,16 @@ static int bcm2835_spi_transfer_one(stru
35 unsigned long hz_per_byte, byte_limit;
36 u32 cs = slv->prepare_cs;
37
38 + if (unlikely(!tfr->len)) {
39 + static int warned;
40 +
41 + if (!warned)
42 + dev_warn(&spi->dev,
43 + "zero-length SPI transfer ignored\n");
44 + warned = 1;
45 + return 0;
46 + }
47 +
48 /* set clock */
49 spi_hz = tfr->speed_hz;
50