diff options
| author | Pei Xiao <xiaopei01@kylinos.cn> | 2026-03-19 06:06:41 +0300 |
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2026-03-24 01:02:39 +0300 |
| commit | 9f61daf2c2debe9f5cf4e1a4471e56a89a6fe45a (patch) | |
| tree | a3b655112af84624b4c72dab3abf56af194bc33e | |
| parent | c369299895a591d96745d6492d4888259b004a9e (diff) | |
| download | linux-9f61daf2c2debe9f5cf4e1a4471e56a89a6fe45a.tar.xz | |
spi: hisi-kunpeng: prevent infinite while() loop in hisi_spi_flush_fifo
The hisi_spi_flush_fifo()'s inner while loop that lacks any timeout
mechanism. Maybe the hardware never becomes empty, the loop will spin
forever, causing the CPU to hang.
Fix this by adding a inner_limit based on loops_per_jiffy. The inner loop
now exits after approximately one jiffy if the FIFO remains non-empty, logs
a ratelimited warning, and breaks out of the outer loop. Additionally, add
a cpu_relax() inside the busy loop to improve power efficiency.
Fixes: c770d8631e18 ("spi: Add HiSilicon SPI Controller Driver for Kunpeng SoCs")
Signed-off-by: Pei Xiao <xiaopei01@kylinos.cn>
Link: https://patch.msgid.link/d834ce28172886bfaeb9c8ca00cfd9bf1c65d5a1.1773889292.git.xiaopei01@kylinos.cn
Signed-off-by: Mark Brown <broonie@kernel.org>
| -rw-r--r-- | drivers/spi/spi-hisi-kunpeng.c | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/drivers/spi/spi-hisi-kunpeng.c b/drivers/spi/spi-hisi-kunpeng.c index 216a0a91fc47..c42d2a2cdf1e 100644 --- a/drivers/spi/spi-hisi-kunpeng.c +++ b/drivers/spi/spi-hisi-kunpeng.c @@ -196,8 +196,18 @@ static void hisi_spi_flush_fifo(struct hisi_spi *hs) unsigned long limit = loops_per_jiffy << 1; do { - while (hisi_spi_rx_not_empty(hs)) + unsigned long inner_limit = loops_per_jiffy; + + while (hisi_spi_rx_not_empty(hs) && --inner_limit) { readl(hs->regs + HISI_SPI_DOUT); + cpu_relax(); + } + + if (!inner_limit) { + dev_warn_ratelimited(hs->dev, "RX FIFO flush timeout\n"); + break; + } + } while (hisi_spi_busy(hs) && limit--); } |
