Re: [PATCH v1 4/5] dmaengine: arm-dma350: Honour dma-channel-mask

From: Frank Li

Date: Wed Oct 28 2026 - 12:53:35 EST


On Fri, Oct 23, 2026 at 05:30:44PM +0800, Jelly Jia wrote:
> 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;
> +

dma-channel-mask is u32 array. If nchan >= 32, you should check
dma-channel-mask[1].

Frank

> dch->base = base + DMACH(i);
> writel_relaxed(CH_CMD_CLEAR, dch->base + CH_CMD);
>
> --
> 2.54.0
>