diff options
author | Thomas Renninger <trenn@suse.de> | 2006-01-27 10:15:26 -0500 |
---|---|---|
committer | Dave Jones <davej@redhat.com> | 2006-01-27 13:36:49 -0500 |
commit | c0672860199ac009af7cf198a134ee7a4c3a9bb3 (patch) | |
tree | 9b59dfaaf655bacb8380dc8f611f9c2e6e66ca7a | |
parent | 0961dd0d217d072df736d964f47c2b6600931e19 (diff) |
[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 @@ | |||
1 | |||
1 | /* | 2 | /* |
2 | * linux/drivers/cpufreq/cpufreq_userspace.c | 3 | * linux/drivers/cpufreq/cpufreq_userspace.c |
3 | * | 4 | * |
@@ -34,7 +35,6 @@ static unsigned int cpu_min_freq[NR_CPUS]; | |||
34 | static unsigned int cpu_cur_freq[NR_CPUS]; /* current CPU freq */ | 35 | static unsigned int cpu_cur_freq[NR_CPUS]; /* current CPU freq */ |
35 | static unsigned int cpu_set_freq[NR_CPUS]; /* CPU freq desired by userspace */ | 36 | static unsigned int cpu_set_freq[NR_CPUS]; /* CPU freq desired by userspace */ |
36 | static unsigned int cpu_is_managed[NR_CPUS]; | 37 | static unsigned int cpu_is_managed[NR_CPUS]; |
37 | static struct cpufreq_policy current_policy[NR_CPUS]; | ||
38 | 38 | ||
39 | static DEFINE_MUTEX (userspace_mutex); | 39 | static DEFINE_MUTEX (userspace_mutex); |
40 | 40 | ||
@@ -65,22 +65,22 @@ static struct notifier_block userspace_cpufreq_notifier_block = { | |||
65 | * | 65 | * |
66 | * Sets the CPU frequency to freq. | 66 | * Sets the CPU frequency to freq. |
67 | */ | 67 | */ |
68 | static int cpufreq_set(unsigned int freq, unsigned int cpu) | 68 | static int cpufreq_set(unsigned int freq, struct cpufreq_policy *policy) |
69 | { | 69 | { |
70 | int ret = -EINVAL; | 70 | int ret = -EINVAL; |
71 | 71 | ||
72 | dprintk("cpufreq_set for cpu %u, freq %u kHz\n", cpu, freq); | 72 | dprintk("cpufreq_set for cpu %u, freq %u kHz\n", policy->cpu, freq); |
73 | 73 | ||
74 | mutex_lock(&userspace_mutex); | 74 | mutex_lock(&userspace_mutex); |
75 | if (!cpu_is_managed[cpu]) | 75 | if (!cpu_is_managed[policy->cpu]) |
76 | goto err; | 76 | goto err; |
77 | 77 | ||
78 | cpu_set_freq[cpu] = freq; | 78 | cpu_set_freq[policy->cpu] = freq; |
79 | 79 | ||
80 | if (freq < cpu_min_freq[cpu]) | 80 | if (freq < cpu_min_freq[policy->cpu]) |
81 | freq = cpu_min_freq[cpu]; | 81 | freq = cpu_min_freq[policy->cpu]; |
82 | if (freq > cpu_max_freq[cpu]) | 82 | if (freq > cpu_max_freq[policy->cpu]) |
83 | freq = cpu_max_freq[cpu]; | 83 | freq = cpu_max_freq[policy->cpu]; |
84 | 84 | ||
85 | /* | 85 | /* |
86 | * We're safe from concurrent calls to ->target() here | 86 | * We're safe from concurrent calls to ->target() here |
@@ -89,8 +89,7 @@ static int cpufreq_set(unsigned int freq, unsigned int cpu) | |||
89 | * A: cpufreq_set (lock userspace_mutex) -> cpufreq_driver_target(lock policy->lock) | 89 | * A: cpufreq_set (lock userspace_mutex) -> cpufreq_driver_target(lock policy->lock) |
90 | * B: cpufreq_set_policy(lock policy->lock) -> __cpufreq_governor -> cpufreq_governor_userspace (lock userspace_mutex) | 90 | * B: cpufreq_set_policy(lock policy->lock) -> __cpufreq_governor -> cpufreq_governor_userspace (lock userspace_mutex) |
91 | */ | 91 | */ |
92 | ret = __cpufreq_driver_target(¤t_policy[cpu], freq, | 92 | ret = __cpufreq_driver_target(policy, freq, CPUFREQ_RELATION_L); |
93 | CPUFREQ_RELATION_L); | ||
94 | 93 | ||
95 | err: | 94 | err: |
96 | mutex_unlock(&userspace_mutex); | 95 | mutex_unlock(&userspace_mutex); |
@@ -114,7 +113,7 @@ store_speed (struct cpufreq_policy *policy, const char *buf, size_t count) | |||
114 | if (ret != 1) | 113 | if (ret != 1) |
115 | return -EINVAL; | 114 | return -EINVAL; |
116 | 115 | ||
117 | cpufreq_set(freq, policy->cpu); | 116 | cpufreq_set(freq, policy); |
118 | 117 | ||
119 | return count; | 118 | return count; |
120 | } | 119 | } |
@@ -142,7 +141,6 @@ static int cpufreq_governor_userspace(struct cpufreq_policy *policy, | |||
142 | cpu_cur_freq[cpu] = policy->cur; | 141 | cpu_cur_freq[cpu] = policy->cur; |
143 | cpu_set_freq[cpu] = policy->cur; | 142 | cpu_set_freq[cpu] = policy->cur; |
144 | sysfs_create_file (&policy->kobj, &freq_attr_scaling_setspeed.attr); | 143 | sysfs_create_file (&policy->kobj, &freq_attr_scaling_setspeed.attr); |
145 | memcpy (¤t_policy[cpu], policy, sizeof(struct cpufreq_policy)); | ||
146 | 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]); | 144 | 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]); |
147 | mutex_unlock(&userspace_mutex); | 145 | mutex_unlock(&userspace_mutex); |
148 | break; | 146 | break; |
@@ -158,20 +156,25 @@ static int cpufreq_governor_userspace(struct cpufreq_policy *policy, | |||
158 | break; | 156 | break; |
159 | case CPUFREQ_GOV_LIMITS: | 157 | case CPUFREQ_GOV_LIMITS: |
160 | mutex_lock(&userspace_mutex); | 158 | mutex_lock(&userspace_mutex); |
161 | cpu_min_freq[cpu] = policy->min; | 159 | dprintk("limit event for cpu %u: %u - %u kHz," |
162 | cpu_max_freq[cpu] = policy->max; | 160 | "currently %u kHz, last set to %u kHz\n", |
163 | 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]); | 161 | cpu, policy->min, policy->max, |
162 | cpu_cur_freq[cpu], cpu_set_freq[cpu]); | ||
164 | if (policy->max < cpu_set_freq[cpu]) { | 163 | if (policy->max < cpu_set_freq[cpu]) { |
165 | __cpufreq_driver_target(¤t_policy[cpu], policy->max, | 164 | __cpufreq_driver_target(policy, policy->max, |
166 | CPUFREQ_RELATION_H); | 165 | CPUFREQ_RELATION_H); |
167 | } else if (policy->min > cpu_set_freq[cpu]) { | 166 | } |
168 | __cpufreq_driver_target(¤t_policy[cpu], policy->min, | 167 | else if (policy->min > cpu_set_freq[cpu]) { |
169 | CPUFREQ_RELATION_L); | 168 | __cpufreq_driver_target(policy, policy->min, |
170 | } else { | 169 | CPUFREQ_RELATION_L); |
171 | __cpufreq_driver_target(¤t_policy[cpu], cpu_set_freq[cpu], | ||
172 | CPUFREQ_RELATION_L); | ||
173 | } | 170 | } |
174 | memcpy (¤t_policy[cpu], policy, sizeof(struct cpufreq_policy)); | 171 | else { |
172 | __cpufreq_driver_target(policy, cpu_set_freq[cpu], | ||
173 | CPUFREQ_RELATION_L); | ||
174 | } | ||
175 | cpu_min_freq[cpu] = policy->min; | ||
176 | cpu_max_freq[cpu] = policy->max; | ||
177 | cpu_cur_freq[cpu] = policy->cur; | ||
175 | mutex_unlock(&userspace_mutex); | 178 | mutex_unlock(&userspace_mutex); |
176 | break; | 179 | break; |
177 | } | 180 | } |