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.c119
1 files changed, 76 insertions, 43 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}