Re: [PATCH] spi: cadence-quadspi: Fix indirect write timeout when DMA read mode is enabled
From: Pandey, Radhey Shyam
Date: Mon Jul 13 2026 - 06:21:31 EST
When use_dma_read is enabled, the IRQ handler unconditionally overwrites
irq_status with the return value of get_dma_status(). For write operations,
DMA status returns 0 since no DMA read is in progress, causing irq_status
to become 0. The subsequent completion signal is never triggered and the
write operation times out with -ETIMEDOUT:
cadence-qspi f1010000.spi: Indirect write timeout
spi-nor spi0.1: operation failed with -110
Fix this by separating the DMA completion path from the write interrupt
path. If get_dma_status() indicates DMA read completion, signal completion
and return immediately. Otherwise, preserve the original irq_status so that
write completion interrupts are correctly recognized and signalled.
Fixes: aac733a96636 ("spi: cadence-qspi: Fix style and improve readability")
Signed-off-by: Srikanth Boyapally <srikanth.boyapally@xxxxxxx>
Reviewed-by: Radhey Shyam Pandey <radhey.shyam.pandey@xxxxxxx>
Thanks!
---
drivers/spi/spi-cadence-quadspi.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c
index 65aff2e70265..89873f8b3f21 100644
--- a/drivers/spi/spi-cadence-quadspi.c
+++ b/drivers/spi/spi-cadence-quadspi.c
@@ -382,12 +382,16 @@ static irqreturn_t cqspi_irq_handler(int this_irq, void *dev)
/* Clear interrupt */
writel(irq_status, cqspi->iobase + CQSPI_REG_IRQSTATUS);
- if (cqspi->use_dma_read && ddata && ddata->get_dma_status)
- irq_status = ddata->get_dma_status(cqspi);
- else if (cqspi->slow_sram)
+ if (cqspi->use_dma_read && ddata && ddata->get_dma_status) {
+ if (ddata->get_dma_status(cqspi)) {
+ complete(&cqspi->transfer_complete);
+ return IRQ_HANDLED;
+ }
+ } else if (cqspi->slow_sram) {
irq_status &= CQSPI_IRQ_MASK_RD_SLOW_SRAM | CQSPI_IRQ_MASK_WR;
- else
+ } else {
irq_status &= CQSPI_IRQ_MASK_RD | CQSPI_IRQ_MASK_WR;
+ }
if (irq_status)
complete(&cqspi->transfer_complete);