Re: [PATCH v2] dmaengine: mediatek: uart: synchronize completion callbacks
From: Frank Li
Date: Tue Oct 27 2026 - 12:20:37 EST
On Thu, Oct 22, 2026 at 01:40:54PM -0600, James Hilliard wrote:
> Terminating a UART APDMA channel waits for its interrupt handler, but
> completion callbacks run in the virt-dma tasklet. A callback already
> removed from desc_completed can still be running after termination
> returns. With no device_synchronize hook, dmaengine_synchronize() does
> not wait for that callback either.
>
> Add vchan_dma_synchronize() with the DMAengine callback signature and
> use it for UART APDMA. The shared helper wraps vchan_synchronize() so
> drivers can assign it directly to device_synchronize. Document that the
> termination path must have stopped the channel and prevented new
> callbacks before using it.
>
> This lets clients finish asynchronous cancellation before reusing
> callback state or freeing DMA buffers. Keep the callback wait out of
> device_terminate_all so it can be performed without locks acquired by
> the callback.
>
> Fixes: 9135408c3ace ("dmaengine: mediatek: Add MediaTek UART APDMA support")
> Suggested-by: Frank Li <Frank.li@xxxxxxxxxxx>
> Signed-off-by: James Hilliard <james.hilliard1@xxxxxxxxx>
> ---
> Changes in v2:
> - Add a documented vchan_dma_synchronize(struct dma_chan *) helper in
> virt-dma.h and use it directly as the UART APDMA device_synchronize
> callback, following Frank Li's review [0].
> - Link to v1: https://patch.msgid.link/20261021-submit-mtk-uart-dma-synchronize-v1-v1-1-4f7718cfef41@xxxxxxxxx
>
> [0] https://lore.kernel.org/r/atoz6M7RHU14_a3J@SMW015318/
> ---
> drivers/dma/mediatek/mtk-uart-apdma.c | 1 +
> drivers/dma/virt-dma.h | 15 +++++++++++++++
Can you create seperate patch for
1: Add vchan_dma_synchronize() and replace all existings dmaengine driver
like stm32_dma_synchronize() with this API.
2: Add for mtk-uart-apdma.c
Frank
> 2 files changed, 16 insertions(+)
>
> diff --git a/drivers/dma/mediatek/mtk-uart-apdma.c b/drivers/dma/mediatek/mtk-uart-apdma.c
> index f74e9a328588..6bc4f20d8b06 100644
> --- a/drivers/dma/mediatek/mtk-uart-apdma.c
> +++ b/drivers/dma/mediatek/mtk-uart-apdma.c
> @@ -514,6 +514,7 @@ static int mtk_uart_apdma_probe(struct platform_device *pdev)
> mtkd->ddev.device_config = mtk_uart_apdma_slave_config;
> mtkd->ddev.device_pause = mtk_uart_apdma_device_pause;
> mtkd->ddev.device_terminate_all = mtk_uart_apdma_terminate_all;
> + mtkd->ddev.device_synchronize = vchan_dma_synchronize;
> mtkd->ddev.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE);
> mtkd->ddev.dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE);
> mtkd->ddev.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
> diff --git a/drivers/dma/virt-dma.h b/drivers/dma/virt-dma.h
> index 59d9eabc8b67..f1fc3bf48275 100644
> --- a/drivers/dma/virt-dma.h
> +++ b/drivers/dma/virt-dma.h
> @@ -234,4 +234,19 @@ static inline void vchan_synchronize(struct virt_dma_chan *vc)
> vchan_dma_desc_free_list(vc, &head);
> }
>
> +/**
> + * vchan_dma_synchronize - DMAengine callback to synchronize a virtual channel
> + * @chan: DMA channel to synchronize
> + *
> + * Use as device_synchronize when device_terminate_all has stopped the channel
> + * and prevented new callbacks from being scheduled. This waits for callbacks
> + * and frees terminated descriptors through vchan_synchronize().
> + *
> + * Context: non-atomic context, with no locks held that callbacks need.
> + */
> +static inline void vchan_dma_synchronize(struct dma_chan *chan)
> +{
> + vchan_synchronize(to_virt_chan(chan));
> +}
> +
> #endif
>
> ---
> base-commit: 93f51579e7df248780214094418f205253383cc5
> change-id: 20261021-submit-mtk-uart-dma-synchronize-v1-158c8303b574
>
> Best regards,
> --
> James Hilliard <james.hilliard1@xxxxxxxxx>
>