More power management updates for v4.7-rc1
- Stable-candidate cpuidle fix to make it check the right variable when deciding whether or not to enable interrupts on the local CPU so as to avoid enabling iterrupts too early in some cases if the system has both coupled and per-core idle states (Daniel Lezcano). - Stable-candidate PM core fix to make it handle failures at the "late suspend" stage of device suspend consistently for all devices regardless of whether or not async suspend/resume is enabled for them (Rafael Wysocki). - Cleanups in the cpufreq core, the schedutil governor and the intel_pstate driver (Rafael Wysocki, Pankaj Gupta, Viresh Kumar). -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQIcBAABCAAGBQJXRglcAAoJEILEb/54YlRxCwEQAKQNLO5wrNnOQmVrMHaOk1XH 4zT+AdggLRVgBld4d4Vcli2zJPZfpnZuzjJdwTB5zLgQ4WIcBb6meOfH87XGqRyJ o4ksyEUhpvDk8AdlmTA5CvvjFuydPJG5ZUSiM035XRT9heebvhgyaMBnT3ucXbq9 7LhNhCQ+a8arndt9ePO7tZnFfQQUbwNJ2BDVuH5DJBqMIFOo2/Kpag43CdFWlWZT jnWaleDCjSmanuJ/45bFJHJeSZ7PK2etnArfzKtb9QLSGnuEfFPdHuUzJYo5dkP7 UBeYA94hhfR3f5FJIqNlF3N+eLEX1idpwxc8+CJLLDKDd1ZCBrbLoz5fwM+fVn0h AfmyR+J1czcbiphsmpViOYDRrKdiQVkbP6SpBswvgMCZAcNDF2bxhzOlcuTUc+u0 8xsjWOtArL6uvzsAHa1HY6hhgUn9FB8m20HX+DmS2/zzqyzoRefenoyVcuLsAhXC fm+sARQ7tvy3OoGRQ9mloWgv2X5iQUY5IVjOG2amIhbUvVmKQutPjVTGTwHqmmcb 2nNYptLsTA6crvnexPcPHY+OFjkQl/omtfaMx+OJl63yhln5ibveGOfZ6F8sPdoB bRqHuHoK/xh9hSNwj117ZFzq1nm54mLjh0Yhw3EXFcV4I9vdsTp8/WeNThGvT17j M+6PDXyjlwh3HZpGm+HW =3vtL -----END PGP SIGNATURE----- Merge tag 'pm-4.7-rc1-more' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm Pull more power management updates from Rafael Wysocki: "These are two stable-candidate fixes (PM core, cpuidle) and a bunch of cpufreq cleanups. Specifics: - Stable-candidate cpuidle fix to make it check the right variable when deciding whether or not to enable interrupts on the local CPU so as to avoid enabling iterrupts too early in some cases if the system has both coupled and per-core idle states (Daniel Lezcano). - Stable-candidate PM core fix to make it handle failures at the "late suspend" stage of device suspend consistently for all devices regardless of whether or not async suspend/resume is enabled for them (Rafael Wysocki). - Cleanups in the cpufreq core, the schedutil governor and the intel_pstate driver (Rafael Wysocki, Pankaj Gupta, Viresh Kumar)" * tag 'pm-4.7-rc1-more' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: PM / sleep: Handle failures in device_suspend_late() consistently cpufreq: schedutil: Improve prints messages with pr_fmt cpuidle: Fix cpuidle_state_is_coupled() argument in cpuidle_enter() cpufreq: simplified goto out in cpufreq_register_driver() cpufreq: governor: CPUFREQ_GOV_STOP never fails cpufreq: governor: CPUFREQ_GOV_POLICY_EXIT never fails intel_pstate: Simplify conditional in intel_pstate_set_policy()
This commit is contained in:
commit
877c057d2b
5 changed files with 39 additions and 67 deletions
|
@ -1267,14 +1267,15 @@ int dpm_suspend_late(pm_message_t state)
|
|||
error = device_suspend_late(dev);
|
||||
|
||||
mutex_lock(&dpm_list_mtx);
|
||||
if (!list_empty(&dev->power.entry))
|
||||
list_move(&dev->power.entry, &dpm_late_early_list);
|
||||
|
||||
if (error) {
|
||||
pm_dev_err(dev, state, " late", error);
|
||||
dpm_save_failed_dev(dev_name(dev));
|
||||
put_device(dev);
|
||||
break;
|
||||
}
|
||||
if (!list_empty(&dev->power.entry))
|
||||
list_move(&dev->power.entry, &dpm_late_early_list);
|
||||
put_device(dev);
|
||||
|
||||
if (async_error)
|
||||
|
|
|
@ -78,9 +78,14 @@ static int cpufreq_governor(struct cpufreq_policy *policy, unsigned int event);
|
|||
static unsigned int __cpufreq_get(struct cpufreq_policy *policy);
|
||||
static int cpufreq_start_governor(struct cpufreq_policy *policy);
|
||||
|
||||
static inline int cpufreq_exit_governor(struct cpufreq_policy *policy)
|
||||
static inline void cpufreq_exit_governor(struct cpufreq_policy *policy)
|
||||
{
|
||||
return cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT);
|
||||
(void)cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT);
|
||||
}
|
||||
|
||||
static inline void cpufreq_stop_governor(struct cpufreq_policy *policy)
|
||||
{
|
||||
(void)cpufreq_governor(policy, CPUFREQ_GOV_STOP);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1026,13 +1031,8 @@ static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy, unsigned int cp
|
|||
return 0;
|
||||
|
||||
down_write(&policy->rwsem);
|
||||
if (has_target()) {
|
||||
ret = cpufreq_governor(policy, CPUFREQ_GOV_STOP);
|
||||
if (ret) {
|
||||
pr_err("%s: Failed to stop governor\n", __func__);
|
||||
goto unlock;
|
||||
}
|
||||
}
|
||||
if (has_target())
|
||||
cpufreq_stop_governor(policy);
|
||||
|
||||
cpumask_set_cpu(cpu, policy->cpus);
|
||||
|
||||
|
@ -1041,8 +1041,6 @@ static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy, unsigned int cp
|
|||
if (ret)
|
||||
pr_err("%s: Failed to start governor\n", __func__);
|
||||
}
|
||||
|
||||
unlock:
|
||||
up_write(&policy->rwsem);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1354,11 +1352,8 @@ static void cpufreq_offline(unsigned int cpu)
|
|||
}
|
||||
|
||||
down_write(&policy->rwsem);
|
||||
if (has_target()) {
|
||||
ret = cpufreq_governor(policy, CPUFREQ_GOV_STOP);
|
||||
if (ret)
|
||||
pr_err("%s: Failed to stop governor\n", __func__);
|
||||
}
|
||||
if (has_target())
|
||||
cpufreq_stop_governor(policy);
|
||||
|
||||
cpumask_clear_cpu(cpu, policy->cpus);
|
||||
|
||||
|
@ -1387,12 +1382,8 @@ static void cpufreq_offline(unsigned int cpu)
|
|||
if (cpufreq_driver->stop_cpu)
|
||||
cpufreq_driver->stop_cpu(policy);
|
||||
|
||||
/* If cpu is last user of policy, free policy */
|
||||
if (has_target()) {
|
||||
ret = cpufreq_exit_governor(policy);
|
||||
if (ret)
|
||||
pr_err("%s: Failed to exit governor\n", __func__);
|
||||
}
|
||||
if (has_target())
|
||||
cpufreq_exit_governor(policy);
|
||||
|
||||
/*
|
||||
* Perform the ->exit() even during light-weight tear-down,
|
||||
|
@ -1626,7 +1617,6 @@ EXPORT_SYMBOL(cpufreq_generic_suspend);
|
|||
void cpufreq_suspend(void)
|
||||
{
|
||||
struct cpufreq_policy *policy;
|
||||
int ret;
|
||||
|
||||
if (!cpufreq_driver)
|
||||
return;
|
||||
|
@ -1639,14 +1629,8 @@ void cpufreq_suspend(void)
|
|||
for_each_active_policy(policy) {
|
||||
if (has_target()) {
|
||||
down_write(&policy->rwsem);
|
||||
ret = cpufreq_governor(policy, CPUFREQ_GOV_STOP);
|
||||
cpufreq_stop_governor(policy);
|
||||
up_write(&policy->rwsem);
|
||||
|
||||
if (ret) {
|
||||
pr_err("%s: Failed to stop governor for policy: %p\n",
|
||||
__func__, policy);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (cpufreq_driver->suspend && cpufreq_driver->suspend(policy))
|
||||
|
@ -2049,16 +2033,15 @@ static int cpufreq_governor(struct cpufreq_policy *policy, unsigned int event)
|
|||
|
||||
ret = policy->governor->governor(policy, event);
|
||||
|
||||
if (!ret) {
|
||||
if (event == CPUFREQ_GOV_POLICY_INIT)
|
||||
if (event == CPUFREQ_GOV_POLICY_INIT) {
|
||||
if (ret)
|
||||
module_put(policy->governor->owner);
|
||||
else
|
||||
policy->governor->initialized++;
|
||||
else if (event == CPUFREQ_GOV_POLICY_EXIT)
|
||||
policy->governor->initialized--;
|
||||
}
|
||||
|
||||
if (((event == CPUFREQ_GOV_POLICY_INIT) && ret) ||
|
||||
((event == CPUFREQ_GOV_POLICY_EXIT) && !ret))
|
||||
} else if (event == CPUFREQ_GOV_POLICY_EXIT) {
|
||||
policy->governor->initialized--;
|
||||
module_put(policy->governor->owner);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -2221,20 +2204,8 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy,
|
|||
old_gov = policy->governor;
|
||||
/* end old governor */
|
||||
if (old_gov) {
|
||||
ret = cpufreq_governor(policy, CPUFREQ_GOV_STOP);
|
||||
if (ret) {
|
||||
/* This can happen due to race with other operations */
|
||||
pr_debug("%s: Failed to Stop Governor: %s (%d)\n",
|
||||
__func__, old_gov->name, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = cpufreq_exit_governor(policy);
|
||||
if (ret) {
|
||||
pr_err("%s: Failed to Exit Governor: %s (%d)\n",
|
||||
__func__, old_gov->name, ret);
|
||||
return ret;
|
||||
}
|
||||
cpufreq_stop_governor(policy);
|
||||
cpufreq_exit_governor(policy);
|
||||
}
|
||||
|
||||
/* start new governor */
|
||||
|
@ -2495,10 +2466,7 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
|
|||
|
||||
register_hotcpu_notifier(&cpufreq_cpu_notifier);
|
||||
pr_debug("driver %s up and running\n", driver_data->name);
|
||||
|
||||
out:
|
||||
put_online_cpus();
|
||||
return ret;
|
||||
goto out;
|
||||
|
||||
err_if_unreg:
|
||||
subsys_interface_unregister(&cpufreq_interface);
|
||||
|
@ -2508,7 +2476,9 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
|
|||
write_lock_irqsave(&cpufreq_driver_lock, flags);
|
||||
cpufreq_driver = NULL;
|
||||
write_unlock_irqrestore(&cpufreq_driver_lock, flags);
|
||||
goto out;
|
||||
out:
|
||||
put_online_cpus();
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cpufreq_register_driver);
|
||||
|
||||
|
|
|
@ -1461,12 +1461,11 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy)
|
|||
intel_pstate_clear_update_util_hook(policy->cpu);
|
||||
|
||||
cpu = all_cpu_data[0];
|
||||
if (cpu->pstate.max_pstate_physical > cpu->pstate.max_pstate) {
|
||||
if (policy->max < policy->cpuinfo.max_freq &&
|
||||
policy->max > cpu->pstate.max_pstate * cpu->pstate.scaling) {
|
||||
pr_debug("policy->max > max non turbo frequency\n");
|
||||
policy->max = policy->cpuinfo.max_freq;
|
||||
}
|
||||
if (cpu->pstate.max_pstate_physical > cpu->pstate.max_pstate &&
|
||||
policy->max < policy->cpuinfo.max_freq &&
|
||||
policy->max > cpu->pstate.max_pstate * cpu->pstate.scaling) {
|
||||
pr_debug("policy->max > max non turbo frequency\n");
|
||||
policy->max = policy->cpuinfo.max_freq;
|
||||
}
|
||||
|
||||
if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) {
|
||||
|
|
|
@ -214,7 +214,7 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
|
|||
tick_broadcast_exit();
|
||||
}
|
||||
|
||||
if (!cpuidle_state_is_coupled(drv, entered_state))
|
||||
if (!cpuidle_state_is_coupled(drv, index))
|
||||
local_irq_enable();
|
||||
|
||||
/*
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/cpufreq.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
|
@ -388,7 +390,7 @@ static int sugov_init(struct cpufreq_policy *policy)
|
|||
mutex_unlock(&global_tunables_lock);
|
||||
|
||||
sugov_policy_free(sg_policy);
|
||||
pr_err("cpufreq: schedutil governor initialization failed (error %d)\n", ret);
|
||||
pr_err("initialization failed (error %d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue