| @@ -50,15 +50,14 @@ struct cpufreq_cooling_device { · 49 unmodified lines |
| 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, · 222 unmodified lines |
| 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, · 14 unmodified lines |
| 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, · 149 unmodified lines |
| 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) · 57 unmodified lines |
| 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 */ |