On 12/21/2022 8:13 PM, Ulf Hansson wrote: > On Tue, 20 Dec 2022 at 08:44, Akhil P Oommen <quic_akhi...@quicinc.com> wrote: >> From: Ulf Hansson <ulf.hans...@linaro.org> >> >> Some genpd providers doesn't ensure that it has turned off at hardware. >> This is fine until the consumer really requires during some special >> scenarios that the power domain collapse at hardware before it is >> turned ON again. >> >> An example is the reset sequence of Adreno GPU which requires that the >> 'gpucc cx gdsc' power domain should move to OFF state in hardware at >> least once before turning in ON again to clear the internal state. >> >> Signed-off-by: Ulf Hansson <ulf.hans...@linaro.org> >> Signed-off-by: Akhil P Oommen <quic_akhi...@quicinc.com> >> --- >> >> (no changes since v2) >> >> Changes in v2: >> - Minor formatting fix >> >> drivers/base/power/domain.c | 23 +++++++++++++++++++++++ >> include/linux/pm_domain.h | 5 +++++ >> 2 files changed, 28 insertions(+) >> >> diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c >> index 967bcf9d415e..53524a102321 100644 >> --- a/drivers/base/power/domain.c >> +++ b/drivers/base/power/domain.c >> @@ -519,6 +519,28 @@ ktime_t dev_pm_genpd_get_next_hrtimer(struct device >> *dev) >> } >> EXPORT_SYMBOL_GPL(dev_pm_genpd_get_next_hrtimer); >> >> +/* >> + * dev_pm_genpd_synced_poweroff - Next power off should be synchronous >> + * >> + * @dev: A device that is attached to the genpd. >> + * >> + * Allows a consumer of the genpd to notify the provider that the next >> power off >> + * should be synchronous. > Nitpick; similar to other dev_pm_genpd_* function-descriptions, I > think it's important to add the below information. > > "It is assumed that the users guarantee that the genpd wouldn't be > detached while this routine is getting called." > > Can you please add that? Thanks. Fixed in revision 4.
-Akhil. > >> + */ >> +void dev_pm_genpd_synced_poweroff(struct device *dev) >> +{ >> + struct generic_pm_domain *genpd; >> + >> + genpd = dev_to_genpd_safe(dev); >> + if (!genpd) >> + return; >> + >> + genpd_lock(genpd); >> + genpd->synced_poweroff = true; >> + genpd_unlock(genpd); >> +} >> +EXPORT_SYMBOL_GPL(dev_pm_genpd_synced_poweroff); >> + >> static int _genpd_power_on(struct generic_pm_domain *genpd, bool timed) >> { >> unsigned int state_idx = genpd->state_idx; >> @@ -562,6 +584,7 @@ static int _genpd_power_on(struct generic_pm_domain >> *genpd, bool timed) >> >> out: >> raw_notifier_call_chain(&genpd->power_notifiers, GENPD_NOTIFY_ON, >> NULL); >> + genpd->synced_poweroff = false; >> return 0; >> err: >> raw_notifier_call_chain(&genpd->power_notifiers, GENPD_NOTIFY_OFF, >> diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h >> index 1cd41bdf73cf..f776fb93eaa0 100644 >> --- a/include/linux/pm_domain.h >> +++ b/include/linux/pm_domain.h >> @@ -136,6 +136,7 @@ struct generic_pm_domain { >> unsigned int prepared_count; /* Suspend counter of prepared >> devices */ >> unsigned int performance_state; /* Aggregated max performance state >> */ >> cpumask_var_t cpus; /* A cpumask of the attached CPUs */ >> + bool synced_poweroff; /* A consumer needs a synced >> poweroff */ >> int (*power_off)(struct generic_pm_domain *domain); >> int (*power_on)(struct generic_pm_domain *domain); >> struct raw_notifier_head power_notifiers; /* Power on/off notifiers >> */ >> @@ -235,6 +236,7 @@ int dev_pm_genpd_add_notifier(struct device *dev, struct >> notifier_block *nb); >> int dev_pm_genpd_remove_notifier(struct device *dev); >> void dev_pm_genpd_set_next_wakeup(struct device *dev, ktime_t next); >> ktime_t dev_pm_genpd_get_next_hrtimer(struct device *dev); >> +void dev_pm_genpd_synced_poweroff(struct device *dev); >> >> extern struct dev_power_governor simple_qos_governor; >> extern struct dev_power_governor pm_domain_always_on_gov; >> @@ -300,6 +302,9 @@ static inline ktime_t >> dev_pm_genpd_get_next_hrtimer(struct device *dev) >> { >> return KTIME_MAX; >> } >> +static inline void dev_pm_genpd_synced_poweroff(struct device *dev) >> +{ } >> + >> #define simple_qos_governor (*(struct dev_power_governor >> *)(NULL)) >> #define pm_domain_always_on_gov (*(struct dev_power_governor >> *)(NULL)) >> #endif >> -- >> 2.7.4 >> > Kind regards > Uffe