[PATCH v24 03/14] dmaengine: qcom: bam_dma: convert tasklet to a BH workqueue
Bartosz Golaszewski <[email protected]> Thu, 23 Jul 2026 19:09:09 +0200
| Newsgroups | org.kernel.vger.linux-crypto,org.infradead.lists.linux-arm-kernel,org.kernel.vger.dmaengine,org.kernel.vger.linux-arm-msm,org.kernel.vger.linux-doc,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
BH workqueues are a modern mechanism, aiming to replace legacy tasklets. Let's convert the BAM DMA driver to using the high-priority variant of the BH workqueue. [Vinod: suggested using the BG workqueue instead of the regular one running in process context] Suggested-by: Vinod Koul <[email protected]> Reviewed-by: Dmitry Baryshkov <[email protected]> Reviewed-by: Bjorn Andersson <[email protected]> Signed-off-by: Bartosz Golaszewski <[email protected]> Reviewed-by: Manivannan Sadhasivam <[email protected]> Signed-off-by: Bartosz Golaszewski <[email protected]> --- drivers/dma/qcom/bam_dma.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/dma/qcom/bam_dma.c b/drivers/dma/qcom/bam_dma.c index fc155e0d1870cbb7e099a2c4280f9f8fbdf6cf15..ea3df28e777f99c0532761b6aee6807ab23ab4ca 100644 --- a/drivers/dma/qcom/bam_dma.c +++ b/drivers/dma/qcom/bam_dma.c @@ -42,6 +42,7 @@ #include <linux/pm_runtime.h> #include <linux/scatterlist.h> #include <linux/slab.h> +#include <linux/workqueue.h> #include "../dmaengine.h" #include "../virt-dma.h" @@ -426,8 +427,8 @@ struct bam_device { struct clk *bamclk; int irq; - /* dma start transaction tasklet */ - struct tasklet_struct task; + /* dma start transaction workqueue */ + struct work_struct work; }; /** @@ -892,7 +893,7 @@ static u32 process_channel_irqs(struct bam_device *bdev) /* * if complete, process cookie. Otherwise * push back to front of desc_issued so that - * it gets restarted by the tasklet + * it gets restarted by the work queue. */ if (!async_desc->num_desc) { vchan_cookie_complete(&async_desc->vd); @@ -922,9 +923,9 @@ static irqreturn_t bam_dma_irq(int irq, void *data) srcs |= process_channel_irqs(bdev); - /* kick off tasklet to start next dma transfer */ + /* kick off the work queue to start next dma transfer */ if (srcs & P_IRQ) - tasklet_schedule(&bdev->task); + queue_work(system_bh_highpri_wq, &bdev->work); ret = pm_runtime_get_sync(bdev->dev); if (ret < 0) @@ -1120,14 +1121,14 @@ static void bam_start_dma(struct bam_chan *bchan) } /** - * dma_tasklet - DMA IRQ tasklet - * @t: tasklet argument (bam controller structure) + * bam_dma_work() - DMA interrupt work queue callback + * @work: work queue struct embedded in the BAM controller device struct * * Sets up next DMA operation and then processes all completed transactions */ -static void dma_tasklet(struct tasklet_struct *t) +static void bam_dma_work(struct work_struct *work) { - struct bam_device *bdev = from_tasklet(bdev, t, task); + struct bam_device *bdev = from_work(bdev, work, work); struct bam_chan *bchan; unsigned int i; @@ -1140,14 +1141,13 @@ static void dma_tasklet(struct tasklet_struct *t) if (!list_empty(&bchan->vc.desc_issued) && !IS_BUSY(bchan)) bam_start_dma(bchan); } - } /** * bam_issue_pending - starts pending transactions * @chan: dma channel * - * Calls tasklet directly which in turn starts any pending transactions + * Calls work queue directly which in turn starts any pending transactions */ static void bam_issue_pending(struct dma_chan *chan) { @@ -1316,14 +1316,14 @@ static int bam_dma_probe(struct platform_device *pdev) if (ret) goto err_disable_clk; - tasklet_setup(&bdev->task, dma_tasklet); + INIT_WORK(&bdev->work, bam_dma_work); bdev->channels = devm_kcalloc(bdev->dev, bdev->num_channels, sizeof(*bdev->channels), GFP_KERNEL); if (!bdev->channels) { ret = -ENOMEM; - goto err_tasklet_kill; + goto err_workqueue_cancel; } /* allocate and initialize channels */ @@ -1389,8 +1389,8 @@ static int bam_dma_probe(struct platform_device *pdev) err_bam_channel_exit: for (i = 0; i < bdev->num_channels; i++) tasklet_kill(&bdev->channels[i].vc.task); -err_tasklet_kill: - tasklet_kill(&bdev->task); +err_workqueue_cancel: + cancel_work_sync(&bdev->work); err_disable_clk: clk_disable_unprepare(bdev->bamclk); @@ -1424,7 +1424,7 @@ static void bam_dma_remove(struct platform_device *pdev) bdev->channels[i].fifo_phys); } - tasklet_kill(&bdev->task); + cancel_work_sync(&bdev->work); clk_disable_unprepare(bdev->bamclk); } -- 2.47.3