[PATCH 07/12] media: stm32: dcmi: use dmaengine_terminate_async in irq context

Alain Volmat
2025-12-18T18:45:21Z

Whenever receiving an OVERRUN event or an end of frame, the driver stops
currently ongoing DMA transfer since the DCMI stops sending data to dma.
Not doing this would lead to having DMA & DCMI no more synchronized in term
of expected data to be copied.
Since this is done in irq handler context, it is not possible to make any
call that would lead to scheduling hence dmaengine_terminate_sync are not
possible.
Since the dcmi driver is NOT using dma callbacks, it is possible thus to
call instead dmaengine_terminate_async (aka without synchronize) and call
again right after a new dmaengine_submit to setup again a new transfer.
And since this is now a dmaengine_submit_async, there is no need to release
the spinlock around calls to the dmaengine_submit_async.

Signed-off-by: Alain Volmat <alain.volmat@foss.st.com>
---
drivers/media/platform/st/stm32/stm32-dcmi.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/media/platform/st/stm32/stm32-dcmi.c b/drivers/media/platform/st/stm32/stm32-dcmi.c
index 06b66095844b..25e95ba2ca84 100644
--- a/drivers/media/platform/st/stm32/stm32-dcmi.c
+++ b/drivers/media/platform/st/stm32/stm32-dcmi.c
@@ -334,10 +334,8 @@ static void dcmi_process_frame(struct stm32_dcmi *dcmi)
dcmi_buffer_done(dcmi, buf, 0, -EIO);
}

- spin_unlock_irq(&dcmi->irqlock);
/* Abort DMA operation */
- dmaengine_terminate_sync(dcmi->dma_chan);
- spin_lock_irq(&dcmi->irqlock);
+ dmaengine_terminate_async(dcmi->dma_chan);
}

static irqreturn_t dcmi_irq_thread(int irq, void *arg)
@@ -355,10 +353,8 @@ static irqreturn_t dcmi_irq_thread(int irq, void *arg)
if (dcmi->overrun_count > OVERRUN_ERROR_THRESHOLD)
dcmi->errors_count++;

- spin_unlock_irq(&dcmi->irqlock);
- dmaengine_terminate_sync(dcmi->dma_chan);
+ dmaengine_terminate_async(dcmi->dma_chan);

- spin_lock_irq(&dcmi->irqlock);
if (dcmi_restart_capture(dcmi))
dev_err(dcmi->dev, "%s: Cannot restart capture\n", __func__);
spin_unlock_irq(&dcmi->irqlock);

--
2.34.1