Skip to content

Commit

Permalink
spi: bcm2835: Workaround/fix for zero-length transfers
Browse files Browse the repository at this point in the history
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: #4100

Signed-off-by: Phil Elwell <phil@raspberrypi.com>

[1] 26751de ("spi: bcm2835: Micro-optimise FIFO loops")
  • Loading branch information
pelwell authored and popcornmix committed Jul 18, 2022
1 parent d8c5b6b commit c643a36
Showing 1 changed file with 10 additions and 0 deletions.
10 changes: 10 additions & 0 deletions drivers/spi/spi-bcm2835.c
Expand Up @@ -1055,6 +1055,16 @@ static int bcm2835_spi_transfer_one(struct spi_controller *ctlr,
unsigned long hz_per_byte, byte_limit;
u32 cs = slv->prepare_cs;

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;

Expand Down

0 comments on commit c643a36

Please sign in to comment.