[PATCH v2 63/64] dmaengine: qcom-gpi: defer callbacks via vchan
Allen Pais <[email protected]> Mon, 27 Jul 2026 13:39:25 -0700
| Newsgroups | org.kernel.vger.dmaengine,org.kernel.vger.linux-arm-msm,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <2685692fbcc37b41bdef7b88e37ffc7ca359986e.1785183549.git.allen.lkml@gmail.com> |
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 <[email protected]> --- 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