Skip to content

Commit 5bc4d26

Browse files
committed
spi_nxp_lpspi: Fix DMA driver async return
We should not release context until transfer ends. The code previously would return from wait_for_completion and then release the context. This is only supposed to be done in the dma callback except for the case of error in the transceive call. For async transfer this was most likely always happening wrong and probably broken for multi threads trying to access the bus due to this premature release of the context. Also we should not enable CS and leave enabled in case of error, move CS enable to after the error check. Signed-off-by: Declan Snyder <declan.snyder@nxp.com>
1 parent 1d16f8a commit 5bc4d26

File tree

1 file changed

+10
-6
lines changed

1 file changed

+10
-6
lines changed

drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_dma.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ static void spi_mcux_dma_callback(const struct device *dev, void *arg, uint32_t
204204
spi_context_cs_control(ctx, false);
205205
LPSPI_FlushFifo(base, true, true);
206206
spi_context_complete(ctx, spi_dev, status);
207+
spi_context_release(ctx, status);
207208
}
208209

209210
static int transceive_dma(const struct device *dev, const struct spi_config *spi_cfg,
@@ -224,12 +225,6 @@ static int transceive_dma(const struct device *dev, const struct spi_config *spi
224225

225226
spi_context_buffers_setup(ctx, tx_bufs, rx_bufs, 1);
226227

227-
if (!(IS_ENABLED(CONFIG_SOC_FAMILY_NXP_IMXRT) || IS_ENABLED(CONFIG_SOC_FAMILY_KINETIS))) {
228-
base->TCR |= LPSPI_TCR_CONT_MASK;
229-
}
230-
231-
spi_context_cs_control(ctx, true);
232-
233228
ret = spi_mcux_dma_next_fill(dev);
234229
if (ret == -ENODATA) {
235230
/* No transfer to do? So just exit */
@@ -239,11 +234,20 @@ static int transceive_dma(const struct device *dev, const struct spi_config *spi
239234
goto out;
240235
}
241236

237+
if (!(IS_ENABLED(CONFIG_SOC_FAMILY_NXP_IMXRT) || IS_ENABLED(CONFIG_SOC_FAMILY_KINETIS))) {
238+
base->TCR |= LPSPI_TCR_CONT_MASK;
239+
}
240+
241+
spi_context_cs_control(ctx, true);
242+
242243
LPSPI_FlushFifo(base, true, true);
243244

244245
LPSPI_EnableDMA(base, kLPSPI_TxDmaEnable | kLPSPI_RxDmaEnable);
245246

246247
ret = spi_context_wait_for_completion(ctx);
248+
if (ret >= 0) {
249+
return ret;
250+
}
247251
out:
248252
spi_context_release(ctx, ret);
249253
return ret;

0 commit comments

Comments
 (0)