aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/thermal/cpu_cooling.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/thermal/cpu_cooling.c')
-rw-r--r--drivers/thermal/cpu_cooling.c37
1 files changed, 21 insertions, 16 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};
54static DEFINE_IDR(cpufreq_idr); 55static DEFINE_IDR(cpufreq_idr);
55static DEFINE_MUTEX(cooling_cpufreq_lock); 56static DEFINE_MUTEX(cooling_cpufreq_lock);
56 57
57static unsigned int cpufreq_dev_count; 58static unsigned int cpufreq_dev_count;
58 59
59/* notify_table passes value to the CPUFREQ_ADJUST callback function. */ 60static LIST_HEAD(cpufreq_dev_list);
60#define NOTIFY_INVALID NULL
61static 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, &notify_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 */