diff options
| author | Marc Kleine-Budde <mkl@pengutronix.de> | 2026-09-14 17:35:58 +0200 |
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2026-10-06 17:30:43 +0200 |
| commit | b8f09251da7871fbb9c62bd83516af422641d816 (patch) | |
| tree | 144ce653fd7c8e5165b433b84c75234707ac5792 /include/linux | |
| parent | 672ba6d88324f223634dd2dc4098f6fb6b346b25 (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
