]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
spi: cadence-quadspi: Fix indirect write timeout when DMA read mode is enabled
authorSrikanth Boyapally <srikanth.boyapally@amd.com>
Wed, 8 Jul 2026 04:51:48 +0000 (10:21 +0530)
committerMark Brown <broonie@kernel.org>
Tue, 14 Jul 2026 11:54:50 +0000 (12:54 +0100)
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@amd.com>
Reviewed-by: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>
Link: https://patch.msgid.link/20260708045148.2993313-1-srikanth.boyapally@amd.com
Signed-off-by: Mark Brown <broonie@kernel.org>
drivers/spi/spi-cadence-quadspi.c

index aaba1a3ad57783a6ac125623b78e7bf9b4009b79..ecb0be39469651749d3e80bfc69da2b296e75038 100644 (file)
@@ -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);