Unverified Commit 9f61daf2 authored by Pei Xiao's avatar Pei Xiao Committed by Mark Brown
Browse files

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: c770d863 ("spi: Add HiSilicon SPI Controller Driver for Kunpeng SoCs")
Signed-off-by: default avatarPei Xiao <xiaopei01@kylinos.cn>
Link: https://patch.msgid.link/d834ce28172886bfaeb9c8ca00cfd9bf1c65d5a1.1773889292.git.xiaopei01@kylinos.cn


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent c3692998
Loading
Loading
Loading
Loading
+11 −1
Original line number Diff line number Diff line
@@ -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--);
}