[PATCH] arm: spi: atmel_qspi: fix race condition in transfer completion check
Eugen Hristev
eugen.hristev at linaro.org
Wed Aug 13 10:00:31 CEST 2025
On 7/22/25 21:27, Ramin Moussavi wrote:
> In atmel_qspi_transfer(), the status register is polled with:
>
> imr = QSPI_SR_INSTRE | QSPI_SR_CSR;
> return readl_poll_timeout(aq->regs + QSPI_SR, sr,
> (sr & imr) == imr,
> ATMEL_QSPI_TIMEOUT);
>
> However, this is racy: QSPI_SR_INSTRE can be set before QSPI_SR_CSR,
> and will then be cleared by the read. If that happens, the condition
> "(sr & imr) == imr" can never be true, and the function times out.
>
> This race condition is avoided in at91bootstrap by accumulating the
> status bits across reads until both bits have been observed:
>
> /* Poll INSTruction End and Chip Select Rise flags. */
> imr = (QSPI_SR_INSTRE | QSPI_SR_CSR);
> sr = 0;
> do {
> udelay(1);
> sr |= qspi_readl(qspi, QSPI_SR) & imr;
> } while ((--timeout) && (sr != imr));
>
> Update U-Boot's atmel_qspi_transfer() to use the same pattern,
> ensuring that both flags are observed even if they are not set
> simultaneously.
>
> Signed-off-by: Ramin Moussavi <lordrasmus at gmail.com>
> ---
Applied to u-boot-at91/master, thanks !
For future, please send out patch updates with 'git send-email -v 2'
(e.g. for a second version) and include a changelog below the '---' line
Eugen
More information about the U-Boot
mailing list