All of lore.kernel.org
 help / color / mirror / Atom feed
From: Frank Li <Frank.li@oss.nxp.com>
To: Allen Pais <allen.lkml@gmail.com>
Cc: "Vinod Koul" <vkoul@kernel.org>, "Frank Li" <Frank.Li@kernel.org>,
	dmaengine@vger.kernel.org, linux-kernel@vger.kernel.org,
	"Arnd Bergmann" <arnd@arndb.de>, "Kees Cook" <kees@kernel.org>,
	"Florian Fainelli" <florian.fainelli@broadcom.com>,
	"Ray Jui" <rjui@broadcom.com>,
	"Scott Branden" <sbranden@broadcom.com>,
	"Broadcom internal kernel review list"
	<bcm-kernel-feedback-list@broadcom.com>,
	"Lars-Peter Clausen" <lars@metafoo.de>,
	"Paul Cercueil" <paul@crapouillou.net>,
	"Eugeniy Paltsev" <Eugeniy.Paltsev@synopsys.com>,
	"Manivannan Sadhasivam" <mani@kernel.org>,
	"Zhou Wang" <wangzhou1@hisilicon.com>,
	"Longfang Liu" <liulongfang@huawei.com>,
	"Andy Shevchenko" <andy@kernel.org>,
	"Sascha Hauer" <s.hauer@pengutronix.de>,
	"Pengutronix Kernel Team" <kernel@pengutronix.de>,
	"Fabio Estevam" <festevam@gmail.com>,
	"Keguang Zhang" <keguang.zhang@gmail.com>,
	"Sean Wang" <sean.wang@mediatek.com>,
	"Matthias Brugger" <matthias.bgg@gmail.com>,
	"AngeloGioacchino Del Regno"
	<angelogioacchino.delregno@collabora.com>,
	"Andreas Färber" <afaerber@suse.de>,
	"Daniel Mack" <daniel@zonque.org>,
	"Haojian Zhuang" <haojian.zhuang@gmail.com>,
	"Robert Jarzmik" <robert.jarzmik@free.fr>,
	"Paul Walmsley" <pjw@kernel.org>,
	"Samuel Holland" <samuel.holland@sifive.com>,
	"Orson Zhai" <orsonzhai@gmail.com>,
	"Baolin Wang" <baolin.wang@linux.alibaba.com>,
	"Chunyan Zhang" <zhang.lyra@gmail.com>,
	"Patrice Chotard" <patrice.chotard@foss.st.com>,
	"Chen-Yu Tsai" <wens@kernel.org>,
	"Jernej Skrabec" <jernej.skrabec@gmail.com>,
	"Laxman Dewangan" <ldewangan@nvidia.com>,
	"Jon Hunter" <jonathanh@nvidia.com>,
	"Thierry Reding" <thierry.reding@kernel.org>,
	"Vignesh Raghavendra" <vigneshr@ti.com>,
	"Bartosz Golaszewski" <brgl@kernel.org>,
	"Konrad Dybcio" <konrad.dybcio@oss.qualcomm.com>,
	"Bjorn Andersson" <andersson@kernel.org>,
	"Kuldeep Singh" <kuldeep.singh@oss.qualcomm.com>,
	"Stephan Gerhold" <stephan.gerhold@linaro.org>,
	linux-rpi-kernel@lists.infradead.org,
	linux-arm-kernel@lists.infradead.org, linux-mips@vger.kernel.org,
	imx@lists.linux.dev, linux-mediatek@lists.infradead.org,
	linux-actions@lists.infradead.org, linux-arm-msm@vger.kernel.org,
	linux-riscv@lists.infradead.org, linux-sunxi@lists.linux.dev,
	linux-tegra@vger.kernel.org
Subject: Re: [PATCH v3 01/34] dmaengine: add tasklet-backed channel BH helpers
Date: Tue, 1 Sep 2026 18:13:16 -0400	[thread overview]
Message-ID: <apdN_G_1M4e81gQd@lizhi-Precision-Tower-5810> (raw)
In-Reply-To: <2c62c39cafc0df59eb5381d3da82b1616a58fa20.1786384168.git.allen.lkml@gmail.com>

On Mon, Aug 10, 2026 at 11:09:02AM -0700, Allen Pais wrote:
> DMAengine drivers commonly use a per-channel tasklet to invoke client
> callbacks. Add helpers that initialize, schedule, and kill a channel
> bottom half, with an initial tasklet-backed implementation that preserves
> the existing execution context.
>
> Convert virt-dma to the new API and remove its private tasklet. Update all
> drivers that directly kill or override that tasklet in the same change so
> no stale users remain. While touching the completion handler, avoid forming
> a result pointer from a NULL cyclic descriptor.
>
> This establishes a backend-independent API before changing how channel
> bottom halves are dispatched.
>
> Signed-off-by: Allen Pais <allen.lkml@gmail.com>
> ---

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

