diff --git a/Documentation/devicetree/bindings/dma/fsl-edma-v3.txt b/Documentation/devicetree/bindings/dma/fsl-edma-v3.txt index 222ccf8605b0..a8d05427f954 100644 --- a/Documentation/devicetree/bindings/dma/fsl-edma-v3.txt +++ b/Documentation/devicetree/bindings/dma/fsl-edma-v3.txt @@ -12,8 +12,12 @@ Required properties: - reg : Specifies base physical address(s) and size of the eDMA channel registers. Each eDMA channel has separated register's address and size. - interrupts : A list of interrupt-specifiers, each channel has one interrupt. -- interrupt-names : Should contain: - "edma-chan12-tx" - the channel12 transmission interrupt +- interrupt-names : Should contain below template: + "edmaX-chanX-Xx" + | | |---> receive/transmit, r or t + | |---> channel id, the max number is 32 + |---> edma controller instance, 0, 1, 2,..etc + - #dma-cells : Must be <3>. The 1st cell specifies the channel ID. The 2nd cell specifies the channel priority. @@ -40,8 +44,8 @@ edma0: dma-controller@40018000 { , , ; - interrupt-names = "edma-chan12-tx", "edma-chan13-tx", - "edma-chan14-tx", "edma-chan15-tx"; + interrupt-names = "edma0-chan12-rx", "edma0-chan13-tx", + "edma0-chan14-rx", "edma0-chan15-tx"; status = "okay"; }; diff --git a/drivers/dma/fsl-edma-v3.c b/drivers/dma/fsl-edma-v3.c index ef8280e0f2e1..28b13fb454e1 100644 --- a/drivers/dma/fsl-edma-v3.c +++ b/drivers/dma/fsl-edma-v3.c @@ -107,6 +107,10 @@ #define ARGS_REMOTE BIT(1) #define ARGS_DFIFO BIT(2) +/* channel name template define in dts */ +#define CHAN_PREFIX "edma0-chan" +#define CHAN_POSFIX "-tx" + struct fsl_edma3_hw_tcd { __le32 saddr; __le16 soff; @@ -806,7 +810,10 @@ static int fsl_edma3_probe(struct platform_device *pdev) INIT_LIST_HEAD(&fsl_edma3->dma_dev.channels); for (i = 0; i < fsl_edma3->n_chans; i++) { struct fsl_edma3_chan *fsl_chan = &fsl_edma3->chans[i]; - char *txirq_name = fsl_chan->txirq_name; + const char *txirq_name = fsl_chan->txirq_name; + char chanid[3], id_len = 0; + char *p = chanid; + unsigned long val; fsl_chan->edma3 = fsl_edma3; /* Get per channel membase */ @@ -819,7 +826,31 @@ static int fsl_edma3_probe(struct platform_device *pdev) * channel0:0x10000, channel1:0x20000... total 32 channels */ fsl_chan->hw_chanid = (res->start >> 16) & 0x1f; - sprintf(txirq_name, "edma-chan%d-tx", fsl_chan->hw_chanid); + + ret = of_property_read_string_index(np, "interrupt-names", i, + &txirq_name); + if (ret) { + dev_err(&pdev->dev, "read interrupt-names fail.\n"); + return ret; + } + /* Get channel id length from dts, one-digit or double-digit */ + id_len = strlen(txirq_name) - strlen(CHAN_PREFIX) - + strlen(CHAN_POSFIX); + if (id_len > 2) { + dev_err(&pdev->dev, "%s is edmaX-chanX-tx in dts?\n", + res->name); + return -EINVAL; + } + /* Grab channel id from txirq_name */ + strncpy(p, txirq_name + strlen(CHAN_PREFIX), id_len); + *(p + id_len) = '\0'; + + /* check if the channel id match well with hw_chanid */ + ret = kstrtoul(chanid, 0, &val); + if (ret || val != fsl_chan->hw_chanid) { + dev_err(&pdev->dev, "%s,wrong id?\n", txirq_name); + return -EINVAL; + } /* request channel irq */ fsl_chan->txirq = platform_get_irq_byname(pdev, txirq_name);