aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq/cpufreq.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/cpufreq/cpufreq.c')
-rw-r--r--drivers/cpufreq/cpufreq.c70
1 files changed, 41 insertions, 29 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 277a843a87a6..7a511479ae29 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
@@ -55,7 +56,7 @@ static 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{
@@ -297,18 +298,18 @@ static int cpufreq_parse_governor (char *str_governor, unsigned int *policy,
297 return -EINVAL; 298 return -EINVAL;
298 } else { 299 } else {
299 struct cpufreq_governor *t; 300 struct cpufreq_governor *t;
300 down(&cpufreq_governor_sem); 301 mutex_lock(&cpufreq_governor_mutex);
301 if (!cpufreq_driver || !cpufreq_driver->target) 302 if (!cpufreq_driver || !cpufreq_driver->target)
302 goto out; 303 goto out;
303 list_for_each_entry(t, &cpufreq_governor_list, governor_list) { 304 list_for_each_entry(t, &cpufreq_governor_list, governor_list) {
304 if (!strnicmp(str_governor,t->name,CPUFREQ_NAME_LEN)) { 305 if (!strnicmp(str_governor,t->name,CPUFREQ_NAME_LEN)) {
305 *governor = t; 306 *governor = t;
306 up(&cpufreq_governor_sem); 307 mutex_unlock(&cpufreq_governor_mutex);
307 return 0; 308 return 0;
308 } 309 }
309 } 310 }
310 out: 311 out:
311 up(&cpufreq_governor_sem); 312 mutex_unlock(&cpufreq_governor_mutex);
312 } 313 }
313 return -EINVAL; 314 return -EINVAL;
314} 315}
@@ -600,7 +601,8 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
600 policy->cpu = cpu; 601 policy->cpu = cpu;
601 policy->cpus = cpumask_of_cpu(cpu); 602 policy->cpus = cpumask_of_cpu(cpu);
602 603
603 init_MUTEX_LOCKED(&policy->lock); 604 mutex_init(&policy->lock);
605 mutex_lock(&policy->lock);
604 init_completion(&policy->kobj_unregister); 606 init_completion(&policy->kobj_unregister);
605 INIT_WORK(&policy->update, handle_update, (void *)(long)cpu); 607 INIT_WORK(&policy->update, handle_update, (void *)(long)cpu);
606 608
@@ -610,6 +612,7 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
610 ret = cpufreq_driver->init(policy); 612 ret = cpufreq_driver->init(policy);
611 if (ret) { 613 if (ret) {
612 dprintk("initialization failed\n"); 614 dprintk("initialization failed\n");
615 mutex_unlock(&policy->lock);
613 goto err_out; 616 goto err_out;
614 } 617 }
615 618
@@ -621,9 +624,10 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
621 strlcpy(policy->kobj.name, "cpufreq", KOBJ_NAME_LEN); 624 strlcpy(policy->kobj.name, "cpufreq", KOBJ_NAME_LEN);
622 625
623 ret = kobject_register(&policy->kobj); 626 ret = kobject_register(&policy->kobj);
624 if (ret) 627 if (ret) {
628 mutex_unlock(&policy->lock);
625 goto err_out_driver_exit; 629 goto err_out_driver_exit;
626 630 }
627 /* set up files for this cpu device */ 631 /* set up files for this cpu device */
628 drv_attr = cpufreq_driver->attr; 632 drv_attr = cpufreq_driver->attr;
629 while ((drv_attr) && (*drv_attr)) { 633 while ((drv_attr) && (*drv_attr)) {
@@ -641,7 +645,7 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
641 spin_unlock_irqrestore(&cpufreq_driver_lock, flags); 645 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
642 policy->governor = NULL; /* to assure that the starting sequence is 646 policy->governor = NULL; /* to assure that the starting sequence is
643 * run in cpufreq_set_policy */ 647 * run in cpufreq_set_policy */
644 up(&policy->lock); 648 mutex_unlock(&policy->lock);
645 649
646 /* set default policy */ 650 /* set default policy */
647 651
@@ -762,10 +766,10 @@ static int cpufreq_remove_dev (struct sys_device * sys_dev)
762 spin_unlock_irqrestore(&cpufreq_driver_lock, flags); 766 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
763#endif 767#endif
764 768
765 down(&data->lock); 769 mutex_lock(&data->lock);
766 if (cpufreq_driver->target) 770 if (cpufreq_driver->target)
767 __cpufreq_governor(data, CPUFREQ_GOV_STOP); 771 __cpufreq_governor(data, CPUFREQ_GOV_STOP);
768 up(&data->lock); 772 mutex_unlock(&data->lock);
769 773
770 kobject_unregister(&data->kobj); 774 kobject_unregister(&data->kobj);
771 775
@@ -834,9 +838,9 @@ unsigned int cpufreq_quick_get(unsigned int cpu)
834 unsigned int ret = 0; 838 unsigned int ret = 0;
835 839
836 if (policy) { 840 if (policy) {
837 down(&policy->lock); 841 mutex_lock(&policy->lock);
838 ret = policy->cur; 842 ret = policy->cur;
839 up(&policy->lock); 843 mutex_unlock(&policy->lock);
840 cpufreq_cpu_put(policy); 844 cpufreq_cpu_put(policy);
841 } 845 }
842 846
@@ -862,7 +866,7 @@ unsigned int cpufreq_get(unsigned int cpu)
862 if (!cpufreq_driver->get) 866 if (!cpufreq_driver->get)
863 goto out; 867 goto out;
864 868
865 down(&policy->lock); 869 mutex_lock(&policy->lock);
866 870
867 ret = cpufreq_driver->get(cpu); 871 ret = cpufreq_driver->get(cpu);
868 872
@@ -875,7 +879,7 @@ unsigned int cpufreq_get(unsigned int cpu)
875 } 879 }
876 } 880 }
877 881
878 up(&policy->lock); 882 mutex_unlock(&policy->lock);
879 883
880 out: 884 out:
881 cpufreq_cpu_put(policy); 885 cpufreq_cpu_put(policy);
@@ -1158,11 +1162,11 @@ int cpufreq_driver_target(struct cpufreq_policy *policy,
1158 if (!policy) 1162 if (!policy)
1159 return -EINVAL; 1163 return -EINVAL;
1160 1164
1161 down(&policy->lock); 1165 mutex_lock(&policy->lock);
1162 1166
1163 ret = __cpufreq_driver_target(policy, target_freq, relation); 1167 ret = __cpufreq_driver_target(policy, target_freq, relation);
1164 1168
1165 up(&policy->lock); 1169 mutex_unlock(&policy->lock);
1166 1170
1167 cpufreq_cpu_put(policy); 1171 cpufreq_cpu_put(policy);
1168 1172
@@ -1199,9 +1203,9 @@ int cpufreq_governor(unsigned int cpu, unsigned int event)
1199 if (!policy) 1203 if (!policy)
1200 return -EINVAL; 1204 return -EINVAL;
1201 1205
1202 down(&policy->lock); 1206 mutex_lock(&policy->lock);
1203 ret = __cpufreq_governor(policy, event); 1207 ret = __cpufreq_governor(policy, event);
1204 up(&policy->lock); 1208 mutex_unlock(&policy->lock);
1205 1209
1206 cpufreq_cpu_put(policy); 1210 cpufreq_cpu_put(policy);
1207 1211
@@ -1217,17 +1221,17 @@ int cpufreq_register_governor(struct cpufreq_governor *governor)
1217 if (!governor) 1221 if (!governor)
1218 return -EINVAL; 1222 return -EINVAL;
1219 1223
1220 down(&cpufreq_governor_sem); 1224 mutex_lock(&cpufreq_governor_mutex);
1221 1225
1222 list_for_each_entry(t, &cpufreq_governor_list, governor_list) { 1226 list_for_each_entry(t, &cpufreq_governor_list, governor_list) {
1223 if (!strnicmp(governor->name,t->name,CPUFREQ_NAME_LEN)) { 1227 if (!strnicmp(governor->name,t->name,CPUFREQ_NAME_LEN)) {
1224 up(&cpufreq_governor_sem); 1228 mutex_unlock(&cpufreq_governor_mutex);
1225 return -EBUSY; 1229 return -EBUSY;
1226 } 1230 }
1227 } 1231 }
1228 list_add(&governor->governor_list, &cpufreq_governor_list); 1232 list_add(&governor->governor_list, &cpufreq_governor_list);
1229 1233
1230 up(&cpufreq_governor_sem); 1234 mutex_unlock(&cpufreq_governor_mutex);
1231 1235
1232 return 0; 1236 return 0;
1233} 1237}
@@ -1239,9 +1243,9 @@ void cpufreq_unregister_governor(struct cpufreq_governor *governor)
1239 if (!governor) 1243 if (!governor)
1240 return; 1244 return;
1241 1245
1242 down(&cpufreq_governor_sem); 1246 mutex_lock(&cpufreq_governor_mutex);
1243 list_del(&governor->governor_list); 1247 list_del(&governor->governor_list);
1244 up(&cpufreq_governor_sem); 1248 mutex_unlock(&cpufreq_governor_mutex);
1245 return; 1249 return;
1246} 1250}
1247EXPORT_SYMBOL_GPL(cpufreq_unregister_governor); 1251EXPORT_SYMBOL_GPL(cpufreq_unregister_governor);
@@ -1268,9 +1272,9 @@ int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu)
1268 if (!cpu_policy) 1272 if (!cpu_policy)
1269 return -EINVAL; 1273 return -EINVAL;
1270 1274
1271 down(&cpu_policy->lock); 1275 mutex_lock(&cpu_policy->lock);
1272 memcpy(policy, cpu_policy, sizeof(struct cpufreq_policy)); 1276 memcpy(policy, cpu_policy, sizeof(struct cpufreq_policy));
1273 up(&cpu_policy->lock); 1277 mutex_unlock(&cpu_policy->lock);
1274 1278
1275 cpufreq_cpu_put(cpu_policy); 1279 cpufreq_cpu_put(cpu_policy);
1276 1280
@@ -1382,7 +1386,7 @@ int cpufreq_set_policy(struct cpufreq_policy *policy)
1382 return -EINVAL; 1386 return -EINVAL;
1383 1387
1384 /* lock this CPU */ 1388 /* lock this CPU */
1385 down(&data->lock); 1389 mutex_lock(&data->lock);
1386 1390
1387 ret = __cpufreq_set_policy(data, policy); 1391 ret = __cpufreq_set_policy(data, policy);
1388 data->user_policy.min = data->min; 1392 data->user_policy.min = data->min;
@@ -1390,7 +1394,7 @@ int cpufreq_set_policy(struct cpufreq_policy *policy)
1390 data->user_policy.policy = data->policy; 1394 data->user_policy.policy = data->policy;
1391 data->user_policy.governor = data->governor; 1395 data->user_policy.governor = data->governor;
1392 1396
1393 up(&data->lock); 1397 mutex_unlock(&data->lock);
1394 cpufreq_cpu_put(data); 1398 cpufreq_cpu_put(data);
1395 1399
1396 return ret; 1400 return ret;
@@ -1414,7 +1418,7 @@ int cpufreq_update_policy(unsigned int cpu)
1414 if (!data) 1418 if (!data)
1415 return -ENODEV; 1419 return -ENODEV;
1416 1420
1417 down(&data->lock); 1421 mutex_lock(&data->lock);
1418 1422
1419 dprintk("updating policy for CPU %u\n", cpu); 1423 dprintk("updating policy for CPU %u\n", cpu);
1420 memcpy(&policy, 1424 memcpy(&policy,
@@ -1425,9 +1429,17 @@ int cpufreq_update_policy(unsigned int cpu)
1425 policy.policy = data->user_policy.policy; 1429 policy.policy = data->user_policy.policy;
1426 policy.governor = data->user_policy.governor; 1430 policy.governor = data->user_policy.governor;
1427 1431
1432 /* BIOS might change freq behind our back
1433 -> ask driver for current freq and notify governors about a change */
1434 if (cpufreq_driver->get) {
1435 policy.cur = cpufreq_driver->get(cpu);
1436 if (data->cur != policy.cur)
1437 cpufreq_out_of_sync(cpu, data->cur, policy.cur);
1438 }
1439
1428 ret = __cpufreq_set_policy(data, &policy); 1440 ret = __cpufreq_set_policy(data, &policy);
1429 1441
1430 up(&data->lock); 1442 mutex_unlock(&data->lock);
1431 1443
1432 cpufreq_cpu_put(data); 1444 cpufreq_cpu_put(data);
1433 return ret; 1445 return ret;