diff options
Diffstat (limited to 'drivers/base/power')
-rw-r--r-- | drivers/base/power/domain.c | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 90a9828fcb2f..ab0b740cc0f1 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -400,6 +400,23 @@ static int genpd_set_performance_state(struct device *dev, unsigned int state) return ret; } +static int genpd_drop_performance_state(struct device *dev) +{ + unsigned int prev_state = dev_gpd_data(dev)->performance_state; + + if (!genpd_set_performance_state(dev, 0)) + return prev_state; + + return 0; +} + +static void genpd_restore_performance_state(struct device *dev, + unsigned int state) +{ + if (state) + genpd_set_performance_state(dev, state); +} + /** * dev_pm_genpd_set_performance_state- Set performance state of device's power * domain. @@ -843,7 +860,8 @@ static int genpd_runtime_suspend(struct device *dev) { struct generic_pm_domain *genpd; bool (*suspend_ok)(struct device *__dev); - struct gpd_timing_data *td = &dev_gpd_data(dev)->td; + struct generic_pm_domain_data *gpd_data = dev_gpd_data(dev); + struct gpd_timing_data *td = &gpd_data->td; bool runtime_pm = pm_runtime_enabled(dev); ktime_t time_start; s64 elapsed_ns; @@ -900,6 +918,7 @@ static int genpd_runtime_suspend(struct device *dev) return 0; genpd_lock(genpd); + gpd_data->rpm_pstate = genpd_drop_performance_state(dev); genpd_power_off(genpd, true, 0); genpd_unlock(genpd); @@ -917,7 +936,8 @@ static int genpd_runtime_suspend(struct device *dev) static int genpd_runtime_resume(struct device *dev) { struct generic_pm_domain *genpd; - struct gpd_timing_data *td = &dev_gpd_data(dev)->td; + struct generic_pm_domain_data *gpd_data = dev_gpd_data(dev); + struct gpd_timing_data *td = &gpd_data->td; bool runtime_pm = pm_runtime_enabled(dev); ktime_t time_start; s64 elapsed_ns; @@ -941,6 +961,8 @@ static int genpd_runtime_resume(struct device *dev) genpd_lock(genpd); ret = genpd_power_on(genpd, 0); + if (!ret) + genpd_restore_performance_state(dev, gpd_data->rpm_pstate); genpd_unlock(genpd); if (ret) @@ -979,6 +1001,7 @@ err_stop: err_poweroff: if (!pm_runtime_is_irq_safe(dev) || genpd_is_irq_safe(genpd)) { genpd_lock(genpd); + gpd_data->rpm_pstate = genpd_drop_performance_state(dev); genpd_power_off(genpd, true, 0); genpd_unlock(genpd); } |