aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/cpufreq')
-rw-r--r--drivers/cpufreq/cpufreq.c174
-rw-r--r--drivers/cpufreq/cpufreq_conservative.c52
-rw-r--r--drivers/cpufreq/cpufreq_ondemand.c41
-rw-r--r--drivers/cpufreq/cpufreq_userspace.c78
4 files changed, 182 insertions, 163 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 277a843a87a6..9582de1c9cad 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -26,6 +26,7 @@
26#include <linux/slab.h> 26#include <linux/slab.h>
27#include <linux/cpu.h> 27#include <linux/cpu.h>
28#include <linux/completion.h> 28#include <linux/completion.h>
29#include <linux/mutex.h>
29 30
30#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_CORE, "cpufreq-core", msg) 31#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_CORE, "cpufreq-core", msg)
31 32
@@ -34,8 +35,8 @@
34 * level driver of CPUFreq support, and its spinlock. This lock 35 * level driver of CPUFreq support, and its spinlock. This lock
35 * also protects the cpufreq_cpu_data array. 36 * also protects the cpufreq_cpu_data array.
36 */ 37 */
37static struct cpufreq_driver *cpufreq_driver; 38static struct cpufreq_driver *cpufreq_driver;
38static struct cpufreq_policy *cpufreq_cpu_data[NR_CPUS]; 39static struct cpufreq_policy *cpufreq_cpu_data[NR_CPUS];
39static DEFINE_SPINLOCK(cpufreq_driver_lock); 40static DEFINE_SPINLOCK(cpufreq_driver_lock);
40 41
41/* internal prototypes */ 42/* internal prototypes */
@@ -49,15 +50,15 @@ static void handle_update(void *data);
49 * changes to devices when the CPU clock speed changes. 50 * changes to devices when the CPU clock speed changes.
50 * The mutex locks both lists. 51 * The mutex locks both lists.
51 */ 52 */
52static struct notifier_block *cpufreq_policy_notifier_list; 53static struct notifier_block *cpufreq_policy_notifier_list;
53static struct notifier_block *cpufreq_transition_notifier_list; 54static struct notifier_block *cpufreq_transition_notifier_list;
54static DECLARE_RWSEM (cpufreq_notifier_rwsem); 55static DECLARE_RWSEM (cpufreq_notifier_rwsem);
55 56
56 57
57static LIST_HEAD(cpufreq_governor_list); 58static LIST_HEAD(cpufreq_governor_list);
58static DECLARE_MUTEX (cpufreq_governor_sem); 59static DEFINE_MUTEX (cpufreq_governor_mutex);
59 60
60struct cpufreq_policy * cpufreq_cpu_get(unsigned int cpu) 61struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu)
61{ 62{
62 struct cpufreq_policy *data; 63 struct cpufreq_policy *data;
63 unsigned long flags; 64 unsigned long flags;
@@ -84,20 +85,19 @@ struct cpufreq_policy * cpufreq_cpu_get(unsigned int cpu)
84 if (!kobject_get(&data->kobj)) 85 if (!kobject_get(&data->kobj))
85 goto err_out_put_module; 86 goto err_out_put_module;
86 87
87
88 spin_unlock_irqrestore(&cpufreq_driver_lock, flags); 88 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
89
90 return data; 89 return data;
91 90
92 err_out_put_module: 91err_out_put_module:
93 module_put(cpufreq_driver->owner); 92 module_put(cpufreq_driver->owner);
94 err_out_unlock: 93err_out_unlock:
95 spin_unlock_irqrestore(&cpufreq_driver_lock, flags); 94 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
96 err_out: 95err_out:
97 return NULL; 96 return NULL;
98} 97}
99EXPORT_SYMBOL_GPL(cpufreq_cpu_get); 98EXPORT_SYMBOL_GPL(cpufreq_cpu_get);
100 99
100
101void cpufreq_cpu_put(struct cpufreq_policy *data) 101void cpufreq_cpu_put(struct cpufreq_policy *data)
102{ 102{
103 kobject_put(&data->kobj); 103 kobject_put(&data->kobj);
@@ -228,44 +228,53 @@ static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci) {
228 228
229 229
230/** 230/**
231 * cpufreq_notify_transition - call notifier chain and adjust_jiffies on frequency transition 231 * cpufreq_notify_transition - call notifier chain and adjust_jiffies
232 * on frequency transition.
232 * 233 *
233 * This function calls the transition notifiers and the "adjust_jiffies" function. It is called 234 * This function calls the transition notifiers and the "adjust_jiffies"
234 * twice on all CPU frequency changes that have external effects. 235 * function. It is called twice on all CPU frequency changes that have
236 * external effects.
235 */ 237 */
236void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state) 238void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state)
237{ 239{
240 struct cpufreq_policy *policy;
241
238 BUG_ON(irqs_disabled()); 242 BUG_ON(irqs_disabled());
239 243
240 freqs->flags = cpufreq_driver->flags; 244 freqs->flags = cpufreq_driver->flags;
241 dprintk("notification %u of frequency transition to %u kHz\n", state, freqs->new); 245 dprintk("notification %u of frequency transition to %u kHz\n",
246 state, freqs->new);
242 247
243 down_read(&cpufreq_notifier_rwsem); 248 down_read(&cpufreq_notifier_rwsem);
249
250 policy = cpufreq_cpu_data[freqs->cpu];
244 switch (state) { 251 switch (state) {
252
245 case CPUFREQ_PRECHANGE: 253 case CPUFREQ_PRECHANGE:
246 /* detect if the driver reported a value as "old frequency" which 254 /* detect if the driver reported a value as "old frequency"
247 * is not equal to what the cpufreq core thinks is "old frequency". 255 * which is not equal to what the cpufreq core thinks is
256 * "old frequency".
248 */ 257 */
249 if (!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) { 258 if (!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
250 if ((likely(cpufreq_cpu_data[freqs->cpu])) && 259 if ((policy) && (policy->cpu == freqs->cpu) &&
251 (likely(cpufreq_cpu_data[freqs->cpu]->cpu == freqs->cpu)) && 260 (policy->cur) && (policy->cur != freqs->old)) {
252 (likely(cpufreq_cpu_data[freqs->cpu]->cur)) && 261 dprintk(KERN_WARNING "Warning: CPU frequency is"
253 (unlikely(freqs->old != cpufreq_cpu_data[freqs->cpu]->cur))) 262 " %u, cpufreq assumed %u kHz.\n",
254 { 263 freqs->old, policy->cur);
255 dprintk(KERN_WARNING "Warning: CPU frequency is %u, " 264 freqs->old = policy->cur;
256 "cpufreq assumed %u kHz.\n", freqs->old, cpufreq_cpu_data[freqs->cpu]->cur);
257 freqs->old = cpufreq_cpu_data[freqs->cpu]->cur;
258 } 265 }
259 } 266 }
260 notifier_call_chain(&cpufreq_transition_notifier_list, CPUFREQ_PRECHANGE, freqs); 267 notifier_call_chain(&cpufreq_transition_notifier_list,
268 CPUFREQ_PRECHANGE, freqs);
261 adjust_jiffies(CPUFREQ_PRECHANGE, freqs); 269 adjust_jiffies(CPUFREQ_PRECHANGE, freqs);
262 break; 270 break;
271
263 case CPUFREQ_POSTCHANGE: 272 case CPUFREQ_POSTCHANGE:
264 adjust_jiffies(CPUFREQ_POSTCHANGE, freqs); 273 adjust_jiffies(CPUFREQ_POSTCHANGE, freqs);
265 notifier_call_chain(&cpufreq_transition_notifier_list, CPUFREQ_POSTCHANGE, freqs); 274 notifier_call_chain(&cpufreq_transition_notifier_list,
266 if ((likely(cpufreq_cpu_data[freqs->cpu])) && 275 CPUFREQ_POSTCHANGE, freqs);
267 (likely(cpufreq_cpu_data[freqs->cpu]->cpu == freqs->cpu))) 276 if (likely(policy) && likely(policy->cpu == freqs->cpu))
268 cpufreq_cpu_data[freqs->cpu]->cur = freqs->new; 277 policy->cur = freqs->new;
269 break; 278 break;
270 } 279 }
271 up_read(&cpufreq_notifier_rwsem); 280 up_read(&cpufreq_notifier_rwsem);
@@ -297,18 +306,18 @@ static int cpufreq_parse_governor (char *str_governor, unsigned int *policy,
297 return -EINVAL; 306 return -EINVAL;
298 } else { 307 } else {
299 struct cpufreq_governor *t; 308 struct cpufreq_governor *t;
300 down(&cpufreq_governor_sem); 309 mutex_lock(&cpufreq_governor_mutex);
301 if (!cpufreq_driver || !cpufreq_driver->target) 310 if (!cpufreq_driver || !cpufreq_driver->target)
302 goto out; 311 goto out;
303 list_for_each_entry(t, &cpufreq_governor_list, governor_list) { 312 list_for_each_entry(t, &cpufreq_governor_list, governor_list) {
304 if (!strnicmp(str_governor,t->name,CPUFREQ_NAME_LEN)) { 313 if (!strnicmp(str_governor,t->name,CPUFREQ_NAME_LEN)) {
305 *governor = t; 314 *governor = t;
306 up(&cpufreq_governor_sem); 315 mutex_unlock(&cpufreq_governor_mutex);
307 return 0; 316 return 0;
308 } 317 }
309 } 318 }
310 out: 319out:
311 up(&cpufreq_governor_sem); 320 mutex_unlock(&cpufreq_governor_mutex);
312 } 321 }
313 return -EINVAL; 322 return -EINVAL;
314} 323}
@@ -414,7 +423,6 @@ static ssize_t store_scaling_governor (struct cpufreq_policy * policy,
414 return -EINVAL; 423 return -EINVAL;
415 424
416 ret = cpufreq_set_policy(&new_policy); 425 ret = cpufreq_set_policy(&new_policy);
417
418 return ret ? ret : count; 426 return ret ? ret : count;
419} 427}
420 428
@@ -445,7 +453,7 @@ static ssize_t show_scaling_available_governors (struct cpufreq_policy * policy,
445 goto out; 453 goto out;
446 i += scnprintf(&buf[i], CPUFREQ_NAME_LEN, "%s ", t->name); 454 i += scnprintf(&buf[i], CPUFREQ_NAME_LEN, "%s ", t->name);
447 } 455 }
448 out: 456out:
449 i += sprintf(&buf[i], "\n"); 457 i += sprintf(&buf[i], "\n");
450 return i; 458 return i;
451} 459}
@@ -600,7 +608,8 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
600 policy->cpu = cpu; 608 policy->cpu = cpu;
601 policy->cpus = cpumask_of_cpu(cpu); 609 policy->cpus = cpumask_of_cpu(cpu);
602 610
603 init_MUTEX_LOCKED(&policy->lock); 611 mutex_init(&policy->lock);
612 mutex_lock(&policy->lock);
604 init_completion(&policy->kobj_unregister); 613 init_completion(&policy->kobj_unregister);
605 INIT_WORK(&policy->update, handle_update, (void *)(long)cpu); 614 INIT_WORK(&policy->update, handle_update, (void *)(long)cpu);
606 615
@@ -610,6 +619,7 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
610 ret = cpufreq_driver->init(policy); 619 ret = cpufreq_driver->init(policy);
611 if (ret) { 620 if (ret) {
612 dprintk("initialization failed\n"); 621 dprintk("initialization failed\n");
622 mutex_unlock(&policy->lock);
613 goto err_out; 623 goto err_out;
614 } 624 }
615 625
@@ -621,9 +631,10 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
621 strlcpy(policy->kobj.name, "cpufreq", KOBJ_NAME_LEN); 631 strlcpy(policy->kobj.name, "cpufreq", KOBJ_NAME_LEN);
622 632
623 ret = kobject_register(&policy->kobj); 633 ret = kobject_register(&policy->kobj);
624 if (ret) 634 if (ret) {
635 mutex_unlock(&policy->lock);
625 goto err_out_driver_exit; 636 goto err_out_driver_exit;
626 637 }
627 /* set up files for this cpu device */ 638 /* set up files for this cpu device */
628 drv_attr = cpufreq_driver->attr; 639 drv_attr = cpufreq_driver->attr;
629 while ((drv_attr) && (*drv_attr)) { 640 while ((drv_attr) && (*drv_attr)) {
@@ -641,7 +652,7 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
641 spin_unlock_irqrestore(&cpufreq_driver_lock, flags); 652 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
642 policy->governor = NULL; /* to assure that the starting sequence is 653 policy->governor = NULL; /* to assure that the starting sequence is
643 * run in cpufreq_set_policy */ 654 * run in cpufreq_set_policy */
644 up(&policy->lock); 655 mutex_unlock(&policy->lock);
645 656
646 /* set default policy */ 657 /* set default policy */
647 658
@@ -762,10 +773,10 @@ static int cpufreq_remove_dev (struct sys_device * sys_dev)
762 spin_unlock_irqrestore(&cpufreq_driver_lock, flags); 773 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
763#endif 774#endif
764 775
765 down(&data->lock); 776 mutex_lock(&data->lock);
766 if (cpufreq_driver->target) 777 if (cpufreq_driver->target)
767 __cpufreq_governor(data, CPUFREQ_GOV_STOP); 778 __cpufreq_governor(data, CPUFREQ_GOV_STOP);
768 up(&data->lock); 779 mutex_unlock(&data->lock);
769 780
770 kobject_unregister(&data->kobj); 781 kobject_unregister(&data->kobj);
771 782
@@ -785,7 +796,6 @@ static int cpufreq_remove_dev (struct sys_device * sys_dev)
785 kfree(data); 796 kfree(data);
786 797
787 cpufreq_debug_enable_ratelimit(); 798 cpufreq_debug_enable_ratelimit();
788
789 return 0; 799 return 0;
790} 800}
791 801
@@ -834,9 +844,9 @@ unsigned int cpufreq_quick_get(unsigned int cpu)
834 unsigned int ret = 0; 844 unsigned int ret = 0;
835 845
836 if (policy) { 846 if (policy) {
837 down(&policy->lock); 847 mutex_lock(&policy->lock);
838 ret = policy->cur; 848 ret = policy->cur;
839 up(&policy->lock); 849 mutex_unlock(&policy->lock);
840 cpufreq_cpu_put(policy); 850 cpufreq_cpu_put(policy);
841 } 851 }
842 852
@@ -862,12 +872,11 @@ unsigned int cpufreq_get(unsigned int cpu)
862 if (!cpufreq_driver->get) 872 if (!cpufreq_driver->get)
863 goto out; 873 goto out;
864 874
865 down(&policy->lock); 875 mutex_lock(&policy->lock);
866 876
867 ret = cpufreq_driver->get(cpu); 877 ret = cpufreq_driver->get(cpu);
868 878
869 if (ret && policy->cur && !(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) 879 if (ret && policy->cur && !(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
870 {
871 /* verify no discrepancy between actual and saved value exists */ 880 /* verify no discrepancy between actual and saved value exists */
872 if (unlikely(ret != policy->cur)) { 881 if (unlikely(ret != policy->cur)) {
873 cpufreq_out_of_sync(cpu, policy->cur, ret); 882 cpufreq_out_of_sync(cpu, policy->cur, ret);
@@ -875,9 +884,9 @@ unsigned int cpufreq_get(unsigned int cpu)
875 } 884 }
876 } 885 }
877 886
878 up(&policy->lock); 887 mutex_unlock(&policy->lock);
879 888
880 out: 889out:
881 cpufreq_cpu_put(policy); 890 cpufreq_cpu_put(policy);
882 891
883 return (ret); 892 return (ret);
@@ -958,7 +967,7 @@ static int cpufreq_suspend(struct sys_device * sysdev, pm_message_t pmsg)
958 cpu_policy->cur = cur_freq; 967 cpu_policy->cur = cur_freq;
959 } 968 }
960 969
961 out: 970out:
962 cpufreq_cpu_put(cpu_policy); 971 cpufreq_cpu_put(cpu_policy);
963 return 0; 972 return 0;
964} 973}
@@ -1158,14 +1167,13 @@ int cpufreq_driver_target(struct cpufreq_policy *policy,
1158 if (!policy) 1167 if (!policy)
1159 return -EINVAL; 1168 return -EINVAL;
1160 1169
1161 down(&policy->lock); 1170 mutex_lock(&policy->lock);
1162 1171
1163 ret = __cpufreq_driver_target(policy, target_freq, relation); 1172 ret = __cpufreq_driver_target(policy, target_freq, relation);
1164 1173
1165 up(&policy->lock); 1174 mutex_unlock(&policy->lock);
1166 1175
1167 cpufreq_cpu_put(policy); 1176 cpufreq_cpu_put(policy);
1168
1169 return ret; 1177 return ret;
1170} 1178}
1171EXPORT_SYMBOL_GPL(cpufreq_driver_target); 1179EXPORT_SYMBOL_GPL(cpufreq_driver_target);
@@ -1199,12 +1207,11 @@ int cpufreq_governor(unsigned int cpu, unsigned int event)
1199 if (!policy) 1207 if (!policy)
1200 return -EINVAL; 1208 return -EINVAL;
1201 1209
1202 down(&policy->lock); 1210 mutex_lock(&policy->lock);
1203 ret = __cpufreq_governor(policy, event); 1211 ret = __cpufreq_governor(policy, event);
1204 up(&policy->lock); 1212 mutex_unlock(&policy->lock);
1205 1213
1206 cpufreq_cpu_put(policy); 1214 cpufreq_cpu_put(policy);
1207
1208 return ret; 1215 return ret;
1209} 1216}
1210EXPORT_SYMBOL_GPL(cpufreq_governor); 1217EXPORT_SYMBOL_GPL(cpufreq_governor);
@@ -1217,18 +1224,17 @@ int cpufreq_register_governor(struct cpufreq_governor *governor)
1217 if (!governor) 1224 if (!governor)
1218 return -EINVAL; 1225 return -EINVAL;
1219 1226
1220 down(&cpufreq_governor_sem); 1227 mutex_lock(&cpufreq_governor_mutex);
1221 1228
1222 list_for_each_entry(t, &cpufreq_governor_list, governor_list) { 1229 list_for_each_entry(t, &cpufreq_governor_list, governor_list) {
1223 if (!strnicmp(governor->name,t->name,CPUFREQ_NAME_LEN)) { 1230 if (!strnicmp(governor->name,t->name,CPUFREQ_NAME_LEN)) {
1224 up(&cpufreq_governor_sem); 1231 mutex_unlock(&cpufreq_governor_mutex);
1225 return -EBUSY; 1232 return -EBUSY;
1226 } 1233 }
1227 } 1234 }
1228 list_add(&governor->governor_list, &cpufreq_governor_list); 1235 list_add(&governor->governor_list, &cpufreq_governor_list);
1229 1236
1230 up(&cpufreq_governor_sem); 1237 mutex_unlock(&cpufreq_governor_mutex);
1231
1232 return 0; 1238 return 0;
1233} 1239}
1234EXPORT_SYMBOL_GPL(cpufreq_register_governor); 1240EXPORT_SYMBOL_GPL(cpufreq_register_governor);
@@ -1239,9 +1245,9 @@ void cpufreq_unregister_governor(struct cpufreq_governor *governor)
1239 if (!governor) 1245 if (!governor)
1240 return; 1246 return;
1241 1247
1242 down(&cpufreq_governor_sem); 1248 mutex_lock(&cpufreq_governor_mutex);
1243 list_del(&governor->governor_list); 1249 list_del(&governor->governor_list);
1244 up(&cpufreq_governor_sem); 1250 mutex_unlock(&cpufreq_governor_mutex);
1245 return; 1251 return;
1246} 1252}
1247EXPORT_SYMBOL_GPL(cpufreq_unregister_governor); 1253EXPORT_SYMBOL_GPL(cpufreq_unregister_governor);
@@ -1268,12 +1274,11 @@ int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu)
1268 if (!cpu_policy) 1274 if (!cpu_policy)
1269 return -EINVAL; 1275 return -EINVAL;
1270 1276
1271 down(&cpu_policy->lock); 1277 mutex_lock(&cpu_policy->lock);
1272 memcpy(policy, cpu_policy, sizeof(struct cpufreq_policy)); 1278 memcpy(policy, cpu_policy, sizeof(struct cpufreq_policy));
1273 up(&cpu_policy->lock); 1279 mutex_unlock(&cpu_policy->lock);
1274 1280
1275 cpufreq_cpu_put(cpu_policy); 1281 cpufreq_cpu_put(cpu_policy);
1276
1277 return 0; 1282 return 0;
1278} 1283}
1279EXPORT_SYMBOL(cpufreq_get_policy); 1284EXPORT_SYMBOL(cpufreq_get_policy);
@@ -1287,9 +1292,7 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data, struct cpufreq_poli
1287 dprintk("setting new policy for CPU %u: %u - %u kHz\n", policy->cpu, 1292 dprintk("setting new policy for CPU %u: %u - %u kHz\n", policy->cpu,
1288 policy->min, policy->max); 1293 policy->min, policy->max);
1289 1294
1290 memcpy(&policy->cpuinfo, 1295 memcpy(&policy->cpuinfo, &data->cpuinfo, sizeof(struct cpufreq_cpuinfo));
1291 &data->cpuinfo,
1292 sizeof(struct cpufreq_cpuinfo));
1293 1296
1294 /* verify the cpu speed can be set within this limit */ 1297 /* verify the cpu speed can be set within this limit */
1295 ret = cpufreq_driver->verify(policy); 1298 ret = cpufreq_driver->verify(policy);
@@ -1320,8 +1323,8 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data, struct cpufreq_poli
1320 1323
1321 up_read(&cpufreq_notifier_rwsem); 1324 up_read(&cpufreq_notifier_rwsem);
1322 1325
1323 data->min = policy->min; 1326 data->min = policy->min;
1324 data->max = policy->max; 1327 data->max = policy->max;
1325 1328
1326 dprintk("new min and max freqs are %u - %u kHz\n", data->min, data->max); 1329 dprintk("new min and max freqs are %u - %u kHz\n", data->min, data->max);
1327 1330
@@ -1358,7 +1361,7 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data, struct cpufreq_poli
1358 __cpufreq_governor(data, CPUFREQ_GOV_LIMITS); 1361 __cpufreq_governor(data, CPUFREQ_GOV_LIMITS);
1359 } 1362 }
1360 1363
1361 error_out: 1364error_out:
1362 cpufreq_debug_enable_ratelimit(); 1365 cpufreq_debug_enable_ratelimit();
1363 return ret; 1366 return ret;
1364} 1367}
@@ -1382,7 +1385,7 @@ int cpufreq_set_policy(struct cpufreq_policy *policy)
1382 return -EINVAL; 1385 return -EINVAL;
1383 1386
1384 /* lock this CPU */ 1387 /* lock this CPU */
1385 down(&data->lock); 1388 mutex_lock(&data->lock);
1386 1389
1387 ret = __cpufreq_set_policy(data, policy); 1390 ret = __cpufreq_set_policy(data, policy);
1388 data->user_policy.min = data->min; 1391 data->user_policy.min = data->min;
@@ -1390,7 +1393,7 @@ int cpufreq_set_policy(struct cpufreq_policy *policy)
1390 data->user_policy.policy = data->policy; 1393 data->user_policy.policy = data->policy;
1391 data->user_policy.governor = data->governor; 1394 data->user_policy.governor = data->governor;
1392 1395
1393 up(&data->lock); 1396 mutex_unlock(&data->lock);
1394 cpufreq_cpu_put(data); 1397 cpufreq_cpu_put(data);
1395 1398
1396 return ret; 1399 return ret;
@@ -1414,20 +1417,31 @@ int cpufreq_update_policy(unsigned int cpu)
1414 if (!data) 1417 if (!data)
1415 return -ENODEV; 1418 return -ENODEV;
1416 1419
1417 down(&data->lock); 1420 mutex_lock(&data->lock);
1418 1421
1419 dprintk("updating policy for CPU %u\n", cpu); 1422 dprintk("updating policy for CPU %u\n", cpu);
1420 memcpy(&policy, 1423 memcpy(&policy, data, sizeof(struct cpufreq_policy));
1421 data,
1422 sizeof(struct cpufreq_policy));
1423 policy.min = data->user_policy.min; 1424 policy.min = data->user_policy.min;
1424 policy.max = data->user_policy.max; 1425 policy.max = data->user_policy.max;
1425 policy.policy = data->user_policy.policy; 1426 policy.policy = data->user_policy.policy;
1426 policy.governor = data->user_policy.governor; 1427 policy.governor = data->user_policy.governor;
1427 1428
1429 /* BIOS might change freq behind our back
1430 -> ask driver for current freq and notify governors about a change */
1431 if (cpufreq_driver->get) {
1432 policy.cur = cpufreq_driver->get(cpu);
1433 if (!data->cur) {
1434 dprintk("Driver did not initialize current freq");
1435 data->cur = policy.cur;
1436 } else {
1437 if (data->cur != policy.cur)
1438 cpufreq_out_of_sync(cpu, data->cur, policy.cur);
1439 }
1440 }
1441
1428 ret = __cpufreq_set_policy(data, &policy); 1442 ret = __cpufreq_set_policy(data, &policy);
1429 1443
1430 up(&data->lock); 1444 mutex_unlock(&data->lock);
1431 1445
1432 cpufreq_cpu_put(data); 1446 cpufreq_cpu_put(data);
1433 return ret; 1447 return ret;
diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c
index 39543a2bed0f..ac38766b2583 100644
--- a/drivers/cpufreq/cpufreq_conservative.c
+++ b/drivers/cpufreq/cpufreq_conservative.c
@@ -28,7 +28,7 @@
28#include <linux/jiffies.h> 28#include <linux/jiffies.h>
29#include <linux/kernel_stat.h> 29#include <linux/kernel_stat.h>
30#include <linux/percpu.h> 30#include <linux/percpu.h>
31 31#include <linux/mutex.h>
32/* 32/*
33 * dbs is used in this file as a shortform for demandbased switching 33 * dbs is used in this file as a shortform for demandbased switching
34 * It helps to keep variable names smaller, simpler 34 * It helps to keep variable names smaller, simpler
@@ -71,7 +71,7 @@ static DEFINE_PER_CPU(struct cpu_dbs_info_s, cpu_dbs_info);
71 71
72static unsigned int dbs_enable; /* number of CPUs using this policy */ 72static unsigned int dbs_enable; /* number of CPUs using this policy */
73 73
74static DECLARE_MUTEX (dbs_sem); 74static DEFINE_MUTEX (dbs_mutex);
75static DECLARE_WORK (dbs_work, do_dbs_timer, NULL); 75static DECLARE_WORK (dbs_work, do_dbs_timer, NULL);
76 76
77struct dbs_tuners { 77struct dbs_tuners {
@@ -139,9 +139,9 @@ static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused,
139 if (ret != 1 ) 139 if (ret != 1 )
140 return -EINVAL; 140 return -EINVAL;
141 141
142 down(&dbs_sem); 142 mutex_lock(&dbs_mutex);
143 dbs_tuners_ins.sampling_down_factor = input; 143 dbs_tuners_ins.sampling_down_factor = input;
144 up(&dbs_sem); 144 mutex_unlock(&dbs_mutex);
145 145
146 return count; 146 return count;
147} 147}
@@ -153,14 +153,14 @@ static ssize_t store_sampling_rate(struct cpufreq_policy *unused,
153 int ret; 153 int ret;
154 ret = sscanf (buf, "%u", &input); 154 ret = sscanf (buf, "%u", &input);
155 155
156 down(&dbs_sem); 156 mutex_lock(&dbs_mutex);
157 if (ret != 1 || input > MAX_SAMPLING_RATE || input < MIN_SAMPLING_RATE) { 157 if (ret != 1 || input > MAX_SAMPLING_RATE || input < MIN_SAMPLING_RATE) {
158 up(&dbs_sem); 158 mutex_unlock(&dbs_mutex);
159 return -EINVAL; 159 return -EINVAL;
160 } 160 }
161 161
162 dbs_tuners_ins.sampling_rate = input; 162 dbs_tuners_ins.sampling_rate = input;
163 up(&dbs_sem); 163 mutex_unlock(&dbs_mutex);
164 164
165 return count; 165 return count;
166} 166}
@@ -172,16 +172,16 @@ static ssize_t store_up_threshold(struct cpufreq_policy *unused,
172 int ret; 172 int ret;
173 ret = sscanf (buf, "%u", &input); 173 ret = sscanf (buf, "%u", &input);
174 174
175 down(&dbs_sem); 175 mutex_lock(&dbs_mutex);
176 if (ret != 1 || input > MAX_FREQUENCY_UP_THRESHOLD || 176 if (ret != 1 || input > MAX_FREQUENCY_UP_THRESHOLD ||
177 input < MIN_FREQUENCY_UP_THRESHOLD || 177 input < MIN_FREQUENCY_UP_THRESHOLD ||
178 input <= dbs_tuners_ins.down_threshold) { 178 input <= dbs_tuners_ins.down_threshold) {
179 up(&dbs_sem); 179 mutex_unlock(&dbs_mutex);
180 return -EINVAL; 180 return -EINVAL;
181 } 181 }
182 182
183 dbs_tuners_ins.up_threshold = input; 183 dbs_tuners_ins.up_threshold = input;
184 up(&dbs_sem); 184 mutex_unlock(&dbs_mutex);
185 185
186 return count; 186 return count;
187} 187}
@@ -193,16 +193,16 @@ static ssize_t store_down_threshold(struct cpufreq_policy *unused,
193 int ret; 193 int ret;
194 ret = sscanf (buf, "%u", &input); 194 ret = sscanf (buf, "%u", &input);
195 195
196 down(&dbs_sem); 196 mutex_lock(&dbs_mutex);
197 if (ret != 1 || input > MAX_FREQUENCY_DOWN_THRESHOLD || 197 if (ret != 1 || input > MAX_FREQUENCY_DOWN_THRESHOLD ||
198 input < MIN_FREQUENCY_DOWN_THRESHOLD || 198 input < MIN_FREQUENCY_DOWN_THRESHOLD ||
199 input >= dbs_tuners_ins.up_threshold) { 199 input >= dbs_tuners_ins.up_threshold) {
200 up(&dbs_sem); 200 mutex_unlock(&dbs_mutex);
201 return -EINVAL; 201 return -EINVAL;
202 } 202 }
203 203
204 dbs_tuners_ins.down_threshold = input; 204 dbs_tuners_ins.down_threshold = input;
205 up(&dbs_sem); 205 mutex_unlock(&dbs_mutex);
206 206
207 return count; 207 return count;
208} 208}
@@ -222,9 +222,9 @@ static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy,
222 if ( input > 1 ) 222 if ( input > 1 )
223 input = 1; 223 input = 1;
224 224
225 down(&dbs_sem); 225 mutex_lock(&dbs_mutex);
226 if ( input == dbs_tuners_ins.ignore_nice ) { /* nothing to do */ 226 if ( input == dbs_tuners_ins.ignore_nice ) { /* nothing to do */
227 up(&dbs_sem); 227 mutex_unlock(&dbs_mutex);
228 return count; 228 return count;
229 } 229 }
230 dbs_tuners_ins.ignore_nice = input; 230 dbs_tuners_ins.ignore_nice = input;
@@ -236,7 +236,7 @@ static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy,
236 j_dbs_info->prev_cpu_idle_up = get_cpu_idle_time(j); 236 j_dbs_info->prev_cpu_idle_up = get_cpu_idle_time(j);
237 j_dbs_info->prev_cpu_idle_down = j_dbs_info->prev_cpu_idle_up; 237 j_dbs_info->prev_cpu_idle_down = j_dbs_info->prev_cpu_idle_up;
238 } 238 }
239 up(&dbs_sem); 239 mutex_unlock(&dbs_mutex);
240 240
241 return count; 241 return count;
242} 242}
@@ -257,9 +257,9 @@ static ssize_t store_freq_step(struct cpufreq_policy *policy,
257 257
258 /* no need to test here if freq_step is zero as the user might actually 258 /* no need to test here if freq_step is zero as the user might actually
259 * want this, they would be crazy though :) */ 259 * want this, they would be crazy though :) */
260 down(&dbs_sem); 260 mutex_lock(&dbs_mutex);
261 dbs_tuners_ins.freq_step = input; 261 dbs_tuners_ins.freq_step = input;
262 up(&dbs_sem); 262 mutex_unlock(&dbs_mutex);
263 263
264 return count; 264 return count;
265} 265}
@@ -444,12 +444,12 @@ static void dbs_check_cpu(int cpu)
444static void do_dbs_timer(void *data) 444static void do_dbs_timer(void *data)
445{ 445{
446 int i; 446 int i;
447 down(&dbs_sem); 447 mutex_lock(&dbs_mutex);
448 for_each_online_cpu(i) 448 for_each_online_cpu(i)
449 dbs_check_cpu(i); 449 dbs_check_cpu(i);
450 schedule_delayed_work(&dbs_work, 450 schedule_delayed_work(&dbs_work,
451 usecs_to_jiffies(dbs_tuners_ins.sampling_rate)); 451 usecs_to_jiffies(dbs_tuners_ins.sampling_rate));
452 up(&dbs_sem); 452 mutex_unlock(&dbs_mutex);
453} 453}
454 454
455static inline void dbs_timer_init(void) 455static inline void dbs_timer_init(void)
@@ -487,7 +487,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
487 if (this_dbs_info->enable) /* Already enabled */ 487 if (this_dbs_info->enable) /* Already enabled */
488 break; 488 break;
489 489
490 down(&dbs_sem); 490 mutex_lock(&dbs_mutex);
491 for_each_cpu_mask(j, policy->cpus) { 491 for_each_cpu_mask(j, policy->cpus) {
492 struct cpu_dbs_info_s *j_dbs_info; 492 struct cpu_dbs_info_s *j_dbs_info;
493 j_dbs_info = &per_cpu(cpu_dbs_info, j); 493 j_dbs_info = &per_cpu(cpu_dbs_info, j);
@@ -521,11 +521,11 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
521 dbs_timer_init(); 521 dbs_timer_init();
522 } 522 }
523 523
524 up(&dbs_sem); 524 mutex_unlock(&dbs_mutex);
525 break; 525 break;
526 526
527 case CPUFREQ_GOV_STOP: 527 case CPUFREQ_GOV_STOP:
528 down(&dbs_sem); 528 mutex_lock(&dbs_mutex);
529 this_dbs_info->enable = 0; 529 this_dbs_info->enable = 0;
530 sysfs_remove_group(&policy->kobj, &dbs_attr_group); 530 sysfs_remove_group(&policy->kobj, &dbs_attr_group);
531 dbs_enable--; 531 dbs_enable--;
@@ -536,12 +536,12 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
536 if (dbs_enable == 0) 536 if (dbs_enable == 0)
537 dbs_timer_exit(); 537 dbs_timer_exit();
538 538
539 up(&dbs_sem); 539 mutex_unlock(&dbs_mutex);
540 540
541 break; 541 break;
542 542
543 case CPUFREQ_GOV_LIMITS: 543 case CPUFREQ_GOV_LIMITS:
544 down(&dbs_sem); 544 mutex_lock(&dbs_mutex);
545 if (policy->max < this_dbs_info->cur_policy->cur) 545 if (policy->max < this_dbs_info->cur_policy->cur)
546 __cpufreq_driver_target( 546 __cpufreq_driver_target(
547 this_dbs_info->cur_policy, 547 this_dbs_info->cur_policy,
@@ -550,7 +550,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
550 __cpufreq_driver_target( 550 __cpufreq_driver_target(
551 this_dbs_info->cur_policy, 551 this_dbs_info->cur_policy,
552 policy->min, CPUFREQ_RELATION_L); 552 policy->min, CPUFREQ_RELATION_L);
553 up(&dbs_sem); 553 mutex_unlock(&dbs_mutex);
554 break; 554 break;
555 } 555 }
556 return 0; 556 return 0;
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index e69fd8dd1f1c..9ee9411f186f 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -27,6 +27,7 @@
27#include <linux/jiffies.h> 27#include <linux/jiffies.h>
28#include <linux/kernel_stat.h> 28#include <linux/kernel_stat.h>
29#include <linux/percpu.h> 29#include <linux/percpu.h>
30#include <linux/mutex.h>
30 31
31/* 32/*
32 * dbs is used in this file as a shortform for demandbased switching 33 * dbs is used in this file as a shortform for demandbased switching
@@ -70,7 +71,7 @@ static DEFINE_PER_CPU(struct cpu_dbs_info_s, cpu_dbs_info);
70 71
71static unsigned int dbs_enable; /* number of CPUs using this policy */ 72static unsigned int dbs_enable; /* number of CPUs using this policy */
72 73
73static DECLARE_MUTEX (dbs_sem); 74static DEFINE_MUTEX (dbs_mutex);
74static DECLARE_WORK (dbs_work, do_dbs_timer, NULL); 75static DECLARE_WORK (dbs_work, do_dbs_timer, NULL);
75 76
76struct dbs_tuners { 77struct dbs_tuners {
@@ -136,9 +137,9 @@ static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused,
136 if (input > MAX_SAMPLING_DOWN_FACTOR || input < 1) 137 if (input > MAX_SAMPLING_DOWN_FACTOR || input < 1)
137 return -EINVAL; 138 return -EINVAL;
138 139
139 down(&dbs_sem); 140 mutex_lock(&dbs_mutex);
140 dbs_tuners_ins.sampling_down_factor = input; 141 dbs_tuners_ins.sampling_down_factor = input;
141 up(&dbs_sem); 142 mutex_unlock(&dbs_mutex);
142 143
143 return count; 144 return count;
144} 145}
@@ -150,14 +151,14 @@ static ssize_t store_sampling_rate(struct cpufreq_policy *unused,
150 int ret; 151 int ret;
151 ret = sscanf (buf, "%u", &input); 152 ret = sscanf (buf, "%u", &input);
152 153
153 down(&dbs_sem); 154 mutex_lock(&dbs_mutex);
154 if (ret != 1 || input > MAX_SAMPLING_RATE || input < MIN_SAMPLING_RATE) { 155 if (ret != 1 || input > MAX_SAMPLING_RATE || input < MIN_SAMPLING_RATE) {
155 up(&dbs_sem); 156 mutex_unlock(&dbs_mutex);
156 return -EINVAL; 157 return -EINVAL;
157 } 158 }
158 159
159 dbs_tuners_ins.sampling_rate = input; 160 dbs_tuners_ins.sampling_rate = input;
160 up(&dbs_sem); 161 mutex_unlock(&dbs_mutex);
161 162
162 return count; 163 return count;
163} 164}
@@ -169,15 +170,15 @@ static ssize_t store_up_threshold(struct cpufreq_policy *unused,
169 int ret; 170 int ret;
170 ret = sscanf (buf, "%u", &input); 171 ret = sscanf (buf, "%u", &input);
171 172
172 down(&dbs_sem); 173 mutex_lock(&dbs_mutex);
173 if (ret != 1 || input > MAX_FREQUENCY_UP_THRESHOLD || 174 if (ret != 1 || input > MAX_FREQUENCY_UP_THRESHOLD ||
174 input < MIN_FREQUENCY_UP_THRESHOLD) { 175 input < MIN_FREQUENCY_UP_THRESHOLD) {
175 up(&dbs_sem); 176 mutex_unlock(&dbs_mutex);
176 return -EINVAL; 177 return -EINVAL;
177 } 178 }
178 179
179 dbs_tuners_ins.up_threshold = input; 180 dbs_tuners_ins.up_threshold = input;
180 up(&dbs_sem); 181 mutex_unlock(&dbs_mutex);
181 182
182 return count; 183 return count;
183} 184}
@@ -197,9 +198,9 @@ static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy,
197 if ( input > 1 ) 198 if ( input > 1 )
198 input = 1; 199 input = 1;
199 200
200 down(&dbs_sem); 201 mutex_lock(&dbs_mutex);
201 if ( input == dbs_tuners_ins.ignore_nice ) { /* nothing to do */ 202 if ( input == dbs_tuners_ins.ignore_nice ) { /* nothing to do */
202 up(&dbs_sem); 203 mutex_unlock(&dbs_mutex);
203 return count; 204 return count;
204 } 205 }
205 dbs_tuners_ins.ignore_nice = input; 206 dbs_tuners_ins.ignore_nice = input;
@@ -211,7 +212,7 @@ static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy,
211 j_dbs_info->prev_cpu_idle_up = get_cpu_idle_time(j); 212 j_dbs_info->prev_cpu_idle_up = get_cpu_idle_time(j);
212 j_dbs_info->prev_cpu_idle_down = j_dbs_info->prev_cpu_idle_up; 213 j_dbs_info->prev_cpu_idle_down = j_dbs_info->prev_cpu_idle_up;
213 } 214 }
214 up(&dbs_sem); 215 mutex_unlock(&dbs_mutex);
215 216
216 return count; 217 return count;
217} 218}
@@ -356,12 +357,12 @@ static void dbs_check_cpu(int cpu)
356static void do_dbs_timer(void *data) 357static void do_dbs_timer(void *data)
357{ 358{
358 int i; 359 int i;
359 down(&dbs_sem); 360 mutex_lock(&dbs_mutex);
360 for_each_online_cpu(i) 361 for_each_online_cpu(i)
361 dbs_check_cpu(i); 362 dbs_check_cpu(i);
362 schedule_delayed_work(&dbs_work, 363 schedule_delayed_work(&dbs_work,
363 usecs_to_jiffies(dbs_tuners_ins.sampling_rate)); 364 usecs_to_jiffies(dbs_tuners_ins.sampling_rate));
364 up(&dbs_sem); 365 mutex_unlock(&dbs_mutex);
365} 366}
366 367
367static inline void dbs_timer_init(void) 368static inline void dbs_timer_init(void)
@@ -399,7 +400,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
399 if (this_dbs_info->enable) /* Already enabled */ 400 if (this_dbs_info->enable) /* Already enabled */
400 break; 401 break;
401 402
402 down(&dbs_sem); 403 mutex_lock(&dbs_mutex);
403 for_each_cpu_mask(j, policy->cpus) { 404 for_each_cpu_mask(j, policy->cpus) {
404 struct cpu_dbs_info_s *j_dbs_info; 405 struct cpu_dbs_info_s *j_dbs_info;
405 j_dbs_info = &per_cpu(cpu_dbs_info, j); 406 j_dbs_info = &per_cpu(cpu_dbs_info, j);
@@ -435,11 +436,11 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
435 dbs_timer_init(); 436 dbs_timer_init();
436 } 437 }
437 438
438 up(&dbs_sem); 439 mutex_unlock(&dbs_mutex);
439 break; 440 break;
440 441
441 case CPUFREQ_GOV_STOP: 442 case CPUFREQ_GOV_STOP:
442 down(&dbs_sem); 443 mutex_lock(&dbs_mutex);
443 this_dbs_info->enable = 0; 444 this_dbs_info->enable = 0;
444 sysfs_remove_group(&policy->kobj, &dbs_attr_group); 445 sysfs_remove_group(&policy->kobj, &dbs_attr_group);
445 dbs_enable--; 446 dbs_enable--;
@@ -450,12 +451,12 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
450 if (dbs_enable == 0) 451 if (dbs_enable == 0)
451 dbs_timer_exit(); 452 dbs_timer_exit();
452 453
453 up(&dbs_sem); 454 mutex_unlock(&dbs_mutex);
454 455
455 break; 456 break;
456 457
457 case CPUFREQ_GOV_LIMITS: 458 case CPUFREQ_GOV_LIMITS:
458 down(&dbs_sem); 459 mutex_lock(&dbs_mutex);
459 if (policy->max < this_dbs_info->cur_policy->cur) 460 if (policy->max < this_dbs_info->cur_policy->cur)
460 __cpufreq_driver_target( 461 __cpufreq_driver_target(
461 this_dbs_info->cur_policy, 462 this_dbs_info->cur_policy,
@@ -464,7 +465,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
464 __cpufreq_driver_target( 465 __cpufreq_driver_target(
465 this_dbs_info->cur_policy, 466 this_dbs_info->cur_policy,
466 policy->min, CPUFREQ_RELATION_L); 467 policy->min, CPUFREQ_RELATION_L);
467 up(&dbs_sem); 468 mutex_unlock(&dbs_mutex);
468 break; 469 break;
469 } 470 }
470 return 0; 471 return 0;
diff --git a/drivers/cpufreq/cpufreq_userspace.c b/drivers/cpufreq/cpufreq_userspace.c
index d32bf3593cd3..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 *
@@ -21,6 +22,7 @@
21#include <linux/types.h> 22#include <linux/types.h>
22#include <linux/fs.h> 23#include <linux/fs.h>
23#include <linux/sysfs.h> 24#include <linux/sysfs.h>
25#include <linux/mutex.h>
24 26
25#include <asm/uaccess.h> 27#include <asm/uaccess.h>
26 28
@@ -33,9 +35,8 @@ static unsigned int cpu_min_freq[NR_CPUS];
33static unsigned int cpu_cur_freq[NR_CPUS]; /* current CPU freq */ 35static unsigned int cpu_cur_freq[NR_CPUS]; /* current CPU freq */
34static 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 */
35static unsigned int cpu_is_managed[NR_CPUS]; 37static unsigned int cpu_is_managed[NR_CPUS];
36static struct cpufreq_policy current_policy[NR_CPUS];
37 38
38static DECLARE_MUTEX (userspace_sem); 39static DEFINE_MUTEX (userspace_mutex);
39 40
40#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_GOVERNOR, "userspace", msg) 41#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_GOVERNOR, "userspace", msg)
41 42
@@ -64,35 +65,34 @@ static struct notifier_block userspace_cpufreq_notifier_block = {
64 * 65 *
65 * Sets the CPU frequency to freq. 66 * Sets the CPU frequency to freq.
66 */ 67 */
67static int cpufreq_set(unsigned int freq, unsigned int cpu) 68static int cpufreq_set(unsigned int freq, struct cpufreq_policy *policy)
68{ 69{
69 int ret = -EINVAL; 70 int ret = -EINVAL;
70 71
71 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);
72 73
73 down(&userspace_sem); 74 mutex_lock(&userspace_mutex);
74 if (!cpu_is_managed[cpu]) 75 if (!cpu_is_managed[policy->cpu])
75 goto err; 76 goto err;
76 77
77 cpu_set_freq[cpu] = freq; 78 cpu_set_freq[policy->cpu] = freq;
78 79
79 if (freq < cpu_min_freq[cpu]) 80 if (freq < cpu_min_freq[policy->cpu])
80 freq = cpu_min_freq[cpu]; 81 freq = cpu_min_freq[policy->cpu];
81 if (freq > cpu_max_freq[cpu]) 82 if (freq > cpu_max_freq[policy->cpu])
82 freq = cpu_max_freq[cpu]; 83 freq = cpu_max_freq[policy->cpu];
83 84
84 /* 85 /*
85 * We're safe from concurrent calls to ->target() here 86 * We're safe from concurrent calls to ->target() here
86 * as we hold the userspace_sem lock. If we were calling 87 * as we hold the userspace_mutex lock. If we were calling
87 * cpufreq_driver_target, a deadlock situation might occur: 88 * cpufreq_driver_target, a deadlock situation might occur:
88 * A: cpufreq_set (lock userspace_sem) -> cpufreq_driver_target(lock policy->lock) 89 * A: cpufreq_set (lock userspace_mutex) -> cpufreq_driver_target(lock policy->lock)
89 * B: cpufreq_set_policy(lock policy->lock) -> __cpufreq_governor -> cpufreq_governor_userspace (lock userspace_sem) 90 * B: cpufreq_set_policy(lock policy->lock) -> __cpufreq_governor -> cpufreq_governor_userspace (lock userspace_mutex)
90 */ 91 */
91 ret = __cpufreq_driver_target(&current_policy[cpu], freq, 92 ret = __cpufreq_driver_target(policy, freq, CPUFREQ_RELATION_L);
92 CPUFREQ_RELATION_L);
93 93
94 err: 94 err:
95 up(&userspace_sem); 95 mutex_unlock(&userspace_mutex);
96 return ret; 96 return ret;
97} 97}
98 98
@@ -113,7 +113,7 @@ store_speed (struct cpufreq_policy *policy, const char *buf, size_t count)
113 if (ret != 1) 113 if (ret != 1)
114 return -EINVAL; 114 return -EINVAL;
115 115
116 cpufreq_set(freq, policy->cpu); 116 cpufreq_set(freq, policy);
117 117
118 return count; 118 return count;
119} 119}
@@ -134,44 +134,48 @@ static int cpufreq_governor_userspace(struct cpufreq_policy *policy,
134 if (!cpu_online(cpu)) 134 if (!cpu_online(cpu))
135 return -EINVAL; 135 return -EINVAL;
136 BUG_ON(!policy->cur); 136 BUG_ON(!policy->cur);
137 down(&userspace_sem); 137 mutex_lock(&userspace_mutex);
138 cpu_is_managed[cpu] = 1; 138 cpu_is_managed[cpu] = 1;
139 cpu_min_freq[cpu] = policy->min; 139 cpu_min_freq[cpu] = policy->min;
140 cpu_max_freq[cpu] = policy->max; 140 cpu_max_freq[cpu] = policy->max;
141 cpu_cur_freq[cpu] = policy->cur; 141 cpu_cur_freq[cpu] = policy->cur;
142 cpu_set_freq[cpu] = policy->cur; 142 cpu_set_freq[cpu] = policy->cur;
143 sysfs_create_file (&policy->kobj, &freq_attr_scaling_setspeed.attr); 143 sysfs_create_file (&policy->kobj, &freq_attr_scaling_setspeed.attr);
144 memcpy (&current_policy[cpu], policy, sizeof(struct cpufreq_policy));
145 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]);
146 up(&userspace_sem); 145 mutex_unlock(&userspace_mutex);
147 break; 146 break;
148 case CPUFREQ_GOV_STOP: 147 case CPUFREQ_GOV_STOP:
149 down(&userspace_sem); 148 mutex_lock(&userspace_mutex);
150 cpu_is_managed[cpu] = 0; 149 cpu_is_managed[cpu] = 0;
151 cpu_min_freq[cpu] = 0; 150 cpu_min_freq[cpu] = 0;
152 cpu_max_freq[cpu] = 0; 151 cpu_max_freq[cpu] = 0;
153 cpu_set_freq[cpu] = 0; 152 cpu_set_freq[cpu] = 0;
154 sysfs_remove_file (&policy->kobj, &freq_attr_scaling_setspeed.attr); 153 sysfs_remove_file (&policy->kobj, &freq_attr_scaling_setspeed.attr);
155 dprintk("managing cpu %u stopped\n", cpu); 154 dprintk("managing cpu %u stopped\n", cpu);
156 up(&userspace_sem); 155 mutex_unlock(&userspace_mutex);
157 break; 156 break;
158 case CPUFREQ_GOV_LIMITS: 157 case CPUFREQ_GOV_LIMITS:
159 down(&userspace_sem); 158 mutex_lock(&userspace_mutex);
160 cpu_min_freq[cpu] = policy->min; 159 dprintk("limit event for cpu %u: %u - %u kHz,"
161 cpu_max_freq[cpu] = policy->max; 160 "currently %u kHz, last set to %u kHz\n",
162 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]);
163 if (policy->max < cpu_set_freq[cpu]) { 163 if (policy->max < cpu_set_freq[cpu]) {
164 __cpufreq_driver_target(&current_policy[cpu], policy->max, 164 __cpufreq_driver_target(policy, policy->max,
165 CPUFREQ_RELATION_H); 165 CPUFREQ_RELATION_H);
166 } else if (policy->min > cpu_set_freq[cpu]) { 166 }
167 __cpufreq_driver_target(&current_policy[cpu], policy->min, 167 else if (policy->min > cpu_set_freq[cpu]) {
168 CPUFREQ_RELATION_L); 168 __cpufreq_driver_target(policy, policy->min,
169 } else { 169 CPUFREQ_RELATION_L);
170 __cpufreq_driver_target(&current_policy[cpu], cpu_set_freq[cpu],
171 CPUFREQ_RELATION_L);
172 } 170 }
173 memcpy (&current_policy[cpu], policy, sizeof(struct cpufreq_policy)); 171 else {
174 up(&userspace_sem); 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;
178 mutex_unlock(&userspace_mutex);
175 break; 179 break;
176 } 180 }
177 return 0; 181 return 0;