Re: [PATCH v3 21/34] dmaengine: zynqmp-dma: switch completion tasklet to dmaengine BH
From: Frank Li
Date: Wed Sep 02 2026 - 12:11:01 EST
On Mon, Aug 10, 2026 at 11:09:22AM -0700, Allen Pais wrote:
> Replace the per-channel tasklet with the shared dmaengine BH helper.
> The handler continues to run in softirq context while dmaengine owns
> the common scheduling and teardown mechanism.
>
> Signed-off-by: Allen Pais <allen.lkml@xxxxxxxxx>
> ---
Reviewed-by: Frank Li <Frank.Li@xxxxxxx>
> drivers/dma/xilinx/zynqmp_dma.c | 19 +++++++++----------
> 1 file changed, 9 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/dma/xilinx/zynqmp_dma.c b/drivers/dma/xilinx/zynqmp_dma.c
> index f6a812e49ddc..e396a35f0e0d 100644
> --- a/drivers/dma/xilinx/zynqmp_dma.c
> +++ b/drivers/dma/xilinx/zynqmp_dma.c
> @@ -207,7 +207,6 @@ struct zynqmp_dma_desc_sw {
> * @dev: The dma device
> * @irq: Channel IRQ
> * @is_dmacoherent: Tells whether dma operations are coherent or not
> - * @tasklet: Cleanup work after irq
> * @idle : Channel status;
> * @desc_size: Size of the low level descriptor
> * @err: Channel has errors
> @@ -232,7 +231,6 @@ struct zynqmp_dma_chan {
> struct device *dev;
> int irq;
> bool is_dmacoherent;
> - struct tasklet_struct tasklet;
> bool idle;
> size_t desc_size;
> bool err;
> @@ -735,7 +733,7 @@ static irqreturn_t zynqmp_dma_irq_handler(int irq, void *data)
>
> writel(isr, chan->regs + ZYNQMP_DMA_ISR);
> if (status & ZYNQMP_DMA_INT_DONE) {
> - tasklet_schedule(&chan->tasklet);
> + dmaengine_schedule_bh(&chan->common);
> ret = IRQ_HANDLED;
> }
>
> @@ -744,7 +742,7 @@ static irqreturn_t zynqmp_dma_irq_handler(int irq, void *data)
>
> if (status & ZYNQMP_DMA_INT_ERR) {
> chan->err = true;
> - tasklet_schedule(&chan->tasklet);
> + dmaengine_schedule_bh(&chan->common);
> dev_err(chan->dev, "Channel %p has errors\n", chan);
> ret = IRQ_HANDLED;
> }
> @@ -760,11 +758,12 @@ static irqreturn_t zynqmp_dma_irq_handler(int irq, void *data)
>
> /**
> * zynqmp_dma_do_tasklet - Schedule completion tasklet
> - * @t: Pointer to the ZynqMP DMA channel structure
> + * @c: Pointer to the ZynqMP DMA channel structure
> */
> -static void zynqmp_dma_do_tasklet(struct tasklet_struct *t)
> +static void zynqmp_dma_do_tasklet(struct dma_chan *c)
> {
> - struct zynqmp_dma_chan *chan = from_tasklet(chan, t, tasklet);
> + struct zynqmp_dma_chan *chan = container_of(c,
> + struct zynqmp_dma_chan, common);
> u32 count;
> unsigned long irqflags;
>
> @@ -815,7 +814,7 @@ static void zynqmp_dma_synchronize(struct dma_chan *dchan)
> {
> struct zynqmp_dma_chan *chan = to_chan(dchan);
>
> - tasklet_kill(&chan->tasklet);
> + dmaengine_kill_bh(&chan->common);
> }
>
> /**
> @@ -887,7 +886,7 @@ static void zynqmp_dma_chan_remove(struct zynqmp_dma_chan *chan)
>
> if (chan->irq)
> devm_free_irq(chan->zdev->dev, chan->irq, chan);
> - tasklet_kill(&chan->tasklet);
> + dmaengine_kill_bh(&chan->common);
> list_del(&chan->common.device_node);
> }
>
> @@ -937,7 +936,7 @@ static int zynqmp_dma_chan_probe(struct zynqmp_dma_device *zdev,
>
> chan->is_dmacoherent = of_property_read_bool(node, "dma-coherent");
> zdev->chan = chan;
> - tasklet_setup(&chan->tasklet, zynqmp_dma_do_tasklet);
> + dmaengine_init_bh(&chan->common, zynqmp_dma_do_tasklet);
> spin_lock_init(&chan->lock);
> INIT_LIST_HEAD(&chan->active_list);
> INIT_LIST_HEAD(&chan->pending_list);
> --
> 2.43.0
>