summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlain Volmat <alain.volmat@foss.st.com>2026-01-06 12:34:35 +0100
committerMauro Carvalho Chehab <mchehab+huawei@kernel.org>2026-03-11 01:05:33 +0100
commit04e047447a05de495ac2a9cb96adf35bf1c0e0f8 (patch)
tree75a5b1bf1a841123379470f5c077ad8c58427126
parentc1cde65747158e90e3e4633d571450d929b4a4fe (diff)
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 <alain.volmat@foss.st.com> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
-rw-r--r--drivers/media/platform/st/stm32/stm32-dcmi.c8
1 files 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 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);