aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2016-05-01 20:27:19 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2016-05-02 07:48:15 -0400
commitba41e1bc28bd862089b0fc00e8136aa258a62b21 (patch)
tree25806e401a76ee786cc923733ed05c17125a1e40
parent2482bc31ca8096241b8fa97610ef23154ce55f45 (diff)
cpufreq: intel_pstate: Fix HWP on boot CPU after system resume
Commit 41cfd64cf49fc "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: 41cfd64cf49fc "Update frequencies of policy->cpus only from ->set_policy()" Tested-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
-rw-r--r--drivers/cpufreq/cpufreq.c26
-rw-r--r--drivers/cpufreq/intel_pstate.c12
2 files changed, 25 insertions, 13 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index e93405f0eac4..c4acfc5273b3 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -1557,21 +1557,25 @@ void cpufreq_suspend(void)
1557 if (!cpufreq_driver) 1557 if (!cpufreq_driver)
1558 return; 1558 return;
1559 1559
1560 if (!has_target()) 1560 if (!has_target() && !cpufreq_driver->suspend)
1561 goto suspend; 1561 goto suspend;
1562 1562
1563 pr_debug("%s: Suspending Governors\n", __func__); 1563 pr_debug("%s: Suspending Governors\n", __func__);
1564 1564
1565 for_each_active_policy(policy) { 1565 for_each_active_policy(policy) {
1566 down_write(&policy->rwsem); 1566 if (has_target()) {
1567 ret = cpufreq_governor(policy, CPUFREQ_GOV_STOP); 1567 down_write(&policy->rwsem);
1568 up_write(&policy->rwsem); 1568 ret = cpufreq_governor(policy, CPUFREQ_GOV_STOP);
1569 up_write(&policy->rwsem);
1569 1570
1570 if (ret) 1571 if (ret) {
1571 pr_err("%s: Failed to stop governor for policy: %p\n", 1572 pr_err("%s: Failed to stop governor for policy: %p\n",
1572 __func__, policy); 1573 __func__, policy);
1573 else if (cpufreq_driver->suspend 1574 continue;
1574 && cpufreq_driver->suspend(policy)) 1575 }
1576 }
1577
1578 if (cpufreq_driver->suspend && cpufreq_driver->suspend(policy))
1575 pr_err("%s: Failed to suspend driver: %p\n", __func__, 1579 pr_err("%s: Failed to suspend driver: %p\n", __func__,
1576 policy); 1580 policy);
1577 } 1581 }
@@ -1596,7 +1600,7 @@ void cpufreq_resume(void)
1596 1600
1597 cpufreq_suspended = false; 1601 cpufreq_suspended = false;
1598 1602
1599 if (!has_target()) 1603 if (!has_target() && !cpufreq_driver->resume)
1600 return; 1604 return;
1601 1605
1602 pr_debug("%s: Resuming Governors\n", __func__); 1606 pr_debug("%s: Resuming Governors\n", __func__);
@@ -1605,7 +1609,7 @@ void cpufreq_resume(void)
1605 if (cpufreq_driver->resume && cpufreq_driver->resume(policy)) { 1609 if (cpufreq_driver->resume && cpufreq_driver->resume(policy)) {
1606 pr_err("%s: Failed to resume driver: %p\n", __func__, 1610 pr_err("%s: Failed to resume driver: %p\n", __func__,
1607 policy); 1611 policy);
1608 } else { 1612 } else if (has_target()) {
1609 down_write(&policy->rwsem); 1613 down_write(&policy->rwsem);
1610 ret = cpufreq_start_governor(policy); 1614 ret = cpufreq_start_governor(policy);
1611 up_write(&policy->rwsem); 1615 up_write(&policy->rwsem);
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index f502d5b90c25..66f7f0071cab 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -453,6 +453,14 @@ static void intel_pstate_hwp_set(const struct cpumask *cpumask)
453 } 453 }
454} 454}
455 455
456static int intel_pstate_hwp_set_policy(struct cpufreq_policy *policy)
457{
458 if (hwp_active)
459 intel_pstate_hwp_set(policy->cpus);
460
461 return 0;
462}
463
456static void intel_pstate_hwp_set_online_cpus(void) 464static void intel_pstate_hwp_set_online_cpus(void)
457{ 465{
458 get_online_cpus(); 466 get_online_cpus();
@@ -1346,8 +1354,7 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy)
1346 out: 1354 out:
1347 intel_pstate_set_update_util_hook(policy->cpu); 1355 intel_pstate_set_update_util_hook(policy->cpu);
1348 1356
1349 if (hwp_active) 1357 intel_pstate_hwp_set_policy(policy);
1350 intel_pstate_hwp_set(policy->cpus);
1351 1358
1352 return 0; 1359 return 0;
1353} 1360}
@@ -1411,6 +1418,7 @@ static struct cpufreq_driver intel_pstate_driver = {
1411 .flags = CPUFREQ_CONST_LOOPS, 1418 .flags = CPUFREQ_CONST_LOOPS,
1412 .verify = intel_pstate_verify_policy, 1419 .verify = intel_pstate_verify_policy,
1413 .setpolicy = intel_pstate_set_policy, 1420 .setpolicy = intel_pstate_set_policy,
1421 .resume = intel_pstate_hwp_set_policy,
1414 .get = intel_pstate_get, 1422 .get = intel_pstate_get,
1415 .init = intel_pstate_cpu_init, 1423 .init = intel_pstate_cpu_init,
1416 .stop_cpu = intel_pstate_stop_cpu, 1424 .stop_cpu = intel_pstate_stop_cpu,