diff options
Diffstat (limited to 'drivers/thermal/cpu_cooling.c')
-rw-r--r-- | drivers/thermal/cpu_cooling.c | 67 |
1 files changed, 59 insertions, 8 deletions
diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c index 02a46f23d14c..4246262c4bd2 100644 --- a/drivers/thermal/cpu_cooling.c +++ b/drivers/thermal/cpu_cooling.c | |||
@@ -174,6 +174,13 @@ static int get_property(unsigned int cpu, unsigned long input, | |||
174 | max_level++; | 174 | max_level++; |
175 | } | 175 | } |
176 | 176 | ||
177 | /* No valid cpu frequency entry */ | ||
178 | if (max_level == 0) | ||
179 | return -EINVAL; | ||
180 | |||
181 | /* max_level is an index, not a counter */ | ||
182 | max_level--; | ||
183 | |||
177 | /* get max level */ | 184 | /* get max level */ |
178 | if (property == GET_MAXL) { | 185 | if (property == GET_MAXL) { |
179 | *output = (unsigned int)max_level; | 186 | *output = (unsigned int)max_level; |
@@ -181,7 +188,7 @@ static int get_property(unsigned int cpu, unsigned long input, | |||
181 | } | 188 | } |
182 | 189 | ||
183 | if (property == GET_FREQ) | 190 | if (property == GET_FREQ) |
184 | level = descend ? input : (max_level - input - 1); | 191 | level = descend ? input : (max_level - input); |
185 | 192 | ||
186 | for (i = 0, j = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) { | 193 | for (i = 0, j = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) { |
187 | /* ignore invalid entry */ | 194 | /* ignore invalid entry */ |
@@ -197,7 +204,7 @@ static int get_property(unsigned int cpu, unsigned long input, | |||
197 | 204 | ||
198 | if (property == GET_LEVEL && (unsigned int)input == freq) { | 205 | if (property == GET_LEVEL && (unsigned int)input == freq) { |
199 | /* get level by frequency */ | 206 | /* get level by frequency */ |
200 | *output = descend ? j : (max_level - j - 1); | 207 | *output = descend ? j : (max_level - j); |
201 | return 0; | 208 | return 0; |
202 | } | 209 | } |
203 | if (property == GET_FREQ && level == j) { | 210 | if (property == GET_FREQ && level == j) { |
@@ -417,18 +424,21 @@ static struct notifier_block thermal_cpufreq_notifier_block = { | |||
417 | }; | 424 | }; |
418 | 425 | ||
419 | /** | 426 | /** |
420 | * cpufreq_cooling_register - function to create cpufreq cooling device. | 427 | * __cpufreq_cooling_register - helper function to create cpufreq cooling device |
428 | * @np: a valid struct device_node to the cooling device device tree node | ||
421 | * @clip_cpus: cpumask of cpus where the frequency constraints will happen. | 429 | * @clip_cpus: cpumask of cpus where the frequency constraints will happen. |
422 | * | 430 | * |
423 | * This interface function registers the cpufreq cooling device with the name | 431 | * This interface function registers the cpufreq cooling device with the name |
424 | * "thermal-cpufreq-%x". This api can support multiple instances of cpufreq | 432 | * "thermal-cpufreq-%x". This api can support multiple instances of cpufreq |
425 | * cooling devices. | 433 | * cooling devices. It also gives the opportunity to link the cooling device |
434 | * with a device tree node, in order to bind it via the thermal DT code. | ||
426 | * | 435 | * |
427 | * Return: a valid struct thermal_cooling_device pointer on success, | 436 | * Return: a valid struct thermal_cooling_device pointer on success, |
428 | * on failure, it returns a corresponding ERR_PTR(). | 437 | * on failure, it returns a corresponding ERR_PTR(). |
429 | */ | 438 | */ |
430 | struct thermal_cooling_device * | 439 | static struct thermal_cooling_device * |
431 | cpufreq_cooling_register(const struct cpumask *clip_cpus) | 440 | __cpufreq_cooling_register(struct device_node *np, |
441 | const struct cpumask *clip_cpus) | ||
432 | { | 442 | { |
433 | struct thermal_cooling_device *cool_dev; | 443 | struct thermal_cooling_device *cool_dev; |
434 | struct cpufreq_cooling_device *cpufreq_dev = NULL; | 444 | struct cpufreq_cooling_device *cpufreq_dev = NULL; |
@@ -467,8 +477,8 @@ cpufreq_cooling_register(const struct cpumask *clip_cpus) | |||
467 | snprintf(dev_name, sizeof(dev_name), "thermal-cpufreq-%d", | 477 | snprintf(dev_name, sizeof(dev_name), "thermal-cpufreq-%d", |
468 | cpufreq_dev->id); | 478 | cpufreq_dev->id); |
469 | 479 | ||
470 | cool_dev = thermal_cooling_device_register(dev_name, cpufreq_dev, | 480 | cool_dev = thermal_of_cooling_device_register(np, dev_name, cpufreq_dev, |
471 | &cpufreq_cooling_ops); | 481 | &cpufreq_cooling_ops); |
472 | if (IS_ERR(cool_dev)) { | 482 | if (IS_ERR(cool_dev)) { |
473 | release_idr(&cpufreq_idr, cpufreq_dev->id); | 483 | release_idr(&cpufreq_idr, cpufreq_dev->id); |
474 | kfree(cpufreq_dev); | 484 | kfree(cpufreq_dev); |
@@ -488,9 +498,50 @@ cpufreq_cooling_register(const struct cpumask *clip_cpus) | |||
488 | 498 | ||
489 | return cool_dev; | 499 | return cool_dev; |
490 | } | 500 | } |
501 | |||
502 | /** | ||
503 | * cpufreq_cooling_register - function to create cpufreq cooling device. | ||
504 | * @clip_cpus: cpumask of cpus where the frequency constraints will happen. | ||
505 | * | ||
506 | * This interface function registers the cpufreq cooling device with the name | ||
507 | * "thermal-cpufreq-%x". This api can support multiple instances of cpufreq | ||
508 | * cooling devices. | ||
509 | * | ||
510 | * Return: a valid struct thermal_cooling_device pointer on success, | ||
511 | * on failure, it returns a corresponding ERR_PTR(). | ||
512 | */ | ||
513 | struct thermal_cooling_device * | ||
514 | cpufreq_cooling_register(const struct cpumask *clip_cpus) | ||
515 | { | ||
516 | return __cpufreq_cooling_register(NULL, clip_cpus); | ||
517 | } | ||
491 | EXPORT_SYMBOL_GPL(cpufreq_cooling_register); | 518 | EXPORT_SYMBOL_GPL(cpufreq_cooling_register); |
492 | 519 | ||
493 | /** | 520 | /** |
521 | * of_cpufreq_cooling_register - function to create cpufreq cooling device. | ||
522 | * @np: a valid struct device_node to the cooling device device tree node | ||
523 | * @clip_cpus: cpumask of cpus where the frequency constraints will happen. | ||
524 | * | ||
525 | * This interface function registers the cpufreq cooling device with the name | ||
526 | * "thermal-cpufreq-%x". This api can support multiple instances of cpufreq | ||
527 | * cooling devices. Using this API, the cpufreq cooling device will be | ||
528 | * linked to the device tree node provided. | ||
529 | * | ||
530 | * Return: a valid struct thermal_cooling_device pointer on success, | ||
531 | * on failure, it returns a corresponding ERR_PTR(). | ||
532 | */ | ||
533 | struct thermal_cooling_device * | ||
534 | of_cpufreq_cooling_register(struct device_node *np, | ||
535 | const struct cpumask *clip_cpus) | ||
536 | { | ||
537 | if (!np) | ||
538 | return ERR_PTR(-EINVAL); | ||
539 | |||
540 | return __cpufreq_cooling_register(np, clip_cpus); | ||
541 | } | ||
542 | EXPORT_SYMBOL_GPL(of_cpufreq_cooling_register); | ||
543 | |||
544 | /** | ||
494 | * cpufreq_cooling_unregister - function to remove cpufreq cooling device. | 545 | * cpufreq_cooling_unregister - function to remove cpufreq cooling device. |
495 | * @cdev: thermal cooling device pointer. | 546 | * @cdev: thermal cooling device pointer. |
496 | * | 547 | * |