| @@ -50,15 +50,14 @@ struct cpufreq_cooling_device { · 49 unmodified lines |
| 50 | 50 | unsigned int cpufreq_state; |
| 51 | 51 | unsigned int cpufreq_val; |
| 52 | 52 | struct cpumask allowed_cpus; |
| 53 | + struct list_head node; |
| 53 | 54 | }; |
| 54 | 55 | static DEFINE_IDR(cpufreq_idr); |
| 55 | 56 | static DEFINE_MUTEX(cooling_cpufreq_lock); |
| 56 | 57 | |
| 57 | 58 | static unsigned int cpufreq_dev_count; |
| 58 | 59 | |
| 59 | | −/* notify_table passes value to the CPUFREQ_ADJUST callback function. */ |
| 60 | | −#define NOTIFY_INVALID NULL |
| 61 | | −static struct cpufreq_cooling_device *notify_device; |
| 60 | +static LIST_HEAD(cpufreq_dev_list); |
| 62 | 61 | |
| 63 | 62 | /** |
| 64 | 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 | 287 | cpufreq_device->cpufreq_state = cooling_state; |
| 289 | 288 | cpufreq_device->cpufreq_val = clip_freq; |
| 290 | | − notify_device = cpufreq_device; |
| 291 | 289 | |
| 292 | 290 | for_each_cpu(cpuid, mask) { |
| 293 | 291 | if (is_cpufreq_valid(cpuid)) |
| 294 | 292 | cpufreq_update_policy(cpuid); |
| 295 | 293 | } |
| 296 | 294 | |
| 297 | | − notify_device = NOTIFY_INVALID; |
| 298 | | − |
| 299 | 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 | 313 | struct cpufreq_policy *policy = data; |
| 318 | 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 | 318 | return 0; |
| 322 | 319 | |
| 323 | | − if (cpumask_test_cpu(policy->cpu, ¬ify_device->allowed_cpus)) |
| 324 | | − max_freq = notify_device->cpufreq_val; |
| 325 | | − else |
| 326 | | − return 0; |
| 320 | + mutex_lock(&cooling_cpufreq_lock); |
| 321 | + list_for_each_entry(cpufreq_dev, &cpufreq_dev_list, node) { |
| 322 | + if (!cpumask_test_cpu(policy->cpu, |
| 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 */ |
| 329 | | − if (max_freq > policy->user_policy.max) |
| 330 | | − max_freq = policy->user_policy.max; |
| 331 | + max_freq = cpufreq_dev->cpufreq_val; |
| 331 | 332 | |
| 332 | | − if (policy->max != max_freq) |
| 333 | | − cpufreq_verify_within_limits(policy, 0, max_freq); |
| 333 | + if (policy->max != max_freq) |
| 334 | + cpufreq_verify_within_limits(policy, 0, max_freq); |
| 335 | + } |
| 336 | + mutex_unlock(&cooling_cpufreq_lock); |
| 334 | 337 | |
| 335 | 338 | return 0; |
| 336 | 339 | } |
| @@ -486,6 +489,7 @@ __cpufreq_cooling_register(struct device_node *np, · 149 unmodified lines |
| 486 | 489 | cpufreq_register_notifier(&thermal_cpufreq_notifier_block, |
| 487 | 490 | CPUFREQ_POLICY_NOTIFIER); |
| 488 | 491 | cpufreq_dev_count++; |
| 492 | + list_add(&cpufreq_dev->node, &cpufreq_dev_list); |
| 489 | 493 | |
| 490 | 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 | 554 | cpufreq_dev = cdev->devdata; |
| 551 | 555 | mutex_lock(&cooling_cpufreq_lock); |
| 556 | + list_del(&cpufreq_dev->node); |
| 552 | 557 | cpufreq_dev_count--; |
| 553 | 558 | |
| 554 | 559 | /* Unregister the notifier for the last cpufreq cooling device */ |