[PATCH v1 4/5] dmaengine: arm-dma350: Honour dma-channel-mask
From: Jelly Jia
Date: Fri Oct 23 2026 - 05:36:39 EST
DMA-350 channels may be reserved for firmware or another processor.
Read the optional dma-channel-mask property and register only the channels
whose bits are set. If the property is absent, preserve the existing
behaviour and expose every hardware channel.
Skip masked channels before accessing their channel registers or
initializing their interrupts and virt-dma state. This avoids clearing
or configuring channels reserved for firmware or another processor.
Signed-off-by: Jelly Jia <Jelly.Jia@xxxxxxxxxxx>
---
drivers/dma/arm-dma350.c | 20 +++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/drivers/dma/arm-dma350.c b/drivers/dma/arm-dma350.c
index 9cb5b2f03113..32ec6f061ee9 100644
--- a/drivers/dma/arm-dma350.c
+++ b/drivers/dma/arm-dma350.c
@@ -1205,9 +1205,10 @@ static int d350_probe(struct platform_device *pdev)
struct clk *clk;
struct d350 *dmac;
void __iomem *base;
+ u32 chan_mask = U32_MAX;
u32 reg;
int ret, nchan, dw, aw, r, p;
- bool coherent, memset;
+ bool coherent, has_chan_mask, memset;
clk = devm_clk_get_optional_enabled(dev, NULL);
if (IS_ERR(clk))
@@ -1285,6 +1286,19 @@ static int d350_probe(struct platform_device *pdev)
dmac->dma.device_config = d350_config;
INIT_LIST_HEAD(&dmac->dma.channels);
+ /*
+ * dma-channel-mask is optional. Firmware-reserved channels stay
+ * clear; if the property is absent, Linux may use every channel.
+ */
+ has_chan_mask = device_property_present(dev, "dma-channel-mask");
+ if (has_chan_mask) {
+ ret = device_property_read_u32(dev, "dma-channel-mask",
+ &chan_mask);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "failed to read dma-channel-mask\n");
+ }
+
reg = readl_relaxed(base + DMANSECCTRL + NSEC_CTRL);
writel_relaxed(reg | INTREN_ANYCHINTR_EN,
base + DMANSECCTRL + NSEC_CTRL);
@@ -1294,6 +1308,10 @@ static int d350_probe(struct platform_device *pdev)
for (int i = 0; i < nchan; i++) {
struct d350_chan *dch = &dmac->channels[i];
+ if (has_chan_mask &&
+ (i >= 32 || !(chan_mask & BIT(i))))
+ continue;
+
dch->base = base + DMACH(i);
writel_relaxed(CH_CMD_CLEAR, dch->base + CH_CMD);
--
2.54.0