aboutsummaryrefslogtreecommitdiffstats
path: root/xen/drivers/cpufreq
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2009-03-19 10:09:24 +0000
committerKeir Fraser <keir.fraser@citrix.com>2009-03-19 10:09:24 +0000
commit7dc1bc818a6a4ba81ec923f0ec07a40199349eed (patch)
treece2d8853b9da394053b8c834f8944f05aff32153 /xen/drivers/cpufreq
parent93d17a53a36a921ab6acbfa8fa7d28f8e466dc0b (diff)
downloadxen-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.c49
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 = {