aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/thermal
diff options
context:
space:
mode:
authorZhang Rui <rui.zhang@intel.com>2014-12-21 09:49:12 -0500
committerZhang Rui <rui.zhang@intel.com>2014-12-21 09:49:12 -0500
commit32c9edc4e356063e0218362d452a269cfa6798ee (patch)
tree43982a1f642c7fedef1cc5f8c247b646582cbe03 /drivers/thermal
parent59c56eb6db0c14fe569b1c9625cb850e52d29d88 (diff)
parent503ccc3fec4a56cdcfedc507cd1ea0d85e1fbfa2 (diff)
Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/evalenti/linux-soc-thermal into thermal-soc
Diffstat (limited to 'drivers/thermal')
-rw-r--r--drivers/thermal/cpu_cooling.c359
-rw-r--r--drivers/thermal/db8500_cpufreq_cooling.c20
-rw-r--r--drivers/thermal/imx_thermal.c15
-rw-r--r--drivers/thermal/samsung/Kconfig2
-rw-r--r--drivers/thermal/samsung/exynos_thermal_common.c12
-rw-r--r--drivers/thermal/samsung/exynos_tmu.c5
-rw-r--r--drivers/thermal/thermal_core.c6
-rw-r--r--drivers/thermal/ti-soc-thermal/ti-thermal-common.c17
8 files changed, 172 insertions, 264 deletions
diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c
index ad09e51ffae4..9b45f6426f44 100644
--- a/drivers/thermal/cpu_cooling.c
+++ b/drivers/thermal/cpu_cooling.c
@@ -4,6 +4,8 @@
4 * Copyright (C) 2012 Samsung Electronics Co., Ltd(http://www.samsung.com) 4 * Copyright (C) 2012 Samsung Electronics Co., Ltd(http://www.samsung.com)
5 * Copyright (C) 2012 Amit Daniel <amit.kachhap@linaro.org> 5 * Copyright (C) 2012 Amit Daniel <amit.kachhap@linaro.org>
6 * 6 *
7 * Copyright (C) 2014 Viresh Kumar <viresh.kumar@linaro.org>
8 *
7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 9 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by 11 * it under the terms of the GNU General Public License as published by
@@ -28,6 +30,20 @@
28#include <linux/cpu.h> 30#include <linux/cpu.h>
29#include <linux/cpu_cooling.h> 31#include <linux/cpu_cooling.h>
30 32
33/*
34 * Cooling state <-> CPUFreq frequency
35 *
36 * Cooling states are translated to frequencies throughout this driver and this
37 * is the relation between them.
38 *
39 * Highest cooling state corresponds to lowest possible frequency.
40 *
41 * i.e.
42 * level 0 --> 1st Max Freq
43 * level 1 --> 2nd Max Freq
44 * ...
45 */
46
31/** 47/**
32 * struct cpufreq_cooling_device - data for cooling device with cpufreq 48 * struct cpufreq_cooling_device - data for cooling device with cpufreq
33 * @id: unique integer value corresponding to each cpufreq_cooling_device 49 * @id: unique integer value corresponding to each cpufreq_cooling_device
@@ -38,25 +54,26 @@
38 * cooling devices. 54 * cooling devices.
39 * @cpufreq_val: integer value representing the absolute value of the clipped 55 * @cpufreq_val: integer value representing the absolute value of the clipped
40 * frequency. 56 * frequency.
57 * @max_level: maximum cooling level. One less than total number of valid
58 * cpufreq frequencies.
41 * @allowed_cpus: all the cpus involved for this cpufreq_cooling_device. 59 * @allowed_cpus: all the cpus involved for this cpufreq_cooling_device.
42 * 60 *
43 * This structure is required for keeping information of each 61 * This structure is required for keeping information of each registered
44 * cpufreq_cooling_device registered. In order to prevent corruption of this a 62 * cpufreq_cooling_device.
45 * mutex lock cooling_cpufreq_lock is used.
46 */ 63 */
47struct cpufreq_cooling_device { 64struct cpufreq_cooling_device {
48 int id; 65 int id;
49 struct thermal_cooling_device *cool_dev; 66 struct thermal_cooling_device *cool_dev;
50 unsigned int cpufreq_state; 67 unsigned int cpufreq_state;
51 unsigned int cpufreq_val; 68 unsigned int cpufreq_val;
69 unsigned int max_level;
70 unsigned int *freq_table; /* In descending order */
52 struct cpumask allowed_cpus; 71 struct cpumask allowed_cpus;
53 struct list_head node; 72 struct list_head node;
54}; 73};
55static DEFINE_IDR(cpufreq_idr); 74static DEFINE_IDR(cpufreq_idr);
56static DEFINE_MUTEX(cooling_cpufreq_lock); 75static DEFINE_MUTEX(cooling_cpufreq_lock);
57 76
58static unsigned int cpufreq_dev_count;
59
60static LIST_HEAD(cpufreq_dev_list); 77static LIST_HEAD(cpufreq_dev_list);
61 78
62/** 79/**
@@ -98,120 +115,30 @@ static void release_idr(struct idr *idr, int id)
98/* Below code defines functions to be used for cpufreq as cooling device */ 115/* Below code defines functions to be used for cpufreq as cooling device */
99 116
100/** 117/**
101 * is_cpufreq_valid - function to check frequency transitioning capability. 118 * get_level: Find the level for a particular frequency
102 * @cpu: cpu for which check is needed. 119 * @cpufreq_dev: cpufreq_dev for which the property is required
120 * @freq: Frequency
103 * 121 *
104 * This function will check the current state of the system if 122 * Return: level on success, THERMAL_CSTATE_INVALID on error.
105 * it is capable of changing the frequency for a given @cpu.
106 *
107 * Return: 0 if the system is not currently capable of changing
108 * the frequency of given cpu. !0 in case the frequency is changeable.
109 */ 123 */
110static int is_cpufreq_valid(int cpu) 124static unsigned long get_level(struct cpufreq_cooling_device *cpufreq_dev,
125 unsigned int freq)
111{ 126{
112 struct cpufreq_policy policy; 127 unsigned long level;
113
114 return !cpufreq_get_policy(&policy, cpu);
115}
116
117enum cpufreq_cooling_property {
118 GET_LEVEL,
119 GET_FREQ,
120 GET_MAXL,
121};
122
123/**
124 * get_property - fetch a property of interest for a give cpu.
125 * @cpu: cpu for which the property is required
126 * @input: query parameter
127 * @output: query return
128 * @property: type of query (frequency, level, max level)
129 *
130 * This is the common function to
131 * 1. get maximum cpu cooling states
132 * 2. translate frequency to cooling state
133 * 3. translate cooling state to frequency
134 * Note that the code may be not in good shape
135 * but it is written in this way in order to:
136 * a) reduce duplicate code as most of the code can be shared.
137 * b) make sure the logic is consistent when translating between
138 * cooling states and frequencies.
139 *
140 * Return: 0 on success, -EINVAL when invalid parameters are passed.
141 */
142static int get_property(unsigned int cpu, unsigned long input,
143 unsigned int *output,
144 enum cpufreq_cooling_property property)
145{
146 int i;
147 unsigned long max_level = 0, level = 0;
148 unsigned int freq = CPUFREQ_ENTRY_INVALID;
149 int descend = -1;
150 struct cpufreq_frequency_table *pos, *table =
151 cpufreq_frequency_get_table(cpu);
152
153 if (!output)
154 return -EINVAL;
155
156 if (!table)
157 return -EINVAL;
158
159 cpufreq_for_each_valid_entry(pos, table) {
160 /* ignore duplicate entry */
161 if (freq == pos->frequency)
162 continue;
163
164 /* get the frequency order */
165 if (freq != CPUFREQ_ENTRY_INVALID && descend == -1)
166 descend = freq > pos->frequency;
167
168 freq = pos->frequency;
169 max_level++;
170 }
171
172 /* No valid cpu frequency entry */
173 if (max_level == 0)
174 return -EINVAL;
175 128
176 /* max_level is an index, not a counter */ 129 for (level = 0; level <= cpufreq_dev->max_level; level++) {
177 max_level--; 130 if (freq == cpufreq_dev->freq_table[level])
131 return level;
178 132
179 /* get max level */ 133 if (freq > cpufreq_dev->freq_table[level])
180 if (property == GET_MAXL) { 134 break;
181 *output = (unsigned int)max_level;
182 return 0;
183 } 135 }
184 136
185 if (property == GET_FREQ) 137 return THERMAL_CSTATE_INVALID;
186 level = descend ? input : (max_level - input);
187
188 i = 0;
189 cpufreq_for_each_valid_entry(pos, table) {
190 /* ignore duplicate entry */
191 if (freq == pos->frequency)
192 continue;
193
194 /* now we have a valid frequency entry */
195 freq = pos->frequency;
196
197 if (property == GET_LEVEL && (unsigned int)input == freq) {
198 /* get level by frequency */
199 *output = descend ? i : (max_level - i);
200 return 0;
201 }
202 if (property == GET_FREQ && level == i) {
203 /* get frequency by level */
204 *output = freq;
205 return 0;
206 }
207 i++;
208 }
209
210 return -EINVAL;
211} 138}
212 139
213/** 140/**
214 * cpufreq_cooling_get_level - for a give cpu, return the cooling level. 141 * cpufreq_cooling_get_level - for a given cpu, return the cooling level.
215 * @cpu: cpu for which the level is required 142 * @cpu: cpu for which the level is required
216 * @freq: the frequency of interest 143 * @freq: the frequency of interest
217 * 144 *
@@ -223,77 +150,21 @@ static int get_property(unsigned int cpu, unsigned long input,
223 */ 150 */
224unsigned long cpufreq_cooling_get_level(unsigned int cpu, unsigned int freq) 151unsigned long cpufreq_cooling_get_level(unsigned int cpu, unsigned int freq)
225{ 152{
226 unsigned int val; 153 struct cpufreq_cooling_device *cpufreq_dev;
227
228 if (get_property(cpu, (unsigned long)freq, &val, GET_LEVEL))
229 return THERMAL_CSTATE_INVALID;
230
231 return (unsigned long)val;
232}
233EXPORT_SYMBOL_GPL(cpufreq_cooling_get_level);
234
235/**
236 * get_cpu_frequency - get the absolute value of frequency from level.
237 * @cpu: cpu for which frequency is fetched.
238 * @level: cooling level
239 *
240 * This function matches cooling level with frequency. Based on a cooling level
241 * of frequency, equals cooling state of cpu cooling device, it will return
242 * the corresponding frequency.
243 * e.g level=0 --> 1st MAX FREQ, level=1 ---> 2nd MAX FREQ, .... etc
244 *
245 * Return: 0 on error, the corresponding frequency otherwise.
246 */
247static unsigned int get_cpu_frequency(unsigned int cpu, unsigned long level)
248{
249 int ret = 0;
250 unsigned int freq;
251
252 ret = get_property(cpu, level, &freq, GET_FREQ);
253 if (ret)
254 return 0;
255
256 return freq;
257}
258
259/**
260 * cpufreq_apply_cooling - function to apply frequency clipping.
261 * @cpufreq_device: cpufreq_cooling_device pointer containing frequency
262 * clipping data.
263 * @cooling_state: value of the cooling state.
264 *
265 * Function used to make sure the cpufreq layer is aware of current thermal
266 * limits. The limits are applied by updating the cpufreq policy.
267 *
268 * Return: 0 on success, an error code otherwise (-EINVAL in case wrong
269 * cooling state).
270 */
271static int cpufreq_apply_cooling(struct cpufreq_cooling_device *cpufreq_device,
272 unsigned long cooling_state)
273{
274 unsigned int cpuid, clip_freq;
275 struct cpumask *mask = &cpufreq_device->allowed_cpus;
276 unsigned int cpu = cpumask_any(mask);
277
278
279 /* Check if the old cooling action is same as new cooling action */
280 if (cpufreq_device->cpufreq_state == cooling_state)
281 return 0;
282
283 clip_freq = get_cpu_frequency(cpu, cooling_state);
284 if (!clip_freq)
285 return -EINVAL;
286
287 cpufreq_device->cpufreq_state = cooling_state;
288 cpufreq_device->cpufreq_val = clip_freq;
289 154
290 for_each_cpu(cpuid, mask) { 155 mutex_lock(&cooling_cpufreq_lock);
291 if (is_cpufreq_valid(cpuid)) 156 list_for_each_entry(cpufreq_dev, &cpufreq_dev_list, node) {
292 cpufreq_update_policy(cpuid); 157 if (cpumask_test_cpu(cpu, &cpufreq_dev->allowed_cpus)) {
158 mutex_unlock(&cooling_cpufreq_lock);
159 return get_level(cpufreq_dev, freq);
160 }
293 } 161 }
162 mutex_unlock(&cooling_cpufreq_lock);
294 163
295 return 0; 164 pr_err("%s: cpu:%d not part of any cooling device\n", __func__, cpu);
165 return THERMAL_CSTATE_INVALID;
296} 166}
167EXPORT_SYMBOL_GPL(cpufreq_cooling_get_level);
297 168
298/** 169/**
299 * cpufreq_thermal_notifier - notifier callback for cpufreq policy change. 170 * cpufreq_thermal_notifier - notifier callback for cpufreq policy change.
@@ -323,11 +194,6 @@ static int cpufreq_thermal_notifier(struct notifier_block *nb,
323 &cpufreq_dev->allowed_cpus)) 194 &cpufreq_dev->allowed_cpus))
324 continue; 195 continue;
325 196
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);
330
331 max_freq = cpufreq_dev->cpufreq_val; 197 max_freq = cpufreq_dev->cpufreq_val;
332 198
333 if (policy->max != max_freq) 199 if (policy->max != max_freq)
@@ -354,19 +220,9 @@ static int cpufreq_get_max_state(struct thermal_cooling_device *cdev,
354 unsigned long *state) 220 unsigned long *state)
355{ 221{
356 struct cpufreq_cooling_device *cpufreq_device = cdev->devdata; 222 struct cpufreq_cooling_device *cpufreq_device = cdev->devdata;
357 struct cpumask *mask = &cpufreq_device->allowed_cpus;
358 unsigned int cpu;
359 unsigned int count = 0;
360 int ret;
361
362 cpu = cpumask_any(mask);
363
364 ret = get_property(cpu, 0, &count, GET_MAXL);
365 223
366 if (count > 0) 224 *state = cpufreq_device->max_level;
367 *state = count; 225 return 0;
368
369 return ret;
370} 226}
371 227
372/** 228/**
@@ -403,8 +259,24 @@ static int cpufreq_set_cur_state(struct thermal_cooling_device *cdev,
403 unsigned long state) 259 unsigned long state)
404{ 260{
405 struct cpufreq_cooling_device *cpufreq_device = cdev->devdata; 261 struct cpufreq_cooling_device *cpufreq_device = cdev->devdata;
262 unsigned int cpu = cpumask_any(&cpufreq_device->allowed_cpus);
263 unsigned int clip_freq;
264
265 /* Request state should be less than max_level */
266 if (WARN_ON(state > cpufreq_device->max_level))
267 return -EINVAL;
268
269 /* Check if the old cooling action is same as new cooling action */
270 if (cpufreq_device->cpufreq_state == state)
271 return 0;
406 272
407 return cpufreq_apply_cooling(cpufreq_device, state); 273 clip_freq = cpufreq_device->freq_table[state];
274 cpufreq_device->cpufreq_state = state;
275 cpufreq_device->cpufreq_val = clip_freq;
276
277 cpufreq_update_policy(cpu);
278
279 return 0;
408} 280}
409 281
410/* Bind cpufreq callbacks to thermal cooling device ops */ 282/* Bind cpufreq callbacks to thermal cooling device ops */
@@ -419,10 +291,25 @@ static struct notifier_block thermal_cpufreq_notifier_block = {
419 .notifier_call = cpufreq_thermal_notifier, 291 .notifier_call = cpufreq_thermal_notifier,
420}; 292};
421 293
294static unsigned int find_next_max(struct cpufreq_frequency_table *table,
295 unsigned int prev_max)
296{
297 struct cpufreq_frequency_table *pos;
298 unsigned int max = 0;
299
300 cpufreq_for_each_valid_entry(pos, table) {
301 if (pos->frequency > max && pos->frequency < prev_max)
302 max = pos->frequency;
303 }
304
305 return max;
306}
307
422/** 308/**
423 * __cpufreq_cooling_register - helper function to create cpufreq cooling device 309 * __cpufreq_cooling_register - helper function to create cpufreq cooling device
424 * @np: a valid struct device_node to the cooling device device tree node 310 * @np: a valid struct device_node to the cooling device device tree node
425 * @clip_cpus: cpumask of cpus where the frequency constraints will happen. 311 * @clip_cpus: cpumask of cpus where the frequency constraints will happen.
312 * Normally this should be same as cpufreq policy->related_cpus.
426 * 313 *
427 * This interface function registers the cpufreq cooling device with the name 314 * This interface function registers the cpufreq cooling device with the name
428 * "thermal-cpufreq-%x". This api can support multiple instances of cpufreq 315 * "thermal-cpufreq-%x". This api can support multiple instances of cpufreq
@@ -437,37 +324,42 @@ __cpufreq_cooling_register(struct device_node *np,
437 const struct cpumask *clip_cpus) 324 const struct cpumask *clip_cpus)
438{ 325{
439 struct thermal_cooling_device *cool_dev; 326 struct thermal_cooling_device *cool_dev;
440 struct cpufreq_cooling_device *cpufreq_dev = NULL; 327 struct cpufreq_cooling_device *cpufreq_dev;
441 unsigned int min = 0, max = 0;
442 char dev_name[THERMAL_NAME_LENGTH]; 328 char dev_name[THERMAL_NAME_LENGTH];
443 int ret = 0, i; 329 struct cpufreq_frequency_table *pos, *table;
444 struct cpufreq_policy policy; 330 unsigned int freq, i;
331 int ret;
445 332
446 /* Verify that all the clip cpus have same freq_min, freq_max limit */ 333 table = cpufreq_frequency_get_table(cpumask_first(clip_cpus));
447 for_each_cpu(i, clip_cpus) { 334 if (!table) {
448 /* continue if cpufreq policy not found and not return error */ 335 pr_debug("%s: CPUFreq table not found\n", __func__);
449 if (!cpufreq_get_policy(&policy, i)) 336 return ERR_PTR(-EPROBE_DEFER);
450 continue;
451 if (min == 0 && max == 0) {
452 min = policy.cpuinfo.min_freq;
453 max = policy.cpuinfo.max_freq;
454 } else {
455 if (min != policy.cpuinfo.min_freq ||
456 max != policy.cpuinfo.max_freq)
457 return ERR_PTR(-EINVAL);
458 }
459 } 337 }
460 cpufreq_dev = kzalloc(sizeof(struct cpufreq_cooling_device), 338
461 GFP_KERNEL); 339 cpufreq_dev = kzalloc(sizeof(*cpufreq_dev), GFP_KERNEL);
462 if (!cpufreq_dev) 340 if (!cpufreq_dev)
463 return ERR_PTR(-ENOMEM); 341 return ERR_PTR(-ENOMEM);
464 342
343 /* Find max levels */
344 cpufreq_for_each_valid_entry(pos, table)
345 cpufreq_dev->max_level++;
346
347 cpufreq_dev->freq_table = kmalloc(sizeof(*cpufreq_dev->freq_table) *
348 cpufreq_dev->max_level, GFP_KERNEL);
349 if (!cpufreq_dev->freq_table) {
350 cool_dev = ERR_PTR(-ENOMEM);
351 goto free_cdev;
352 }
353
354 /* max_level is an index, not a counter */
355 cpufreq_dev->max_level--;
356
465 cpumask_copy(&cpufreq_dev->allowed_cpus, clip_cpus); 357 cpumask_copy(&cpufreq_dev->allowed_cpus, clip_cpus);
466 358
467 ret = get_idr(&cpufreq_idr, &cpufreq_dev->id); 359 ret = get_idr(&cpufreq_idr, &cpufreq_dev->id);
468 if (ret) { 360 if (ret) {
469 kfree(cpufreq_dev); 361 cool_dev = ERR_PTR(ret);
470 return ERR_PTR(-EINVAL); 362 goto free_table;
471 } 363 }
472 364
473 snprintf(dev_name, sizeof(dev_name), "thermal-cpufreq-%d", 365 snprintf(dev_name, sizeof(dev_name), "thermal-cpufreq-%d",
@@ -475,25 +367,44 @@ __cpufreq_cooling_register(struct device_node *np,
475 367
476 cool_dev = thermal_of_cooling_device_register(np, dev_name, cpufreq_dev, 368 cool_dev = thermal_of_cooling_device_register(np, dev_name, cpufreq_dev,
477 &cpufreq_cooling_ops); 369 &cpufreq_cooling_ops);
478 if (IS_ERR(cool_dev)) { 370 if (IS_ERR(cool_dev))
479 release_idr(&cpufreq_idr, cpufreq_dev->id); 371 goto remove_idr;
480 kfree(cpufreq_dev); 372
481 return cool_dev; 373 /* Fill freq-table in descending order of frequencies */
374 for (i = 0, freq = -1; i <= cpufreq_dev->max_level; i++) {
375 freq = find_next_max(table, freq);
376 cpufreq_dev->freq_table[i] = freq;
377
378 /* Warn for duplicate entries */
379 if (!freq)
380 pr_warn("%s: table has duplicate entries\n", __func__);
381 else
382 pr_debug("%s: freq:%u KHz\n", __func__, freq);
482 } 383 }
384
385 cpufreq_dev->cpufreq_val = cpufreq_dev->freq_table[0];
483 cpufreq_dev->cool_dev = cool_dev; 386 cpufreq_dev->cool_dev = cool_dev;
484 cpufreq_dev->cpufreq_state = 0; 387
485 mutex_lock(&cooling_cpufreq_lock); 388 mutex_lock(&cooling_cpufreq_lock);
486 389
487 /* Register the notifier for first cpufreq cooling device */ 390 /* Register the notifier for first cpufreq cooling device */
488 if (cpufreq_dev_count == 0) 391 if (list_empty(&cpufreq_dev_list))
489 cpufreq_register_notifier(&thermal_cpufreq_notifier_block, 392 cpufreq_register_notifier(&thermal_cpufreq_notifier_block,
490 CPUFREQ_POLICY_NOTIFIER); 393 CPUFREQ_POLICY_NOTIFIER);
491 cpufreq_dev_count++;
492 list_add(&cpufreq_dev->node, &cpufreq_dev_list); 394 list_add(&cpufreq_dev->node, &cpufreq_dev_list);
493 395
494 mutex_unlock(&cooling_cpufreq_lock); 396 mutex_unlock(&cooling_cpufreq_lock);
495 397
496 return cool_dev; 398 return cool_dev;
399
400remove_idr:
401 release_idr(&cpufreq_idr, cpufreq_dev->id);
402free_table:
403 kfree(cpufreq_dev->freq_table);
404free_cdev:
405 kfree(cpufreq_dev);
406
407 return cool_dev;
497} 408}
498 409
499/** 410/**
@@ -554,16 +465,16 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev)
554 cpufreq_dev = cdev->devdata; 465 cpufreq_dev = cdev->devdata;
555 mutex_lock(&cooling_cpufreq_lock); 466 mutex_lock(&cooling_cpufreq_lock);
556 list_del(&cpufreq_dev->node); 467 list_del(&cpufreq_dev->node);
557 cpufreq_dev_count--;
558 468
559 /* Unregister the notifier for the last cpufreq cooling device */ 469 /* Unregister the notifier for the last cpufreq cooling device */
560 if (cpufreq_dev_count == 0) 470 if (list_empty(&cpufreq_dev_list))
561 cpufreq_unregister_notifier(&thermal_cpufreq_notifier_block, 471 cpufreq_unregister_notifier(&thermal_cpufreq_notifier_block,
562 CPUFREQ_POLICY_NOTIFIER); 472 CPUFREQ_POLICY_NOTIFIER);
563 mutex_unlock(&cooling_cpufreq_lock); 473 mutex_unlock(&cooling_cpufreq_lock);
564 474
565 thermal_cooling_device_unregister(cpufreq_dev->cool_dev); 475 thermal_cooling_device_unregister(cpufreq_dev->cool_dev);
566 release_idr(&cpufreq_idr, cpufreq_dev->id); 476 release_idr(&cpufreq_idr, cpufreq_dev->id);
477 kfree(cpufreq_dev->freq_table);
567 kfree(cpufreq_dev); 478 kfree(cpufreq_dev);
568} 479}
569EXPORT_SYMBOL_GPL(cpufreq_cooling_unregister); 480EXPORT_SYMBOL_GPL(cpufreq_cooling_unregister);
diff --git a/drivers/thermal/db8500_cpufreq_cooling.c b/drivers/thermal/db8500_cpufreq_cooling.c
index 000d53e934a0..607b62c7e611 100644
--- a/drivers/thermal/db8500_cpufreq_cooling.c
+++ b/drivers/thermal/db8500_cpufreq_cooling.c
@@ -18,7 +18,6 @@
18 */ 18 */
19 19
20#include <linux/cpu_cooling.h> 20#include <linux/cpu_cooling.h>
21#include <linux/cpufreq.h>
22#include <linux/err.h> 21#include <linux/err.h>
23#include <linux/module.h> 22#include <linux/module.h>
24#include <linux/of.h> 23#include <linux/of.h>
@@ -28,18 +27,17 @@
28static int db8500_cpufreq_cooling_probe(struct platform_device *pdev) 27static int db8500_cpufreq_cooling_probe(struct platform_device *pdev)
29{ 28{
30 struct thermal_cooling_device *cdev; 29 struct thermal_cooling_device *cdev;
31 struct cpumask mask_val;
32
33 /* make sure cpufreq driver has been initialized */
34 if (!cpufreq_frequency_get_table(0))
35 return -EPROBE_DEFER;
36
37 cpumask_set_cpu(0, &mask_val);
38 cdev = cpufreq_cooling_register(&mask_val);
39 30
31 cdev = cpufreq_cooling_register(cpu_present_mask);
40 if (IS_ERR(cdev)) { 32 if (IS_ERR(cdev)) {
41 dev_err(&pdev->dev, "Failed to register cooling device\n"); 33 int ret = PTR_ERR(cdev);
42 return PTR_ERR(cdev); 34
35 if (ret != -EPROBE_DEFER)
36 dev_err(&pdev->dev,
37 "Failed to register cooling device %d\n",
38 ret);
39
40 return ret;
43 } 41 }
44 42
45 platform_set_drvdata(pdev, cdev); 43 platform_set_drvdata(pdev, cdev);
diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c
index 88b32f942dcf..c1188ac053c9 100644
--- a/drivers/thermal/imx_thermal.c
+++ b/drivers/thermal/imx_thermal.c
@@ -9,7 +9,6 @@
9 9
10#include <linux/clk.h> 10#include <linux/clk.h>
11#include <linux/cpu_cooling.h> 11#include <linux/cpu_cooling.h>
12#include <linux/cpufreq.h>
13#include <linux/delay.h> 12#include <linux/delay.h>
14#include <linux/device.h> 13#include <linux/device.h>
15#include <linux/init.h> 14#include <linux/init.h>
@@ -454,15 +453,10 @@ static int imx_thermal_probe(struct platform_device *pdev)
454 const struct of_device_id *of_id = 453 const struct of_device_id *of_id =
455 of_match_device(of_imx_thermal_match, &pdev->dev); 454 of_match_device(of_imx_thermal_match, &pdev->dev);
456 struct imx_thermal_data *data; 455 struct imx_thermal_data *data;
457 struct cpumask clip_cpus;
458 struct regmap *map; 456 struct regmap *map;
459 int measure_freq; 457 int measure_freq;
460 int ret; 458 int ret;
461 459
462 if (!cpufreq_get_current_driver()) {
463 dev_dbg(&pdev->dev, "no cpufreq driver!");
464 return -EPROBE_DEFER;
465 }
466 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); 460 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
467 if (!data) 461 if (!data)
468 return -ENOMEM; 462 return -ENOMEM;
@@ -516,12 +510,13 @@ static int imx_thermal_probe(struct platform_device *pdev)
516 regmap_write(map, MISC0 + REG_SET, MISC0_REFTOP_SELBIASOFF); 510 regmap_write(map, MISC0 + REG_SET, MISC0_REFTOP_SELBIASOFF);
517 regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_POWER_DOWN); 511 regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_POWER_DOWN);
518 512
519 cpumask_set_cpu(0, &clip_cpus); 513 data->cdev = cpufreq_cooling_register(cpu_present_mask);
520 data->cdev = cpufreq_cooling_register(&clip_cpus);
521 if (IS_ERR(data->cdev)) { 514 if (IS_ERR(data->cdev)) {
522 ret = PTR_ERR(data->cdev); 515 ret = PTR_ERR(data->cdev);
523 dev_err(&pdev->dev, 516 if (ret != -EPROBE_DEFER)
524 "failed to register cpufreq cooling device: %d\n", ret); 517 dev_err(&pdev->dev,
518 "failed to register cpufreq cooling device: %d\n",
519 ret);
525 return ret; 520 return ret;
526 } 521 }
527 522
diff --git a/drivers/thermal/samsung/Kconfig b/drivers/thermal/samsung/Kconfig
index f760389a204c..c43306ecc0ab 100644
--- a/drivers/thermal/samsung/Kconfig
+++ b/drivers/thermal/samsung/Kconfig
@@ -1,6 +1,6 @@
1config EXYNOS_THERMAL 1config EXYNOS_THERMAL
2 tristate "Exynos thermal management unit driver" 2 tristate "Exynos thermal management unit driver"
3 depends on ARCH_HAS_BANDGAP && OF 3 depends on OF
4 help 4 help
5 If you say yes here you get support for the TMU (Thermal Management 5 If you say yes here you get support for the TMU (Thermal Management
6 Unit) driver for SAMSUNG EXYNOS series of SoCs. This driver initialises 6 Unit) driver for SAMSUNG EXYNOS series of SoCs. This driver initialises
diff --git a/drivers/thermal/samsung/exynos_thermal_common.c b/drivers/thermal/samsung/exynos_thermal_common.c
index b6be572704a4..6dc3815cc73f 100644
--- a/drivers/thermal/samsung/exynos_thermal_common.c
+++ b/drivers/thermal/samsung/exynos_thermal_common.c
@@ -347,7 +347,6 @@ void exynos_report_trigger(struct thermal_sensor_conf *conf)
347int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf) 347int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf)
348{ 348{
349 int ret; 349 int ret;
350 struct cpumask mask_val;
351 struct exynos_thermal_zone *th_zone; 350 struct exynos_thermal_zone *th_zone;
352 351
353 if (!sensor_conf || !sensor_conf->read_temperature) { 352 if (!sensor_conf || !sensor_conf->read_temperature) {
@@ -367,13 +366,14 @@ int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf)
367 * sensor 366 * sensor
368 */ 367 */
369 if (sensor_conf->cooling_data.freq_clip_count > 0) { 368 if (sensor_conf->cooling_data.freq_clip_count > 0) {
370 cpumask_set_cpu(0, &mask_val);
371 th_zone->cool_dev[th_zone->cool_dev_size] = 369 th_zone->cool_dev[th_zone->cool_dev_size] =
372 cpufreq_cooling_register(&mask_val); 370 cpufreq_cooling_register(cpu_present_mask);
373 if (IS_ERR(th_zone->cool_dev[th_zone->cool_dev_size])) { 371 if (IS_ERR(th_zone->cool_dev[th_zone->cool_dev_size])) {
374 dev_err(sensor_conf->dev, 372 ret = PTR_ERR(th_zone->cool_dev[th_zone->cool_dev_size]);
375 "Failed to register cpufreq cooling device\n"); 373 if (ret != -EPROBE_DEFER)
376 ret = -EINVAL; 374 dev_err(sensor_conf->dev,
375 "Failed to register cpufreq cooling device: %d\n",
376 ret);
377 goto err_unregister; 377 goto err_unregister;
378 } 378 }
379 th_zone->cool_dev_size++; 379 th_zone->cool_dev_size++;
diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
index d44d91d681d4..d2f1e62a4232 100644
--- a/drivers/thermal/samsung/exynos_tmu.c
+++ b/drivers/thermal/samsung/exynos_tmu.c
@@ -927,7 +927,10 @@ static int exynos_tmu_probe(struct platform_device *pdev)
927 /* Register the sensor with thermal management interface */ 927 /* Register the sensor with thermal management interface */
928 ret = exynos_register_thermal(sensor_conf); 928 ret = exynos_register_thermal(sensor_conf);
929 if (ret) { 929 if (ret) {
930 dev_err(&pdev->dev, "Failed to register thermal interface\n"); 930 if (ret != -EPROBE_DEFER)
931 dev_err(&pdev->dev,
932 "Failed to register thermal interface: %d\n",
933 ret);
931 goto err_clk; 934 goto err_clk;
932 } 935 }
933 data->reg_conf = sensor_conf; 936 data->reg_conf = sensor_conf;
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
index 84fdf0792e27..87e0b0782023 100644
--- a/drivers/thermal/thermal_core.c
+++ b/drivers/thermal/thermal_core.c
@@ -930,7 +930,7 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
930 struct thermal_zone_device *pos1; 930 struct thermal_zone_device *pos1;
931 struct thermal_cooling_device *pos2; 931 struct thermal_cooling_device *pos2;
932 unsigned long max_state; 932 unsigned long max_state;
933 int result; 933 int result, ret;
934 934
935 if (trip >= tz->trips || (trip < 0 && trip != THERMAL_TRIPS_NONE)) 935 if (trip >= tz->trips || (trip < 0 && trip != THERMAL_TRIPS_NONE))
936 return -EINVAL; 936 return -EINVAL;
@@ -947,7 +947,9 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
947 if (tz != pos1 || cdev != pos2) 947 if (tz != pos1 || cdev != pos2)
948 return -EINVAL; 948 return -EINVAL;
949 949
950 cdev->ops->get_max_state(cdev, &max_state); 950 ret = cdev->ops->get_max_state(cdev, &max_state);
951 if (ret)
952 return ret;
951 953
952 /* lower default 0, upper default max_state */ 954 /* lower default 0, upper default max_state */
953 lower = lower == THERMAL_NO_LIMIT ? 0 : lower; 955 lower = lower == THERMAL_NO_LIMIT ? 0 : lower;
diff --git a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
index 5fd03865e396..3fb054a10f6a 100644
--- a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
+++ b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
@@ -28,7 +28,6 @@
28#include <linux/kernel.h> 28#include <linux/kernel.h>
29#include <linux/workqueue.h> 29#include <linux/workqueue.h>
30#include <linux/thermal.h> 30#include <linux/thermal.h>
31#include <linux/cpufreq.h>
32#include <linux/cpumask.h> 31#include <linux/cpumask.h>
33#include <linux/cpu_cooling.h> 32#include <linux/cpu_cooling.h>
34#include <linux/of.h> 33#include <linux/of.h>
@@ -407,17 +406,17 @@ int ti_thermal_register_cpu_cooling(struct ti_bandgap *bgp, int id)
407 if (!data) 406 if (!data)
408 return -EINVAL; 407 return -EINVAL;
409 408
410 if (!cpufreq_get_current_driver()) {
411 dev_dbg(bgp->dev, "no cpufreq driver yet\n");
412 return -EPROBE_DEFER;
413 }
414
415 /* Register cooling device */ 409 /* Register cooling device */
416 data->cool_dev = cpufreq_cooling_register(cpu_present_mask); 410 data->cool_dev = cpufreq_cooling_register(cpu_present_mask);
417 if (IS_ERR(data->cool_dev)) { 411 if (IS_ERR(data->cool_dev)) {
418 dev_err(bgp->dev, 412 int ret = PTR_ERR(data->cool_dev);
419 "Failed to register cpufreq cooling device\n"); 413
420 return PTR_ERR(data->cool_dev); 414 if (ret != -EPROBE_DEFER)
415 dev_err(bgp->dev,
416 "Failed to register cpu cooling device %d\n",
417 ret);
418
419 return ret;
421 } 420 }
422 ti_bandgap_set_sensor_data(bgp, id, data); 421 ti_bandgap_set_sensor_data(bgp, id, data);
423 422