aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/cpufreq')
-rw-r--r--drivers/cpufreq/cpufreq.c119
-rw-r--r--drivers/cpufreq/cpufreq_conservative.c2
-rw-r--r--drivers/cpufreq/cpufreq_ondemand.c20
-rw-r--r--drivers/cpufreq/cpufreq_userspace.c3
4 files changed, 91 insertions, 53 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 1ba4039777e8..b3df613ae4ec 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -284,39 +284,69 @@ EXPORT_SYMBOL_GPL(cpufreq_notify_transition);
284 * SYSFS INTERFACE * 284 * SYSFS INTERFACE *
285 *********************************************************************/ 285 *********************************************************************/
286 286
287static struct cpufreq_governor *__find_governor(const char *str_governor)
288{
289 struct cpufreq_governor *t;
290
291 list_for_each_entry(t, &cpufreq_governor_list, governor_list)
292 if (!strnicmp(str_governor,t->name,CPUFREQ_NAME_LEN))
293 return t;
294
295 return NULL;
296}
297
287/** 298/**
288 * cpufreq_parse_governor - parse a governor string 299 * cpufreq_parse_governor - parse a governor string
289 */ 300 */
290static int cpufreq_parse_governor (char *str_governor, unsigned int *policy, 301static int cpufreq_parse_governor (char *str_governor, unsigned int *policy,
291 struct cpufreq_governor **governor) 302 struct cpufreq_governor **governor)
292{ 303{
304 int err = -EINVAL;
305
293 if (!cpufreq_driver) 306 if (!cpufreq_driver)
294 return -EINVAL; 307 goto out;
308
295 if (cpufreq_driver->setpolicy) { 309 if (cpufreq_driver->setpolicy) {
296 if (!strnicmp(str_governor, "performance", CPUFREQ_NAME_LEN)) { 310 if (!strnicmp(str_governor, "performance", CPUFREQ_NAME_LEN)) {
297 *policy = CPUFREQ_POLICY_PERFORMANCE; 311 *policy = CPUFREQ_POLICY_PERFORMANCE;
298 return 0; 312 err = 0;
299 } else if (!strnicmp(str_governor, "powersave", CPUFREQ_NAME_LEN)) { 313 } else if (!strnicmp(str_governor, "powersave", CPUFREQ_NAME_LEN)) {
300 *policy = CPUFREQ_POLICY_POWERSAVE; 314 *policy = CPUFREQ_POLICY_POWERSAVE;
301 return 0; 315 err = 0;
302 } 316 }
303 return -EINVAL; 317 } else if (cpufreq_driver->target) {
304 } else {
305 struct cpufreq_governor *t; 318 struct cpufreq_governor *t;
319
306 mutex_lock(&cpufreq_governor_mutex); 320 mutex_lock(&cpufreq_governor_mutex);
307 if (!cpufreq_driver || !cpufreq_driver->target) 321
308 goto out; 322 t = __find_governor(str_governor);
309 list_for_each_entry(t, &cpufreq_governor_list, governor_list) { 323
310 if (!strnicmp(str_governor,t->name,CPUFREQ_NAME_LEN)) { 324 if (t == NULL) {
311 *governor = t; 325 char *name = kasprintf(GFP_KERNEL, "cpufreq_%s", str_governor);
326
327 if (name) {
328 int ret;
329
312 mutex_unlock(&cpufreq_governor_mutex); 330 mutex_unlock(&cpufreq_governor_mutex);
313 return 0; 331 ret = request_module(name);
332 mutex_lock(&cpufreq_governor_mutex);
333
334 if (ret == 0)
335 t = __find_governor(str_governor);
314 } 336 }
337
338 kfree(name);
315 } 339 }
316out: 340
341 if (t != NULL) {
342 *governor = t;
343 err = 0;
344 }
345
317 mutex_unlock(&cpufreq_governor_mutex); 346 mutex_unlock(&cpufreq_governor_mutex);
318 } 347 }
319 return -EINVAL; 348 out:
349 return err;
320} 350}
321 351
322 352
@@ -364,10 +394,12 @@ static ssize_t store_##file_name \
364 if (ret != 1) \ 394 if (ret != 1) \
365 return -EINVAL; \ 395 return -EINVAL; \
366 \ 396 \
397 lock_cpu_hotplug(); \
367 mutex_lock(&policy->lock); \ 398 mutex_lock(&policy->lock); \
368 ret = __cpufreq_set_policy(policy, &new_policy); \ 399 ret = __cpufreq_set_policy(policy, &new_policy); \
369 policy->user_policy.object = policy->object; \ 400 policy->user_policy.object = policy->object; \
370 mutex_unlock(&policy->lock); \ 401 mutex_unlock(&policy->lock); \
402 unlock_cpu_hotplug(); \
371 \ 403 \
372 return ret ? ret : count; \ 404 return ret ? ret : count; \
373} 405}
@@ -423,6 +455,8 @@ static ssize_t store_scaling_governor (struct cpufreq_policy * policy,
423 if (cpufreq_parse_governor(str_governor, &new_policy.policy, &new_policy.governor)) 455 if (cpufreq_parse_governor(str_governor, &new_policy.policy, &new_policy.governor))
424 return -EINVAL; 456 return -EINVAL;
425 457
458 lock_cpu_hotplug();
459
426 /* Do not use cpufreq_set_policy here or the user_policy.max 460 /* Do not use cpufreq_set_policy here or the user_policy.max
427 will be wrongly overridden */ 461 will be wrongly overridden */
428 mutex_lock(&policy->lock); 462 mutex_lock(&policy->lock);
@@ -432,6 +466,8 @@ static ssize_t store_scaling_governor (struct cpufreq_policy * policy,
432 policy->user_policy.governor = policy->governor; 466 policy->user_policy.governor = policy->governor;
433 mutex_unlock(&policy->lock); 467 mutex_unlock(&policy->lock);
434 468
469 unlock_cpu_hotplug();
470
435 return ret ? ret : count; 471 return ret ? ret : count;
436} 472}
437 473
@@ -1193,20 +1229,18 @@ EXPORT_SYMBOL(cpufreq_unregister_notifier);
1193 *********************************************************************/ 1229 *********************************************************************/
1194 1230
1195 1231
1232/* Must be called with lock_cpu_hotplug held */
1196int __cpufreq_driver_target(struct cpufreq_policy *policy, 1233int __cpufreq_driver_target(struct cpufreq_policy *policy,
1197 unsigned int target_freq, 1234 unsigned int target_freq,
1198 unsigned int relation) 1235 unsigned int relation)
1199{ 1236{
1200 int retval = -EINVAL; 1237 int retval = -EINVAL;
1201 1238
1202 lock_cpu_hotplug();
1203 dprintk("target for CPU %u: %u kHz, relation %u\n", policy->cpu, 1239 dprintk("target for CPU %u: %u kHz, relation %u\n", policy->cpu,
1204 target_freq, relation); 1240 target_freq, relation);
1205 if (cpu_online(policy->cpu) && cpufreq_driver->target) 1241 if (cpu_online(policy->cpu) && cpufreq_driver->target)
1206 retval = cpufreq_driver->target(policy, target_freq, relation); 1242 retval = cpufreq_driver->target(policy, target_freq, relation);
1207 1243
1208 unlock_cpu_hotplug();
1209
1210 return retval; 1244 return retval;
1211} 1245}
1212EXPORT_SYMBOL_GPL(__cpufreq_driver_target); 1246EXPORT_SYMBOL_GPL(__cpufreq_driver_target);
@@ -1221,17 +1255,23 @@ int cpufreq_driver_target(struct cpufreq_policy *policy,
1221 if (!policy) 1255 if (!policy)
1222 return -EINVAL; 1256 return -EINVAL;
1223 1257
1258 lock_cpu_hotplug();
1224 mutex_lock(&policy->lock); 1259 mutex_lock(&policy->lock);
1225 1260
1226 ret = __cpufreq_driver_target(policy, target_freq, relation); 1261 ret = __cpufreq_driver_target(policy, target_freq, relation);
1227 1262
1228 mutex_unlock(&policy->lock); 1263 mutex_unlock(&policy->lock);
1264 unlock_cpu_hotplug();
1229 1265
1230 cpufreq_cpu_put(policy); 1266 cpufreq_cpu_put(policy);
1231 return ret; 1267 return ret;
1232} 1268}
1233EXPORT_SYMBOL_GPL(cpufreq_driver_target); 1269EXPORT_SYMBOL_GPL(cpufreq_driver_target);
1234 1270
1271/*
1272 * Locking: Must be called with the lock_cpu_hotplug() lock held
1273 * when "event" is CPUFREQ_GOV_LIMITS
1274 */
1235 1275
1236static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event) 1276static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event)
1237{ 1277{
@@ -1253,43 +1293,23 @@ static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event)
1253} 1293}
1254 1294
1255 1295
1256int cpufreq_governor(unsigned int cpu, unsigned int event)
1257{
1258 int ret = 0;
1259 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
1260
1261 if (!policy)
1262 return -EINVAL;
1263
1264 mutex_lock(&policy->lock);
1265 ret = __cpufreq_governor(policy, event);
1266 mutex_unlock(&policy->lock);
1267
1268 cpufreq_cpu_put(policy);
1269 return ret;
1270}
1271EXPORT_SYMBOL_GPL(cpufreq_governor);
1272
1273
1274int cpufreq_register_governor(struct cpufreq_governor *governor) 1296int cpufreq_register_governor(struct cpufreq_governor *governor)
1275{ 1297{
1276 struct cpufreq_governor *t; 1298 int err;
1277 1299
1278 if (!governor) 1300 if (!governor)
1279 return -EINVAL; 1301 return -EINVAL;
1280 1302
1281 mutex_lock(&cpufreq_governor_mutex); 1303 mutex_lock(&cpufreq_governor_mutex);
1282 1304
1283 list_for_each_entry(t, &cpufreq_governor_list, governor_list) { 1305 err = -EBUSY;
1284 if (!strnicmp(governor->name,t->name,CPUFREQ_NAME_LEN)) { 1306 if (__find_governor(governor->name) == NULL) {
1285 mutex_unlock(&cpufreq_governor_mutex); 1307 err = 0;
1286 return -EBUSY; 1308 list_add(&governor->governor_list, &cpufreq_governor_list);
1287 }
1288 } 1309 }
1289 list_add(&governor->governor_list, &cpufreq_governor_list);
1290 1310
1291 mutex_unlock(&cpufreq_governor_mutex); 1311 mutex_unlock(&cpufreq_governor_mutex);
1292 return 0; 1312 return err;
1293} 1313}
1294EXPORT_SYMBOL_GPL(cpufreq_register_governor); 1314EXPORT_SYMBOL_GPL(cpufreq_register_governor);
1295 1315
@@ -1338,6 +1358,9 @@ int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu)
1338EXPORT_SYMBOL(cpufreq_get_policy); 1358EXPORT_SYMBOL(cpufreq_get_policy);
1339 1359
1340 1360
1361/*
1362 * Locking: Must be called with the lock_cpu_hotplug() lock held
1363 */
1341static int __cpufreq_set_policy(struct cpufreq_policy *data, struct cpufreq_policy *policy) 1364static int __cpufreq_set_policy(struct cpufreq_policy *data, struct cpufreq_policy *policy)
1342{ 1365{
1343 int ret = 0; 1366 int ret = 0;
@@ -1348,6 +1371,11 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data, struct cpufreq_poli
1348 1371
1349 memcpy(&policy->cpuinfo, &data->cpuinfo, sizeof(struct cpufreq_cpuinfo)); 1372 memcpy(&policy->cpuinfo, &data->cpuinfo, sizeof(struct cpufreq_cpuinfo));
1350 1373
1374 if (policy->min > data->min && policy->min > policy->max) {
1375 ret = -EINVAL;
1376 goto error_out;
1377 }
1378
1351 /* verify the cpu speed can be set within this limit */ 1379 /* verify the cpu speed can be set within this limit */
1352 ret = cpufreq_driver->verify(policy); 1380 ret = cpufreq_driver->verify(policy);
1353 if (ret) 1381 if (ret)
@@ -1432,6 +1460,8 @@ int cpufreq_set_policy(struct cpufreq_policy *policy)
1432 if (!data) 1460 if (!data)
1433 return -EINVAL; 1461 return -EINVAL;
1434 1462
1463 lock_cpu_hotplug();
1464
1435 /* lock this CPU */ 1465 /* lock this CPU */
1436 mutex_lock(&data->lock); 1466 mutex_lock(&data->lock);
1437 1467
@@ -1442,6 +1472,8 @@ int cpufreq_set_policy(struct cpufreq_policy *policy)
1442 data->user_policy.governor = data->governor; 1472 data->user_policy.governor = data->governor;
1443 1473
1444 mutex_unlock(&data->lock); 1474 mutex_unlock(&data->lock);
1475
1476 unlock_cpu_hotplug();
1445 cpufreq_cpu_put(data); 1477 cpufreq_cpu_put(data);
1446 1478
1447 return ret; 1479 return ret;
@@ -1465,6 +1497,7 @@ int cpufreq_update_policy(unsigned int cpu)
1465 if (!data) 1497 if (!data)
1466 return -ENODEV; 1498 return -ENODEV;
1467 1499
1500 lock_cpu_hotplug();
1468 mutex_lock(&data->lock); 1501 mutex_lock(&data->lock);
1469 1502
1470 dprintk("updating policy for CPU %u\n", cpu); 1503 dprintk("updating policy for CPU %u\n", cpu);
@@ -1490,7 +1523,7 @@ int cpufreq_update_policy(unsigned int cpu)
1490 ret = __cpufreq_set_policy(data, &policy); 1523 ret = __cpufreq_set_policy(data, &policy);
1491 1524
1492 mutex_unlock(&data->lock); 1525 mutex_unlock(&data->lock);
1493 1526 unlock_cpu_hotplug();
1494 cpufreq_cpu_put(data); 1527 cpufreq_cpu_put(data);
1495 return ret; 1528 return ret;
1496} 1529}
diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c
index b3ebc8f01975..c4c578defabf 100644
--- a/drivers/cpufreq/cpufreq_conservative.c
+++ b/drivers/cpufreq/cpufreq_conservative.c
@@ -525,7 +525,6 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
525 break; 525 break;
526 526
527 case CPUFREQ_GOV_LIMITS: 527 case CPUFREQ_GOV_LIMITS:
528 lock_cpu_hotplug();
529 mutex_lock(&dbs_mutex); 528 mutex_lock(&dbs_mutex);
530 if (policy->max < this_dbs_info->cur_policy->cur) 529 if (policy->max < this_dbs_info->cur_policy->cur)
531 __cpufreq_driver_target( 530 __cpufreq_driver_target(
@@ -536,7 +535,6 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
536 this_dbs_info->cur_policy, 535 this_dbs_info->cur_policy,
537 policy->min, CPUFREQ_RELATION_L); 536 policy->min, CPUFREQ_RELATION_L);
538 mutex_unlock(&dbs_mutex); 537 mutex_unlock(&dbs_mutex);
539 unlock_cpu_hotplug();
540 break; 538 break;
541 } 539 }
542 return 0; 540 return 0;
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index 87299924e735..52cf1f021825 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -239,6 +239,8 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
239 total_ticks = (unsigned int) cputime64_sub(cur_jiffies, 239 total_ticks = (unsigned int) cputime64_sub(cur_jiffies,
240 this_dbs_info->prev_cpu_wall); 240 this_dbs_info->prev_cpu_wall);
241 this_dbs_info->prev_cpu_wall = cur_jiffies; 241 this_dbs_info->prev_cpu_wall = cur_jiffies;
242 if (!total_ticks)
243 return;
242 /* 244 /*
243 * Every sampling_rate, we check, if current idle time is less 245 * Every sampling_rate, we check, if current idle time is less
244 * than 20% (default), then we try to increase frequency 246 * than 20% (default), then we try to increase frequency
@@ -304,7 +306,12 @@ static void do_dbs_timer(void *data)
304 unsigned int cpu = smp_processor_id(); 306 unsigned int cpu = smp_processor_id();
305 struct cpu_dbs_info_s *dbs_info = &per_cpu(cpu_dbs_info, cpu); 307 struct cpu_dbs_info_s *dbs_info = &per_cpu(cpu_dbs_info, cpu);
306 308
309 if (!dbs_info->enable)
310 return;
311
312 lock_cpu_hotplug();
307 dbs_check_cpu(dbs_info); 313 dbs_check_cpu(dbs_info);
314 unlock_cpu_hotplug();
308 queue_delayed_work_on(cpu, kondemand_wq, &dbs_info->work, 315 queue_delayed_work_on(cpu, kondemand_wq, &dbs_info->work,
309 usecs_to_jiffies(dbs_tuners_ins.sampling_rate)); 316 usecs_to_jiffies(dbs_tuners_ins.sampling_rate));
310} 317}
@@ -319,11 +326,11 @@ static inline void dbs_timer_init(unsigned int cpu)
319 return; 326 return;
320} 327}
321 328
322static inline void dbs_timer_exit(unsigned int cpu) 329static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info)
323{ 330{
324 struct cpu_dbs_info_s *dbs_info = &per_cpu(cpu_dbs_info, cpu); 331 dbs_info->enable = 0;
325 332 cancel_delayed_work(&dbs_info->work);
326 cancel_rearming_delayed_workqueue(kondemand_wq, &dbs_info->work); 333 flush_workqueue(kondemand_wq);
327} 334}
328 335
329static int cpufreq_governor_dbs(struct cpufreq_policy *policy, 336static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
@@ -396,8 +403,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
396 403
397 case CPUFREQ_GOV_STOP: 404 case CPUFREQ_GOV_STOP:
398 mutex_lock(&dbs_mutex); 405 mutex_lock(&dbs_mutex);
399 dbs_timer_exit(policy->cpu); 406 dbs_timer_exit(this_dbs_info);
400 this_dbs_info->enable = 0;
401 sysfs_remove_group(&policy->kobj, &dbs_attr_group); 407 sysfs_remove_group(&policy->kobj, &dbs_attr_group);
402 dbs_enable--; 408 dbs_enable--;
403 if (dbs_enable == 0) 409 if (dbs_enable == 0)
@@ -408,7 +414,6 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
408 break; 414 break;
409 415
410 case CPUFREQ_GOV_LIMITS: 416 case CPUFREQ_GOV_LIMITS:
411 lock_cpu_hotplug();
412 mutex_lock(&dbs_mutex); 417 mutex_lock(&dbs_mutex);
413 if (policy->max < this_dbs_info->cur_policy->cur) 418 if (policy->max < this_dbs_info->cur_policy->cur)
414 __cpufreq_driver_target(this_dbs_info->cur_policy, 419 __cpufreq_driver_target(this_dbs_info->cur_policy,
@@ -419,7 +424,6 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
419 policy->min, 424 policy->min,
420 CPUFREQ_RELATION_L); 425 CPUFREQ_RELATION_L);
421 mutex_unlock(&dbs_mutex); 426 mutex_unlock(&dbs_mutex);
422 unlock_cpu_hotplug();
423 break; 427 break;
424 } 428 }
425 return 0; 429 return 0;
diff --git a/drivers/cpufreq/cpufreq_userspace.c b/drivers/cpufreq/cpufreq_userspace.c
index 44ae5e5b94cf..a06c204589cd 100644
--- a/drivers/cpufreq/cpufreq_userspace.c
+++ b/drivers/cpufreq/cpufreq_userspace.c
@@ -18,6 +18,7 @@
18#include <linux/spinlock.h> 18#include <linux/spinlock.h>
19#include <linux/interrupt.h> 19#include <linux/interrupt.h>
20#include <linux/cpufreq.h> 20#include <linux/cpufreq.h>
21#include <linux/cpu.h>
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>
@@ -70,6 +71,7 @@ static int cpufreq_set(unsigned int freq, struct cpufreq_policy *policy)
70 71
71 dprintk("cpufreq_set for cpu %u, freq %u kHz\n", policy->cpu, freq); 72 dprintk("cpufreq_set for cpu %u, freq %u kHz\n", policy->cpu, freq);
72 73
74 lock_cpu_hotplug();
73 mutex_lock(&userspace_mutex); 75 mutex_lock(&userspace_mutex);
74 if (!cpu_is_managed[policy->cpu]) 76 if (!cpu_is_managed[policy->cpu])
75 goto err; 77 goto err;
@@ -92,6 +94,7 @@ static int cpufreq_set(unsigned int freq, struct cpufreq_policy *policy)
92 94
93 err: 95 err:
94 mutex_unlock(&userspace_mutex); 96 mutex_unlock(&userspace_mutex);
97 unlock_cpu_hotplug();
95 return ret; 98 return ret;
96} 99}
97 100