diff options
author | Ulf Hansson <ulf.hansson@linaro.org> | 2023-01-02 16:18:27 +0530 |
---|---|---|
committer | Bjorn Andersson <andersson@kernel.org> | 2023-01-10 11:07:10 -0600 |
commit | a9236a0aa7d7f52a974cc7eaa971fae92aa477c5 (patch) | |
tree | 6357a9433b6d9b976dd798f6a2fe95ebba2a9035 /drivers | |
parent | 1b929c02afd37871d5afb9d498426f83432e71c2 (diff) | |
download | linux-a9236a0aa7d7f52a974cc7eaa971fae92aa477c5.tar.gz linux-a9236a0aa7d7f52a974cc7eaa971fae92aa477c5.tar.bz2 linux-a9236a0aa7d7f52a974cc7eaa971fae92aa477c5.zip |
PM: domains: Allow a genpd consumer to require a synced power off
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.hansson@linaro.org>
Signed-off-by: Akhil P Oommen <quic_akhilpo@quicinc.com>
Reviewed-by: Bjorn Andersson <andersson@kernel.org>
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
Link: https://lore.kernel.org/r/20230102161757.v5.1.I3e6b1f078ad0f1ca9358c573daa7b70ec132cdbe@changeid
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/base/power/domain.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 967bcf9d415e..84662d338188 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -519,6 +519,31 @@ 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. + * + * It is assumed that the users guarantee that the genpd wouldn't be detached + * while this routine is getting called. + */ +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 +587,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, |