diff options
author | Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> | 2015-12-01 19:52:14 -0500 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2015-12-02 17:50:33 -0500 |
commit | 69030dd1c3671625c6f766af0b64a4bb4409ac3b (patch) | |
tree | 9d7d4ecc711c024b79b9fe2d39500acf4393a5a1 | |
parent | 584ee3dcb1d6232857c1e38bb28d9f6bf0ec89f5 (diff) |
cpufreq: use last policy after online for drivers with ->setpolicy
For cpufreq drivers which use setpolicy interface, after offline->online
the policy is set to default. This can be reproduced by setting the
default policy of intel_pstate or longrun to ondemand and then change to
"performance". After offline and online, the setpolicy will be called with
the policy=ondemand.
For drivers using governors this condition is handled by storing
last_governor, during offline and restoring during online. The same should
be done for drivers using setpolicy interface. Storing last_policy during
offline and restoring during online.
Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r-- | drivers/cpufreq/cpufreq.c | 14 | ||||
-rw-r--r-- | include/linux/cpufreq.h | 1 |
2 files changed, 11 insertions, 4 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index a83c995a62df..8412ce5f93a7 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -976,10 +976,14 @@ static int cpufreq_init_policy(struct cpufreq_policy *policy) | |||
976 | 976 | ||
977 | new_policy.governor = gov; | 977 | new_policy.governor = gov; |
978 | 978 | ||
979 | /* Use the default policy if its valid. */ | 979 | /* Use the default policy if there is no last_policy. */ |
980 | if (cpufreq_driver->setpolicy) | 980 | if (cpufreq_driver->setpolicy) { |
981 | cpufreq_parse_governor(gov->name, &new_policy.policy, NULL); | 981 | if (policy->last_policy) |
982 | 982 | new_policy.policy = policy->last_policy; | |
983 | else | ||
984 | cpufreq_parse_governor(gov->name, &new_policy.policy, | ||
985 | NULL); | ||
986 | } | ||
983 | /* set default policy */ | 987 | /* set default policy */ |
984 | return cpufreq_set_policy(policy, &new_policy); | 988 | return cpufreq_set_policy(policy, &new_policy); |
985 | } | 989 | } |
@@ -1330,6 +1334,8 @@ static void cpufreq_offline_prepare(unsigned int cpu) | |||
1330 | if (has_target()) | 1334 | if (has_target()) |
1331 | strncpy(policy->last_governor, policy->governor->name, | 1335 | strncpy(policy->last_governor, policy->governor->name, |
1332 | CPUFREQ_NAME_LEN); | 1336 | CPUFREQ_NAME_LEN); |
1337 | else | ||
1338 | policy->last_policy = policy->policy; | ||
1333 | } else if (cpu == policy->cpu) { | 1339 | } else if (cpu == policy->cpu) { |
1334 | /* Nominate new CPU */ | 1340 | /* Nominate new CPU */ |
1335 | policy->cpu = cpumask_any(policy->cpus); | 1341 | policy->cpu = cpumask_any(policy->cpus); |
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index ef4c5b1a860f..177c7680c1a8 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h | |||
@@ -77,6 +77,7 @@ struct cpufreq_policy { | |||
77 | unsigned int suspend_freq; /* freq to set during suspend */ | 77 | unsigned int suspend_freq; /* freq to set during suspend */ |
78 | 78 | ||
79 | unsigned int policy; /* see above */ | 79 | unsigned int policy; /* see above */ |
80 | unsigned int last_policy; /* policy before unplug */ | ||
80 | struct cpufreq_governor *governor; /* see below */ | 81 | struct cpufreq_governor *governor; /* see below */ |
81 | void *governor_data; | 82 | void *governor_data; |
82 | bool governor_enabled; /* governor start/stop flag */ | 83 | bool governor_enabled; /* governor start/stop flag */ |