UPSTREAM: PM / Domains: Allow genpd to power on during system PM phases
[firefly-linux-kernel-4.4.55.git] / drivers / base / power / domain.c
index 376bf27108f97078783bb9965dad1d34daf7474b..0fc29774dc70866212afb1ae5a32543d1f9823c9 100644 (file)
@@ -183,8 +183,7 @@ static int __genpd_poweron(struct generic_pm_domain *genpd, unsigned int depth)
        struct gpd_link *link;
        int ret = 0;
 
-       if (genpd->status == GPD_STATE_ACTIVE
-           || (genpd->prepared_count > 0 && genpd->suspend_power_off))
+       if (genpd->status == GPD_STATE_ACTIVE)
                return 0;
 
        /*
@@ -693,21 +692,22 @@ static int pm_genpd_prepare(struct device *dev)
 
        mutex_lock(&genpd->lock);
 
-       if (genpd->prepared_count++ == 0) {
+       if (genpd->prepared_count++ == 0)
                genpd->suspended_count = 0;
-               genpd->suspend_power_off = genpd->status == GPD_STATE_POWER_OFF;
-       }
 
        mutex_unlock(&genpd->lock);
 
-       if (genpd->suspend_power_off)
-               return 0;
-
        /*
-        * The PM domain must be in the GPD_STATE_ACTIVE state at this point,
-        * so genpd_poweron() will return immediately, but if the device
-        * is suspended (e.g. it's been stopped by genpd_stop_dev()), we need
-        * to make it operational.
+        * Even if the PM domain is powered off at this point, we can't expect
+        * it to remain in that state during the entire system PM suspend
+        * phase. Any subsystem/driver for a device in the PM domain, may still
+        * need to serve a request which may require the device to be runtime
+        * resumed and its PM domain to be powered.
+        *
+        * As we are disabling runtime PM at this point, we are preventing the
+        * subsystem/driver to decide themselves. For that reason, we need to
+        * make sure the device is operational as it may be required in some
+        * cases.
         */
        pm_runtime_resume(dev);
        __pm_runtime_disable(dev, false);
