summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorMarc Kleine-Budde <mkl@pengutronix.de>2026-09-14 17:35:58 +0200
committerMark Brown <broonie@kernel.org>2026-10-06 17:30:43 +0200
commitb8f09251da7871fbb9c62bd83516af422641d816 (patch)
tree144ce653fd7c8e5165b433b84c75234707ac5792 /include/linux
parent672ba6d88324f223634dd2dc4098f6fb6b346b25 (diff)
spi: spi-sun4i: sun4i_spi_handler(): fix race condition between transfer completion and RX FIFO interrupt
In commit 196737912da5 ("spi: sun4i: Allow transfers larger than FIFO size"), support for transfers larger than the FIFO size was added. This commit moves the draining of the RX-FIFO from sun4i_spi_transfer_one() (after completion of the transfer) to the IRQ handler when the IRQ "transfer complete" is handled. In addition, the IRQ "RX-FIFO 3/4 full" is activated for all transfers. However, this does not take into account that the RX-IRQ for transfers that exceed 3/4 of the FIFO size is still pending after the IRQ "transfer complete" has been processed. All interrupt sources are only deactivated after the wait_for_completion_timeout() in sun4i_spi_transfer_one(). This opens a race window for "RX-FIFO 3/4 full" interrupts to come. The sequence is as follows: | sun4i_spi_transfer_one() | sun4i_spi_fill_fifo() // fill TX-FIFO with 48 bytes | // enable RX-FIFO 3/4 full IRQ | wait_for_completion_timeout(); | | // SPI controller transfers 48 bytes | // SPI controller issues "transfer complete" and "RX-FIFO 3/4 full" IRQ | | // IRQ handler start | sun4i_spi_handler() | // ACK "transfer complete" IRQ | sun4i_spi_drain_fifo(); | complete(); ----. | return IRQ_HANDLED; \ | // IRQ handler end \__ race | / window | // wait_for_completion_timeout() continues / | // disable all IRQ sources ----' Avoid the race condition by disabling all interrupts when handling the "transfer complete" IRQ and before calling complete(). Also move the draining of the RX-FIFO back into sun4i_spi_transfer_one() where it was before commit 196737912da5 ("spi: sun4i: Allow transfers larger than FIFO size"). This has the added benefit of spending a little less time in the IRQ handler. With all interrupts disabled once the transfer completed, omit the clearing of the Transfer Complete bit in sun4i_spi_handler. This is safe because sun4i_spi_transfer_one() takes care of this before enabling any interrupts again. Cc: Tobias Schramm <t.schramm@manjaro.org> Fixes: 196737912da5 ("spi: sun4i: Allow transfers larger than FIFO size") Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de> Signed-off-by: Jonas Rebmann <jre@pengutronix.de> Link: https://patch.msgid.link/20260914-spi-sun4i-fixes-v3-4-9fe919d5cecf@pengutronix.de Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'include/linux')
0 files changed, 0 insertions, 0 deletions