>  drivers/dma/bcm2835-dma.c                     |  2 +-
>  drivers/dma/dma-axi-dmac.c                    | 10 +++--
>  drivers/dma/dma-jz4780.c                      |  2 +-
>  drivers/dma/dmaengine.c                       | 42 +++++++++++++++++++
>  .../dma/dw-axi-dmac/dw-axi-dmac-platform.c    |  2 +-
>  drivers/dma/dw-edma/dw-edma-core.c            |  2 +-
>  drivers/dma/fsl-edma-common.c                 |  2 +-
>  drivers/dma/fsl-qdma.c                        |  2 +-
>  drivers/dma/hisi_dma.c                        |  2 +-
>  drivers/dma/hsu/hsu.c                         |  2 +-
>  drivers/dma/idma64.c                          |  4 +-
>  drivers/dma/img-mdc-dma.c                     |  2 +-
>  drivers/dma/imx-sdma.c                        |  4 +-
>  drivers/dma/k3dma.c                           |  2 +-
>  drivers/dma/loongson/loongson1-apb-dma.c      |  2 +-
>  drivers/dma/mediatek/mtk-cqdma.c              |  2 +-
>  drivers/dma/mediatek/mtk-hsdma.c              |  2 +-
>  drivers/dma/mediatek/mtk-uart-apdma.c         |  4 +-
>  drivers/dma/owl-dma.c                         |  2 +-
>  drivers/dma/pxa_dma.c                         |  2 +-
>  drivers/dma/qcom/bam_dma.c                    |  4 +-
>  drivers/dma/qcom/qcom_adm.c                   |  4 +-
>  drivers/dma/sa11x0-dma.c                      |  2 +-
>  drivers/dma/sf-pdma/sf-pdma.c                 |  2 +-
>  drivers/dma/sprd-dma.c                        |  2 +-
>  drivers/dma/st_fdma.c                         |  2 +-
>  drivers/dma/sun6i-dma.c                       |  2 +-
>  drivers/dma/tegra186-gpc-dma.c                |  2 +-
>  drivers/dma/tegra210-adma.c                   |  2 +-
>  drivers/dma/ti/edma.c                         |  2 +-
>  drivers/dma/ti/k3-udma.c                      | 12 +++---
>  drivers/dma/ti/omap-dma.c                     |  2 +-
>  drivers/dma/virt-dma.c                        | 12 +++---
>  drivers/dma/virt-dma.h                        |  7 ++--
>  include/linux/dmaengine.h                     | 28 +++++++++++++
>  35 files changed, 125 insertions(+), 54 deletions(-)
>
> diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c
> index 06d830d36882..c8add249dbfb 100644
> --- a/drivers/dma/bcm2835-dma.c
> +++ b/drivers/dma/bcm2835-dma.c
> @@ -829,7 +829,7 @@ static void bcm2835_dma_free(struct bcm2835_dmadev *od)
>  	list_for_each_entry_safe(c, next, &od->ddev.channels,
>  				 vc.chan.device_node) {
>  		list_del(&c->vc.chan.device_node);
> -		tasklet_kill(&c->vc.task);
> +		dmaengine_kill_bh(&c->vc.chan);
>  	}
>
>  	dma_unmap_page_attrs(od->ddev.dev, od->zero_page, PAGE_SIZE,
> diff --git a/drivers/dma/dma-axi-dmac.c b/drivers/dma/dma-axi-dmac.c
> index d47ff27e1408..d245d04c3a27 100644
> --- a/drivers/dma/dma-axi-dmac.c
> +++ b/drivers/dma/dma-axi-dmac.c
> @@ -1195,9 +1195,11 @@ static int axi_dmac_detect_caps(struct axi_dmac *dmac, unsigned int version)
>  	return 0;
>  }
>
> -static void axi_dmac_tasklet_kill(void *task)
> +static void axi_dmac_kill_bh(void *data)
>  {
> -	tasklet_kill(task);
> +	struct dma_chan *chan = data;
> +
> +	dmaengine_kill_bh(chan);
>  }
>
>  static void axi_dmac_free_dma_controller(void *of_node)
> @@ -1302,8 +1304,8 @@ static int axi_dmac_probe(struct platform_device *pdev)
>  	 * Put the action in here so it get's done before unregistering the DMA
>  	 * device.
>  	 */
> -	ret = devm_add_action_or_reset(&pdev->dev, axi_dmac_tasklet_kill,
> -				       &dmac->chan.vchan.task);
> +	ret = devm_add_action_or_reset(&pdev->dev, axi_dmac_kill_bh,
> +				       &dmac->chan.vchan.chan);
>  	if (ret)
>  		return ret;
>
> diff --git a/drivers/dma/dma-jz4780.c b/drivers/dma/dma-jz4780.c
> index 6070dfdb7114..738801501e29 100644
> --- a/drivers/dma/dma-jz4780.c
> +++ b/drivers/dma/dma-jz4780.c
> @@ -1019,7 +1019,7 @@ static void jz4780_dma_remove(struct platform_device *pdev)
>  	free_irq(jzdma->irq, jzdma);
>
>  	for (i = 0; i < jzdma->soc_data->nb_channels; i++)
> -		tasklet_kill(&jzdma->chan[i].vchan.task);
> +		dmaengine_kill_bh(&jzdma->chan[i].vchan.chan);
>  }
>
>  static const struct jz4780_dma_soc_data jz4740_dma_soc_data = {
> diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
> index 9049171df857..d8fc7eb71b48 100644
> --- a/drivers/dma/dmaengine.c
> +++ b/drivers/dma/dmaengine.c
> @@ -1428,6 +1428,48 @@ static void dmaengine_destroy_unmap_pool(void)
>  	}
>  }
>
> +static void dma_chan_bh_entry(struct tasklet_struct *tasklet)
> +{
> +	struct dma_chan *chan = from_tasklet(chan, tasklet, bh_tasklet);
> +	dmaengine_bh_work_fn fn = READ_ONCE(chan->bh_work_fn);
> +
> +	if (fn)
> +		fn(chan);
> +}
> +
> +void dmaengine_init_bh(struct dma_chan *chan, dmaengine_bh_work_fn fn)
> +{
> +	if (WARN_ON(!fn))
> +		return;
> +
> +	if (WARN_ON(chan->bh_work_initialized))
> +		return;
> +
> +	chan->bh_work_fn = fn;
> +	tasklet_setup(&chan->bh_tasklet, dma_chan_bh_entry);
> +	chan->bh_work_initialized = true;
> +}
> +EXPORT_SYMBOL_GPL(dmaengine_init_bh);
> +
> +bool dmaengine_schedule_bh(struct dma_chan *chan)
> +{
> +	if (WARN_ON(!chan->bh_work_initialized))
> +		return false;
> +
> +	tasklet_schedule(&chan->bh_tasklet);
> +	return true;
> +}
> +EXPORT_SYMBOL_GPL(dmaengine_schedule_bh);
> +
> +void dmaengine_kill_bh(struct dma_chan *chan)
> +{
> +	if (!chan->bh_work_initialized)
> +		return;
> +
> +	tasklet_kill(&chan->bh_tasklet);
> +}
> +EXPORT_SYMBOL_GPL(dmaengine_kill_bh);
> +
>  static int __init dmaengine_init_unmap_pool(void)
>  {
>  	int i;
> diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
> index bcefaff03b5c..a2b688e7f47e 100644
> --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
> +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
> @@ -1663,7 +1663,7 @@ static void dw_remove(struct platform_device *pdev)
>  	list_for_each_entry_safe(chan, _chan, &dw->dma.channels,
>  				 vc.chan.device_node) {
>  		list_del(&chan->vc.chan.device_node);
> -		tasklet_kill(&chan->vc.task);
> +		dmaengine_kill_bh(&chan->vc.chan);
>  	}
>  }
>
> diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-edma-core.c
> index 89a4c498a17b..ade866fba2ad 100644
> --- a/drivers/dma/dw-edma/dw-edma-core.c
> +++ b/drivers/dma/dw-edma/dw-edma-core.c
> @@ -1170,7 +1170,7 @@ int dw_edma_remove(struct dw_edma_chip *chip)
>  	dma_async_device_unregister(&dw->dma);
>  	list_for_each_entry_safe(chan, _chan, &dw->dma.channels,
>  				 vc.chan.device_node) {
> -		tasklet_kill(&chan->vc.task);
> +		dmaengine_kill_bh(&chan->vc.chan);
>  		list_del(&chan->vc.chan.device_node);
>  	}
>
> diff --git a/drivers/dma/fsl-edma-common.c b/drivers/dma/fsl-edma-common.c
> index bb7531c456df..90ae678c68d4 100644
> --- a/drivers/dma/fsl-edma-common.c
> +++ b/drivers/dma/fsl-edma-common.c
> @@ -915,7 +915,7 @@ void fsl_edma_cleanup_vchan(struct dma_device *dmadev)
>  	list_for_each_entry_safe(chan, _chan,
>  				&dmadev->channels, vchan.chan.device_node) {
>  		list_del(&chan->vchan.chan.device_node);
> -		tasklet_kill(&chan->vchan.task);
> +		dmaengine_kill_bh(&chan->vchan.chan);
>  	}
>  }
>
> diff --git a/drivers/dma/fsl-qdma.c b/drivers/dma/fsl-qdma.c
> index df843fad0ece..b0ace8bad498 100644
> --- a/drivers/dma/fsl-qdma.c
> +++ b/drivers/dma/fsl-qdma.c
> @@ -1255,7 +1255,7 @@ static void fsl_qdma_cleanup_vchan(struct dma_device *dmadev)
>  	list_for_each_entry_safe(chan, _chan,
>  				 &dmadev->channels, vchan.chan.device_node) {
>  		list_del(&chan->vchan.chan.device_node);
> -		tasklet_kill(&chan->vchan.task);
> +		dmaengine_kill_bh(&chan->vchan.chan);
>  	}
>  }
>
> diff --git a/drivers/dma/hisi_dma.c b/drivers/dma/hisi_dma.c
> index 28bf818f9aa6..10eb98350b9f 100644
> --- a/drivers/dma/hisi_dma.c
> +++ b/drivers/dma/hisi_dma.c
> @@ -720,7 +720,7 @@ static void hisi_dma_disable_qps(struct hisi_dma_dev *hdma_dev)
>
>  	for (i = 0; i < hdma_dev->chan_num; i++) {
>  		hisi_dma_disable_qp(hdma_dev, i);
> -		tasklet_kill(&hdma_dev->chan[i].vc.task);
> +		dmaengine_kill_bh(&hdma_dev->chan[i].vc.chan);
>  	}
>  }
>
> diff --git a/drivers/dma/hsu/hsu.c b/drivers/dma/hsu/hsu.c
> index f62d60d7bc6b..315d0ebecd57 100644
> --- a/drivers/dma/hsu/hsu.c
> +++ b/drivers/dma/hsu/hsu.c
> @@ -500,7 +500,7 @@ int hsu_dma_remove(struct hsu_dma_chip *chip)
>  	for (i = 0; i < hsu->nr_channels; i++) {
>  		struct hsu_dma_chan *hsuc = &hsu->chan[i];
>
> -		tasklet_kill(&hsuc->vchan.task);
> +		dmaengine_kill_bh(&hsuc->vchan.chan);
>  	}
>
>  	return 0;
> diff --git a/drivers/dma/idma64.c b/drivers/dma/idma64.c
> index 5fcd1befc92d..1d395fb735ff 100644
> --- a/drivers/dma/idma64.c
> +++ b/drivers/dma/idma64.c
> @@ -617,14 +617,14 @@ static void idma64_remove(struct idma64_chip *chip)
>
>  	/*
>  	 * Explicitly call devm_request_irq() to avoid the side effects with
> -	 * the scheduled tasklets.
> +	 * scheduled BH work.
>  	 */
>  	devm_free_irq(chip->dev, chip->irq, idma64);
>
>  	for (i = 0; i < idma64->dma.chancnt; i++) {
>  		struct idma64_chan *idma64c = &idma64->chan[i];
>
> -		tasklet_kill(&idma64c->vchan.task);
> +		dmaengine_kill_bh(&idma64c->vchan.chan);
>  	}
>  }
>
> diff --git a/drivers/dma/img-mdc-dma.c b/drivers/dma/img-mdc-dma.c
> index b3765ba15803..0c6024088444 100644
> --- a/drivers/dma/img-mdc-dma.c
> +++ b/drivers/dma/img-mdc-dma.c
> @@ -1031,7 +1031,7 @@ static void mdc_dma_remove(struct platform_device *pdev)
>
>  		devm_free_irq(&pdev->dev, mchan->irq, mchan);
>
> -		tasklet_kill(&mchan->vc.task);
> +		dmaengine_kill_bh(&mchan->vc.chan);
>  	}
>
>  	pm_runtime_disable(&pdev->dev);
> diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
> index 36368835a845..4d13b9d2880d 100644
> --- a/drivers/dma/imx-sdma.c
> +++ b/drivers/dma/imx-sdma.c
> @@ -2399,11 +2399,11 @@ static void sdma_remove(struct platform_device *pdev)
>  	int i;
>
>  	devm_free_irq(&pdev->dev, sdma->irq, sdma);
> -	/* Kill the tasklet */
> +	/* Kill the channel BH */
>  	for (i = 0; i < MAX_DMA_CHANNELS; i++) {
>  		struct sdma_channel *sdmac = &sdma->channel[i];
>
> -		tasklet_kill(&sdmac->vc.task);
> +		dmaengine_kill_bh(&sdmac->vc.chan);
>  		sdma_free_chan_resources(&sdmac->vc.chan);
>  	}
>
> diff --git a/drivers/dma/k3dma.c b/drivers/dma/k3dma.c
> index e84f197fea76..3d73b391e42e 100644
> --- a/drivers/dma/k3dma.c
> +++ b/drivers/dma/k3dma.c
> @@ -976,7 +976,7 @@ static void k3_dma_remove(struct platform_device *op)
>
>  	list_for_each_entry_safe(c, cn, &d->slave.channels, vc.chan.device_node) {
>  		list_del(&c->vc.chan.device_node);
> -		tasklet_kill(&c->vc.task);
> +		dmaengine_kill_bh(&c->vc.chan);
>  	}
>  	tasklet_kill(&d->task);
>  	clk_disable_unprepare(d->clk);
> diff --git a/drivers/dma/loongson/loongson1-apb-dma.c b/drivers/dma/loongson/loongson1-apb-dma.c
> index 89786cbd20ab..52a360719644 100644
> --- a/drivers/dma/loongson/loongson1-apb-dma.c
> +++ b/drivers/dma/loongson/loongson1-apb-dma.c
> @@ -552,7 +552,7 @@ static void ls1x_dma_chan_remove(struct ls1x_dma *dma)
>
>  		if (chan->vc.chan.device == &dma->ddev) {
>  			list_del(&chan->vc.chan.device_node);
> -			tasklet_kill(&chan->vc.task);
> +			dmaengine_kill_bh(&chan->vc.chan);
>  		}
>  	}
>  }
> diff --git a/drivers/dma/mediatek/mtk-cqdma.c b/drivers/dma/mediatek/mtk-cqdma.c
> index 80791e30aec2..7b44d3358cda 100644
> --- a/drivers/dma/mediatek/mtk-cqdma.c
> +++ b/drivers/dma/mediatek/mtk-cqdma.c
> @@ -895,7 +895,7 @@ static void mtk_cqdma_remove(struct platform_device *pdev)
>  		vc = &cqdma->vc[i];
>
>  		list_del(&vc->vc.chan.device_node);
> -		tasklet_kill(&vc->vc.task);
> +		dmaengine_kill_bh(&vc->vc.chan);
>  	}
>
>  	/* disable interrupt */
> diff --git a/drivers/dma/mediatek/mtk-hsdma.c b/drivers/dma/mediatek/mtk-hsdma.c
> index a43412ff5edd..75555fa41536 100644
> --- a/drivers/dma/mediatek/mtk-hsdma.c
> +++ b/drivers/dma/mediatek/mtk-hsdma.c
> @@ -1020,7 +1020,7 @@ static void mtk_hsdma_remove(struct platform_device *pdev)
>  		vc = &hsdma->vc[i];
>
>  		list_del(&vc->vc.chan.device_node);
> -		tasklet_kill(&vc->vc.task);
> +		dmaengine_kill_bh(&vc->vc.chan);
>  	}
>
>  	/* Disable DMA interrupt */
> diff --git a/drivers/dma/mediatek/mtk-uart-apdma.c b/drivers/dma/mediatek/mtk-uart-apdma.c
> index c269d84d7bd2..8ce206a0ecc5 100644
> --- a/drivers/dma/mediatek/mtk-uart-apdma.c
> +++ b/drivers/dma/mediatek/mtk-uart-apdma.c
> @@ -312,7 +312,7 @@ static void mtk_uart_apdma_free_chan_resources(struct dma_chan *chan)
>
>  	free_irq(c->irq, chan);
>
> -	tasklet_kill(&c->vc.task);
> +	dmaengine_kill_bh(&c->vc.chan);
>
>  	vchan_free_chan_resources(&c->vc);
>
> @@ -463,7 +463,7 @@ static void mtk_uart_apdma_free(struct mtk_uart_apdmadev *mtkd)
>  			struct mtk_chan, vc.chan.device_node);
>
>  		list_del(&c->vc.chan.device_node);
> -		tasklet_kill(&c->vc.task);
> +		dmaengine_kill_bh(&c->vc.chan);
>  	}
>  }
>
> diff --git a/drivers/dma/owl-dma.c b/drivers/dma/owl-dma.c
> index 7c80572fc71d..0d9f324adba0 100644
> --- a/drivers/dma/owl-dma.c
> +++ b/drivers/dma/owl-dma.c
> @@ -1055,7 +1055,7 @@ static inline void owl_dma_free(struct owl_dma *od)
>  	list_for_each_entry_safe(vchan,
>  				 next, &od->dma.channels, vc.chan.device_node) {
>  		list_del(&vchan->vc.chan.device_node);
> -		tasklet_kill(&vchan->vc.task);
> +		dmaengine_kill_bh(&vchan->vc.chan);
>  	}
>  }
>
> diff --git a/drivers/dma/pxa_dma.c b/drivers/dma/pxa_dma.c
> index fa2ee0b3e09f..2cca8c31929c 100644
> --- a/drivers/dma/pxa_dma.c
> +++ b/drivers/dma/pxa_dma.c
> @@ -1215,7 +1215,7 @@ static void pxad_free_channels(struct dma_device *dmadev)
>  	list_for_each_entry_safe(c, cn, &dmadev->channels,
>  				 vc.chan.device_node) {
>  		list_del(&c->vc.chan.device_node);
> -		tasklet_kill(&c->vc.task);
> +		dmaengine_kill_bh(&c->vc.chan);
>  	}
>  }
>
> diff --git a/drivers/dma/qcom/bam_dma.c b/drivers/dma/qcom/bam_dma.c
> index 1bb26af0405f..c23496c3ac69 100644
> --- a/drivers/dma/qcom/bam_dma.c
> +++ b/drivers/dma/qcom/bam_dma.c
> @@ -1387,7 +1387,7 @@ static int bam_dma_probe(struct platform_device *pdev)
>  	dma_async_device_unregister(&bdev->common);
>  err_bam_channel_exit:
>  	for (i = 0; i < bdev->num_channels; i++)
> -		tasklet_kill(&bdev->channels[i].vc.task);
> +		dmaengine_kill_bh(&bdev->channels[i].vc.chan);
>  err_tasklet_kill:
>  	tasklet_kill(&bdev->task);
>  err_disable_clk:
> @@ -1413,7 +1413,7 @@ static void bam_dma_remove(struct platform_device *pdev)
>
>  	for (i = 0; i < bdev->num_channels; i++) {
>  		bam_dma_terminate_all(&bdev->channels[i].vc.chan);
> -		tasklet_kill(&bdev->channels[i].vc.task);
> +		dmaengine_kill_bh(&bdev->channels[i].vc.chan);
>
>  		if (!bdev->channels[i].fifo_virt)
>  			continue;
> diff --git a/drivers/dma/qcom/qcom_adm.c b/drivers/dma/qcom/qcom_adm.c
> index 07fbe32d31fa..13f5ca8ff808 100644
> --- a/drivers/dma/qcom/qcom_adm.c
> +++ b/drivers/dma/qcom/qcom_adm.c
> @@ -918,8 +918,8 @@ static void adm_dma_remove(struct platform_device *pdev)
>  		/* mask IRQs for this channel/EE pair */
>  		writel(0, adev->regs + ADM_CH_RSLT_CONF(achan->id, adev->ee));
>
> -		tasklet_kill(&adev->channels[i].vc.task);
> -		adm_terminate_all(&adev->channels[i].vc.chan);
> +		dmaengine_kill_bh(&achan->vc.chan);
> +		adm_terminate_all(&achan->vc.chan);
>  	}
>
>  	devm_free_irq(adev->dev, adev->irq, adev);
> diff --git a/drivers/dma/sa11x0-dma.c b/drivers/dma/sa11x0-dma.c
> index a6fa431530e3..e14566fa2d74 100644
> --- a/drivers/dma/sa11x0-dma.c
> +++ b/drivers/dma/sa11x0-dma.c
> @@ -891,7 +891,7 @@ static void sa11x0_dma_free_channels(struct dma_device *dmadev)
>
>  	list_for_each_entry_safe(c, cn, &dmadev->channels, vc.chan.device_node) {
>  		list_del(&c->vc.chan.device_node);
> -		tasklet_kill(&c->vc.task);
> +		dmaengine_kill_bh(&c->vc.chan);
>  		kfree(c);
>  	}
>  }
> diff --git a/drivers/dma/sf-pdma/sf-pdma.c b/drivers/dma/sf-pdma/sf-pdma.c
> index 6f79cc28703e..a08ca355dadb 100644
> --- a/drivers/dma/sf-pdma/sf-pdma.c
> +++ b/drivers/dma/sf-pdma/sf-pdma.c
> @@ -602,7 +602,7 @@ static void sf_pdma_remove(struct platform_device *pdev)
>  		devm_free_irq(&pdev->dev, ch->txirq, ch);
>  		devm_free_irq(&pdev->dev, ch->errirq, ch);
>  		list_del(&ch->vchan.chan.device_node);
> -		tasklet_kill(&ch->vchan.task);
> +		dmaengine_kill_bh(&ch->vchan.chan);
>  		tasklet_kill(&ch->done_tasklet);
>  		tasklet_kill(&ch->err_tasklet);
>  	}
> diff --git a/drivers/dma/sprd-dma.c b/drivers/dma/sprd-dma.c
> index 087fea3af2e4..f90f5d8d5a1e 100644
> --- a/drivers/dma/sprd-dma.c
> +++ b/drivers/dma/sprd-dma.c
> @@ -1253,7 +1253,7 @@ static void sprd_dma_remove(struct platform_device *pdev)
>  	list_for_each_entry_safe(c, cn, &sdev->dma_dev.channels,
>  				 vc.chan.device_node) {
>  		list_del(&c->vc.chan.device_node);
> -		tasklet_kill(&c->vc.task);
> +		dmaengine_kill_bh(&c->vc.chan);
>  	}
>
>  	of_dma_controller_free(pdev->dev.of_node);
> diff --git a/drivers/dma/st_fdma.c b/drivers/dma/st_fdma.c
> index d9547017f3bd..cae0a7fe6ceb 100644
> --- a/drivers/dma/st_fdma.c
> +++ b/drivers/dma/st_fdma.c
> @@ -733,7 +733,7 @@ static void st_fdma_free(struct st_fdma_dev *fdev)
>  	for (i = 0; i < fdev->nr_channels; i++) {
>  		fchan = &fdev->chans[i];
>  		list_del(&fchan->vchan.chan.device_node);
> -		tasklet_kill(&fchan->vchan.task);
> +		dmaengine_kill_bh(&fchan->vchan.chan);
>  	}
>  }
>
> diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
> index f47a326dd7ff..4ddea3cdcd66 100644
> --- a/drivers/dma/sun6i-dma.c
> +++ b/drivers/dma/sun6i-dma.c
> @@ -1094,7 +1094,7 @@ static inline void sun6i_dma_free(struct sun6i_dma_dev *sdev)
>  		struct sun6i_vchan *vchan = &sdev->vchans[i];
>
>  		list_del(&vchan->vc.chan.device_node);
> -		tasklet_kill(&vchan->vc.task);
> +		dmaengine_kill_bh(&vchan->vc.chan);
>  	}
>  }
>
> diff --git a/drivers/dma/tegra186-gpc-dma.c b/drivers/dma/tegra186-gpc-dma.c
> index 64cedef1050a..3a27a83a3288 100644
> --- a/drivers/dma/tegra186-gpc-dma.c
> +++ b/drivers/dma/tegra186-gpc-dma.c
> @@ -1284,7 +1284,7 @@ static void tegra_dma_free_chan_resources(struct dma_chan *dc)
>  	tegra_dma_terminate_all(dc);
>  	synchronize_irq(tdc->irq);
>
> -	tasklet_kill(&tdc->vc.task);
> +	dmaengine_kill_bh(&tdc->vc.chan);
>  	tdc->config_init = false;
>  	tdc->slave_id = -1;
>  	tdc->sid_dir = DMA_TRANS_NONE;
> diff --git a/drivers/dma/tegra210-adma.c b/drivers/dma/tegra210-adma.c
> index ceaee1e33e68..780863199224 100644
> --- a/drivers/dma/tegra210-adma.c
> +++ b/drivers/dma/tegra210-adma.c
> @@ -811,7 +811,7 @@ static void tegra_adma_free_chan_resources(struct dma_chan *dc)
>
>  	tegra_adma_terminate_all(dc);
>  	vchan_free_chan_resources(&tdc->vc);
> -	tasklet_kill(&tdc->vc.task);
> +	dmaengine_kill_bh(&tdc->vc.chan);
>  	free_irq(tdc->irq, tdc);
>  	pm_runtime_put(tdc2dev(tdc));
>
> diff --git a/drivers/dma/ti/edma.c b/drivers/dma/ti/edma.c
> index d97db5af3555..c0ad0cdabb87 100644
> --- a/drivers/dma/ti/edma.c
> +++ b/drivers/dma/ti/edma.c
> @@ -2560,7 +2560,7 @@ static void edma_cleanupp_vchan(struct dma_device *dmadev)
>  	list_for_each_entry_safe(echan, _echan,
>  			&dmadev->channels, vchan.chan.device_node) {
>  		list_del(&echan->vchan.chan.device_node);
> -		tasklet_kill(&echan->vchan.task);
> +		dmaengine_kill_bh(&echan->vchan.chan);
>  	}
>  }
>
> diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c
> index 1cf158eb7bdb..fd428c26799a 100644
> --- a/drivers/dma/ti/k3-udma.c
> +++ b/drivers/dma/ti/k3-udma.c
> @@ -4042,12 +4042,12 @@ static void udma_desc_pre_callback(struct virt_dma_chan *vc,
>  }
>
>  /*
> - * This tasklet handles the completion of a DMA descriptor by
> + * This BH handles the completion of a DMA descriptor by
>   * calling its callback and freeing it.
>   */
> -static void udma_vchan_complete(struct tasklet_struct *t)
> +static void udma_vchan_complete(struct dma_chan *chan)
>  {
> -	struct virt_dma_chan *vc = from_tasklet(vc, t, task);
> +	struct virt_dma_chan *vc = to_virt_chan(chan);
>  	struct virt_dma_desc *vd, *_vd;
>  	struct dmaengine_desc_callback cb;
>  	LIST_HEAD(head);
> @@ -4112,7 +4112,7 @@ static void udma_free_chan_resources(struct dma_chan *chan)
>  	}
>
>  	vchan_free_chan_resources(&uc->vc);
> -	tasklet_kill(&uc->vc.task);
> +	dmaengine_kill_bh(&uc->vc.chan);
>
>  	bcdma_free_bchan_resources(uc);
>  	udma_free_tx_resources(uc);
> @@ -5627,8 +5627,8 @@ static int udma_probe(struct platform_device *pdev)
>  		if (!uc->name)
>  			return -ENOMEM;
>  		vchan_init(&uc->vc, &ud->ddev);
> -		/* Use custom vchan completion handling */
> -		tasklet_setup(&uc->vc.task, udma_vchan_complete);
> +		/* Override the default vchan completion handler */
> +		uc->vc.chan.bh_work_fn = udma_vchan_complete;
>  		init_completion(&uc->teardown_completed);
>  		INIT_DELAYED_WORK(&uc->tx_drain.work, udma_check_tx_completion);
>  	}
> diff --git a/drivers/dma/ti/omap-dma.c b/drivers/dma/ti/omap-dma.c
> index 55ece7fd0d99..899c5eeeac88 100644
> --- a/drivers/dma/ti/omap-dma.c
> +++ b/drivers/dma/ti/omap-dma.c
> @@ -1521,7 +1521,7 @@ static void omap_dma_free(struct omap_dmadev *od)
>  			struct omap_chan, vc.chan.device_node);
>
>  		list_del(&c->vc.chan.device_node);
> -		tasklet_kill(&c->vc.task);
> +		dmaengine_kill_bh(&c->vc.chan);
>  		kfree(c);
>  	}
>  }
> diff --git a/drivers/dma/virt-dma.c b/drivers/dma/virt-dma.c
> index 7961172a780d..d407af6cc1da 100644
> --- a/drivers/dma/virt-dma.c
> +++ b/drivers/dma/virt-dma.c
> @@ -77,12 +77,12 @@ struct virt_dma_desc *vchan_find_desc(struct virt_dma_chan *vc,
>  EXPORT_SYMBOL_GPL(vchan_find_desc);
>
>  /*
> - * This tasklet handles the completion of a DMA descriptor by
> - * calling its callback and freeing it.
> + * This bottom-half handler completes a DMA descriptor by invoking its
> + * callback and freeing it.
>   */
> -static void vchan_complete(struct tasklet_struct *t)
> +static void vchan_complete(struct dma_chan *chan)
>  {
> -	struct virt_dma_chan *vc = from_tasklet(vc, t, task);
> +	struct virt_dma_chan *vc = to_virt_chan(chan);
>  	struct virt_dma_desc *vd, *_vd;
>  	struct dmaengine_desc_callback cb;
>  	LIST_HEAD(head);
> @@ -98,7 +98,7 @@ static void vchan_complete(struct tasklet_struct *t)
>  	}
>  	spin_unlock_irq(&vc->lock);
>
> -	dmaengine_desc_callback_invoke(&cb, &vd->tx_result);
> +	dmaengine_desc_callback_invoke(&cb, vd ? &vd->tx_result : NULL);
>
>  	list_for_each_entry_safe(vd, _vd, &head, node) {
>  		dmaengine_desc_get_callback(&vd->tx, &cb);
> @@ -131,7 +131,7 @@ void vchan_init(struct virt_dma_chan *vc, struct dma_device *dmadev)
>  	INIT_LIST_HEAD(&vc->desc_completed);
>  	INIT_LIST_HEAD(&vc->desc_terminated);
>
> -	tasklet_setup(&vc->task, vchan_complete);
> +	dmaengine_init_bh(&vc->chan, vchan_complete);
>
>  	vc->chan.device = dmadev;
>  	list_add_tail(&vc->chan.device_node, &dmadev->channels);
> diff --git a/drivers/dma/virt-dma.h b/drivers/dma/virt-dma.h
> index 59d9eabc8b67..0ba42fded2cc 100644
> --- a/drivers/dma/virt-dma.h
> +++ b/drivers/dma/virt-dma.h
> @@ -21,7 +21,6 @@ struct virt_dma_desc {
>
>  struct virt_dma_chan {
>  	struct dma_chan	chan;
> -	struct tasklet_struct task;
>  	void (*desc_free)(struct virt_dma_desc *);
>
>  	spinlock_t lock;
> @@ -106,7 +105,7 @@ static inline void vchan_cookie_complete(struct virt_dma_desc *vd)
>  		 vd, cookie);
>  	list_add_tail(&vd->node, &vc->desc_completed);
>
> -	tasklet_schedule(&vc->task);
> +	dmaengine_schedule_bh(&vc->chan);
>  }
>
>  /**
> @@ -137,7 +136,7 @@ static inline void vchan_cyclic_callback(struct virt_dma_desc *vd)
>  	struct virt_dma_chan *vc = to_virt_chan(vd->tx.chan);
>
>  	vc->cyclic = vd;
> -	tasklet_schedule(&vc->task);
> +	dmaengine_schedule_bh(&vc->chan);
>  }
>
>  /**
> @@ -223,7 +222,7 @@ static inline void vchan_synchronize(struct virt_dma_chan *vc)
>  	LIST_HEAD(head);
>  	unsigned long flags;
>
> -	tasklet_kill(&vc->task);
> +	dmaengine_kill_bh(&vc->chan);
>
>  	spin_lock_irqsave(&vc->lock, flags);
>
> diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
> index b3d251c9734e..a1437bdbda9b 100644
> --- a/include/linux/dmaengine.h
> +++ b/include/linux/dmaengine.h
> @@ -12,6 +12,7 @@
>  #include <linux/scatterlist.h>
>  #include <linux/bitmap.h>
>  #include <linux/types.h>
> +#include <linux/interrupt.h>
>  #include <asm/page.h>
>
>  /**
> @@ -295,6 +296,10 @@ enum dma_desc_metadata_mode {
>  	DESC_METADATA_ENGINE = BIT(1),
>  };
>
> +struct dma_chan;
> +
> +typedef void (*dmaengine_bh_work_fn)(struct dma_chan *chan);
> +
>  /**
>   * struct dma_chan_percpu - the per-CPU part of struct dma_chan
>   * @memcpy_count: transaction counter
> @@ -334,6 +339,9 @@ struct dma_router {
>   * @router: pointer to the DMA router structure
>   * @route_data: channel specific data for the router
>   * @private: private data for certain client-channel associations
> + * @bh_tasklet: bottom-half tasklet stored per-channel
> + * @bh_work_fn: callback executed when @bh_tasklet runs
> + * @bh_work_initialized: indicates whether @bh_tasklet has been initialized
>   */
>  struct dma_chan {
>  	struct dma_device *device;
> @@ -359,6 +367,9 @@ struct dma_chan {
>  	void *route_data;
>
>  	void *private;
> +	struct tasklet_struct bh_tasklet;
> +	dmaengine_bh_work_fn bh_work_fn;
> +	bool bh_work_initialized;
>  };
>
>  /**
> @@ -1529,6 +1540,9 @@ struct dma_chan *devm_dma_request_chan(struct device *dev, const char *name);
>
>  void dma_release_channel(struct dma_chan *chan);
>  int dma_get_slave_caps(struct dma_chan *chan, struct dma_slave_caps *caps);
> +void dmaengine_init_bh(struct dma_chan *chan, dmaengine_bh_work_fn fn);
> +bool dmaengine_schedule_bh(struct dma_chan *chan);
> +void dmaengine_kill_bh(struct dma_chan *chan);
>  #else
>  static inline struct dma_chan *dma_find_channel(enum dma_transaction_type tx_type)
>  {
> @@ -1576,6 +1590,20 @@ static inline int dma_get_slave_caps(struct dma_chan *chan,
>  {
>  	return -ENXIO;
>  }
> +
> +static inline void dmaengine_init_bh(struct dma_chan *chan,
> +				     dmaengine_bh_work_fn fn)
> +{
> +}
> +
> +static inline bool dmaengine_schedule_bh(struct dma_chan *chan)
> +{
> +	return false;
> +}
> +
> +static inline void dmaengine_kill_bh(struct dma_chan *chan)
> +{
> +}
>  #endif
>
>  static inline int dmaengine_desc_set_reuse(struct dma_async_tx_descriptor *tx)
> --
> 2.43.0
>

WARNING: multiple messages have this Message-ID (diff)
From: Frank Li <Frank.li@oss.nxp.com>
To: Allen Pais <allen.lkml@gmail.com>
Cc: "Vinod Koul" <vkoul@kernel.org>, "Frank Li" <Frank.Li@kernel.org>,
	dmaengine@vger.kernel.org, linux-kernel@vger.kernel.org,
	"Arnd Bergmann" <arnd@arndb.de>, "Kees Cook" <kees@kernel.org>,
	"Florian Fainelli" <florian.fainelli@broadcom.com>,
	"Ray Jui" <rjui@broadcom.com>,
	"Scott Branden" <sbranden@broadcom.com>,
	"Broadcom internal kernel review list"
	<bcm-kernel-feedback-list@broadcom.com>,
	"Lars-Peter Clausen" <lars@metafoo.de>,
	"Paul Cercueil" <paul@crapouillou.net>,
	"Eugeniy Paltsev" <Eugeniy.Paltsev@synopsys.com>,
	"Manivannan Sadhasivam" <mani@kernel.org>,
	"Zhou Wang" <wangzhou1@hisilicon.com>,
	"Longfang Liu" <liulongfang@huawei.com>,
	"Andy Shevchenko" <andy@kernel.org>,
	"Sascha Hauer" <s.hauer@pengutronix.de>,
	"Pengutronix Kernel Team" <kernel@pengutronix.de>,
	"Fabio Estevam" <festevam@gmail.com>,
	"Keguang Zhang" <keguang.zhang@gmail.com>,
	"Sean Wang" <sean.wang@mediatek.com>,
	"Matthias Brugger" <matthias.bgg@gmail.com>,
	"AngeloGioacchino Del Regno"
	<angelogioacchino.delregno@collabora.com>,
	"Andreas Färber" <afaerber@suse.de>,
	"Daniel Mack" <daniel@zonque.org>,
	"Haojian Zhuang" <haojian.zhuang@gmail.com>,
	"Robert Jarzmik" <robert.jarzmik@free.fr>,
	"Paul Walmsley" <pjw@kernel.org>,
	"Samuel Holland" <samuel.holland@sifive.com>,
	"Orson Zhai" <orsonzhai@gmail.com>,
	"Baolin Wang" <baolin.wang@linux.alibaba.com>,
	"Chunyan Zhang" <zhang.lyra@gmail.com>,
	"Patrice Chotard" <patrice.chotard@foss.st.com>,
	"Chen-Yu Tsai" <wens@kernel.org>,
	"Jernej Skrabec" <jernej.skrabec@gmail.com>,
	"Laxman Dewangan" <ldewangan@nvidia.com>,
	"Jon Hunter" <jonathanh@nvidia.com>,
	"Thierry Reding" <thierry.reding@kernel.org>,
	"Vignesh Raghavendra" <vigneshr@ti.com>,
	"Bartosz Golaszewski" <brgl@kernel.org>,
	"Konrad Dybcio" <konrad.dybcio@oss.qualcomm.com>,
	"Bjorn Andersson" <andersson@kernel.org>,
	"Kuldeep Singh" <kuldeep.singh@oss.qualcomm.com>,
	"Stephan Gerhold" <stephan.gerhold@linaro.org>,
	linux-rpi-kernel@lists.infradead.org,
	linux-arm-kernel@lists.infradead.org, linux-mips@vger.kernel.org,
	imx@lists.linux.dev, linux-mediatek@lists.infradead.org,
	linux-actions@lists.infradead.org, linux-arm-msm@vger.kernel.org,
	linux-riscv@lists.infradead.org, linux-sunxi@lists.linux.dev,
	linux-tegra@vger.kernel.org
Subject: Re: [PATCH v3 01/34] dmaengine: add tasklet-backed channel BH helpers
Date: Tue, 1 Sep 2026 18:13:16 -0400	[thread overview]
Message-ID: <apdN_G_1M4e81gQd@lizhi-Precision-Tower-5810> (raw)
In-Reply-To: <2c62c39cafc0df59eb5381d3da82b1616a58fa20.1786384168.git.allen.lkml@gmail.com>

On Mon, Aug 10, 2026 at 11:09:02AM -0700, Allen Pais wrote:
> DMAengine drivers commonly use a per-channel tasklet to invoke client
> callbacks. Add helpers that initialize, schedule, and kill a channel
> bottom half, with an initial tasklet-backed implementation that preserves
> the existing execution context.
>
> Convert virt-dma to the new API and remove its private tasklet. Update all
> drivers that directly kill or override that tasklet in the same change so
> no stale users remain. While touching the completion handler, avoid forming
> a result pointer from a NULL cyclic descriptor.
>
> This establishes a backend-independent API before changing how channel
> bottom halves are dispatched.
>
> Signed-off-by: Allen Pais <allen.lkml@gmail.com>
> ---

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

>  drivers/dma/bcm2835-dma.c                     |  2 +-
>  drivers/dma/dma-axi-dmac.c                    | 10 +++--
>  drivers/dma/dma-jz4780.c                      |  2 +-
>  drivers/dma/dmaengine.c                       | 42 +++++++++++++++++++
>  .../dma/dw-axi-dmac/dw-axi-dmac-platform.c    |  2 +-
>  drivers/dma/dw-edma/dw-edma-core.c            |  2 +-
>  drivers/dma/fsl-edma-common.c                 |  2 +-
>  drivers/dma/fsl-qdma.c                        |  2 +-
>  drivers/dma/hisi_dma.c                        |  2 +-
>  drivers/dma/hsu/hsu.c                         |  2 +-
>  drivers/dma/idma64.c                          |  4 +-
>  drivers/dma/img-mdc-dma.c                     |  2 +-
>  drivers/dma/imx-sdma.c                        |  4 +-
>  drivers/dma/k3dma.c                           |  2 +-
>  drivers/dma/loongson/loongson1-apb-dma.c      |  2 +-
>  drivers/dma/mediatek/mtk-cqdma.c              |  2 +-
>  drivers/dma/mediatek/mtk-hsdma.c              |  2 +-
>  drivers/dma/mediatek/mtk-uart-apdma.c         |  4 +-
>  drivers/dma/owl-dma.c                         |  2 +-
>  drivers/dma/pxa_dma.c                         |  2 +-
>  drivers/dma/qcom/bam_dma.c                    |  4 +-
>  drivers/dma/qcom/qcom_adm.c                   |  4 +-
>  drivers/dma/sa11x0-dma.c                      |  2 +-
>  drivers/dma/sf-pdma/sf-pdma.c                 |  2 +-
>  drivers/dma/sprd-dma.c                        |  2 +-
>  drivers/dma/st_fdma.c                         |  2 +-
>  drivers/dma/sun6i-dma.c                       |  2 +-
>  drivers/dma/tegra186-gpc-dma.c                |  2 +-
>  drivers/dma/tegra210-adma.c                   |  2 +-
>  drivers/dma/ti/edma.c                         |  2 +-
>  drivers/dma/ti/k3-udma.c                      | 12 +++---
>  drivers/dma/ti/omap-dma.c                     |  2 +-
>  drivers/dma/virt-dma.c                        | 12 +++---
>  drivers/dma/virt-dma.h                        |  7 ++--
>  include/linux/dmaengine.h                     | 28 +++++++++++++
>  35 files changed, 125 insertions(+), 54 deletions(-)
>
> diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c
> index 06d830d36882..c8add249dbfb 100644
> --- a/drivers/dma/bcm2835-dma.c
> +++ b/drivers/dma/bcm2835-dma.c
> @@ -829,7 +829,7 @@ static void bcm2835_dma_free(struct bcm2835_dmadev *od)
>  	list_for_each_entry_safe(c, next, &od->ddev.channels,
>  				 vc.chan.device_node) {
>  		list_del(&c->vc.chan.device_node);
> -		tasklet_kill(&c->vc.task);
> +		dmaengine_kill_bh(&c->vc.chan);
>  	}
>
>  	dma_unmap_page_attrs(od->ddev.dev, od->zero_page, PAGE_SIZE,
> diff --git a/drivers/dma/dma-axi-dmac.c b/drivers/dma/dma-axi-dmac.c
> index d47ff27e1408..d245d04c3a27 100644
> --- a/drivers/dma/dma-axi-dmac.c
> +++ b/drivers/dma/dma-axi-dmac.c
> @@ -1195,9 +1195,11 @@ static int axi_dmac_detect_caps(struct axi_dmac *dmac, unsigned int version)
>  	return 0;
>  }
>
> -static void axi_dmac_tasklet_kill(void *task)
> +static void axi_dmac_kill_bh(void *data)
>  {
> -	tasklet_kill(task);
> +	struct dma_chan *chan = data;
> +
> +	dmaengine_kill_bh(chan);
>  }
>
>  static void axi_dmac_free_dma_controller(void *of_node)
> @@ -1302,8 +1304,8 @@ static int axi_dmac_probe(struct platform_device *pdev)
>  	 * Put the action in here so it get's done before unregistering the DMA
>  	 * device.
>  	 */
> -	ret = devm_add_action_or_reset(&pdev->dev, axi_dmac_tasklet_kill,
> -				       &dmac->chan.vchan.task);
> +	ret = devm_add_action_or_reset(&pdev->dev, axi_dmac_kill_bh,
> +				       &dmac->chan.vchan.chan);
>  	if (ret)
>  		return ret;
>
> diff --git a/drivers/dma/dma-jz4780.c b/drivers/dma/dma-jz4780.c
> index 6070dfdb7114..738801501e29 100644
> --- a/drivers/dma/dma-jz4780.c
> +++ b/drivers/dma/dma-jz4780.c
> @@ -1019,7 +1019,7 @@ static void jz4780_dma_remove(struct platform_device *pdev)
>  	free_irq(jzdma->irq, jzdma);
>
>  	for (i = 0; i < jzdma->soc_data->nb_channels; i++)
> -		tasklet_kill(&jzdma->chan[i].vchan.task);
> +		dmaengine_kill_bh(&jzdma->chan[i].vchan.chan);
>  }
>
>  static const struct jz4780_dma_soc_data jz4740_dma_soc_data = {
> diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
> index 9049171df857..d8fc7eb71b48 100644
> --- a/drivers/dma/dmaengine.c
> +++ b/drivers/dma/dmaengine.c
> @@ -1428,6 +1428,48 @@ static void dmaengine_destroy_unmap_pool(void)
>  	}
>  }
>
> +static void dma_chan_bh_entry(struct tasklet_struct *tasklet)
> +{
> +	struct dma_chan *chan = from_tasklet(chan, tasklet, bh_tasklet);
> +	dmaengine_bh_work_fn fn = READ_ONCE(chan->bh_work_fn);
> +
> +	if (fn)
> +		fn(chan);
> +}
> +
> +void dmaengine_init_bh(struct dma_chan *chan, dmaengine_bh_work_fn fn)
> +{
> +	if (WARN_ON(!fn))
> +		return;
> +
> +	if (WARN_ON(chan->bh_work_initialized))
> +		return;
> +
> +	chan->bh_work_fn = fn;
> +	tasklet_setup(&chan->bh_tasklet, dma_chan_bh_entry);
> +	chan->bh_work_initialized = true;
> +}
> +EXPORT_SYMBOL_GPL(dmaengine_init_bh);
> +
> +bool dmaengine_schedule_bh(struct dma_chan *chan)
> +{
> +	if (WARN_ON(!chan->bh_work_initialized))
> +		return false;
> +
> +	tasklet_schedule(&chan->bh_tasklet);
> +	return true;
> +}
> +EXPORT_SYMBOL_GPL(dmaengine_schedule_bh);
> +
> +void dmaengine_kill_bh(struct dma_chan *chan)
> +{
> +	if (!chan->bh_work_initialized)
> +		return;
> +
> +	tasklet_kill(&chan->bh_tasklet);
> +}
> +EXPORT_SYMBOL_GPL(dmaengine_kill_bh);
> +
>  static int __init dmaengine_init_unmap_pool(void)
>  {
>  	int i;
> diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
> index bcefaff03b5c..a2b688e7f47e 100644
> --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
> +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
> @@ -1663,7 +1663,7 @@ static void dw_remove(struct platform_device *pdev)
>  	list_for_each_entry_safe(chan, _chan, &dw->dma.channels,
>  				 vc.chan.device_node) {
>  		list_del(&chan->vc.chan.device_node);
> -		tasklet_kill(&chan->vc.task);
> +		dmaengine_kill_bh(&chan->vc.chan);
>  	}
>  }
>
> diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-edma-core.c
> index 89a4c498a17b..ade866fba2ad 100644
> --- a/drivers/dma/dw-edma/dw-edma-core.c
> +++ b/drivers/dma/dw-edma/dw-edma-core.c
> @@ -1170,7 +1170,7 @@ int dw_edma_remove(struct dw_edma_chip *chip)
>  	dma_async_device_unregister(&dw->dma);
>  	list_for_each_entry_safe(chan, _chan, &dw->dma.channels,
>  				 vc.chan.device_node) {
> -		tasklet_kill(&chan->vc.task);
> +		dmaengine_kill_bh(&chan->vc.chan);
>  		list_del(&chan->vc.chan.device_node);
>  	}
>
> diff --git a/drivers/dma/fsl-edma-common.c b/drivers/dma/fsl-edma-common.c
> index bb7531c456df..90ae678c68d4 100644
> --- a/drivers/dma/fsl-edma-common.c
> +++ b/drivers/dma/fsl-edma-common.c
> @@ -915,7 +915,7 @@ void fsl_edma_cleanup_vchan(struct dma_device *dmadev)
>  	list_for_each_entry_safe(chan, _chan,
>  				&dmadev->channels, vchan.chan.device_node) {
>  		list_del(&chan->vchan.chan.device_node);
> -		tasklet_kill(&chan->vchan.task);
> +		dmaengine_kill_bh(&chan->vchan.chan);
>  	}
>  }
>
> diff --git a/drivers/dma/fsl-qdma.c b/drivers/dma/fsl-qdma.c
> index df843fad0ece..b0ace8bad498 100644
> --- a/drivers/dma/fsl-qdma.c
> +++ b/drivers/dma/fsl-qdma.c
> @@ -1255,7 +1255,7 @@ static void fsl_qdma_cleanup_vchan(struct dma_device *dmadev)
>  	list_for_each_entry_safe(chan, _chan,
>  				 &dmadev->channels, vchan.chan.device_node) {
>  		list_del(&chan->vchan.chan.device_node);
> -		tasklet_kill(&chan->vchan.task);
> +		dmaengine_kill_bh(&chan->vchan.chan);
>  	}
>  }
>
> diff --git a/drivers/dma/hisi_dma.c b/drivers/dma/hisi_dma.c
> index 28bf818f9aa6..10eb98350b9f 100644
> --- a/drivers/dma/hisi_dma.c
> +++ b/drivers/dma/hisi_dma.c
> @@ -720,7 +720,7 @@ static void hisi_dma_disable_qps(struct hisi_dma_dev *hdma_dev)
>
>  	for (i = 0; i < hdma_dev->chan_num; i++) {
>  		hisi_dma_disable_qp(hdma_dev, i);
> -		tasklet_kill(&hdma_dev->chan[i].vc.task);
> +		dmaengine_kill_bh(&hdma_dev->chan[i].vc.chan);
>  	}
>  }
>
> diff --git a/drivers/dma/hsu/hsu.c b/drivers/dma/hsu/hsu.c
> index f62d60d7bc6b..315d0ebecd57 100644
> --- a/drivers/dma/hsu/hsu.c
> +++ b/drivers/dma/hsu/hsu.c
> @@ -500,7 +500,7 @@ int hsu_dma_remove(struct hsu_dma_chip *chip)
>  	for (i = 0; i < hsu->nr_channels; i++) {
>  		struct hsu_dma_chan *hsuc = &hsu->chan[i];
>
> -		tasklet_kill(&hsuc->vchan.task);
> +		dmaengine_kill_bh(&hsuc->vchan.chan);
>  	}
>
>  	return 0;
> diff --git a/drivers/dma/idma64.c b/drivers/dma/idma64.c
> index 5fcd1befc92d..1d395fb735ff 100644
> --- a/drivers/dma/idma64.c
> +++ b/drivers/dma/idma64.c
> @@ -617,14 +617,14 @@ static void idma64_remove(struct idma64_chip *chip)
>
>  	/*
>  	 * Explicitly call devm_request_irq() to avoid the side effects with
> -	 * the scheduled tasklets.
> +	 * scheduled BH work.
>  	 */
>  	devm_free_irq(chip->dev, chip->irq, idma64);
>
>  	for (i = 0; i < idma64->dma.chancnt; i++) {
>  		struct idma64_chan *idma64c = &idma64->chan[i];
>
> -		tasklet_kill(&idma64c->vchan.task);
> +		dmaengine_kill_bh(&idma64c->vchan.chan);
>  	}
>  }
>
> diff --git a/drivers/dma/img-mdc-dma.c b/drivers/dma/img-mdc-dma.c
> index b3765ba15803..0c6024088444 100644
> --- a/drivers/dma/img-mdc-dma.c
> +++ b/drivers/dma/img-mdc-dma.c
> @@ -1031,7 +1031,7 @@ static void mdc_dma_remove(struct platform_device *pdev)
>
>  		devm_free_irq(&pdev->dev, mchan->irq, mchan);
>
> -		tasklet_kill(&mchan->vc.task);
> +		dmaengine_kill_bh(&mchan->vc.chan);
>  	}
>
>  	pm_runtime_disable(&pdev->dev);
> diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
> index 36368835a845..4d13b9d2880d 100644
> --- a/drivers/dma/imx-sdma.c
> +++ b/drivers/dma/imx-sdma.c
> @@ -2399,11 +2399,11 @@ static void sdma_remove(struct platform_device *pdev)
>  	int i;
>
>  	devm_free_irq(&pdev->dev, sdma->irq, sdma);
> -	/* Kill the tasklet */
> +	/* Kill the channel BH */
>  	for (i = 0; i < MAX_DMA_CHANNELS; i++) {
>  		struct sdma_channel *sdmac = &sdma->channel[i];
>
> -		tasklet_kill(&sdmac->vc.task);
> +		dmaengine_kill_bh(&sdmac->vc.chan);
>  		sdma_free_chan_resources(&sdmac->vc.chan);
>  	}
>
> diff --git a/drivers/dma/k3dma.c b/drivers/dma/k3dma.c
> index e84f197fea76..3d73b391e42e 100644
> --- a/drivers/dma/k3dma.c
> +++ b/drivers/dma/k3dma.c
> @@ -976,7 +976,7 @@ static void k3_dma_remove(struct platform_device *op)
>
>  	list_for_each_entry_safe(c, cn, &d->slave.channels, vc.chan.device_node) {
>  		list_del(&c->vc.chan.device_node);
> -		tasklet_kill(&c->vc.task);
> +		dmaengine_kill_bh(&c->vc.chan);
>  	}
>  	tasklet_kill(&d->task);
>  	clk_disable_unprepare(d->clk);
> diff --git a/drivers/dma/loongson/loongson1-apb-dma.c b/drivers/dma/loongson/loongson1-apb-dma.c
> index 89786cbd20ab..52a360719644 100644
> --- a/drivers/dma/loongson/loongson1-apb-dma.c
> +++ b/drivers/dma/loongson/loongson1-apb-dma.c
> @@ -552,7 +552,7 @@ static void ls1x_dma_chan_remove(struct ls1x_dma *dma)
>
>  		if (chan->vc.chan.device == &dma->ddev) {
>  			list_del(&chan->vc.chan.device_node);
> -			tasklet_kill(&chan->vc.task);
> +			dmaengine_kill_bh(&chan->vc.chan);
>  		}
>  	}
>  }
> diff --git a/drivers/dma/mediatek/mtk-cqdma.c b/drivers/dma/mediatek/mtk-cqdma.c
> index 80791e30aec2..7b44d3358cda 100644
> --- a/drivers/dma/mediatek/mtk-cqdma.c
> +++ b/drivers/dma/mediatek/mtk-cqdma.c
> @@ -895,7 +895,7 @@ static void mtk_cqdma_remove(struct platform_device *pdev)
>  		vc = &cqdma->vc[i];
>
>  		list_del(&vc->vc.chan.device_node);
> -		tasklet_kill(&vc->vc.task);
> +		dmaengine_kill_bh(&vc->vc.chan);
>  	}
>
>  	/* disable interrupt */
> diff --git a/drivers/dma/mediatek/mtk-hsdma.c b/drivers/dma/mediatek/mtk-hsdma.c
> index a43412ff5edd..75555fa41536 100644
> --- a/drivers/dma/mediatek/mtk-hsdma.c
> +++ b/drivers/dma/mediatek/mtk-hsdma.c
> @@ -1020,7 +1020,7 @@ static void mtk_hsdma_remove(struct platform_device *pdev)
>  		vc = &hsdma->vc[i];
>
>  		list_del(&vc->vc.chan.device_node);
> -		tasklet_kill(&vc->vc.task);
> +		dmaengine_kill_bh(&vc->vc.chan);
>  	}
>
>  	/* Disable DMA interrupt */
> diff --git a/drivers/dma/mediatek/mtk-uart-apdma.c b/drivers/dma/mediatek/mtk-uart-apdma.c
> index c269d84d7bd2..8ce206a0ecc5 100644
> --- a/drivers/dma/mediatek/mtk-uart-apdma.c
> +++ b/drivers/dma/mediatek/mtk-uart-apdma.c
> @@ -312,7 +312,7 @@ static void mtk_uart_apdma_free_chan_resources(struct dma_chan *chan)
>
>  	free_irq(c->irq, chan);
>
> -	tasklet_kill(&c->vc.task);
> +	dmaengine_kill_bh(&c->vc.chan);
>
>  	vchan_free_chan_resources(&c->vc);
>
> @@ -463,7 +463,7 @@ static void mtk_uart_apdma_free(struct mtk_uart_apdmadev *mtkd)
>  			struct mtk_chan, vc.chan.device_node);
>
>  		list_del(&c->vc.chan.device_node);
> -		tasklet_kill(&c->vc.task);
> +		dmaengine_kill_bh(&c->vc.chan);
>  	}
>  }
>
> diff --git a/drivers/dma/owl-dma.c b/drivers/dma/owl-dma.c
> index 7c80572fc71d..0d9f324adba0 100644
> --- a/drivers/dma/owl-dma.c
> +++ b/drivers/dma/owl-dma.c
> @@ -1055,7 +1055,7 @@ static inline void owl_dma_free(struct owl_dma *od)
>  	list_for_each_entry_safe(vchan,
>  				 next, &od->dma.channels, vc.chan.device_node) {
>  		list_del(&vchan->vc.chan.device_node);
> -		tasklet_kill(&vchan->vc.task);
> +		dmaengine_kill_bh(&vchan->vc.chan);
>  	}
>  }
>
> diff --git a/drivers/dma/pxa_dma.c b/drivers/dma/pxa_dma.c
> index fa2ee0b3e09f..2cca8c31929c 100644
> --- a/drivers/dma/pxa_dma.c
> +++ b/drivers/dma/pxa_dma.c
> @@ -1215,7 +1215,7 @@ static void pxad_free_channels(struct dma_device *dmadev)
>  	list_for_each_entry_safe(c, cn, &dmadev->channels,
>  				 vc.chan.device_node) {
>  		list_del(&c->vc.chan.device_node);
> -		tasklet_kill(&c->vc.task);
> +		dmaengine_kill_bh(&c->vc.chan);
>  	}
>  }
>
> diff --git a/drivers/dma/qcom/bam_dma.c b/drivers/dma/qcom/bam_dma.c
> index 1bb26af0405f..c23496c3ac69 100644
> --- a/drivers/dma/qcom/bam_dma.c
> +++ b/drivers/dma/qcom/bam_dma.c
> @@ -1387,7 +1387,7 @@ static int bam_dma_probe(struct platform_device *pdev)
>  	dma_async_device_unregister(&bdev->common);
>  err_bam_channel_exit:
>  	for (i = 0; i < bdev->num_channels; i++)
> -		tasklet_kill(&bdev->channels[i].vc.task);
> +		dmaengine_kill_bh(&bdev->channels[i].vc.chan);
>  err_tasklet_kill:
>  	tasklet_kill(&bdev->task);
>  err_disable_clk:
> @@ -1413,7 +1413,7 @@ static void bam_dma_remove(struct platform_device *pdev)
>
>  	for (i = 0; i < bdev->num_channels; i++) {
>  		bam_dma_terminate_all(&bdev->channels[i].vc.chan);
> -		tasklet_kill(&bdev->channels[i].vc.task);
> +		dmaengine_kill_bh(&bdev->channels[i].vc.chan);
>
>  		if (!bdev->channels[i].fifo_virt)
>  			continue;
> diff --git a/drivers/dma/qcom/qcom_adm.c b/drivers/dma/qcom/qcom_adm.c
> index 07fbe32d31fa..13f5ca8ff808 100644
> --- a/drivers/dma/qcom/qcom_adm.c
> +++ b/drivers/dma/qcom/qcom_adm.c
> @@ -918,8 +918,8 @@ static void adm_dma_remove(struct platform_device *pdev)
>  		/* mask IRQs for this channel/EE pair */
>  		writel(0, adev->regs + ADM_CH_RSLT_CONF(achan->id, adev->ee));
>
> -		tasklet_kill(&adev->channels[i].vc.task);
> -		adm_terminate_all(&adev->channels[i].vc.chan);
> +		dmaengine_kill_bh(&achan->vc.chan);
> +		adm_terminate_all(&achan->vc.chan);
>  	}
>
>  	devm_free_irq(adev->dev, adev->irq, adev);
> diff --git a/drivers/dma/sa11x0-dma.c b/drivers/dma/sa11x0-dma.c
> index a6fa431530e3..e14566fa2d74 100644
> --- a/drivers/dma/sa11x0-dma.c
> +++ b/drivers/dma/sa11x0-dma.c
> @@ -891,7 +891,7 @@ static void sa11x0_dma_free_channels(struct dma_device *dmadev)
>
>  	list_for_each_entry_safe(c, cn, &dmadev->channels, vc.chan.device_node) {
>  		list_del(&c->vc.chan.device_node);
> -		tasklet_kill(&c->vc.task);
> +		dmaengine_kill_bh(&c->vc.chan);
>  		kfree(c);
>  	}
>  }
> diff --git a/drivers/dma/sf-pdma/sf-pdma.c b/drivers/dma/sf-pdma/sf-pdma.c
> index 6f79cc28703e..a08ca355dadb 100644
> --- a/drivers/dma/sf-pdma/sf-pdma.c
> +++ b/drivers/dma/sf-pdma/sf-pdma.c
> @@ -602,7 +602,7 @@ static void sf_pdma_remove(struct platform_device *pdev)
>  		devm_free_irq(&pdev->dev, ch->txirq, ch);
>  		devm_free_irq(&pdev->dev, ch->errirq, ch);
>  		list_del(&ch->vchan.chan.device_node);
> -		tasklet_kill(&ch->vchan.task);
> +		dmaengine_kill_bh(&ch->vchan.chan);
>  		tasklet_kill(&ch->done_tasklet);
>  		tasklet_kill(&ch->err_tasklet);
>  	}
> diff --git a/drivers/dma/sprd-dma.c b/drivers/dma/sprd-dma.c
> index 087fea3af2e4..f90f5d8d5a1e 100644
> --- a/drivers/dma/sprd-dma.c
> +++ b/drivers/dma/sprd-dma.c
> @@ -1253,7 +1253,7 @@ static void sprd_dma_remove(struct platform_device *pdev)
>  	list_for_each_entry_safe(c, cn, &sdev->dma_dev.channels,
>  				 vc.chan.device_node) {
>  		list_del(&c->vc.chan.device_node);
> -		tasklet_kill(&c->vc.task);
> +		dmaengine_kill_bh(&c->vc.chan);
>  	}
>
>  	of_dma_controller_free(pdev->dev.of_node);
> diff --git a/drivers/dma/st_fdma.c b/drivers/dma/st_fdma.c
> index d9547017f3bd..cae0a7fe6ceb 100644
> --- a/drivers/dma/st_fdma.c
> +++ b/drivers/dma/st_fdma.c
> @@ -733,7 +733,7 @@ static void st_fdma_free(struct st_fdma_dev *fdev)
>  	for (i = 0; i < fdev->nr_channels; i++) {
>  		fchan = &fdev->chans[i];
>  		list_del(&fchan->vchan.chan.device_node);
> -		tasklet_kill(&fchan->vchan.task);
> +		dmaengine_kill_bh(&fchan->vchan.chan);
>  	}
>  }
>
> diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
> index f47a326dd7ff..4ddea3cdcd66 100644
> --- a/drivers/dma/sun6i-dma.c
> +++ b/drivers/dma/sun6i-dma.c
> @@ -1094,7 +1094,7 @@ static inline void sun6i_dma_free(struct sun6i_dma_dev *sdev)
>  		struct sun6i_vchan *vchan = &sdev->vchans[i];
>
>  		list_del(&vchan->vc.chan.device_node);
> -		tasklet_kill(&vchan->vc.task);
> +		dmaengine_kill_bh(&vchan->vc.chan);
>  	}
>  }
>
> diff --git a/drivers/dma/tegra186-gpc-dma.c b/drivers/dma/tegra186-gpc-dma.c
> index 64cedef1050a..3a27a83a3288 100644
> --- a/drivers/dma/tegra186-gpc-dma.c
> +++ b/drivers/dma/tegra186-gpc-dma.c
> @@ -1284,7 +1284,7 @@ static void tegra_dma_free_chan_resources(struct dma_chan *dc)
>  	tegra_dma_terminate_all(dc);
>  	synchronize_irq(tdc->irq);
>
> -	tasklet_kill(&tdc->vc.task);
> +	dmaengine_kill_bh(&tdc->vc.chan);
>  	tdc->config_init = false;
>  	tdc->slave_id = -1;
>  	tdc->sid_dir = DMA_TRANS_NONE;
> diff --git a/drivers/dma/tegra210-adma.c b/drivers/dma/tegra210-adma.c
> index ceaee1e33e68..780863199224 100644
> --- a/drivers/dma/tegra210-adma.c
> +++ b/drivers/dma/tegra210-adma.c
> @@ -811,7 +811,7 @@ static void tegra_adma_free_chan_resources(struct dma_chan *dc)
>
>  	tegra_adma_terminate_all(dc);
>  	vchan_free_chan_resources(&tdc->vc);
> -	tasklet_kill(&tdc->vc.task);
> +	dmaengine_kill_bh(&tdc->vc.chan);
>  	free_irq(tdc->irq, tdc);
>  	pm_runtime_put(tdc2dev(tdc));
>
> diff --git a/drivers/dma/ti/edma.c b/drivers/dma/ti/edma.c
> index d97db5af3555..c0ad0cdabb87 100644
> --- a/drivers/dma/ti/edma.c
> +++ b/drivers/dma/ti/edma.c
> @@ -2560,7 +2560,7 @@ static void edma_cleanupp_vchan(struct dma_device *dmadev)
>  	list_for_each_entry_safe(echan, _echan,
>  			&dmadev->channels, vchan.chan.device_node) {
>  		list_del(&echan->vchan.chan.device_node);
> -		tasklet_kill(&echan->vchan.task);
> +		dmaengine_kill_bh(&echan->vchan.chan);
>  	}
>  }
>
> diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c
> index 1cf158eb7bdb..fd428c26799a 100644
> --- a/drivers/dma/ti/k3-udma.c
> +++ b/drivers/dma/ti/k3-udma.c
> @@ -4042,12 +4042,12 @@ static void udma_desc_pre_callback(struct virt_dma_chan *vc,
>  }
>
>  /*
> - * This tasklet handles the completion of a DMA descriptor by
> + * This BH handles the completion of a DMA descriptor by
>   * calling its callback and freeing it.
>   */
> -static void udma_vchan_complete(struct tasklet_struct *t)
> +static void udma_vchan_complete(struct dma_chan *chan)
>  {
> -	struct virt_dma_chan *vc = from_tasklet(vc, t, task);
> +	struct virt_dma_chan *vc = to_virt_chan(chan);
>  	struct virt_dma_desc *vd, *_vd;
>  	struct dmaengine_desc_callback cb;
>  	LIST_HEAD(head);
> @@ -4112,7 +4112,7 @@ static void udma_free_chan_resources(struct dma_chan *chan)
>  	}
>
>  	vchan_free_chan_resources(&uc->vc);
> -	tasklet_kill(&uc->vc.task);
> +	dmaengine_kill_bh(&uc->vc.chan);
>
>  	bcdma_free_bchan_resources(uc);
>  	udma_free_tx_resources(uc);
> @@ -5627,8 +5627,8 @@ static int udma_probe(struct platform_device *pdev)
>  		if (!uc->name)
>  			return -ENOMEM;
>  		vchan_init(&uc->vc, &ud->ddev);
> -		/* Use custom vchan completion handling */
> -		tasklet_setup(&uc->vc.task, udma_vchan_complete);
> +		/* Override the default vchan completion handler */
> +		uc->vc.chan.bh_work_fn = udma_vchan_complete;
>  		init_completion(&uc->teardown_completed);
>  		INIT_DELAYED_WORK(&uc->tx_drain.work, udma_check_tx_completion);
>  	}
> diff --git a/drivers/dma/ti/omap-dma.c b/drivers/dma/ti/omap-dma.c
> index 55ece7fd0d99..899c5eeeac88 100644
> --- a/drivers/dma/ti/omap-dma.c
> +++ b/drivers/dma/ti/omap-dma.c
> @@ -1521,7 +1521,7 @@ static void omap_dma_free(struct omap_dmadev *od)
>  			struct omap_chan, vc.chan.device_node);
>
>  		list_del(&c->vc.chan.device_node);
> -		tasklet_kill(&c->vc.task);
> +		dmaengine_kill_bh(&c->vc.chan);
>  		kfree(c);
>  	}
>  }
> diff --git a/drivers/dma/virt-dma.c b/drivers/dma/virt-dma.c
> index 7961172a780d..d407af6cc1da 100644
> --- a/drivers/dma/virt-dma.c
> +++ b/drivers/dma/virt-dma.c
> @@ -77,12 +77,12 @@ struct virt_dma_desc *vchan_find_desc(struct virt_dma_chan *vc,
>  EXPORT_SYMBOL_GPL(vchan_find_desc);
>
>  /*
> - * This tasklet handles the completion of a DMA descriptor by
> - * calling its callback and freeing it.
> + * This bottom-half handler completes a DMA descriptor by invoking its
> + * callback and freeing it.
>   */
> -static void vchan_complete(struct tasklet_struct *t)
> +static void vchan_complete(struct dma_chan *chan)
>  {
> -	struct virt_dma_chan *vc = from_tasklet(vc, t, task);
> +	struct virt_dma_chan *vc = to_virt_chan(chan);
>  	struct virt_dma_desc *vd, *_vd;
>  	struct dmaengine_desc_callback cb;
>  	LIST_HEAD(head);
> @@ -98,7 +98,7 @@ static void vchan_complete(struct tasklet_struct *t)
>  	}
>  	spin_unlock_irq(&vc->lock);
>
> -	dmaengine_desc_callback_invoke(&cb, &vd->tx_result);
> +	dmaengine_desc_callback_invoke(&cb, vd ? &vd->tx_result : NULL);
>
>  	list_for_each_entry_safe(vd, _vd, &head, node) {
>  		dmaengine_desc_get_callback(&vd->tx, &cb);
> @@ -131,7 +131,7 @@ void vchan_init(struct virt_dma_chan *vc, struct dma_device *dmadev)
>  	INIT_LIST_HEAD(&vc->desc_completed);
>  	INIT_LIST_HEAD(&vc->desc_terminated);
>
> -	tasklet_setup(&vc->task, vchan_complete);
> +	dmaengine_init_bh(&vc->chan, vchan_complete);
>
>  	vc->chan.device = dmadev;
>  	list_add_tail(&vc->chan.device_node, &dmadev->channels);
> diff --git a/drivers/dma/virt-dma.h b/drivers/dma/virt-dma.h
> index 59d9eabc8b67..0ba42fded2cc 100644
> --- a/drivers/dma/virt-dma.h
> +++ b/drivers/dma/virt-dma.h
> @@ -21,7 +21,6 @@ struct virt_dma_desc {
>
>  struct virt_dma_chan {
>  	struct dma_chan	chan;
> -	struct tasklet_struct task;
>  	void (*desc_free)(struct virt_dma_desc *);
>
>  	spinlock_t lock;
> @@ -106,7 +105,7 @@ static inline void vchan_cookie_complete(struct virt_dma_desc *vd)
>  		 vd, cookie);
>  	list_add_tail(&vd->node, &vc->desc_completed);
>
> -	tasklet_schedule(&vc->task);
> +	dmaengine_schedule_bh(&vc->chan);
>  }
>
>  /**
> @@ -137,7 +136,7 @@ static inline void vchan_cyclic_callback(struct virt_dma_desc *vd)
>  	struct virt_dma_chan *vc = to_virt_chan(vd->tx.chan);
>
>  	vc->cyclic = vd;
> -	tasklet_schedule(&vc->task);
> +	dmaengine_schedule_bh(&vc->chan);
>  }
>
>  /**
> @@ -223,7 +222,7 @@ static inline void vchan_synchronize(struct virt_dma_chan *vc)
>  	LIST_HEAD(head);
>  	unsigned long flags;
>
> -	tasklet_kill(&vc->task);
> +	dmaengine_kill_bh(&vc->chan);
>
>  	spin_lock_irqsave(&vc->lock, flags);
>
> diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
> index b3d251c9734e..a1437bdbda9b 100644
> --- a/include/linux/dmaengine.h
> +++ b/include/linux/dmaengine.h
> @@ -12,6 +12,7 @@
>  #include <linux/scatterlist.h>
>  #include <linux/bitmap.h>
>  #include <linux/types.h>
> +#include <linux/interrupt.h>
>  #include <asm/page.h>
>
>  /**
> @@ -295,6 +296,10 @@ enum dma_desc_metadata_mode {
>  	DESC_METADATA_ENGINE = BIT(1),
>  };
>
> +struct dma_chan;
> +
> +typedef void (*dmaengine_bh_work_fn)(struct dma_chan *chan);
> +
>  /**
>   * struct dma_chan_percpu - the per-CPU part of struct dma_chan
>   * @memcpy_count: transaction counter
> @@ -334,6 +339,9 @@ struct dma_router {
>   * @router: pointer to the DMA router structure
>   * @route_data: channel specific data for the router
>   * @private: private data for certain client-channel associations
> + * @bh_tasklet: bottom-half tasklet stored per-channel
> + * @bh_work_fn: callback executed when @bh_tasklet runs
> + * @bh_work_initialized: indicates whether @bh_tasklet has been initialized
>   */
>  struct dma_chan {
>  	struct dma_device *device;
> @@ -359,6 +367,9 @@ struct dma_chan {
>  	void *route_data;
>
>  	void *private;
> +	struct tasklet_struct bh_tasklet;
> +	dmaengine_bh_work_fn bh_work_fn;
> +	bool bh_work_initialized;
>  };
>
>  /**
> @@ -1529,6 +1540,9 @@ struct dma_chan *devm_dma_request_chan(struct device *dev, const char *name);
>
>  void dma_release_channel(struct dma_chan *chan);
>  int dma_get_slave_caps(struct dma_chan *chan, struct dma_slave_caps *caps);
> +void dmaengine_init_bh(struct dma_chan *chan, dmaengine_bh_work_fn fn);
> +bool dmaengine_schedule_bh(struct dma_chan *chan);
> +void dmaengine_kill_bh(struct dma_chan *chan);
>  #else
>  static inline struct dma_chan *dma_find_channel(enum dma_transaction_type tx_type)
>  {
> @@ -1576,6 +1590,20 @@ static inline int dma_get_slave_caps(struct dma_chan *chan,
>  {
>  	return -ENXIO;
>  }
> +
> +static inline void dmaengine_init_bh(struct dma_chan *chan,
> +				     dmaengine_bh_work_fn fn)
> +{
> +}
> +
> +static inline bool dmaengine_schedule_bh(struct dma_chan *chan)
> +{
> +	return false;
> +}
> +
> +static inline void dmaengine_kill_bh(struct dma_chan *chan)
> +{
> +}
>  #endif
>
>  static inline int dmaengine_desc_set_reuse(struct dma_async_tx_descriptor *tx)
> --
> 2.43.0
>

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

  parent reply	other threads:[~2026-09-01 22:13 UTC|newest]

Thread overview: 263+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-01-08  8:03 [RFC PATCH 0/1] dmaengine: introduce dmaengine_bh_wq and bh helpers Allen Pais
2026-01-08  8:03 ` [RFC PATCH 1/1] " Allen Pais
2026-01-08 10:26   ` Arnd Bergmann
2026-01-08 19:22     ` Allen
2026-01-09 16:42       ` Arnd Bergmann
2026-01-12 22:20         ` Allen
2026-01-13  7:33           ` Arnd Bergmann
2026-01-13 19:31             ` Allen
2026-01-12  6:26   ` kernel test robot
2026-01-14  7:13   ` kernel test robot
2026-01-14  7:35   ` kernel test robot
2026-01-14  8:49   ` kernel test robot
2026-07-27 20:28 ` [PATCH v2 00/64] dmaengine: migrate channel tasklets to WQ_BH Allen Pais
2026-07-27 20:28   ` [PATCH v2 01/64] dmaengine: add tasklet-backed channel BH helpers Allen Pais
2026-07-27 20:56     ` sashiko-bot
2026-07-29 12:46       ` Vinod Koul
2026-07-29 12:48     ` Vinod Koul
2026-08-04  3:32       ` Allen
2026-07-27 20:28   ` [PATCH v2 02/64] dmaengine: back channel BH helpers with WQ_BH Allen Pais
2026-07-27 20:28   ` [PATCH v2 03/64] dmaengine: apple-admac: use dma_chan BH callback Allen Pais
2026-07-27 20:28   ` [PATCH v2 04/64] dmaengine: at_xdmac: move irq bottom half to dma_chan BH Allen Pais
2026-07-27 20:56     ` sashiko-bot
2026-07-27 20:28   ` [PATCH v2 05/64] dmaengine: ep93xx: hook callbacks via " Allen Pais
2026-07-27 20:59     ` sashiko-bot
2026-07-27 20:28   ` [PATCH v2 06/64] dmaengine: fsldma: migrate tasklet to " Allen Pais
2026-07-27 20:56     ` sashiko-bot
2026-07-27 20:28   ` [PATCH v2 07/64] dmaengine: fsl_raid: run completions via " Allen Pais
2026-07-27 20:55     ` sashiko-bot
2026-07-27 20:28   ` [PATCH v2 08/64] dmaengine: imx-dma: flip per-chan tasklet to " Allen Pais
2026-07-27 20:57     ` sashiko-bot
2026-07-27 20:28   ` [PATCH v2 09/64] dmaengine: ioat: convert cleanup " Allen Pais
2026-07-27 20:38     ` Dave Jiang
2026-07-27 21:02     ` sashiko-bot
2026-07-27 20:28   ` [PATCH v2 10/64] dmaengine: mmp_pdma: replace per-chan tasklet with " Allen Pais
2026-07-27 20:54     ` sashiko-bot
2026-07-27 20:28   ` [PATCH v2 11/64] dmaengine: mmp_tdma: hook completions to " Allen Pais
2026-07-27 20:55     ` sashiko-bot
2026-07-27 20:28   ` [PATCH v2 12/64] dmaengine: mv_xor: convert irq tasklet " Allen Pais
2026-07-27 20:57     ` sashiko-bot
2026-07-27 20:28   ` [PATCH v2 13/64] dmaengine: mxs-dma: use dma_chan BH scheduling Allen Pais
2026-07-27 20:59     ` sashiko-bot
2026-07-27 20:28   ` [PATCH v2 14/64] dmaengine: nbpfaxi: switch callbacks to dma_chan BH Allen Pais
2026-07-27 20:28   ` [PATCH v2 15/64] dmaengine: pch_dma: convert tasklet " Allen Pais
2026-07-27 20:57     ` sashiko-bot
2026-07-27 20:28   ` [PATCH v2 16/64] dmaengine: ppc4xx: replace irq tasklet with " Allen Pais
2026-07-27 20:54     ` sashiko-bot
2026-07-27 20:28   ` [PATCH v2 17/64] dmaengine: ste_dma40: convert per-channel tasklet to " Allen Pais
2026-07-27 21:00     ` sashiko-bot
2026-07-28 19:33     ` Linus Walleij
2026-07-27 20:28   ` [PATCH v2 18/64] dmaengine: xgene-dma: wire descriptor cleanup " Allen Pais
2026-07-27 20:59     ` sashiko-bot
2026-07-27 20:28   ` [PATCH v2 19/64] dmaengine: xilinx-dma: use dma_chan BH instead of tasklets Allen Pais
2026-07-27 20:59     ` sashiko-bot
2026-07-27 20:28   ` [PATCH v2 20/64] dmaengine: xilinx-dpdma: kill vchan BH on remove Allen Pais
2026-07-27 20:59     ` sashiko-bot
2026-07-27 20:28   ` [PATCH v2 21/64] dmaengine: zynqmp-dma: switch completion tasklet to dma_chan BH Allen Pais
2026-07-27 20:54     ` sashiko-bot
2026-07-27 20:28   ` [PATCH v2 22/64] dmaengine: tegra20-apb: use channel BH helpers Allen Pais
2026-07-27 20:28   ` [PATCH v2 23/64] dmaengine: timb_dma: route callbacks via channel BH Allen Pais
2026-07-27 21:09     ` sashiko-bot
2026-07-27 20:28   ` [PATCH v2 24/64] dmaengine: txx9dmac: " Allen Pais
2026-07-27 21:00     ` sashiko-bot
2026-07-27 20:28   ` [PATCH v2 25/64] dmaengine: mv_xor_v2: use channel BH helpers Allen Pais
2026-07-27 21:02     ` sashiko-bot
2026-07-27 20:28   ` [PATCH v2 26/64] dmaengine: mpc512x: route callbacks via channel BH Allen Pais
2026-07-27 21:07     ` sashiko-bot
2026-07-27 20:28   ` [PATCH v2 27/64] dmaengine: k3dma: kill vchan BH on remove Allen Pais
2026-07-27 21:02     ` sashiko-bot
2026-07-27 20:28   ` [PATCH v2 28/64] dmaengine: plx_dma: use channel BH helpers Allen Pais
2026-07-27 20:38     ` Logan Gunthorpe
2026-07-27 21:09     ` sashiko-bot
2026-07-27 20:28   ` [PATCH v2 29/64] dmaengine: sf-pdma: route error callbacks through channel BH Allen Pais
2026-07-27 20:28     ` Allen Pais
2026-07-27 21:06     ` sashiko-bot
2026-07-27 20:28   ` [PATCH v2 30/64] dmaengine: sa11x0-dma: kill vchan BH on remove Allen Pais
2026-07-27 21:07     ` sashiko-bot
2026-07-27 20:28   ` [PATCH v2 31/64] dmaengine: pl330: route callbacks via channel BH Allen Pais
2026-07-27 20:34     ` Allen Pais
2026-07-27 21:07     ` sashiko-bot
2026-07-27 20:34   ` [PATCH v2 32/64] dmaengine: k3-udma: use channel BH for vchan completions Allen Pais
2026-07-27 21:10     ` sashiko-bot
2026-07-27 20:36   ` [PATCH v2 33/64] dmaengine: sun6i: kill vchan BH on teardown Allen Pais
2026-07-27 21:08     ` sashiko-bot
2026-07-27 20:37   ` [PATCH v2 34/64] dmaengine: mtk-cqdma: " Allen Pais
2026-07-27 21:09     ` sashiko-bot
2026-07-27 20:38   ` [PATCH v2 35/64] dmaengine: altera-msgdma: use channel BH helpers Allen Pais
2026-07-27 21:06     ` sashiko-bot
2026-07-27 20:38   ` [PATCH v2 36/64] dmaengine: sprd-dma: kill vchan BH on teardown Allen Pais
2026-07-27 21:07     ` sashiko-bot
2026-07-27 20:38   ` [PATCH v2 37/64] dmaengine: idma64: " Allen Pais
2026-07-27 21:07     ` sashiko-bot
2026-07-27 20:39   ` [PATCH v2 38/64] dmaengine: img-mdc-dma: " Allen Pais
2026-07-27 21:09     ` sashiko-bot
2026-07-27 20:39   ` [PATCH v2 39/64] dmaengine: fsl-edma-common: " Allen Pais
2026-07-27 21:14     ` sashiko-bot
2026-07-27 20:39   ` [PATCH v2 40/64] dmaengine: dw-axi-dmac: " Allen Pais
2026-07-27 21:11     ` sashiko-bot
2026-07-27 20:39   ` [PATCH v2 41/64] dmaengine: hsu: " Allen Pais
2026-07-27 21:10     ` sashiko-bot
2026-07-28  8:47     ` Andy Shevchenko
2026-07-27 20:39   ` [PATCH v2 42/64] dmaengine: jz4780: " Allen Pais
2026-07-27 21:09     ` sashiko-bot
2026-07-27 20:39   ` [PATCH v2 43/64] dmaengine: pxa_dma: " Allen Pais
2026-07-27 21:10     ` sashiko-bot
2026-07-27 20:39   ` [PATCH v2 44/64] dmaengine: mtk-hsdma: " Allen Pais
2026-07-27 21:09     ` sashiko-bot
2026-07-27 20:39   ` [PATCH v2 45/64] dmaengine: mtk-uart-apdma: " Allen Pais
2026-07-27 21:14     ` sashiko-bot
2026-07-27 20:39   ` [PATCH v2 46/64] dmaengine: imx-sdma: " Allen Pais
2026-07-27 21:17     ` sashiko-bot
2026-07-27 20:39   ` [PATCH v2 47/64] dmaengine: loongson1-apb: " Allen Pais
2026-07-27 21:17     ` sashiko-bot
2026-07-27 20:39   ` [PATCH v2 48/64] dmaengine: owl-dma: " Allen Pais
2026-07-27 21:17     ` sashiko-bot
2026-07-27 20:39   ` [PATCH v2 49/64] dmaengine: hisi: " Allen Pais
2026-07-27 21:20     ` sashiko-bot
2026-07-27 20:39   ` [PATCH v2 50/64] dmaengine: dw-edma: " Allen Pais
2026-07-27 21:18     ` sashiko-bot
2026-07-27 20:39   ` [PATCH v2 51/64] dmaengine: bcm2835: " Allen Pais
2026-07-27 21:20     ` sashiko-bot
2026-07-27 20:39   ` [PATCH v2 52/64] dmaengine: tegra210-adma: " Allen Pais
2026-07-27 21:17     ` sashiko-bot
2026-07-27 20:39   ` [PATCH v2 53/64] dmaengine: fsl-qdma: use dma_chan_kill_bh Allen Pais
2026-07-27 21:17     ` sashiko-bot
2026-07-27 20:39   ` [PATCH v2 54/64] dmaengine: st_fdma: " Allen Pais
2026-07-27 21:18     ` sashiko-bot
2026-07-27 20:39   ` [PATCH v2 55/64] dmaengine: dma-axi-dmac: " Allen Pais
2026-07-27 21:18     ` sashiko-bot
2026-07-27 20:39   ` [PATCH v2 56/64] dmaengine: omap-dma: " Allen Pais
2026-07-27 21:25     ` sashiko-bot
2026-07-27 20:39   ` [PATCH v2 57/64] dmaengine: edma: " Allen Pais
2026-07-27 21:20     ` sashiko-bot
2026-07-27 20:39   ` [PATCH v2 58/64] dmaengine: qcom-adm: " Allen Pais
2026-07-27 21:17     ` sashiko-bot
2026-07-27 20:39   ` [PATCH v2 59/64] dmaengine: tegra186-gpc: " Allen Pais
2026-07-27 21:23     ` sashiko-bot
2026-07-27 20:39   ` [PATCH v2 60/64] dmaengine: bam-dma: " Allen Pais
2026-07-27 21:19     ` sashiko-bot
2026-07-28  8:38     ` Bartosz Golaszewski
2026-07-27 20:39   ` [PATCH v2 61/64] dmaengine: dw: defer callbacks via channel BH Allen Pais
2026-07-27 21:31     ` sashiko-bot
2026-07-27 20:39   ` [PATCH v2 62/64] dmaengine: hidma: " Allen Pais
2026-07-27 21:25     ` sashiko-bot
2026-07-27 20:39   ` [PATCH v2 63/64] dmaengine: qcom-gpi: defer callbacks via vchan Allen Pais
2026-07-27 21:24     ` sashiko-bot
2026-07-27 20:39   ` [PATCH v2 64/64] dmaengine: switchtec: use channel BH helpers Allen Pais
2026-07-27 21:08     ` Logan Gunthorpe
2026-07-27 21:22     ` sashiko-bot
2026-07-28 20:39   ` [PATCH v2 00/64] dmaengine: migrate channel tasklets to WQ_BH Arnd Bergmann
2026-08-04  3:29     ` Allen
2026-08-10 18:09   ` [PATCH v3 00/34] " Allen Pais
2026-08-10 18:09     ` [PATCH v3 01/34] dmaengine: add tasklet-backed channel BH helpers Allen Pais
2026-08-10 18:09       ` Allen Pais
2026-08-10 18:30       ` sashiko-bot
2026-09-01 22:13       ` Frank Li [this message]
2026-09-01 22:13         ` Frank Li
2026-09-02 15:16       ` Frank Li
2026-09-02 15:16         ` Frank Li
2026-08-10 18:09     ` [PATCH v3 02/34] dmaengine: back channel BH helpers with WQ_BH Allen Pais
2026-08-11 17:49       ` Vinod Koul
2026-09-01 22:17       ` Frank Li
2026-08-10 18:09     ` [PATCH v3 03/34] dmaengine: apple-admac: use dmaengine BH callback Allen Pais
2026-08-10 18:29       ` sashiko-bot
2026-09-02 15:33       ` Frank Li
2026-08-10 18:09     ` [PATCH v3 04/34] dmaengine: at_xdmac: move irq bottom half to dmaengine BH Allen Pais
2026-08-10 18:35       ` sashiko-bot
2026-09-01 22:32       ` Frank Li
2026-08-10 18:09     ` [PATCH v3 05/34] dmaengine: ep93xx: hook callbacks via " Allen Pais
2026-08-10 18:31       ` sashiko-bot
2026-09-02 15:35       ` Frank Li
2026-08-10 18:09     ` [PATCH v3 06/34] dmaengine: fsldma: migrate tasklet to " Allen Pais
2026-08-10 18:29       ` sashiko-bot
2026-09-02 14:52       ` Frank Li
2026-08-10 18:09     ` [PATCH v3 07/34] dmaengine: fsl_raid: run completions via " Allen Pais
2026-08-10 18:27       ` sashiko-bot
2026-08-10 18:09     ` [PATCH v3 08/34] dmaengine: imx-dma: flip per-chan tasklet to " Allen Pais
2026-08-10 18:34       ` sashiko-bot
2026-09-02 15:17       ` Frank Li
2026-09-02 15:28       ` Frank Li
2026-08-10 18:09     ` [PATCH v3 09/34] dmaengine: ioat: convert cleanup " Allen Pais
2026-08-10 18:27       ` sashiko-bot
2026-09-02 14:44       ` Frank Li
2026-08-10 18:09     ` [PATCH v3 10/34] dmaengine: mmp_pdma: replace per-chan tasklet with " Allen Pais
2026-08-10 18:28       ` sashiko-bot
2026-09-02 14:52       ` Frank Li
2026-08-10 18:09     ` [PATCH v3 11/34] dmaengine: mmp_tdma: hook completions to " Allen Pais
2026-08-10 18:28       ` sashiko-bot
2026-09-02 15:30       ` Frank Li
2026-08-10 18:09     ` [PATCH v3 12/34] dmaengine: mv_xor: convert irq tasklet " Allen Pais
2026-08-10 18:27       ` sashiko-bot
2026-09-02 14:42       ` Frank Li
2026-08-10 18:09     ` [PATCH v3 13/34] dmaengine: mxs-dma: use dmaengine BH scheduling Allen Pais
2026-08-10 18:27       ` sashiko-bot
2026-09-02 15:33       ` Frank Li
2026-08-10 18:09     ` [PATCH v3 14/34] dmaengine: nbpfaxi: switch callbacks to dmaengine BH Allen Pais
2026-08-10 18:23       ` sashiko-bot
2026-08-10 18:09     ` [PATCH v3 15/34] dmaengine: pch_dma: convert tasklet " Allen Pais
2026-08-10 18:34       ` sashiko-bot
2026-09-02 14:55       ` Frank Li
2026-08-10 18:09     ` [PATCH v3 16/34] dmaengine: ppc4xx: replace irq tasklet with " Allen Pais
2026-08-10 18:36       ` sashiko-bot
2026-09-02 15:29       ` Frank Li
2026-08-10 18:09     ` [PATCH v3 17/34] dmaengine: ste_dma40: convert per-channel tasklet to " Allen Pais
2026-08-10 18:34       ` sashiko-bot
2026-09-02 14:43       ` Frank Li
2026-08-10 18:09     ` [PATCH v3 18/34] dmaengine: xgene-dma: wire descriptor cleanup " Allen Pais
2026-08-10 18:35       ` sashiko-bot
2026-09-02 15:29       ` Frank Li
2026-08-10 18:09     ` [PATCH v3 19/34] dmaengine: xilinx-dma: use dmaengine BH instead of tasklets Allen Pais
2026-08-10 18:28       ` sashiko-bot
2026-09-02 15:35       ` Frank Li
2026-08-10 18:09     ` [PATCH v3 20/34] dmaengine: xilinx-dpdma: kill vchan BH on remove Allen Pais
2026-08-10 18:31       ` sashiko-bot
2026-09-02 15:31       ` Frank Li
2026-08-10 18:09     ` [PATCH v3 21/34] dmaengine: zynqmp-dma: switch completion tasklet to dmaengine BH Allen Pais
2026-08-10 18:35       ` sashiko-bot
2026-09-02 15:30       ` Frank Li
2026-08-10 18:09     ` [PATCH v3 22/34] dmaengine: tegra20-apb: use channel BH helpers Allen Pais
2026-08-10 18:40       ` sashiko-bot
2026-08-10 18:09     ` [PATCH v3 23/34] dmaengine: timb_dma: route callbacks via channel BH Allen Pais
2026-08-10 18:45       ` sashiko-bot
2026-09-01 22:22       ` Frank Li
2026-08-10 18:09     ` [PATCH v3 24/34] dmaengine: txx9dmac: " Allen Pais
2026-08-10 18:34       ` sashiko-bot
2026-09-02 14:51       ` Frank Li
2026-08-10 18:09     ` [PATCH v3 25/34] dmaengine: mv_xor_v2: use channel BH helpers Allen Pais
2026-08-10 18:46       ` sashiko-bot
2026-09-02 15:32       ` Frank Li
2026-08-10 18:09     ` [PATCH v3 26/34] dmaengine: mpc512x: route callbacks via channel BH Allen Pais
2026-08-10 18:50       ` sashiko-bot
2026-09-02 14:48       ` Frank Li
2026-08-10 18:09     ` [PATCH v3 27/34] dmaengine: plx_dma: use channel BH helpers Allen Pais
2026-08-10 18:39       ` sashiko-bot
2026-09-02 14:44       ` Frank Li
2026-08-10 18:09     ` [PATCH v3 28/34] dmaengine: sf-pdma: route error callbacks through channel BH Allen Pais
2026-08-10 18:09       ` Allen Pais
2026-08-10 18:41       ` sashiko-bot
2026-09-02 15:39       ` Frank Li
2026-09-02 15:39         ` Frank Li
2026-08-10 18:09     ` [PATCH v3 29/34] dmaengine: pl330: route callbacks via " Allen Pais
2026-08-10 18:39       ` sashiko-bot
2026-09-02 15:40       ` Frank Li
2026-08-10 18:09     ` [PATCH v3 30/34] dmaengine: altera-msgdma: use channel BH helpers Allen Pais
2026-08-10 18:49       ` sashiko-bot
2026-09-01 22:31       ` Frank Li
2026-08-10 18:09     ` [PATCH v3 31/34] dmaengine: dw: defer callbacks via channel BH Allen Pais
2026-08-10 18:44       ` sashiko-bot
2026-08-11 10:51       ` Andy Shevchenko
2026-09-02 14:55       ` Frank Li
2026-08-10 18:09     ` [PATCH v3 32/34] dmaengine: hidma: " Allen Pais
2026-08-10 18:45       ` sashiko-bot
2026-09-02 15:47       ` Frank Li
2026-08-10 18:09     ` [PATCH v3 33/34] dmaengine: qcom-gpi: defer callbacks via vchan Allen Pais
2026-08-10 18:50       ` sashiko-bot
2026-09-01 22:30       ` Frank Li
2026-08-10 18:09     ` [PATCH v3 34/34] dmaengine: switchtec: use channel BH helpers Allen Pais
2026-08-10 18:43       ` sashiko-bot
2026-09-02 15:35       ` Frank Li
2026-08-11 10:30     ` [PATCH v3 00/34] dmaengine: migrate channel tasklets to WQ_BH Andy Shevchenko
2026-08-11 10:50     ` Andy Shevchenko
2026-08-11 20:44       ` Allen
2026-08-12  7:24         ` Andy Shevchenko
2026-09-02 15:49     ` Frank Li

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=apdN_G_1M4e81gQd@lizhi-Precision-Tower-5810 \
    --to=frank.li@oss.nxp.com \
    --cc=Eugeniy.Paltsev@synopsys.com \
    --cc=Frank.Li@kernel.org \
    --cc=afaerber@suse.de \
    --cc=allen.lkml@gmail.com \
    --cc=andersson@kernel.org \
    --cc=andy@kernel.org \
    --cc=angelogioacchino.delregno@collabora.com \
    --cc=arnd@arndb.de \
    --cc=baolin.wang@linux.alibaba.com \
    --cc=bcm-kernel-feedback-list@broadcom.com \
    --cc=brgl@kernel.org \
    --cc=daniel@zonque.org \
    --cc=dmaengine@vger.kernel.org \
    --cc=festevam@gmail.com \
    --cc=florian.fainelli@broadcom.com \
    --cc=haojian.zhuang@gmail.com \
    --cc=imx@lists.linux.dev \
    --cc=jernej.skrabec@gmail.com \
    --cc=jonathanh@nvidia.com \
    --cc=kees@kernel.org \
    --cc=keguang.zhang@gmail.com \
    --cc=kernel@pengutronix.de \
    --cc=konrad.dybcio@oss.qualcomm.com \
    --cc=kuldeep.singh@oss.qualcomm.com \
    --cc=lars@metafoo.de \
    --cc=ldewangan@nvidia.com \
    --cc=linux-actions@lists.infradead.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mediatek@lists.infradead.org \
    --cc=linux-mips@vger.kernel.org \
    --cc=linux-riscv@lists.infradead.org \
    --cc=linux-rpi-kernel@lists.infradead.org \
    --cc=linux-sunxi@lists.linux.dev \
    --cc=linux-tegra@vger.kernel.org \
    --cc=liulongfang@huawei.com \
    --cc=mani@kernel.org \
    --cc=matthias.bgg@gmail.com \
    --cc=orsonzhai@gmail.com \
    --cc=patrice.chotard@foss.st.com \
    --cc=paul@crapouillou.net \
    --cc=pjw@kernel.org \
    --cc=rjui@broadcom.com \
    --cc=robert.jarzmik@free.fr \
    --cc=s.hauer@pengutronix.de \
    --cc=samuel.holland@sifive.com \
    --cc=sbranden@broadcom.com \
    --cc=sean.wang@mediatek.com \
    --cc=stephan.gerhold@linaro.org \
    --cc=thierry.reding@kernel.org \
    --cc=vigneshr@ti.com \
    --cc=vkoul@kernel.org \
    --cc=wangzhou1@hisilicon.com \
    --cc=wens@kernel.org \
    --cc=zhang.lyra@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.