aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq/cpufreq.c
diff options
context:
space:
mode:
authorSteven Whitehouse <steve@men-an-tol.chygwyn.com>2006-02-23 04:49:43 -0500
committerSteven Whitehouse <swhiteho@redhat.com>2006-02-23 04:49:43 -0500
commitd35462b4bb847b68321c55e95c926aa485aecce2 (patch)
treeb08e18bf6e672633402871ee763102fdb5e63229 /drivers/cpufreq/cpufreq.c
parent91ffd7db71e7451f89941a8f428b4daa2a7c1e38 (diff)
parent9e956c2dac9bec602ed1ba29181b45ba6d2b6448 (diff)
Merge branch 'master'
Diffstat (limited to 'drivers/cpufreq/cpufreq.c')
-rw-r--r--drivers/cpufreq/cpufreq.c174
1 files changed, 94 insertions, 80 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;