]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
dmaengine: dw-edma: Set status for callback_result
authorDevendra K Verma <devverma@amd.com>
Thu, 21 Aug 2025 12:15:05 +0000 (17:45 +0530)
committerVinod Koul <vkoul@kernel.org>
Tue, 2 Sep 2025 07:14:45 +0000 (12:44 +0530)
DMA Engine has support for the callback_result which provides
the status of the request and the residue. This helps in
determining the correct status of the request and in
efficient resource management of the request.
The 'callback_result' method is preferred over the deprecated
'callback' method.

Signed-off-by: Devendra K Verma <devverma@amd.com>
Link: https://lore.kernel.org/r/20250821121505.318179-1-devverma@amd.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
drivers/dma/dw-edma/dw-edma-core.c

index b43255f914f3395f5d0be438151d9dd0d52764ff..8e5f7defa6b678eefe0f312ebc59f654677c744f 100644 (file)
@@ -584,6 +584,25 @@ dw_edma_device_prep_interleaved_dma(struct dma_chan *dchan,
        return dw_edma_device_transfer(&xfer);
 }
 
+static void dw_hdma_set_callback_result(struct virt_dma_desc *vd,
+                                       enum dmaengine_tx_result result)
+{
+       u32 residue = 0;
+       struct dw_edma_desc *desc;
+       struct dmaengine_result *res;
+
+       if (!vd->tx.callback_result)
+               return;
+
+       desc = vd2dw_edma_desc(vd);
+       if (desc)
+               residue = desc->alloc_sz - desc->xfer_sz;
+
+       res = &vd->tx_result;
+       res->result = result;
+       res->residue = residue;
+}
+
 static void dw_edma_done_interrupt(struct dw_edma_chan *chan)
 {
        struct dw_edma_desc *desc;
@@ -597,6 +616,8 @@ static void dw_edma_done_interrupt(struct dw_edma_chan *chan)
                case EDMA_REQ_NONE:
                        desc = vd2dw_edma_desc(vd);
                        if (!desc->chunks_alloc) {
+                               dw_hdma_set_callback_result(vd,
+                                                           DMA_TRANS_NOERROR);
                                list_del(&vd->node);
                                vchan_cookie_complete(vd);
                        }
@@ -633,6 +654,7 @@ static void dw_edma_abort_interrupt(struct dw_edma_chan *chan)
        spin_lock_irqsave(&chan->vc.lock, flags);
        vd = vchan_next_desc(&chan->vc);
        if (vd) {
+               dw_hdma_set_callback_result(vd, DMA_TRANS_ABORTED);
                list_del(&vd->node);
                vchan_cookie_complete(vd);
        }