From 04e047447a05de495ac2a9cb96adf35bf1c0e0f8 Mon Sep 17 00:00:00 2001 From: Alain Volmat Date: Tue, 6 Jan 2026 12:34:35 +0100 Subject: media: stm32: dcmi: use dmaengine_terminate_async in irq context 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 Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/st/stm32/stm32-dcmi.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/st/stm32/stm32-dcmi.c b/drivers/media/platform/st/stm32/stm32-dcmi.c index 66bb79038c54..6ca0ffcd97a3 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); -- cgit v1.2.3