@@ -716,8 +716,7 @@ static int pm_genpd_prepare(struct device *dev)
        if (ret) {
                mutex_lock(&genpd->lock);
 
-               if (--genpd->prepared_count == 0)
-                       genpd->suspend_power_off = false;
+               genpd->prepared_count--;
 
                mutex_unlock(&genpd->lock);
                pm_runtime_enable(dev);
@@ -744,7 +743,7 @@ static int pm_genpd_suspend(struct device *dev)
        if (IS_ERR(genpd))
                return -EINVAL;
 
-       return genpd->suspend_power_off ? 0 : pm_generic_suspend(dev);
+       return pm_generic_suspend(dev);
 }
 
 /**
@@ -765,7 +764,7 @@ static int pm_genpd_suspend_late(struct device *dev)
        if (IS_ERR(genpd))
                return -EINVAL;
 
-       return genpd->suspend_power_off ? 0 : pm_generic_suspend_late(dev);
+       return pm_generic_suspend_late(dev);
 }
 
 /**
@@ -785,8 +784,7 @@ static int pm_genpd_suspend_noirq(struct device *dev)
        if (IS_ERR(genpd))
                return -EINVAL;
 
-       if (genpd->suspend_power_off
-           || (dev->power.wakeup_path && genpd_dev_active_wakeup(genpd, dev)))
+       if (dev->power.wakeup_path && genpd_dev_active_wakeup(genpd, dev))
                return 0;
 
        genpd_stop_dev(genpd, dev);
@@ -818,8 +816,7 @@ static int pm_genpd_resume_noirq(struct device *dev)
        if (IS_ERR(genpd))
                return -EINVAL;
 
-       if (genpd->suspend_power_off
-           || (dev->power.wakeup_path && genpd_dev_active_wakeup(genpd, dev)))
+       if (dev->power.wakeup_path && genpd_dev_active_wakeup(genpd, dev))
                return 0;
 
        /*
@@ -852,7 +849,7 @@ static int pm_genpd_resume_early(struct device *dev)
        if (IS_ERR(genpd))
                return -EINVAL;
 
-       return genpd->suspend_power_off ? 0 : pm_generic_resume_early(dev);
+       return pm_generic_resume_early(dev);
 }
 
 /**
@@ -873,7 +870,7 @@ static int pm_genpd_resume(struct device *dev)
        if (IS_ERR(genpd))
                return -EINVAL;
 
-       return genpd->suspend_power_off ? 0 : pm_generic_resume(dev);
+       return pm_generic_resume(dev);
 }
 
 /**
@@ -894,7 +891,7 @@ static int pm_genpd_freeze(struct device *dev)
        if (IS_ERR(genpd))
                return -EINVAL;
 
-       return genpd->suspend_power_off ? 0 : pm_generic_freeze(dev);
+       return pm_generic_freeze(dev);
 }
 
 /**
@@ -916,7 +913,7 @@ static int pm_genpd_freeze_late(struct device *dev)
        if (IS_ERR(genpd))
                return -EINVAL;
 
-       return genpd->suspend_power_off ? 0 : pm_generic_freeze_late(dev);
+       return pm_generic_freeze_late(dev);
 }
 
 /**
@@ -938,7 +935,7 @@ static int pm_genpd_freeze_noirq(struct device *dev)
        if (IS_ERR(genpd))
                return -EINVAL;
 
-       return genpd->suspend_power_off ? 0 : genpd_stop_dev(genpd, dev);
+       return genpd_stop_dev(genpd, dev);
 }
 
 /**
@@ -958,8 +955,7 @@ static int pm_genpd_thaw_noirq(struct device *dev)
        if (IS_ERR(genpd))
                return -EINVAL;
 
-       return genpd->suspend_power_off ?
-               0 : genpd_start_dev(genpd, dev);
+       return genpd_start_dev(genpd, dev);
 }
 
 /**
@@ -981,7 +977,7 @@ static int pm_genpd_thaw_early(struct device *dev)
        if (IS_ERR(genpd))
                return -EINVAL;
 
-       return genpd->suspend_power_off ? 0 : pm_generic_thaw_early(dev);
+       return pm_generic_thaw_early(dev);
 }
 
 /**
@@ -1002,7 +998,7 @@ static int pm_genpd_thaw(struct device *dev)
        if (IS_ERR(genpd))
                return -EINVAL;
 
-       return genpd->suspend_power_off ? 0 : pm_generic_thaw(dev);
+       return pm_generic_thaw(dev);
 }
 
 /**
@@ -1030,26 +1026,13 @@ static int pm_genpd_restore_noirq(struct device *dev)
         * At this point suspended_count == 0 means we are being run for the
         * first time for the given domain in the present cycle.
         */
-       if (genpd->suspended_count++ == 0) {
+       if (genpd->suspended_count++ == 0)
                /*
                 * The boot kernel might put the domain into arbitrary state,
                 * so make it appear as powered off to pm_genpd_sync_poweron(),
                 * so that it tries to power it on in case it was really off.
                 */
                genpd->status = GPD_STATE_POWER_OFF;
-               if (genpd->suspend_power_off) {
-                       /*
-                        * If the domain was off before the hibernation, make
-                        * sure it will be off going forward.
-                        */
-                       genpd_power_off(genpd, true);
-
-                       return 0;
-               }
-       }
-
-       if (genpd->suspend_power_off)
-               return 0;
 
        pm_genpd_sync_poweron(genpd, true);
 
@@ -1068,7 +1051,6 @@ static int pm_genpd_restore_noirq(struct device *dev)
 static void pm_genpd_complete(struct device *dev)
 {
        struct generic_pm_domain *genpd;
-       bool run_complete;
 
        dev_dbg(dev, "%s()\n", __func__);
 
@@ -1078,18 +1060,14 @@ static void pm_genpd_complete(struct device *dev)
 
        mutex_lock(&genpd->lock);
 
-       run_complete = !genpd->suspend_power_off;
-       if (--genpd->prepared_count == 0)
-               genpd->suspend_power_off = false;
+       genpd->prepared_count--;
 
        mutex_unlock(&genpd->lock);
 
-       if (run_complete) {
-               pm_generic_complete(dev);
-               pm_runtime_set_active(dev);
-               pm_runtime_enable(dev);
-               pm_request_idle(dev);
-       }
+       pm_generic_complete(dev);
+       pm_runtime_set_active(dev);
+       pm_runtime_enable(dev);
+       pm_request_idle(dev);
 }
 
 /**