summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNuno Sá <nuno.sa@analog.com>2026-03-03 13:25:02 +0300
committerVinod Koul <vkoul@kernel.org>2026-03-09 10:28:21 +0300
commitc60990ba1fb2a6c1ff2789e610aa130f3047a2ff (patch)
tree7f690136cfc5fe0e5750923f214897d80c9156d0
parentac85913ab71e0de9827b7f8f7fccb9f20943c02f (diff)
downloadlinux-c60990ba1fb2a6c1ff2789e610aa130f3047a2ff.tar.xz
dmaengine: dma-axi-dmac: Add helper for getting next desc
Add a new helper for getting the next valid struct axi_dmac_desc. This will be extended in follow up patches to support to gracefully terminate cyclic transfers. Reviewed-by: Frank Li <Frank.Li@nxp.com> Signed-off-by: Nuno Sá <nuno.sa@analog.com> Link: https://patch.msgid.link/20260303-axi-dac-cyclic-support-v2-3-0db27b4be95a@analog.com Signed-off-by: Vinod Koul <vkoul@kernel.org>
-rw-r--r--drivers/dma/dma-axi-dmac.c33
1 files changed, 23 insertions, 10 deletions
diff --git a/drivers/dma/dma-axi-dmac.c b/drivers/dma/dma-axi-dmac.c
index 79c01b7d9732..a47e08d3dbbc 100644
--- a/drivers/dma/dma-axi-dmac.c
+++ b/drivers/dma/dma-axi-dmac.c
@@ -227,10 +227,29 @@ static bool axi_dmac_check_addr(struct axi_dmac_chan *chan, dma_addr_t addr)
return true;
}
+static struct axi_dmac_desc *axi_dmac_get_next_desc(struct axi_dmac *dmac,
+ struct axi_dmac_chan *chan)
+{
+ struct virt_dma_desc *vdesc;
+ struct axi_dmac_desc *desc;
+
+ if (chan->next_desc)
+ return chan->next_desc;
+
+ vdesc = vchan_next_desc(&chan->vchan);
+ if (!vdesc)
+ return NULL;
+
+ list_move_tail(&vdesc->node, &chan->active_descs);
+ desc = to_axi_dmac_desc(vdesc);
+ chan->next_desc = desc;
+
+ return desc;
+}
+
static void axi_dmac_start_transfer(struct axi_dmac_chan *chan)
{
struct axi_dmac *dmac = chan_to_axi_dmac(chan);
- struct virt_dma_desc *vdesc;
struct axi_dmac_desc *desc;
struct axi_dmac_sg *sg;
unsigned int flags = 0;
@@ -240,16 +259,10 @@ static void axi_dmac_start_transfer(struct axi_dmac_chan *chan)
if (val) /* Queue is full, wait for the next SOT IRQ */
return;
- desc = chan->next_desc;
+ desc = axi_dmac_get_next_desc(dmac, chan);
+ if (!desc)
+ return;
- if (!desc) {
- vdesc = vchan_next_desc(&chan->vchan);
- if (!vdesc)
- return;
- list_move_tail(&vdesc->node, &chan->active_descs);
- desc = to_axi_dmac_desc(vdesc);
- chan->next_desc = desc;
- }
sg = &desc->sg[desc->num_submitted];
/* Already queued in cyclic mode. Wait for it to finish */