diff options
| -rw-r--r-- | drivers/thermal/cpu_cooling.c | 37 | ||||
| -rw-r--r-- | drivers/thermal/samsung/exynos_thermal_common.c | 9 | ||||
| -rw-r--r-- | drivers/thermal/st/st_thermal.c | 3 |
3 files changed, 27 insertions, 22 deletions
diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c index 1ab0018271c5..ad09e51ffae4 100644 --- a/drivers/thermal/cpu_cooling.c +++ b/drivers/thermal/cpu_cooling.c | |||
| @@ -50,15 +50,14 @@ struct cpufreq_cooling_device { | |||
| 50 | unsigned int cpufreq_state; | 50 | unsigned int cpufreq_state; |
| 51 | unsigned int cpufreq_val; | 51 | unsigned int cpufreq_val; |
| 52 | struct cpumask allowed_cpus; | 52 | struct cpumask allowed_cpus; |
| 53 | struct list_head node; | ||
| 53 | }; | 54 | }; |
| 54 | static DEFINE_IDR(cpufreq_idr); | 55 | static DEFINE_IDR(cpufreq_idr); |
| 55 | static DEFINE_MUTEX(cooling_cpufreq_lock); | 56 | static DEFINE_MUTEX(cooling_cpufreq_lock); |
| 56 | 57 | ||
| 57 | static unsigned int cpufreq_dev_count; | 58 | static unsigned int cpufreq_dev_count; |
| 58 | 59 | ||
| 59 | /* notify_table passes value to the CPUFREQ_ADJUST callback function. */ | 60 | static LIST_HEAD(cpufreq_dev_list); |
| 60 | #define NOTIFY_INVALID NULL | ||
| 61 | static struct cpufreq_cooling_device *notify_device; | ||
| 62 | 61 | ||
| 63 | /** | 62 | /** |
| 64 | * get_idr - function to get a unique id. | 63 | * get_idr - function to get a unique id. |
| @@ -287,15 +286,12 @@ static int cpufreq_apply_cooling(struct cpufreq_cooling_device *cpufreq_device, | |||
| 287 | 286 | ||
| 288 | cpufreq_device->cpufreq_state = cooling_state; | 287 | cpufreq_device->cpufreq_state = cooling_state; |
| 289 | cpufreq_device->cpufreq_val = clip_freq; | 288 | cpufreq_device->cpufreq_val = clip_freq; |
| 290 | notify_device = cpufreq_device; | ||
| 291 | 289 | ||
| 292 | for_each_cpu(cpuid, mask) { | 290 | for_each_cpu(cpuid, mask) { |
| 293 | if (is_cpufreq_valid(cpuid)) | 291 | if (is_cpufreq_valid(cpuid)) |
| 294 | cpufreq_update_policy(cpuid); | 292 | cpufreq_update_policy(cpuid); |
| 295 | } | 293 | } |
| 296 | 294 | ||
| 297 | notify_device = NOTIFY_INVALID; | ||
| 298 | |||
| 299 | return 0; | 295 | return 0; |
| 300 | } | 296 | } |
| 301 | 297 | ||
| @@ -316,21 +312,28 @@ static int cpufreq_thermal_notifier(struct notifier_block *nb, | |||
| 316 | { | 312 | { |
| 317 | struct cpufreq_policy *policy = data; | 313 | struct cpufreq_policy *policy = data; |
| 318 | unsigned long max_freq = 0; | 314 | unsigned long max_freq = 0; |
| 315 | struct cpufreq_cooling_device *cpufreq_dev; | ||
| 319 | 316 | ||
| 320 | if (event != CPUFREQ_ADJUST || notify_device == NOTIFY_INVALID) | 317 | if (event != CPUFREQ_ADJUST) |
| 321 | return 0; | 318 | return 0; |
| 322 | 319 | ||
| 323 | if (cpumask_test_cpu(policy->cpu, ¬ify_device->allowed_cpus)) | 320 | mutex_lock(&cooling_cpufreq_lock); |
| 324 | max_freq = notify_device->cpufreq_val; | 321 | list_for_each_entry(cpufreq_dev, &cpufreq_dev_list, node) { |
| 325 | else | 322 | if (!cpumask_test_cpu(policy->cpu, |
| 326 | return 0; | 323 | &cpufreq_dev->allowed_cpus)) |
| 324 | continue; | ||
| 325 | |||
| 326 | if (!cpufreq_dev->cpufreq_val) | ||
| 327 | cpufreq_dev->cpufreq_val = get_cpu_frequency( | ||
| 328 | cpumask_any(&cpufreq_dev->allowed_cpus), | ||
| 329 | cpufreq_dev->cpufreq_state); | ||
| 327 | 330 | ||
| 328 | /* Never exceed user_policy.max */ | 331 | max_freq = cpufreq_dev->cpufreq_val; |
| 329 | if (max_freq > policy->user_policy.max) | ||
| 330 | max_freq = policy->user_policy.max; | ||
| 331 | 332 | ||
| 332 | if (policy->max != max_freq) | 333 | if (policy->max != max_freq) |
| 333 | cpufreq_verify_within_limits(policy, 0, max_freq); | 334 | cpufreq_verify_within_limits(policy, 0, max_freq); |
| 335 | } | ||
| 336 | mutex_unlock(&cooling_cpufreq_lock); | ||
| 334 | 337 | ||
| 335 | return 0; | 338 | return 0; |
| 336 | } | 339 | } |
| @@ -486,6 +489,7 @@ __cpufreq_cooling_register(struct device_node *np, | |||
| 486 | cpufreq_register_notifier(&thermal_cpufreq_notifier_block, | 489 | cpufreq_register_notifier(&thermal_cpufreq_notifier_block, |
| 487 | CPUFREQ_POLICY_NOTIFIER); | 490 | CPUFREQ_POLICY_NOTIFIER); |
| 488 | cpufreq_dev_count++; | 491 | cpufreq_dev_count++; |
| 492 | list_add(&cpufreq_dev->node, &cpufreq_dev_list); | ||
| 489 | 493 | ||
| 490 | mutex_unlock(&cooling_cpufreq_lock); | 494 | mutex_unlock(&cooling_cpufreq_lock); |
| 491 | 495 | ||
| @@ -549,6 +553,7 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev) | |||
| 549 | 553 | ||
| 550 | cpufreq_dev = cdev->devdata; | 554 | cpufreq_dev = cdev->devdata; |
| 551 | mutex_lock(&cooling_cpufreq_lock); | 555 | mutex_lock(&cooling_cpufreq_lock); |
| 556 | list_del(&cpufreq_dev->node); | ||
| 552 | cpufreq_dev_count--; | 557 | cpufreq_dev_count--; |
| 553 | 558 | ||
| 554 | /* Unregister the notifier for the last cpufreq cooling device */ | 559 | /* Unregister the notifier for the last cpufreq cooling device */ |
diff --git a/drivers/thermal/samsung/exynos_thermal_common.c b/drivers/thermal/samsung/exynos_thermal_common.c index 3f5ad25ddca8..b6be572704a4 100644 --- a/drivers/thermal/samsung/exynos_thermal_common.c +++ b/drivers/thermal/samsung/exynos_thermal_common.c | |||
| @@ -417,13 +417,10 @@ void exynos_unregister_thermal(struct thermal_sensor_conf *sensor_conf) | |||
| 417 | 417 | ||
| 418 | th_zone = sensor_conf->pzone_data; | 418 | th_zone = sensor_conf->pzone_data; |
| 419 | 419 | ||
| 420 | if (th_zone->therm_dev) | 420 | thermal_zone_device_unregister(th_zone->therm_dev); |
| 421 | thermal_zone_device_unregister(th_zone->therm_dev); | ||
| 422 | 421 | ||
| 423 | for (i = 0; i < th_zone->cool_dev_size; i++) { | 422 | for (i = 0; i < th_zone->cool_dev_size; ++i) |
| 424 | if (th_zone->cool_dev[i]) | 423 | cpufreq_cooling_unregister(th_zone->cool_dev[i]); |
| 425 | cpufreq_cooling_unregister(th_zone->cool_dev[i]); | ||
| 426 | } | ||
| 427 | 424 | ||
| 428 | dev_info(sensor_conf->dev, | 425 | dev_info(sensor_conf->dev, |
| 429 | "Exynos: Kernel Thermal management unregistered\n"); | 426 | "Exynos: Kernel Thermal management unregistered\n"); |
diff --git a/drivers/thermal/st/st_thermal.c b/drivers/thermal/st/st_thermal.c index 90163b384660..d1ec5804c0bb 100644 --- a/drivers/thermal/st/st_thermal.c +++ b/drivers/thermal/st/st_thermal.c | |||
| @@ -275,6 +275,7 @@ int st_thermal_unregister(struct platform_device *pdev) | |||
| 275 | } | 275 | } |
| 276 | EXPORT_SYMBOL_GPL(st_thermal_unregister); | 276 | EXPORT_SYMBOL_GPL(st_thermal_unregister); |
| 277 | 277 | ||
| 278 | #ifdef CONFIG_PM_SLEEP | ||
| 278 | static int st_thermal_suspend(struct device *dev) | 279 | static int st_thermal_suspend(struct device *dev) |
| 279 | { | 280 | { |
| 280 | struct platform_device *pdev = to_platform_device(dev); | 281 | struct platform_device *pdev = to_platform_device(dev); |
| @@ -305,6 +306,8 @@ static int st_thermal_resume(struct device *dev) | |||
| 305 | 306 | ||
| 306 | return 0; | 307 | return 0; |
| 307 | } | 308 | } |
| 309 | #endif | ||
| 310 | |||
| 308 | SIMPLE_DEV_PM_OPS(st_thermal_pm_ops, st_thermal_suspend, st_thermal_resume); | 311 | SIMPLE_DEV_PM_OPS(st_thermal_pm_ops, st_thermal_suspend, st_thermal_resume); |
| 309 | EXPORT_SYMBOL_GPL(st_thermal_pm_ops); | 312 | EXPORT_SYMBOL_GPL(st_thermal_pm_ops); |
| 310 | 313 | ||
