diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2009-03-19 10:09:24 +0000 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2009-03-19 10:09:24 +0000 |
commit | 7dc1bc818a6a4ba81ec923f0ec07a40199349eed (patch) | |
tree | ce2d8853b9da394053b8c834f8944f05aff32153 /xen/drivers/cpufreq | |
parent | 93d17a53a36a921ab6acbfa8fa7d28f8e466dc0b (diff) | |
download | xen-7dc1bc818a6a4ba81ec923f0ec07a40199349eed.tar.gz xen-7dc1bc818a6a4ba81ec923f0ec07a40199349eed.tar.bz2 xen-7dc1bc818a6a4ba81ec923f0ec07a40199349eed.zip |
Fix a cpufreq userspace limitation bug
Fix a cpufreq userspace limitation bug, so that userspace freq can
return to correct freq when freq_limitation return to high value (like
ppc event)
Signed-off-by: Liu, Jinsong <jinsong.liu@intel.com>=
Diffstat (limited to 'xen/drivers/cpufreq')
-rw-r--r-- | xen/drivers/cpufreq/cpufreq_misc_governors.c | 49 |
1 files changed, 38 insertions, 11 deletions
diff --git a/xen/drivers/cpufreq/cpufreq_misc_governors.c b/xen/drivers/cpufreq/cpufreq_misc_governors.c index a375a25bb9..1c63ec1815 100644 --- a/xen/drivers/cpufreq/cpufreq_misc_governors.c +++ b/xen/drivers/cpufreq/cpufreq_misc_governors.c @@ -18,34 +18,38 @@ #include <xen/sched.h> #include <acpi/cpufreq/cpufreq.h> -static unsigned int usr_speed; - /* * cpufreq userspace governor */ +static unsigned int cpu_set_freq[NR_CPUS]; + static int cpufreq_governor_userspace(struct cpufreq_policy *policy, unsigned int event) { int ret = 0; - unsigned int freq; + unsigned int cpu; - if (!policy) + if (unlikely(!policy) || + unlikely(!cpu_online(cpu = policy->cpu))) return -EINVAL; switch (event) { case CPUFREQ_GOV_START: + if (!cpu_set_freq[cpu]) + cpu_set_freq[cpu] = policy->cur; + break; case CPUFREQ_GOV_STOP: + cpu_set_freq[cpu] = 0; break; case CPUFREQ_GOV_LIMITS: - freq = usr_speed ? : policy->cur; - if (policy->max < freq) + if (policy->max < cpu_set_freq[cpu]) ret = __cpufreq_driver_target(policy, policy->max, CPUFREQ_RELATION_H); - else if (policy->min > freq) + else if (policy->min > cpu_set_freq[cpu]) ret = __cpufreq_driver_target(policy, policy->min, CPUFREQ_RELATION_L); - else if (usr_speed) - ret = __cpufreq_driver_target(policy, freq, + else + ret = __cpufreq_driver_target(policy, cpu_set_freq[cpu], CPUFREQ_RELATION_L); break; @@ -57,11 +61,34 @@ static int cpufreq_governor_userspace(struct cpufreq_policy *policy, return ret; } +int write_userspace_scaling_setspeed(unsigned int cpu, unsigned int freq) +{ + struct cpufreq_policy *policy = cpufreq_cpu_policy[cpu]; + + if (!cpu_online(cpu) || !policy) + return -EINVAL; + + cpu_set_freq[cpu] = freq; + + if (freq < policy->min) + freq = policy->min; + if (freq > policy->max) + freq = policy->max; + + return __cpufreq_driver_target(policy, freq, CPUFREQ_RELATION_L); +} + static void __init cpufreq_userspace_handle_option(const char *name, const char *val) { - if (!strcmp(name, "speed") && val) - usr_speed = simple_strtoul(val, NULL, 0); + if (!strcmp(name, "speed") && val) { + unsigned int usr_cmdline_freq; + unsigned int cpu; + + usr_cmdline_freq = simple_strtoul(val, NULL, 0); + for (cpu = 0; cpu < NR_CPUS; cpu++) + cpu_set_freq[cpu] = usr_cmdline_freq; + } } struct cpufreq_governor cpufreq_gov_userspace = { |