aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/cpufreq')
-rw-r--r--drivers/cpufreq/cpufreq_userspace.c53
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];
34static unsigned int cpu_cur_freq[NR_CPUS]; /* current CPU freq */ 35static unsigned int cpu_cur_freq[NR_CPUS]; /* current CPU freq */
35static unsigned int cpu_set_freq[NR_CPUS]; /* CPU freq desired by userspace */ 36static unsigned int cpu_set_freq[NR_CPUS]; /* CPU freq desired by userspace */
36static unsigned int cpu_is_managed[NR_CPUS]; 37static unsigned int cpu_is_managed[NR_CPUS];
37static struct cpufreq_policy current_policy[NR_CPUS];
38 38
39static DEFINE_MUTEX (userspace_mutex); 39static 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 */
68static int cpufreq_set(unsigned int freq, unsigned int cpu) 68static 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(&current_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 (&current_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(&current_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(&current_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(&current_policy[cpu], cpu_set_freq[cpu],
172 CPUFREQ_RELATION_L);
173 } 170 }
174 memcpy (&current_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 }