[PATCH v2 63/64] dmaengine: qcom-gpi: defer callbacks via vchan

From: Allen Pais

Date: Mon Jul 27 2026 - 16:54:08 EST


Complete descriptors through virt-dma instead of invoking callbacks
directly from event processing. This preserves the transfer result for
the shared vchan BH, which invokes the callback and frees the descriptor;
drain that BH before releasing channel resources.

Signed-off-by: Allen Pais <allen.lkml@xxxxxxxxx>
---
drivers/dma/qcom/gpi.c | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/drivers/dma/qcom/gpi.c b/drivers/dma/qcom/gpi.c
index a5055a6273af..4cf68cf8eb2e 100644
--- a/drivers/dma/qcom/gpi.c
+++ b/drivers/dma/qcom/gpi.c
@@ -981,8 +981,12 @@ static void gpi_process_imed_data_event(struct gchan *gchan,
result.result = DMA_TRANS_NOERROR;
result.residue = gpi_desc->len - imed_event->length;

- dma_cookie_complete(&vd->tx);
- dmaengine_desc_get_callback_invoke(&vd->tx, &result);
+ spin_lock_irqsave(&gchan->vc.lock, flags);
+ list_del(&vd->node);
+ vd->tx_result = result;
+ vchan_cookie_complete(vd);
+ spin_unlock_irqrestore(&gchan->vc.lock, flags);
+ return;

gpi_free_desc:
spin_lock_irqsave(&gchan->vc.lock, flags);
@@ -1060,8 +1064,12 @@ static void gpi_process_xfer_compl_event(struct gchan *gchan,
result.residue = gpi_desc->len - compl_event->length;
dev_dbg(gpii->gpi_dev->dev, "Residue %d\n", result.residue);

- dma_cookie_complete(&vd->tx);
- dmaengine_desc_get_callback_invoke(&vd->tx, &result);
+ spin_lock_irqsave(&gchan->vc.lock, flags);
+ list_del(&vd->node);
+ vd->tx_result = result;
+ vchan_cookie_complete(vd);
+ spin_unlock_irqrestore(&gchan->vc.lock, flags);
+ return;

gpi_free_desc:
spin_lock_irqsave(&gchan->vc.lock, flags);
@@ -2009,6 +2017,7 @@ static void gpi_free_chan_resources(struct dma_chan *chan)

/* free all allocated memory */
gpi_free_ring(&gchan->ch_ring, gpii);
+ dma_chan_kill_bh(&gchan->vc.chan);
vchan_free_chan_resources(&gchan->vc);
kfree(gchan->config);

--
2.43.0