diff options
Diffstat (limited to 'drivers/cpufreq/cpufreq.c')
-rw-r--r-- | drivers/cpufreq/cpufreq.c | 57 |
1 files changed, 54 insertions, 3 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 3acc42805e21..629806dc5cbf 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1640,9 +1640,9 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data, unsigned int pmax = policy->max; qmin = min((unsigned int)pm_qos_request(PM_QOS_CPU_FREQ_MIN), - data->max); + data->user_policy.max); qmax = max((unsigned int)pm_qos_request(PM_QOS_CPU_FREQ_MAX), - data->min); + data->user_policy.min); pr_debug("setting new policy for CPU %u: %u - %u (%u - %u) kHz\n", policy->cpu, pmin, pmax, qmin, qmax); @@ -1654,7 +1654,8 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data, memcpy(&policy->cpuinfo, &data->cpuinfo, sizeof(struct cpufreq_cpuinfo)); - if (policy->min > data->max || policy->max < data->min) { + if (policy->min > data->user_policy.max || + policy->max < data->user_policy.min) { ret = -EINVAL; goto error_out; } @@ -1785,6 +1786,56 @@ no_policy: } EXPORT_SYMBOL(cpufreq_update_policy); +/* + * cpufreq_set_gov - set governor for a cpu + * @cpu: CPU whose governor needs to be changed + * @target_gov: new governor to be set + */ +int cpufreq_set_gov(char *target_gov, unsigned int cpu) +{ + int ret = 0; + struct cpufreq_policy new_policy; + struct cpufreq_policy *cur_policy; + + if (target_gov == NULL) + return -EINVAL; + + /* Get current governer */ + cur_policy = cpufreq_cpu_get(cpu); + if (!cur_policy) + return -EINVAL; + + new_policy = *cur_policy; + if (!strncmp(cur_policy->governor->name, target_gov, + strlen(target_gov))) { + /* Target governer & current governer is same */ + ret = -EINVAL; + goto err_out; + } else { + if (cpufreq_parse_governor(target_gov, &new_policy.policy, + &new_policy.governor)) { + ret = -EINVAL; + goto err_out; + } + + if (lock_policy_rwsem_write(cur_policy->cpu) < 0) { + ret = -EINVAL; + goto err_out; + } + + ret = __cpufreq_set_policy(cur_policy, &new_policy); + + cur_policy->user_policy.policy = cur_policy->policy; + cur_policy->user_policy.governor = cur_policy->governor; + + unlock_policy_rwsem_write(cur_policy->cpu); + } +err_out: + cpufreq_cpu_put(cur_policy); + return ret; +} +EXPORT_SYMBOL(cpufreq_set_gov); + static int __cpuinit cpufreq_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { |