[PATCH] spi: cadence-quadspi: Fix race between DMA completion and transfer start
From: Radhey Shyam Pandey
Date: Wed Nov 04 2026 - 02:20:59 EST
From: Frederic Konrad <fkonrad@xxxxxxx>
In cqspi_versal_indirect_read_dma(), the DMA transfer is started by
writing CQSPI_REG_INDIRECTRD_START_MASK to the indirect read control
register. Under certain timing conditions, the DMA completion interrupt
may be triggered and complete the transfer before the completion
structure is reinitialized.
This creates a race where the completion event is lost, causing
wait_for_completion_timeout() to time out even though the transfer has
already completed, resulting in errors such as:
spi-nor spi0.0: CS0: operation failed with -110
Fix this by reinitializing the completion structure before starting the
DMA transfer, ensuring that any completion event generated after the
transfer begins is correctly observed.
Fixes: 1a6f854f7daa ("spi: cadence-quadspi: Add Xilinx Versal external DMA support")
Signed-off-by: Frederic Konrad <fkonrad@xxxxxxx>
Signed-off-by: Srikanth Boyapally <srikanth.boyapally@xxxxxxx>
Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey@xxxxxxx>
---
drivers/spi/spi-cadence-quadspi.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c
index 73ea51c41f95..44d96b8cf8f0 100644
--- a/drivers/spi/spi-cadence-quadspi.c
+++ b/drivers/spi/spi-cadence-quadspi.c
@@ -955,11 +955,11 @@ static int cqspi_versal_indirect_read_dma(struct cqspi_flash_pdata *f_pdata,
writel(CQSPI_REG_VERSAL_DMA_DST_CTRL_VAL,
reg_base + CQSPI_REG_VERSAL_DMA_DST_CTRL);
+ reinit_completion(&cqspi->transfer_complete);
+
writel(CQSPI_REG_INDIRECTRD_START_MASK,
reg_base + CQSPI_REG_INDIRECTRD);
- reinit_completion(&cqspi->transfer_complete);
-
if (!wait_for_completion_timeout(&cqspi->transfer_complete,
msecs_to_jiffies(max_t(size_t, bytes_to_dma, 500)))) {
ret = -ETIMEDOUT;
base-commit: 05441d697f7f9a927264f4058cbbc6a03dfcac9d
--
2.44.4