Skip to content

Commit 3d0ef05

Browse files
Pei Xiaogregkh
authored andcommitted
spi: hisi-kunpeng: prevent infinite while() loop in hisi_spi_flush_fifo
[ Upstream commit 9f61daf ] 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: c770d86 ("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> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent eae672a commit 3d0ef05

1 file changed

Lines changed: 11 additions & 1 deletion

File tree

drivers/spi/spi-hisi-kunpeng.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,18 @@ static void hisi_spi_flush_fifo(struct hisi_spi *hs)
196196
unsigned long limit = loops_per_jiffy << 1;
197197

198198
do {
199-
while (hisi_spi_rx_not_empty(hs))
199+
unsigned long inner_limit = loops_per_jiffy;
200+
201+
while (hisi_spi_rx_not_empty(hs) && --inner_limit) {
200202
readl(hs->regs + HISI_SPI_DOUT);
203+
cpu_relax();
204+
}
205+
206+
if (!inner_limit) {
207+
dev_warn_ratelimited(hs->dev, "RX FIFO flush timeout\n");
208+
break;
209+
}
210+
201211
} while (hisi_spi_busy(hs) && limit--);
202212
}
203213

0 commit comments

Comments
 (0)