Commit ba41e1bc authored by Rafael J. Wysocki's avatar Rafael J. Wysocki

cpufreq: intel_pstate: Fix HWP on boot CPU after system resume

Commit 41cfd64c "Update frequencies of policy->cpus only from
->set_policy()" changed the way the intel_pstate driver's ->set_policy
callback updates the HWP (hardware-managed P-states) settings.
A side effect of it is that if those settings are modified on the
boot CPU during system suspend and wakeup, they will never be
restored during subsequent system resume.

To address this problem, allow cpufreq drivers that don't provide
->target or ->target_index callbacks to use ->suspend and ->resume
callbacks and add a ->resume callback to intel_pstate to restore
the HWP settings on the CPUs that belong to the given policy.

Fixes: 41cfd64c "Update frequencies of policy->cpus only from ->set_policy()"
Tested-by: default avatarSrinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: default avatarViresh Kumar <viresh.kumar@linaro.org>
parent 2482bc31
...@@ -1557,21 +1557,25 @@ void cpufreq_suspend(void) ...@@ -1557,21 +1557,25 @@ void cpufreq_suspend(void)
if (!cpufreq_driver) if (!cpufreq_driver)
return; return;
if (!has_target()) if (!has_target() && !cpufreq_driver->suspend)
goto suspend; goto suspend;
pr_debug("%s: Suspending Governors\n", __func__); pr_debug("%s: Suspending Governors\n", __func__);
for_each_active_policy(policy) { for_each_active_policy(policy) {
down_write(&policy->rwsem); if (has_target()) {
ret = cpufreq_governor(policy, CPUFREQ_GOV_STOP); down_write(&policy->rwsem);
up_write(&policy->rwsem); ret = cpufreq_governor(policy, CPUFREQ_GOV_STOP);
up_write(&policy->rwsem);
if (ret) if (ret) {
pr_err("%s: Failed to stop governor for policy: %p\n", pr_err("%s: Failed to stop governor for policy: %p\n",
__func__, policy); __func__, policy);
else if (cpufreq_driver->suspend continue;
&& cpufreq_driver->suspend(policy)) }
}
if (cpufreq_driver->suspend && cpufreq_driver->suspend(policy))
pr_err("%s: Failed to suspend driver: %p\n", __func__, pr_err("%s: Failed to suspend driver: %p\n", __func__,
policy); policy);
} }
...@@ -1596,7 +1600,7 @@ void cpufreq_resume(void) ...@@ -1596,7 +1600,7 @@ void cpufreq_resume(void)
cpufreq_suspended = false; cpufreq_suspended = false;
if (!has_target()) if (!has_target() && !cpufreq_driver->resume)
return; return;
pr_debug("%s: Resuming Governors\n", __func__); pr_debug("%s: Resuming Governors\n", __func__);
...@@ -1605,7 +1609,7 @@ void cpufreq_resume(void) ...@@ -1605,7 +1609,7 @@ void cpufreq_resume(void)
if (cpufreq_driver->resume && cpufreq_driver->resume(policy)) { if (cpufreq_driver->resume && cpufreq_driver->resume(policy)) {
pr_err("%s: Failed to resume driver: %p\n", __func__, pr_err("%s: Failed to resume driver: %p\n", __func__,
policy); policy);
} else { } else if (has_target()) {
down_write(&policy->rwsem); down_write(&policy->rwsem);
ret = cpufreq_start_governor(policy); ret = cpufreq_start_governor(policy);
up_write(&policy->rwsem); up_write(&policy->rwsem);
......
...@@ -453,6 +453,14 @@ static void intel_pstate_hwp_set(const struct cpumask *cpumask) ...@@ -453,6 +453,14 @@ static void intel_pstate_hwp_set(const struct cpumask *cpumask)
} }
} }
static int intel_pstate_hwp_set_policy(struct cpufreq_policy *policy)
{
if (hwp_active)
intel_pstate_hwp_set(policy->cpus);
return 0;
}
static void intel_pstate_hwp_set_online_cpus(void) static void intel_pstate_hwp_set_online_cpus(void)
{ {
get_online_cpus(); get_online_cpus();
...@@ -1346,8 +1354,7 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy) ...@@ -1346,8 +1354,7 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy)
out: out:
intel_pstate_set_update_util_hook(policy->cpu); intel_pstate_set_update_util_hook(policy->cpu);
if (hwp_active) intel_pstate_hwp_set_policy(policy);
intel_pstate_hwp_set(policy->cpus);
return 0; return 0;
} }
...@@ -1411,6 +1418,7 @@ static struct cpufreq_driver intel_pstate_driver = { ...@@ -1411,6 +1418,7 @@ static struct cpufreq_driver intel_pstate_driver = {
.flags = CPUFREQ_CONST_LOOPS, .flags = CPUFREQ_CONST_LOOPS,
.verify = intel_pstate_verify_policy, .verify = intel_pstate_verify_policy,
.setpolicy = intel_pstate_set_policy, .setpolicy = intel_pstate_set_policy,
.resume = intel_pstate_hwp_set_policy,
.get = intel_pstate_get, .get = intel_pstate_get,
.init = intel_pstate_cpu_init, .init = intel_pstate_cpu_init,
.stop_cpu = intel_pstate_stop_cpu, .stop_cpu = intel_pstate_stop_cpu,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment