[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