[PATCH v2 62/64] dmaengine: hidma: defer callbacks via channel BH
From: Allen Pais
Date: Mon Jul 27 2026 - 16:54:03 EST
Move descriptor callback processing out of the low-level completion
path and schedule it through per-channel BH work. Drain that work while
freeing channels so callbacks cannot outlive channel storage.
Signed-off-by: Allen Pais <allen.lkml@xxxxxxxxx>
---
drivers/dma/qcom/hidma.c | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/drivers/dma/qcom/hidma.c b/drivers/dma/qcom/hidma.c
index c939635be21d..1f875a499ab3 100644
--- a/drivers/dma/qcom/hidma.c
+++ b/drivers/dma/qcom/hidma.c
@@ -90,7 +90,13 @@ static inline struct hidma_chan *to_hidma_chan(struct dma_chan *dmach)
static void hidma_free(struct hidma_dev *dmadev)
{
- INIT_LIST_HEAD(&dmadev->ddev.channels);
+ struct hidma_chan *mchan, *next;
+
+ list_for_each_entry_safe(mchan, next, &dmadev->ddev.channels,
+ chan.device_node) {
+ dma_chan_kill_bh(&mchan->chan);
+ list_del(&mchan->chan.device_node);
+ }
}
static unsigned int nr_desc_prm;
@@ -155,6 +161,13 @@ static void hidma_process_completed(struct hidma_chan *mchan)
}
}
+static void hidma_chan_bh(struct dma_chan *chan)
+{
+ struct hidma_chan *mchan = to_hidma_chan(chan);
+
+ hidma_process_completed(mchan);
+}
+
/*
* Called once for each submitted descriptor.
* PM is locked once for each descriptor that is currently
@@ -181,7 +194,7 @@ static void hidma_callback(void *data)
}
spin_unlock_irqrestore(&mchan->lock, irqflags);
- hidma_process_completed(mchan);
+ dma_chan_schedule_bh(&mchan->chan);
if (queued) {
pm_runtime_mark_last_busy(dmadev->ddev.dev);
@@ -203,6 +216,7 @@ static int hidma_chan_init(struct hidma_dev *dmadev, u32 dma_sig)
mchan->dmadev = dmadev;
mchan->chan.device = ddev;
dma_cookie_init(&mchan->chan);
+ dma_chan_init_bh(&mchan->chan, hidma_chan_bh);
INIT_LIST_HEAD(&mchan->free);
INIT_LIST_HEAD(&mchan->prepared);
--
2.43.0