Message ID | 20250609-james-nxp-spi-dma-v1-1-2b831e714be2@linaro.org |
---|---|
State | New |
Headers | show |
Series | spi: spi-fsl-dspi: Target mode improvements | expand |
diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index 863781ba6c16..386a17871e79 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c @@ -983,11 +983,13 @@ static int dspi_transfer_one_message(struct spi_controller *ctlr, if (dspi->devtype_data->trans_mode == DSPI_DMA_MODE) { status = dspi_dma_xfer(dspi); } else { + if (dspi->irq) + reinit_completion(&dspi->xfer_done); + dspi_fifo_write(dspi); if (dspi->irq) { wait_for_completion(&dspi->xfer_done); - reinit_completion(&dspi->xfer_done); } else { do { status = dspi_poll(dspi);
In target mode, extra interrupts can be received between the end of a transfer and halting the module if the host continues sending more data. If the interrupt from this occurs after the reinit_completion() then the completion counter is left at a non-zero value. The next unrelated transfer initiated by userspace will then complete immediately without waiting for the interrupt or writing to the RX buffer. Fix it by resetting the counter before the transfer so that lingering values are cleared. This is done after clearing the FIFOs and the status register but before the transfer is initiated, so no interrupts should be received at this point resulting in other race conditions. Fixes: 4f5ee75ea171 ("spi: spi-fsl-dspi: Replace interruptible wait queue with a simple completion") Signed-off-by: James Clark <james.clark@linaro.org> --- drivers/spi/spi-fsl-dspi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)