OSDN Git Service

Merge tag 'dmaengine-5.3-rc1' of git://git.infradead.org/users/vkoul/slave-dma
[tomoyo/tomoyo-test1.git] / drivers / dma / pl330.c
index 56f9fab..1163af2 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/err.h>
 #include <linux/pm_runtime.h>
 #include <linux/bug.h>
+#include <linux/reset.h>
 
 #include "dmaengine.h"
 #define PL330_MAX_CHAN         8
@@ -496,6 +497,9 @@ struct pl330_dmac {
        unsigned int num_peripherals;
        struct dma_pl330_chan *peripherals; /* keep at end */
        int quirks;
+
+       struct reset_control    *rstc;
+       struct reset_control    *rstc_ocp;
 };
 
 static struct pl330_of_quirks {
@@ -3024,6 +3028,32 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 
        amba_set_drvdata(adev, pl330);
 
+       pl330->rstc = devm_reset_control_get_optional(&adev->dev, "dma");
+       if (IS_ERR(pl330->rstc)) {
+               if (PTR_ERR(pl330->rstc) != -EPROBE_DEFER)
+                       dev_err(&adev->dev, "Failed to get reset!\n");
+               return PTR_ERR(pl330->rstc);
+       } else {
+               ret = reset_control_deassert(pl330->rstc);
+               if (ret) {
+                       dev_err(&adev->dev, "Couldn't deassert the device from reset!\n");
+                       return ret;
+               }
+       }
+
+       pl330->rstc_ocp = devm_reset_control_get_optional(&adev->dev, "dma-ocp");
+       if (IS_ERR(pl330->rstc_ocp)) {
+               if (PTR_ERR(pl330->rstc_ocp) != -EPROBE_DEFER)
+                       dev_err(&adev->dev, "Failed to get OCP reset!\n");
+               return PTR_ERR(pl330->rstc_ocp);
+       } else {
+               ret = reset_control_deassert(pl330->rstc_ocp);
+               if (ret) {
+                       dev_err(&adev->dev, "Couldn't deassert the device from OCP reset!\n");
+                       return ret;
+               }
+       }
+
        for (i = 0; i < AMBA_NR_IRQS; i++) {
                irq = adev->irq[i];
                if (irq) {
@@ -3164,6 +3194,11 @@ probe_err3:
 probe_err2:
        pl330_del(pl330);
 
+       if (pl330->rstc_ocp)
+               reset_control_assert(pl330->rstc_ocp);
+
+       if (pl330->rstc)
+               reset_control_assert(pl330->rstc);
        return ret;
 }
 
@@ -3202,6 +3237,11 @@ static int pl330_remove(struct amba_device *adev)
 
        pl330_del(pl330);
 
+       if (pl330->rstc_ocp)
+               reset_control_assert(pl330->rstc_ocp);
+
+       if (pl330->rstc)
+               reset_control_assert(pl330->rstc);
        return 0;
 }