Files
openwrt-armor-g5/target/linux/bcm27xx/patches-6.6/950-0276-spi-bcm2835-Workaround-fix-for-zero-length-transfers.patch
domenico 27c9d80f51
Some checks failed
Build Kernel / Build all affected Kernels (push) Has been cancelled
Build all core packages / Build all core packages for selected target (push) Has been cancelled
Build and Push prebuilt tools container / Build and Push all prebuilt containers (push) Has been cancelled
Build Toolchains / Build Toolchains for each target (push) Has been cancelled
Build host tools / Build host tools for linux and macos based systems (push) Has been cancelled
Coverity scan build / Coverity x86/64 build (push) Has been cancelled
Initial commit
2025-06-24 12:51:15 +02:00

51 lines
1.7 KiB
Diff

From a7c6699c4ddfe450cfef583f4f490bbafcfcff18 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.com>
Date: Thu, 28 Jan 2021 11:30:04 +0000
Subject: [PATCH 0276/1085] 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
@@ -1055,6 +1055,16 @@ static int bcm2835_spi_transfer_one(stru
unsigned long hz_per_byte, byte_limit;
u32 cs = target->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;