From 1a0833a4b8db6a054b654b109313278bdbc11ef2 Mon Sep 17 00:00:00 2001 From: Robin Gong Date: Wed, 17 Apr 2019 17:05:42 +0800 Subject: [PATCH] MLK-22284-1 dmaengine: fsl-edma-v3: add power domains for each channel Add power domains for each dma channel so that edma channel could know the power state of every dma channel anytime and clear easily unexpected interrupt which triggered before the last partition reset. Signed-off-by: Robin Gong Reviewed-by: S.j. Wang (cherry picked from commit 0b6da46b7bdb2284e24757d48466268b9feb5b7c) --- .../devicetree/bindings/dma/fsl-edma-v3.txt | 3 +++ drivers/dma/fsl-edma-v3.c | 27 +++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/Documentation/devicetree/bindings/dma/fsl-edma-v3.txt b/Documentation/devicetree/bindings/dma/fsl-edma-v3.txt index a8d05427f954..2fb7d1b69604 100644 --- a/Documentation/devicetree/bindings/dma/fsl-edma-v3.txt +++ b/Documentation/devicetree/bindings/dma/fsl-edma-v3.txt @@ -30,6 +30,7 @@ Required properties: 0: not dual fifo case, 1: dualfifo case. See the SoC's reference manual for all the supported request sources. - dma-channels : Number of channels supported by the controller +- pdomains: Power domains for edma channel used. Examples: edma0: dma-controller@40018000 { @@ -46,6 +47,8 @@ edma0: dma-controller@40018000 { ; interrupt-names = "edma0-chan12-rx", "edma0-chan13-tx", "edma0-chan14-rx", "edma0-chan15-tx"; + pdomains = <&pd_dma0_chan12>, <&pd_dma0_chan13>, + <&pd_dma0_chan14>, <&pd_dma0_chan15>, status = "okay"; }; diff --git a/drivers/dma/fsl-edma-v3.c b/drivers/dma/fsl-edma-v3.c index 0e7f5eeca2cb..1d63c6866d15 100644 --- a/drivers/dma/fsl-edma-v3.c +++ b/drivers/dma/fsl-edma-v3.c @@ -27,6 +27,8 @@ #include #include #include +#include +#include #include #include @@ -799,8 +801,10 @@ static int fsl_edma3_alloc_chan_resources(struct dma_chan *chan) fsl_chan->tcd_pool = dma_pool_create("tcd_pool", chan->device->dev, sizeof(struct fsl_edma3_hw_tcd), 32, 0); + pm_runtime_get_sync(&fsl_chan->vchan.chan.dev->device); /* clear meaningless pending irq anyway */ writel(1, fsl_chan->membase + EDMA_CH_INT); + ret = devm_request_irq(&pdev->dev, fsl_chan->txirq, fsl_edma3_tx_handler, fsl_chan->edma3->irqflag, fsl_chan->txirq_name, fsl_chan); @@ -831,6 +835,7 @@ static void fsl_edma3_free_chan_resources(struct dma_chan *chan) dma_pool_destroy(fsl_chan->tcd_pool); fsl_chan->tcd_pool = NULL; fsl_chan->used = false; + pm_runtime_put_sync(&fsl_chan->vchan.chan.dev->device); } static void fsl_edma3_synchronize(struct dma_chan *chan) @@ -975,6 +980,28 @@ static int fsl_edma3_probe(struct platform_device *pdev) dev_err(&pdev->dev, "Can't register Freescale eDMA engine.\n"); return ret; } + /* Attach power domains from dts for each dma chanel device */ + for (i = 0; i < fsl_edma3->n_chans; i++) { + struct fsl_edma3_chan *fsl_chan = &fsl_edma3->chans[i]; + struct device *dev = &fsl_chan->vchan.chan.dev->device; + struct of_phandle_args args; + + ret = of_parse_phandle_with_args(np, "pdomains", NULL, i, + &args); + if (ret < 0) { + dev_err(dev, "parse phandle failed(%d)\n", ret); + return ret; + } + + of_genpd_add_device(&args, dev); + pm_runtime_dont_use_autosuspend(dev); + pm_runtime_enable(dev); + + pm_runtime_get_sync(dev); + /* clear meaningless pending irq anyway */ + writel(1, fsl_chan->membase + EDMA_CH_INT); + pm_runtime_put_sync(dev); + } ret = of_dma_controller_register(np, fsl_edma3_xlate, fsl_edma3); if (ret) { -- 2.17.1