[PATCH v3 21/34] dmaengine: zynqmp-dma: switch completion tasklet to dmaengine BH

Frank Li Frank.li at oss.nxp.com
Wed Sep 2 08:30:51 PDT 2026


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 at gmail.com>
> ---

Reviewed-by: Frank Li <Frank.Li at nxp.com>

>  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
>



More information about the linux-arm-kernel mailing list