Skip to content

Commit 4244015

Browse files
Mateusz Litwingregkh
authored andcommitted
spi: cadence-quadspi: Prevent lost complete() call during indirect read
[ Upstream commit d67396c ] 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> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 3762535 commit 4244015

1 file changed

Lines changed: 9 additions & 1 deletion

File tree

drivers/spi/spi-cadence-quadspi.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -758,6 +758,7 @@ static int cqspi_indirect_read_execute(struct cqspi_flash_pdata *f_pdata,
758758
readl(reg_base + CQSPI_REG_INDIRECTRD); /* Flush posted write. */
759759

760760
while (remaining > 0) {
761+
ret = 0;
761762
if (use_irq &&
762763
!wait_for_completion_timeout(&cqspi->transfer_complete,
763764
msecs_to_jiffies(CQSPI_READ_TIMEOUT_MS)))
@@ -770,6 +771,14 @@ static int cqspi_indirect_read_execute(struct cqspi_flash_pdata *f_pdata,
770771
if (cqspi->slow_sram)
771772
writel(0x0, reg_base + CQSPI_REG_IRQMASK);
772773

774+
/*
775+
* Prevent lost interrupt and race condition by reinitializing early.
776+
* A spurious wakeup and another wait cycle can occur here,
777+
* which is preferable to waiting until timeout if interrupt is lost.
778+
*/
779+
if (use_irq)
780+
reinit_completion(&cqspi->transfer_complete);
781+
773782
bytes_to_read = cqspi_get_rd_sram_level(cqspi);
774783

775784
if (ret && bytes_to_read == 0) {
@@ -802,7 +811,6 @@ static int cqspi_indirect_read_execute(struct cqspi_flash_pdata *f_pdata,
802811
}
803812

804813
if (use_irq && remaining > 0) {
805-
reinit_completion(&cqspi->transfer_complete);
806814
if (cqspi->slow_sram)
807815
writel(CQSPI_REG_IRQ_WATERMARK, reg_base + CQSPI_REG_IRQMASK);
808816
}

0 commit comments

Comments
 (0)