Some dma channels may not be available, so we need to tell the driver the available dma channels, use the general dt binding "dma-channel-mask" for this purpose. Signed-off-by: Jisheng Zhang <jszhang@xxxxxxxxxx> --- .../dma/dw-axi-dmac/dw-axi-dmac-platform.c | 19 +++++++++++++++++++ drivers/dma/dw-axi-dmac/dw-axi-dmac.h | 1 + 2 files changed, 20 insertions(+) diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c index edb1c089a8eb..a6e46cb66000 100644 --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c @@ -216,6 +216,8 @@ static void axi_dma_hw_init(struct axi_dma_chip *chip) u32 i; for (i = 0; i < chip->dw->hdata->nr_channels; i++) { + if (!(chip->dw->hdata->channels_mask & (1 << i))) + continue; axi_chan_irq_disable(&chip->dw->chan[i], DWAXIDMAC_IRQ_ALL); axi_chan_disable(&chip->dw->chan[i]); } @@ -1390,6 +1392,14 @@ static int parse_device_properties(struct axi_dma_chip *chip) chip->dw->hdata->axi_rw_burst_len = tmp; } + /* + * Use all channels if there's no dma-channel-mask property + */ + ret = device_property_read_u32(dev, "dma-channel-mask", &tmp); + if (ret) + tmp = GENMASK(chip->dw->hdata->nr_channels - 1, 0); + chip->dw->hdata->channels_mask = tmp; + chip->dw->hdata->perch_irq = device_property_read_bool(dev, "snps,perch_irq"); return 0; @@ -1450,6 +1460,10 @@ static int dw_probe(struct platform_device *pdev) if (hdata->perch_irq) { char irqname[8]; for (i = 0; i < hdata->nr_channels; i++) { + if (!(hdata->channels_mask & (1 << i))) { + dw->chan[i].irq = -1; + continue; + } snprintf(irqname, sizeof(irqname), "ch%u", i); dw->chan[i].irq = platform_get_irq_byname(pdev, irqname); if (dw->chan[i].irq < 0) @@ -1475,6 +1489,9 @@ static int dw_probe(struct platform_device *pdev) for (i = 0; i < hdata->nr_channels; i++) { struct axi_dma_chan *chan = &dw->chan[i]; + if (!(hdata->channels_mask & (1 << i))) + continue; + chan->chip = chip; chan->id = i; chan->chan_regs = chip->regs + COMMON_REG_LEN + i * CHAN_REG_LEN; @@ -1572,6 +1589,8 @@ static int dw_remove(struct platform_device *pdev) clk_prepare_enable(chip->core_clk); axi_dma_irq_disable(chip); for (i = 0; i < dw->hdata->nr_channels; i++) { + if (!(dw->hdata->channels_mask & (1 << i))) + continue; axi_chan_disable(&chip->dw->chan[i]); axi_chan_irq_disable(&chip->dw->chan[i], DWAXIDMAC_IRQ_ALL); } diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h index 83ac839b4394..f57961620d2d 100644 --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h @@ -30,6 +30,7 @@ struct dw_axi_dma_hcfg { u32 priority[DMAC_MAX_CHANNELS]; /* maximum supported axi burst length */ u32 axi_rw_burst_len; + u32 channels_mask; /* Register map for DMAX_NUM_CHANNELS <= 8 */ bool reg_map_8_channels; bool restrict_axi_burst_len; -- 2.39.2