PM / Domains: Add GENPD_FLAG_RPM_ALWAYS_ON flag
authorLeonard Crestez <leonard.crestez@nxp.com>
Tue, 30 Apr 2019 15:06:11 +0000 (15:06 +0000)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Mon, 13 May 2019 08:51:31 +0000 (10:51 +0200)
This is for power domains which can only be powered off for suspend but
not as part of runtime PM.

Suggested-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Leonard Crestez <leonard.crestez@nxp.com>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
drivers/base/power/domain.c
include/linux/pm_domain.h

index 3d899e8abd585f09f49f8d5de7218a8d2357db55..a887575fafa9605154a8f4d2dab59beb834ec581 100644 (file)
@@ -130,6 +130,7 @@ static const struct genpd_lock_ops genpd_spin_ops = {
 #define genpd_is_always_on(genpd)      (genpd->flags & GENPD_FLAG_ALWAYS_ON)
 #define genpd_is_active_wakeup(genpd)  (genpd->flags & GENPD_FLAG_ACTIVE_WAKEUP)
 #define genpd_is_cpu_domain(genpd)     (genpd->flags & GENPD_FLAG_CPU_DOMAIN)
+#define genpd_is_rpm_always_on(genpd)  (genpd->flags & GENPD_FLAG_RPM_ALWAYS_ON)
 
 static inline bool irq_safe_dev_in_no_sleep_domain(struct device *dev,
                const struct generic_pm_domain *genpd)
@@ -517,7 +518,9 @@ static int genpd_power_off(struct generic_pm_domain *genpd, bool one_dev_on,
         * (1) The domain is configured as always on.
         * (2) When the domain has a subdomain being powered on.
         */
-       if (genpd_is_always_on(genpd) || atomic_read(&genpd->sd_count) > 0)
+       if (genpd_is_always_on(genpd) ||
+                       genpd_is_rpm_always_on(genpd) ||
+                       atomic_read(&genpd->sd_count) > 0)
                return -EBUSY;
 
        list_for_each_entry(pdd, &genpd->dev_list, list_node) {
@@ -1814,7 +1817,8 @@ int pm_genpd_init(struct generic_pm_domain *genpd,
        }
 
        /* Always-on domains must be powered on at initialization. */
-       if (genpd_is_always_on(genpd) && !genpd_status_on(genpd))
+       if ((genpd_is_always_on(genpd) || genpd_is_rpm_always_on(genpd)) &&
+                       !genpd_status_on(genpd))
                return -EINVAL;
 
        if (genpd_is_cpu_domain(genpd) &&
index 0e8e356bed6a406725dbc55e5d0dae72e419105c..b21f35f0ee2eafbfae04fa7c193f5be543d75825 100644 (file)
  *                             driver must then comply with the so called,
  *                             last-man-standing algorithm, for the CPUs in the
  *                             PM domain.
+ *
+ * GENPD_FLAG_RPM_ALWAYS_ON:   Instructs genpd to always keep the PM domain
+ *                             powered on except for system suspend.
  */
 #define GENPD_FLAG_PM_CLK       (1U << 0)
 #define GENPD_FLAG_IRQ_SAFE     (1U << 1)
 #define GENPD_FLAG_ALWAYS_ON    (1U << 2)
 #define GENPD_FLAG_ACTIVE_WAKEUP (1U << 3)
 #define GENPD_FLAG_CPU_DOMAIN   (1U << 4)
+#define GENPD_FLAG_RPM_ALWAYS_ON (1U << 5)
 
 enum gpd_status {
        GPD_STATE_ACTIVE = 0,   /* PM domain is active */