Skip to content

Commit 69695f5

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 81531bd commit 69695f5

File tree

1 file changed

+9
-1
lines changed

1 file changed

+9
-1
lines changed

drivers/spi/spi-cadence-quadspi.c

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

771771
while (remaining > 0) {
772+
ret = 0;
772773
if (use_irq &&
773774
!wait_for_completion_timeout(&cqspi->transfer_complete,
774775
msecs_to_jiffies(CQSPI_READ_TIMEOUT_MS)))
@@ -781,6 +782,14 @@ static int cqspi_indirect_read_execute(struct cqspi_flash_pdata *f_pdata,
781782
if (cqspi->slow_sram)
782783
writel(0x0, reg_base + CQSPI_REG_IRQMASK);
783784

785+
/*
786+
* Prevent lost interrupt and race condition by reinitializing early.
787+
* A spurious wakeup and another wait cycle can occur here,
788+
* which is preferable to waiting until timeout if interrupt is lost.
789+
*/
790+
if (use_irq)
791+
reinit_completion(&cqspi->transfer_complete);
792+
784793
bytes_to_read = cqspi_get_rd_sram_level(cqspi);
785794

786795
if (ret && bytes_to_read == 0) {
@@ -813,7 +822,6 @@ static int cqspi_indirect_read_execute(struct cqspi_flash_pdata *f_pdata,
813822
}
814823

815824
if (use_irq && remaining > 0) {
816-
reinit_completion(&cqspi->transfer_complete);
817825
if (cqspi->slow_sram)
818826
writel(CQSPI_REG_IRQ_WATERMARK, reg_base + CQSPI_REG_IRQMASK);
819827
}

0 commit comments

Comments
 (0)