Commit ab05d97a authored by Yue Hu's avatar Yue Hu Committed by Rafael J. Wysocki

cpufreq: Don't find governor for setpolicy drivers in cpufreq_init_policy()

In cpufreq_init_policy() we will check if there's last_governor for target
and setpolicy type. However last_governor is set only if has_target() is
true in cpufreq_offline(). That means find last_governor for setpolicy
type is pointless. Also new_policy.governor will not be used if ->setpolicy
callback is set in cpufreq_set_policy().

Moreover, there's duplicate ->setpolicy check in using default policy path.
Let's add a new helper function to avoid it. Also update comments.
Signed-off-by: default avatarYue Hu <huyue2@yulong.com>
Acked-by: default avatarViresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 2acb9bda
...@@ -619,50 +619,52 @@ static struct cpufreq_governor *find_governor(const char *str_governor) ...@@ -619,50 +619,52 @@ static struct cpufreq_governor *find_governor(const char *str_governor)
return NULL; return NULL;
} }
static int cpufreq_parse_policy(char *str_governor,
struct cpufreq_policy *policy)
{
if (!strncasecmp(str_governor, "performance", CPUFREQ_NAME_LEN)) {
policy->policy = CPUFREQ_POLICY_PERFORMANCE;
return 0;
}
if (!strncasecmp(str_governor, "powersave", CPUFREQ_NAME_LEN)) {
policy->policy = CPUFREQ_POLICY_POWERSAVE;
return 0;
}
return -EINVAL;
}
/** /**
* cpufreq_parse_governor - parse a governor string * cpufreq_parse_governor - parse a governor string only for !setpolicy
*/ */
static int cpufreq_parse_governor(char *str_governor, static int cpufreq_parse_governor(char *str_governor,
struct cpufreq_policy *policy) struct cpufreq_policy *policy)
{ {
if (cpufreq_driver->setpolicy) { struct cpufreq_governor *t;
if (!strncasecmp(str_governor, "performance", CPUFREQ_NAME_LEN)) {
policy->policy = CPUFREQ_POLICY_PERFORMANCE;
return 0;
}
if (!strncasecmp(str_governor, "powersave", CPUFREQ_NAME_LEN)) {
policy->policy = CPUFREQ_POLICY_POWERSAVE;
return 0;
}
} else {
struct cpufreq_governor *t;
mutex_lock(&cpufreq_governor_mutex); mutex_lock(&cpufreq_governor_mutex);
t = find_governor(str_governor); t = find_governor(str_governor);
if (!t) { if (!t) {
int ret; int ret;
mutex_unlock(&cpufreq_governor_mutex); mutex_unlock(&cpufreq_governor_mutex);
ret = request_module("cpufreq_%s", str_governor); ret = request_module("cpufreq_%s", str_governor);
if (ret) if (ret)
return -EINVAL; return -EINVAL;
mutex_lock(&cpufreq_governor_mutex); mutex_lock(&cpufreq_governor_mutex);
t = find_governor(str_governor); t = find_governor(str_governor);
} }
if (t && !try_module_get(t->owner)) if (t && !try_module_get(t->owner))
t = NULL; t = NULL;
mutex_unlock(&cpufreq_governor_mutex); mutex_unlock(&cpufreq_governor_mutex);
if (t) { if (t) {
policy->governor = t; policy->governor = t;
return 0; return 0;
}
} }
return -EINVAL; return -EINVAL;
...@@ -784,8 +786,13 @@ static ssize_t store_scaling_governor(struct cpufreq_policy *policy, ...@@ -784,8 +786,13 @@ static ssize_t store_scaling_governor(struct cpufreq_policy *policy,
if (ret != 1) if (ret != 1)
return -EINVAL; return -EINVAL;
if (cpufreq_parse_governor(str_governor, &new_policy)) if (cpufreq_driver->setpolicy) {
return -EINVAL; if (cpufreq_parse_policy(str_governor, &new_policy))
return -EINVAL;
} else {
if (cpufreq_parse_governor(str_governor, &new_policy))
return -EINVAL;
}
ret = cpufreq_set_policy(policy, &new_policy); ret = cpufreq_set_policy(policy, &new_policy);
...@@ -1051,32 +1058,39 @@ __weak struct cpufreq_governor *cpufreq_default_governor(void) ...@@ -1051,32 +1058,39 @@ __weak struct cpufreq_governor *cpufreq_default_governor(void)
static int cpufreq_init_policy(struct cpufreq_policy *policy) static int cpufreq_init_policy(struct cpufreq_policy *policy)
{ {
struct cpufreq_governor *gov = NULL; struct cpufreq_governor *gov = NULL, *def_gov = NULL;
struct cpufreq_policy new_policy; struct cpufreq_policy new_policy;
memcpy(&new_policy, policy, sizeof(*policy)); memcpy(&new_policy, policy, sizeof(*policy));
/* Update governor of new_policy to the governor used before hotplug */ def_gov = cpufreq_default_governor();
gov = find_governor(policy->last_governor);
if (gov) { if (has_target()) {
pr_debug("Restoring governor %s for cpu %d\n", /*
* Update governor of new_policy to the governor used before
* hotplug
*/
gov = find_governor(policy->last_governor);
if (gov) {
pr_debug("Restoring governor %s for cpu %d\n",
policy->governor->name, policy->cpu); policy->governor->name, policy->cpu);
} else {
if (!def_gov)
return -ENODATA;
gov = def_gov;
}
new_policy.governor = gov;
} else { } else {
gov = cpufreq_default_governor(); /* Use the default policy if there is no last_policy. */
if (!gov) if (policy->last_policy) {
return -ENODATA;
}
new_policy.governor = gov;
/* Use the default policy if there is no last_policy. */
if (cpufreq_driver->setpolicy) {
if (policy->last_policy)
new_policy.policy = policy->last_policy; new_policy.policy = policy->last_policy;
else } else {
cpufreq_parse_governor(gov->name, &new_policy); if (!def_gov)
return -ENODATA;
cpufreq_parse_policy(def_gov->name, &new_policy);
}
} }
/* set default policy */
return cpufreq_set_policy(policy, &new_policy); return cpufreq_set_policy(policy, &new_policy);
} }
......
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