Message ID | 68ccb5a90d1d2a596e7ed94ba3245171f013c781.1556313614.git.leonard.crestez@nxp.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | Allow imx6qp PU domain off in suspend | expand |
On Fri, 26 Apr 2019 at 23:38, Leonard Crestez <leonard.crestez@nxp.com> wrote: > > 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> > --- > drivers/base/power/domain.c | 8 ++++++-- > include/linux/pm_domain.h | 4 ++++ > 2 files changed, 10 insertions(+), 2 deletions(-) > > diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c > index 189d7e14c611..f502218a0ddb 100644 > --- a/drivers/base/power/domain.c > +++ b/drivers/base/power/domain.c > @@ -126,10 +126,11 @@ static const struct genpd_lock_ops genpd_spin_ops = { > #define genpd_status_on(genpd) (genpd->status == GPD_STATE_ACTIVE) > #define genpd_is_irq_safe(genpd) (genpd->flags & GENPD_FLAG_IRQ_SAFE) > #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_no_runtime_off(genpd) (genpd->flags & GENPD_FLAG_NO_RUNTIME_OFF) May I suggest to switch the name to, GENPD_FLAG_RUNTIME_ON. Other than that, this looks good to me! Kind regards Uffe > > static inline bool irq_safe_dev_in_no_sleep_domain(struct device *dev, > const struct generic_pm_domain *genpd) > { > bool ret; > @@ -513,11 +514,13 @@ static int genpd_power_off(struct generic_pm_domain *genpd, bool one_dev_on, > /* > * Abort power off for the PM domain in the following situations: > * (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_no_runtime_off(genpd) || > + atomic_read(&genpd->sd_count) > 0) > return -EBUSY; > > list_for_each_entry(pdd, &genpd->dev_list, list_node) { > enum pm_qos_flags_status stat; > > @@ -1813,11 +1816,12 @@ int pm_genpd_init(struct generic_pm_domain *genpd, > genpd->dev_ops.stop = pm_clk_suspend; > genpd->dev_ops.start = pm_clk_resume; > } > > /* 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_no_runtime_off(genpd)) && > + !genpd_status_on(genpd)) > return -EINVAL; > > if (genpd_is_cpu_domain(genpd) && > !zalloc_cpumask_var(&genpd->cpus, GFP_KERNEL)) > return -ENOMEM; > diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h > index bc82e74560ee..c9f3137e2c00 100644 > --- a/include/linux/pm_domain.h > +++ b/include/linux/pm_domain.h > @@ -51,16 +51,20 @@ > * deploy idle power management support for CPUs > * and groups of CPUs. Note that, the backend > * driver must then comply with the so called, > * last-man-standing algorithm, for the CPUs in the > * PM domain. > + * > + * GENPD_FLAG_NO_RUNTIME_OFF: 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_NO_RUNTIME_OFF (1U << 5) /* Never powered off by RPM */ > > enum gpd_status { > GPD_STATE_ACTIVE = 0, /* PM domain is active */ > GPD_STATE_POWER_OFF, /* PM domain is off */ > }; > -- > 2.17.1 >
On 4/29/2019 12:11 PM, Ulf Hansson wrote: > On Fri, 26 Apr 2019 at 23:38, Leonard Crestez <leonard.crestez@nxp.com> wrote: >> >> This is for power domains which can only be powered off for suspend but >> not as part of runtime PM. >> >> @@ -126,10 +126,11 @@ static const struct genpd_lock_ops genpd_spin_ops = { >> #define genpd_status_on(genpd) (genpd->status == GPD_STATE_ACTIVE) >> #define genpd_is_irq_safe(genpd) (genpd->flags & GENPD_FLAG_IRQ_SAFE) >> #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_no_runtime_off(genpd) (genpd->flags & GENPD_FLAG_NO_RUNTIME_OFF) > > May I suggest to switch the name to, GENPD_FLAG_RUNTIME_ON. > > Other than that, this looks good to me! Then it's easy to confuse genpd_status_on with genpd_is_runtime_on. How about genpd_is_rpm_always_on? -- Regards, Leonard
On Mon, 29 Apr 2019 at 16:39, Leonard Crestez <leonard.crestez@nxp.com> wrote: > > On 4/29/2019 12:11 PM, Ulf Hansson wrote: > > On Fri, 26 Apr 2019 at 23:38, Leonard Crestez <leonard.crestez@nxp.com> wrote: > >> > >> This is for power domains which can only be powered off for suspend but > >> not as part of runtime PM. > >> > >> @@ -126,10 +126,11 @@ static const struct genpd_lock_ops genpd_spin_ops = { > >> #define genpd_status_on(genpd) (genpd->status == GPD_STATE_ACTIVE) > >> #define genpd_is_irq_safe(genpd) (genpd->flags & GENPD_FLAG_IRQ_SAFE) > >> #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_no_runtime_off(genpd) (genpd->flags & GENPD_FLAG_NO_RUNTIME_OFF) > > > May I suggest to switch the name to, GENPD_FLAG_RUNTIME_ON. > > > > Other than that, this looks good to me! > > Then it's easy to confuse genpd_status_on with genpd_is_runtime_on. How > about genpd_is_rpm_always_on? Even better, let's take that. Kind regards Uffe
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 189d7e14c611..f502218a0ddb 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -126,10 +126,11 @@ static const struct genpd_lock_ops genpd_spin_ops = { #define genpd_status_on(genpd) (genpd->status == GPD_STATE_ACTIVE) #define genpd_is_irq_safe(genpd) (genpd->flags & GENPD_FLAG_IRQ_SAFE) #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_no_runtime_off(genpd) (genpd->flags & GENPD_FLAG_NO_RUNTIME_OFF) static inline bool irq_safe_dev_in_no_sleep_domain(struct device *dev, const struct generic_pm_domain *genpd) { bool ret; @@ -513,11 +514,13 @@ static int genpd_power_off(struct generic_pm_domain *genpd, bool one_dev_on, /* * Abort power off for the PM domain in the following situations: * (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_no_runtime_off(genpd) || + atomic_read(&genpd->sd_count) > 0) return -EBUSY; list_for_each_entry(pdd, &genpd->dev_list, list_node) { enum pm_qos_flags_status stat; @@ -1813,11 +1816,12 @@ int pm_genpd_init(struct generic_pm_domain *genpd, genpd->dev_ops.stop = pm_clk_suspend; genpd->dev_ops.start = pm_clk_resume; } /* 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_no_runtime_off(genpd)) && + !genpd_status_on(genpd)) return -EINVAL; if (genpd_is_cpu_domain(genpd) && !zalloc_cpumask_var(&genpd->cpus, GFP_KERNEL)) return -ENOMEM; diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index bc82e74560ee..c9f3137e2c00 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h @@ -51,16 +51,20 @@ * deploy idle power management support for CPUs * and groups of CPUs. Note that, the backend * driver must then comply with the so called, * last-man-standing algorithm, for the CPUs in the * PM domain. + * + * GENPD_FLAG_NO_RUNTIME_OFF: 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_NO_RUNTIME_OFF (1U << 5) /* Never powered off by RPM */ enum gpd_status { GPD_STATE_ACTIVE = 0, /* PM domain is active */ GPD_STATE_POWER_OFF, /* PM domain is off */ };
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> --- drivers/base/power/domain.c | 8 ++++++-- include/linux/pm_domain.h | 4 ++++ 2 files changed, 10 insertions(+), 2 deletions(-)