mirror of
git://git.yoctoproject.org/linux-yocto.git
synced 2026-01-27 12:47:24 +01:00
spi: cadence-quadspi: Prevent lost complete() call during indirect read
[ Upstream commit d67396c9d697041b385d70ff2fd59cb07ae167e8 ] 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>
This commit is contained in:
parent
81531bdea9
commit
69695f5331
|
|
@ -769,6 +769,7 @@ static int cqspi_indirect_read_execute(struct cqspi_flash_pdata *f_pdata,
|
|||
readl(reg_base + CQSPI_REG_INDIRECTRD); /* Flush posted write. */
|
||||
|
||||
while (remaining > 0) {
|
||||
ret = 0;
|
||||
if (use_irq &&
|
||||
!wait_for_completion_timeout(&cqspi->transfer_complete,
|
||||
msecs_to_jiffies(CQSPI_READ_TIMEOUT_MS)))
|
||||
|
|
@ -781,6 +782,14 @@ static int cqspi_indirect_read_execute(struct cqspi_flash_pdata *f_pdata,
|
|||
if (cqspi->slow_sram)
|
||||
writel(0x0, reg_base + CQSPI_REG_IRQMASK);
|
||||
|
||||
/*
|
||||
* Prevent lost interrupt and race condition by reinitializing early.
|
||||
* A spurious wakeup and another wait cycle can occur here,
|
||||
* which is preferable to waiting until timeout if interrupt is lost.
|
||||
*/
|
||||
if (use_irq)
|
||||
reinit_completion(&cqspi->transfer_complete);
|
||||
|
||||
bytes_to_read = cqspi_get_rd_sram_level(cqspi);
|
||||
|
||||
if (ret && bytes_to_read == 0) {
|
||||
|
|
@ -813,7 +822,6 @@ static int cqspi_indirect_read_execute(struct cqspi_flash_pdata *f_pdata,
|
|||
}
|
||||
|
||||
if (use_irq && remaining > 0) {
|
||||
reinit_completion(&cqspi->transfer_complete);
|
||||
if (cqspi->slow_sram)
|
||||
writel(CQSPI_REG_IRQ_WATERMARK, reg_base + CQSPI_REG_IRQMASK);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user