diff options
author | Thomas Renninger <trenn@suse.de> | 2006-01-27 16:15:26 +0100 |
---|---|---|
committer | Dave Jones <davej@redhat.com> | 2006-01-27 10:36:49 -0800 |
commit | c0672860199ac009af7cf198a134ee7a4c3a9bb3 (patch) | |
tree | 9b59dfaaf655bacb8380dc8f611f9c2e6e66ca7a | |
parent | 0961dd0d217d072df736d964f47c2b6600931e19 (diff) | |
download | lwn-c0672860199ac009af7cf198a134ee7a4c3a9bb3.tar.gz lwn-c0672860199ac009af7cf198a134ee7a4c3a9bb3.zip |
[CPUFREQ] Get rid of userspace policy struct, make userspace gov _PPC safe.
Userspace governor need not to hold it's own cpufreq_policy,
better make use of the global core policy.
Also fixes a bug in case of frequency changes via _PPC.
Old min/max values have wrongly been passed to __cpufreq_driver_target()
(kind of buffered) and when max freq was available again, only the old
max(normally lowest freq) was still active.
Signed-off-by: Thomas Renninger <trenn@suse.de>
Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
Signed-off-by: Dave Jones <davej@redhat.com>
cpufreq_userspace.c | 53 +++++++++++++++++++++++++++-------------------------
1 files changed, 28 insertions(+), 25 deletions(-)
-rw-r--r-- | drivers/cpufreq/cpufreq_userspace.c | 53 |
1 files changed, 28 insertions, 25 deletions
diff --git a/drivers/cpufreq/cpufreq_userspace.c b/drivers/cpufreq/cpufreq_userspace.c index 4d6fa63da598..92a0be22a2a9 100644 --- a/drivers/cpufreq/cpufreq_userspace.c +++ b/drivers/cpufreq/cpufreq_userspace.c @@ -1,3 +1,4 @@ + /* * linux/drivers/cpufreq/cpufreq_userspace.c * @@ -34,7 +35,6 @@ static unsigned int cpu_min_freq[NR_CPUS]; static unsigned int cpu_cur_freq[NR_CPUS]; /* current CPU freq */ static unsigned int cpu_set_freq[NR_CPUS]; /* CPU freq desired by userspace */ static unsigned int cpu_is_managed[NR_CPUS]; -static struct cpufreq_policy current_policy[NR_CPUS]; static DEFINE_MUTEX (userspace_mutex); @@ -65,22 +65,22 @@ static struct notifier_block userspace_cpufreq_notifier_block = { * * Sets the CPU frequency to freq. */ -static int cpufreq_set(unsigned int freq, unsigned int cpu) +static int cpufreq_set(unsigned int freq, struct cpufreq_policy *policy) { int ret = -EINVAL; - dprintk("cpufreq_set for cpu %u, freq %u kHz\n", cpu, freq); + dprintk("cpufreq_set for cpu %u, freq %u kHz\n", policy->cpu, freq); mutex_lock(&userspace_mutex); - if (!cpu_is_managed[cpu]) + if (!cpu_is_managed[policy->cpu]) goto err; - cpu_set_freq[cpu] = freq; + cpu_set_freq[policy->cpu] = freq; - if (freq < cpu_min_freq[cpu]) - freq = cpu_min_freq[cpu]; - if (freq > cpu_max_freq[cpu]) - freq = cpu_max_freq[cpu]; + if (freq < cpu_min_freq[policy->cpu]) + freq = cpu_min_freq[policy->cpu]; + if (freq > cpu_max_freq[policy->cpu]) + freq = cpu_max_freq[policy->cpu]; /* * We're safe from concurrent calls to ->target() here @@ -89,8 +89,7 @@ static int cpufreq_set(unsigned int freq, unsigned int cpu) * A: cpufreq_set (lock userspace_mutex) -> cpufreq_driver_target(lock policy->lock) * B: cpufreq_set_policy(lock policy->lock) -> __cpufreq_governor -> cpufreq_governor_userspace (lock userspace_mutex) */ - ret = __cpufreq_driver_target(¤t_policy[cpu], freq, - CPUFREQ_RELATION_L); + ret = __cpufreq_driver_target(policy, freq, CPUFREQ_RELATION_L); err: mutex_unlock(&userspace_mutex); @@ -114,7 +113,7 @@ store_speed (struct cpufreq_policy *policy, const char *buf, size_t count) if (ret != 1) return -EINVAL; - cpufreq_set(freq, policy->cpu); + cpufreq_set(freq, policy); return count; } @@ -142,7 +141,6 @@ static int cpufreq_governor_userspace(struct cpufreq_policy *policy, cpu_cur_freq[cpu] = policy->cur; cpu_set_freq[cpu] = policy->cur; sysfs_create_file (&policy->kobj, &freq_attr_scaling_setspeed.attr); - memcpy (¤t_policy[cpu], policy, sizeof(struct cpufreq_policy)); dprintk("managing cpu %u started (%u - %u kHz, currently %u kHz)\n", cpu, cpu_min_freq[cpu], cpu_max_freq[cpu], cpu_cur_freq[cpu]); mutex_unlock(&userspace_mutex); break; @@ -158,20 +156,25 @@ static int cpufreq_governor_userspace(struct cpufreq_policy *policy, break; case CPUFREQ_GOV_LIMITS: mutex_lock(&userspace_mutex); - cpu_min_freq[cpu] = policy->min; - cpu_max_freq[cpu] = policy->max; - dprintk("limit event for cpu %u: %u - %u kHz, currently %u kHz, last set to %u kHz\n", cpu, cpu_min_freq[cpu], cpu_max_freq[cpu], cpu_cur_freq[cpu], cpu_set_freq[cpu]); + dprintk("limit event for cpu %u: %u - %u kHz," + "currently %u kHz, last set to %u kHz\n", + cpu, policy->min, policy->max, + cpu_cur_freq[cpu], cpu_set_freq[cpu]); if (policy->max < cpu_set_freq[cpu]) { - __cpufreq_driver_target(¤t_policy[cpu], policy->max, - CPUFREQ_RELATION_H); - } else if (policy->min > cpu_set_freq[cpu]) { - __cpufreq_driver_target(¤t_policy[cpu], policy->min, - CPUFREQ_RELATION_L); - } else { - __cpufreq_driver_target(¤t_policy[cpu], cpu_set_freq[cpu], - CPUFREQ_RELATION_L); + __cpufreq_driver_target(policy, policy->max, + CPUFREQ_RELATION_H); + } + else if (policy->min > cpu_set_freq[cpu]) { + __cpufreq_driver_target(policy, policy->min, + CPUFREQ_RELATION_L); } - memcpy (¤t_policy[cpu], policy, sizeof(struct cpufreq_policy)); + else { + __cpufreq_driver_target(policy, cpu_set_freq[cpu], + CPUFREQ_RELATION_L); + } + cpu_min_freq[cpu] = policy->min; + cpu_max_freq[cpu] = policy->max; + cpu_cur_freq[cpu] = policy->cur; mutex_unlock(&userspace_mutex); break; } |