spi: cadence-quadspi: Prevent lost complete() call during indirect read

A race condition exists between the read loop and IRQ `complete()` call.
An interrupt could call the complete() between the inner loop and
reinit_completion(), potentially losing the completion event and causing
an unnecessary timeout. Moving reinit_completion() before the loop
prevents this. A premature signal will only result in a spurious wakeup
and another wait cycle, which is preferable to waiting for a timeout.

Signed-off-by: Mateusz Litwin <mateusz.litwin@nokia.com>
Link: https://patch.msgid.link/20251218-cqspi_indirect_read_improve-v2-1-396079972f2a@nokia.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by Mateusz Litwin and committed by Mark Brown d67396c9 9448598b

+9 -1
+9 -1
drivers/spi/spi-cadence-quadspi.c
··· 769 769 readl(reg_base + CQSPI_REG_INDIRECTRD); /* Flush posted write. */ 770 770 771 771 while (remaining > 0) { 772 + ret = 0; 772 773 if (use_irq && 773 774 !wait_for_completion_timeout(&cqspi->transfer_complete, 774 775 msecs_to_jiffies(CQSPI_READ_TIMEOUT_MS))) ··· 781 780 */ 782 781 if (cqspi->slow_sram) 783 782 writel(0x0, reg_base + CQSPI_REG_IRQMASK); 783 + 784 + /* 785 + * Prevent lost interrupt and race condition by reinitializing early. 786 + * A spurious wakeup and another wait cycle can occur here, 787 + * which is preferable to waiting until timeout if interrupt is lost. 788 + */ 789 + if (use_irq) 790 + reinit_completion(&cqspi->transfer_complete); 784 791 785 792 bytes_to_read = cqspi_get_rd_sram_level(cqspi); 786 793 ··· 822 813 } 823 814 824 815 if (use_irq && remaining > 0) { 825 - reinit_completion(&cqspi->transfer_complete); 826 816 if (cqspi->slow_sram) 827 817 writel(CQSPI_REG_IRQ_WATERMARK, reg_base + CQSPI_REG_IRQMASK); 828 818 }