Hi Daniil On 5/24/21 12:24 AM, Daniil Stas wrote: > TCF flag only means that all data was sent to FIFO. To check if the > data was sent out of FIFO we should also wait for the BUSY flag to be > cleared. Otherwise there is a race condition which can lead to > inability to write short (one byte long) data. > > Signed-off-by: Daniil Stas <daniil.s...@posteo.net> > Cc: Patrick Delaunay <patrick.delau...@foss.st.com> > Cc: Patrice Chotard <patrice.chot...@foss.st.com> > --- > drivers/spi/stm32_qspi.c | 29 +++++++++++++++-------------- > 1 file changed, 15 insertions(+), 14 deletions(-) > > diff --git a/drivers/spi/stm32_qspi.c b/drivers/spi/stm32_qspi.c > index 4acc9047b9..8f4aabc3d1 100644 > --- a/drivers/spi/stm32_qspi.c > +++ b/drivers/spi/stm32_qspi.c > @@ -148,23 +148,24 @@ static int _stm32_qspi_wait_cmd(struct stm32_qspi_priv > *priv, > const struct spi_mem_op *op) > { > u32 sr; > - int ret; > - > - if (!op->data.nbytes) > - return _stm32_qspi_wait_for_not_busy(priv); > + int ret = 0; > > - ret = readl_poll_timeout(&priv->regs->sr, sr, > - sr & STM32_QSPI_SR_TCF, > - STM32_QSPI_CMD_TIMEOUT_US); > - if (ret) { > - log_err("cmd timeout (stat:%#x)\n", sr); > - } else if (readl(&priv->regs->sr) & STM32_QSPI_SR_TEF) { > - log_err("transfer error (stat:%#x)\n", sr); > - ret = -EIO; > + if (op->data.nbytes) { > + ret = readl_poll_timeout(&priv->regs->sr, sr, > + sr & STM32_QSPI_SR_TCF, > + STM32_QSPI_CMD_TIMEOUT_US); > + if (ret) { > + log_err("cmd timeout (stat:%#x)\n", sr); > + } else if (readl(&priv->regs->sr) & STM32_QSPI_SR_TEF) { > + log_err("transfer error (stat:%#x)\n", sr); > + ret = -EIO; > + } > + /* clear flags */ > + writel(STM32_QSPI_FCR_CTCF | STM32_QSPI_FCR_CTEF, > &priv->regs->fcr); > } > > - /* clear flags */ > - writel(STM32_QSPI_FCR_CTCF | STM32_QSPI_FCR_CTEF, &priv->regs->fcr); > + if (!ret) > + ret = _stm32_qspi_wait_for_not_busy(priv); > > return ret; > } >
Have you got a simple test to reproduce the described race condition ? Thanks Patrice