drm/tegra: sor: Prepare for generic PM domain support
authorJon Hunter <jonathanh@nvidia.com>
Fri, 1 Jul 2016 13:21:38 +0000 (14:21 +0100)
committerThierry Reding <treding@nvidia.com>
Thu, 14 Jul 2016 12:57:03 +0000 (14:57 +0200)
The SOR driver for Tegra requires the SOR power partition to be enabled.
Now that Tegra supports the generic PM domain framework we manage the
SOR power partition via this framework. However, the sequence for
gating/ungating the SOR power partition requires that the SOR reset is
asserted/de-asserted at the time the SOR power partition is
gated/ungated, respectively. Now that the reset control core assumes
that resets are exclusive, the Tegra generic PM domain code and the SOR
driver cannot request the same reset unless we mark the reset as shared.
Sharing resets will not work in this case because we cannot guarantee
that the reset will be asserted/de-asserted at the appropriate time.
Therefore, given that the Tegra generic PM domain code will handle the
resets, do not request the reset in the SOR driver if the SOR device has
a PM domain associated.

Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
Signed-off-by: Thierry Reding <treding@nvidia.com>
drivers/gpu/drm/tegra/sor.c

index b652201eadad234930a305264ce2988fc907695c..cb7e0606217426911cc384a927800e8b3ac58181 100644 (file)
@@ -2350,10 +2350,13 @@ static int tegra_sor_init(struct host1x_client *client)
         * XXX: Remove this reset once proper hand-over from firmware to
         * kernel is possible.
         */
-       err = reset_control_assert(sor->rst);
-       if (err < 0) {
-               dev_err(sor->dev, "failed to assert SOR reset: %d\n", err);
-               return err;
+       if (sor->rst) {
+               err = reset_control_assert(sor->rst);
+               if (err < 0) {
+                       dev_err(sor->dev, "failed to assert SOR reset: %d\n",
+                               err);
+                       return err;
+               }
        }
 
        err = clk_prepare_enable(sor->clk);
@@ -2364,10 +2367,13 @@ static int tegra_sor_init(struct host1x_client *client)
 
        usleep_range(1000, 3000);
 
-       err = reset_control_deassert(sor->rst);
-       if (err < 0) {
-               dev_err(sor->dev, "failed to deassert SOR reset: %d\n", err);
-               return err;
+       if (sor->rst) {
+               err = reset_control_deassert(sor->rst);
+               if (err < 0) {
+                       dev_err(sor->dev, "failed to deassert SOR reset: %d\n",
+                               err);
+                       return err;
+               }
        }
 
        err = clk_prepare_enable(sor->clk_safe);
@@ -2601,11 +2607,14 @@ static int tegra_sor_probe(struct platform_device *pdev)
                goto remove;
        }
 
-       sor->rst = devm_reset_control_get(&pdev->dev, "sor");
-       if (IS_ERR(sor->rst)) {
-               err = PTR_ERR(sor->rst);
-               dev_err(&pdev->dev, "failed to get reset control: %d\n", err);
-               goto remove;
+       if (!pdev->dev.pm_domain) {
+               sor->rst = devm_reset_control_get(&pdev->dev, "sor");
+               if (IS_ERR(sor->rst)) {
+                       err = PTR_ERR(sor->rst);
+                       dev_err(&pdev->dev, "failed to get reset control: %d\n",
+                               err);
+                       goto remove;
+               }
        }
 
        sor->clk = devm_clk_get(&pdev->dev, NULL);
@@ -2711,10 +2720,12 @@ static int tegra_sor_suspend(struct device *dev)
        struct tegra_sor *sor = dev_get_drvdata(dev);
        int err;
 
-       err = reset_control_assert(sor->rst);
-       if (err < 0) {
-               dev_err(dev, "failed to assert reset: %d\n", err);
-               return err;
+       if (sor->rst) {
+               err = reset_control_assert(sor->rst);
+               if (err < 0) {
+                       dev_err(dev, "failed to assert reset: %d\n", err);
+                       return err;
+               }
        }
 
        usleep_range(1000, 2000);
@@ -2737,11 +2748,13 @@ static int tegra_sor_resume(struct device *dev)
 
        usleep_range(1000, 2000);
 
-       err = reset_control_deassert(sor->rst);
-       if (err < 0) {
-               dev_err(dev, "failed to deassert reset: %d\n", err);
-               clk_disable_unprepare(sor->clk);
-               return err;
+       if (sor->rst) {
+               err = reset_control_deassert(sor->rst);
+               if (err < 0) {
+                       dev_err(dev, "failed to deassert reset: %d\n", err);
+                       clk_disable_unprepare(sor->clk);
+                       return err;
+               }
        }
 
        return 0;