aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/layerscape/patches-5.4/806-dma-0022-MLK-22284-1-dmaengine-fsl-edma-v3-add-power-domains-.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/layerscape/patches-5.4/806-dma-0022-MLK-22284-1-dmaengine-fsl-edma-v3-add-power-domains-.patch')
-rw-r--r--target/linux/layerscape/patches-5.4/806-dma-0022-MLK-22284-1-dmaengine-fsl-edma-v3-add-power-domains-.patch170
1 files changed, 170 insertions, 0 deletions
diff --git a/target/linux/layerscape/patches-5.4/806-dma-0022-MLK-22284-1-dmaengine-fsl-edma-v3-add-power-domains-.patch b/target/linux/layerscape/patches-5.4/806-dma-0022-MLK-22284-1-dmaengine-fsl-edma-v3-add-power-domains-.patch
new file mode 100644
index 0000000000..8c7fc44b91
--- /dev/null
+++ b/target/linux/layerscape/patches-5.4/806-dma-0022-MLK-22284-1-dmaengine-fsl-edma-v3-add-power-domains-.patch
@@ -0,0 +1,170 @@
+From 9050c0619cdf5399d19e3683d6fb1db355dda110 Mon Sep 17 00:00:00 2001
+From: Robin Gong <yibin.gong@nxp.com>
+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 <yibin.gong@nxp.com>
+Reviewed-by: S.j. Wang <shengjiu.wang@nxp.com>
+(cherry picked from commit 0b6da46b7bdb2284e24757d48466268b9feb5b7c)
+---
+ .../devicetree/bindings/dma/fsl-edma-v3.txt | 11 +++-
+ drivers/dma/fsl-edma-v3.c | 58 +++++++++++++++++++++-
+ 2 files changed, 67 insertions(+), 2 deletions(-)
+
+--- a/Documentation/devicetree/bindings/dma/fsl-edma-v3.txt
++++ b/Documentation/devicetree/bindings/dma/fsl-edma-v3.txt
+@@ -30,6 +30,8 @@ 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
++- power-domains: Power domains for edma channel used.
++- power-domain-names: Power domains name for edma channel used.
+
+ Examples:
+ edma0: dma-controller@40018000 {
+@@ -46,6 +48,12 @@ edma0: dma-controller@40018000 {
+ <GIC_SPI 437 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "edma0-chan12-rx", "edma0-chan13-tx",
+ "edma0-chan14-rx", "edma0-chan15-tx";
++ power-domains = <&pd IMX_SC_R_DMA_0_CH12>,
++ <&pd IMX_SC_R_DMA_0_CH13>,
++ <&pd IMX_SC_R_DMA_0_CH14>,
++ <&pd IMX_SC_R_DMA_0_CH15>;
++ power-domain-names = "edma0-chan12", "edma0-chan13",
++ "edma0-chan14", "edma0-chan15";
+ status = "okay";
+ };
+
+@@ -65,7 +73,8 @@ lpuart1: serial@5a070000 {
+ clock-names = "ipg";
+ assigned-clock-names = <&clk IMX8QM_UART1_CLK>;
+ assigned-clock-rates = <80000000>;
+- power-domains = <&pd_dma_lpuart1>;
++ power-domains = <&pd IMX_SC_R_UART_1>,
++ power-domain-names = "uart";
+ dma-names = "tx","rx";
+ dmas = <&edma0 15 0 0>,
+ <&edma0 14 0 1>;
+--- a/drivers/dma/fsl-edma-v3.c
++++ b/drivers/dma/fsl-edma-v3.c
+@@ -27,6 +27,8 @@
+ #include <linux/of_address.h>
+ #include <linux/of_irq.h>
+ #include <linux/of_dma.h>
++#include <linux/pm_runtime.h>
++#include <linux/pm_domain.h>
+
+ #include "virt-dma.h"
+
+@@ -164,6 +166,7 @@ struct fsl_edma3_chan {
+ u32 chn_real_count;
+ char txirq_name[32];
+ struct platform_device *pdev;
++ struct device *dev;
+ };
+
+ struct fsl_edma3_desc {
+@@ -798,8 +801,10 @@ static int fsl_edma3_alloc_chan_resource
+ 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->dev);
+ /* 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);
+@@ -830,6 +835,7 @@ static void fsl_edma3_free_chan_resource
+ dma_pool_destroy(fsl_chan->tcd_pool);
+ fsl_chan->tcd_pool = NULL;
+ fsl_chan->used = false;
++ pm_runtime_put_sync(fsl_chan->dev);
+ }
+
+ static void fsl_edma3_synchronize(struct dma_chan *chan)
+@@ -839,6 +845,37 @@ static void fsl_edma3_synchronize(struct
+ vchan_synchronize(&fsl_chan->vchan);
+ }
+
++static struct device *fsl_edma3_attach_pd(struct device *dev,
++ struct device_node *np, int index)
++{
++ const char *domn = "edma0-chan01";
++ struct device *pd_chan;
++ struct device_link *link;
++ int ret;
++
++ ret = of_property_read_string_index(np, "power-domain-names", index,
++ &domn);
++ if (ret) {
++ dev_err(dev, "parse power-domain-names error.(%d)\n", ret);
++ return NULL;
++ }
++
++ pd_chan = dev_pm_domain_attach_by_name(dev, domn);
++ if (!pd_chan)
++ return NULL;
++
++ link = device_link_add(dev, pd_chan, DL_FLAG_STATELESS |
++ DL_FLAG_PM_RUNTIME |
++ DL_FLAG_RPM_ACTIVE);
++ if (IS_ERR(link)) {
++ dev_err(dev, "Failed to add device_link to %s: %ld\n", domn,
++ PTR_ERR(link));
++ return NULL;
++ }
++
++ return pd_chan;
++}
++
+ static int fsl_edma3_probe(struct platform_device *pdev)
+ {
+ struct device_node *np = pdev->dev.of_node;
+@@ -962,6 +999,22 @@ static int fsl_edma3_probe(struct platfo
+ 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;
++
++ dev = fsl_edma3_attach_pd(&pdev->dev, np, i);
++ if (!dev) {
++ dev_err(dev, "edma channel attach failed.\n");
++ return -EINVAL;
++ }
++
++ fsl_chan->dev = 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) {
+@@ -970,6 +1023,9 @@ static int fsl_edma3_probe(struct platfo
+ return ret;
+ }
+
++ pm_runtime_dont_use_autosuspend(&pdev->dev);
++ pm_runtime_enable(&pdev->dev);
++
+ return 0;
+ }
+
+@@ -1068,7 +1124,7 @@ static int __init fsl_edma3_init(void)
+ {
+ return platform_driver_register(&fsl_edma3_driver);
+ }
+-subsys_initcall(fsl_edma3_init);
++fs_initcall(fsl_edma3_init);
+
+ static void __exit fsl_edma3_exit(void)
+ {