[RFC PATCH] dmaengine: xilinx_dma: Fix per-channel direction reporting via device_caps
From: Folker Schwesinger <hidden>
Date: 2026-02-17 18:57:32
Also in:
dmaengine, lkml
Subsystem:
dma generic offload engine subsystem, the rest · Maintainers:
Vinod Koul, Linus Torvalds
Since commit 7e01511443c3 ("dmaengine: xilinx_dma: Set dma_device
directions") all channel directions are aggregated into
dma_device.directions so that dma_get_slave_caps() works for IIO
DMAEngine buffers.
However, this caused a regression in ASoC audio on ZynqMP platforms,
that causes cyclic playback to fail after the first buffer period,
because ASoC dmaengine PCM expects fixed per-channel direction reporting
from dma_get_slave_caps().
Implement optional device_caps() callback and override caps->directions
with the channel's fixed direction. This keeps device-wide direction
reporting for IIO intact while restoring correct per-channel semantics
for ASoC.
Other dma_slave_caps fields are left unchanged from their respective
values initialized from dma_get_slave_caps(). In case there should ever
be the need to override other fields, these can be added later.
Fixes: 7e01511443c3 ("dmaengine: xilinx_dma: Set dma_device directions")
Cc: stable@vger.kernel.org
Reported-by: Rahul Navale <redacted>
Closes: https://lore.kernel.org/dmaengine/20260211140051.8177-1-rahulnavale04@gmail.com/T/#u (local)
Closes: https://lore.kernel.org/dmaengine/CY1PR12MB96978AEBD6072FC469DFEAF1B762A@CY1PR12MB9697.namprd12.prod.outlook.com/T/#u (local)
Signed-off-by: Folker Schwesinger <redacted>
---
Posting this as RFC because I can't verify this actually fixes the
regression as I don't have a ZynqMP. So Rahul, could you test if this
fixes the issue and report back? BR F.
---
drivers/dma/xilinx/xilinx_dma.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c
index 64b3fba4e44f..bdd16173d762 100644
--- a/drivers/dma/xilinx/xilinx_dma.c
+++ b/drivers/dma/xilinx/xilinx_dma.c@@ -1711,6 +1711,19 @@ static void xilinx_dma_issue_pending(struct dma_chan *dchan) spin_unlock_irqrestore(&chan->lock, flags); } +/** + * xilinx_dma_device_caps - Write channel-specific DMA slave capabilities + * @dchan: DMA channel + * @caps: DMA slave capabilities of DMA channel + */ +static void xilinx_dma_device_caps(struct dma_chan *dchan, + struct dma_slave_caps *caps) +{ + struct xilinx_dma_chan *chan = to_xilinx_chan(dchan); + + caps->directions = chan->direction; +} + /** * xilinx_dma_device_config - Configure the DMA channel * @dchan: DMA channel
@@ -3292,6 +3305,7 @@ static int xilinx_dma_probe(struct platform_device *pdev) xdev->common.device_tx_status = xilinx_dma_tx_status; xdev->common.device_issue_pending = xilinx_dma_issue_pending; xdev->common.device_config = xilinx_dma_device_config; + xdev->common.device_caps = xilinx_dma_device_caps; if (xdev->dma_config->dmatype == XDMA_TYPE_AXIDMA) { dma_cap_set(DMA_CYCLIC, xdev->common.cap_mask); xdev->common.device_prep_peripheral_dma_vec = xilinx_dma_prep_peripheral_dma_vec;
base-commit: ab736ed52e3409b58a4888715e4425b6e8ac444f -- 2.53.0