aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/thermal
diff options
context:
space:
mode:
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/int340x_thermal/Makefile1
-rw-r--r--drivers/thermal/int340x_thermal/acpi_thermal_rel.c8
-rw-r--r--drivers/thermal/int340x_thermal/int3400_thermal.c1
-rw-r--r--drivers/thermal/int340x_thermal/int3402_thermal.c1
-rw-r--r--drivers/thermal/int340x_thermal/int3403_thermal.c4
-rw-r--r--drivers/thermal/int340x_thermal/processor_thermal_device.c309
-rw-r--r--drivers/thermal/intel_powerclamp.c1
-rw-r--r--drivers/thermal/rockchip_thermal.c1
-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
16 files changed, 491 insertions, 271 deletions
diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c
index 588185abeab0..f65f0d109fc8 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,26 +54,27 @@
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 * @node: list_head to link all cpufreq_cooling_device together. 60 * @node: list_head to link all cpufreq_cooling_device together.
43 * 61 *
44 * This structure is required for keeping information of each 62 * This structure is required for keeping information of each registered
45 * cpufreq_cooling_device registered. In order to prevent corruption of this a 63 * cpufreq_cooling_device.
46 * mutex lock cooling_cpufreq_lock is used.
47 */ 64 */
48struct cpufreq_cooling_device { 65struct cpufreq_cooling_device {
49 int id; 66 int id;
50 struct thermal_cooling_device *cool_dev; 67 struct thermal_cooling_device *cool_dev;
51 unsigned int cpufreq_state; 68 unsigned int cpufreq_state;
52 unsigned int cpufreq_val; 69 unsigned int cpufreq_val;
70 unsigned int max_level;
71 unsigned int *freq_table; /* In descending order */
53 struct cpumask allowed_cpus; 72 struct cpumask allowed_cpus;
54 struct list_head node; 73 struct list_head node;
55}; 74};
56static DEFINE_IDR(cpufreq_idr); 75static DEFINE_IDR(cpufreq_idr);
57static DEFINE_MUTEX(cooling_cpufreq_lock); 76static DEFINE_MUTEX(cooling_cpufreq_lock);
58 77
59static unsigned int cpufreq_dev_count;
60
61static LIST_HEAD(cpufreq_dev_list); 78static LIST_HEAD(cpufreq_dev_list);
62 79
63/** 80/**
@@ -99,120 +116,30 @@ static void release_idr(struct idr *idr, int id)
99/* Below code defines functions to be used for cpufreq as cooling device */ 116/* Below code defines functions to be used for cpufreq as cooling device */
100 117
101/** 118/**
102 * is_cpufreq_valid - function to check frequency transitioning capability. 119 * get_level: Find the level for a particular frequency
103 * @cpu: cpu for which check is needed. 120 * @cpufreq_dev: cpufreq_dev for which the property is required
121 * @freq: Frequency
104 * 122 *
105 * This function will check the current state of the system if 123 * Return: level on success, THERMAL_CSTATE_INVALID on error.
106 * it is capable of changing the frequency for a given @cpu.
107 *
108 * Return: 0 if the system is not currently capable of changing
109 * the frequency of given cpu. !0 in case the frequency is changeable.
110 */ 124 */
111static int is_cpufreq_valid(int cpu) 125static unsigned long get_level(struct cpufreq_cooling_device *cpufreq_dev,
126 unsigned int freq)
112{ 127{
113 struct cpufreq_policy policy; 128 unsigned long level;
114
115 return !cpufreq_get_policy(&policy, cpu);
116}
117
118enum cpufreq_cooling_property {
119 GET_LEVEL,
120 GET_FREQ,
121 GET_MAXL,
122};
123
124/**
125 * get_property - fetch a property of interest for a give cpu.
126 * @cpu: cpu for which the property is required
127 * @input: query parameter
128 * @output: query return
129 * @property: type of query (frequency, level, max level)
130 *
131 * This is the common function to
132 * 1. get maximum cpu cooling states
133 * 2. translate frequency to cooling state
134 * 3. translate cooling state to frequency
135 * Note that the code may be not in good shape
136 * but it is written in this way in order to:
137 * a) reduce duplicate code as most of the code can be shared.
138 * b) make sure the logic is consistent when translating between
139 * cooling states and frequencies.
140 *
141 * Return: 0 on success, -EINVAL when invalid parameters are passed.
142 */
143static int get_property(unsigned int cpu, unsigned long input,
144 unsigned int *output,
145 enum cpufreq_cooling_property property)
146{
147 int i;
148 unsigned long max_level = 0, level = 0;
149 unsigned int freq = CPUFREQ_ENTRY_INVALID;
150 int descend = -1;
151 struct cpufreq_frequency_table *pos, *table =
152 cpufreq_frequency_get_table(cpu);
153
154 if (!output)
155 return -EINVAL;
156
157 if (!table)
158 return -EINVAL;
159
160 cpufreq_for_each_valid_entry(pos, table) {
161 /* ignore duplicate entry */
162 if (freq == pos->frequency)
163 continue;
164
165 /* get the frequency order */
166 if (freq != CPUFREQ_ENTRY_INVALID && descend == -1)
167 descend = freq > pos->frequency;
168
169 freq = pos->frequency;
170 max_level++;
171 }
172
173 /* No valid cpu frequency entry */
174 if (max_level == 0)
175 return -EINVAL;
176 129
177 /* max_level is an index, not a counter */ 130 for (level = 0; level <= cpufreq_dev->max_level; level++) {
178 max_level--; 131 if (freq == cpufreq_dev->freq_table[level])
132 return level;
179 133
180 /* get max level */ 134 if (freq > cpufreq_dev->freq_table[level])
181 if (property == GET_MAXL) { 135 break;
182 *output = (unsigned int)max_level;
183 return 0;
184 } 136 }
185 137
186 if (property == GET_FREQ) 138 return THERMAL_CSTATE_INVALID;
187 level = descend ? input : (max_level - input);
188
189 i = 0;
190 cpufreq_for_each_valid_entry(pos, table) {
191 /* ignore duplicate entry */
192 if (freq == pos->frequency)
193 continue;
194
195 /* now we have a valid frequency entry */
196 freq = pos->frequency;
197
198 if (property == GET_LEVEL && (unsigned int)input == freq) {
199 /* get level by frequency */
200 *output = descend ? i : (max_level - i);
201 return 0;
202 }
203 if (property == GET_FREQ && level == i) {
204 /* get frequency by level */
205 *output = freq;
206 return 0;
207 }
208 i++;
209 }
210
211 return -EINVAL;
212} 139}
213 140
214/** 141/**
215 * cpufreq_cooling_get_level - for a give cpu, return the cooling level. 142 * cpufreq_cooling_get_level - for a given cpu, return the cooling level.
216 * @cpu: cpu for which the level is required 143 * @cpu: cpu for which the level is required
217 * @freq: the frequency of interest 144 * @freq: the frequency of interest
218 * 145 *
@@ -224,77 +151,21 @@ static int get_property(unsigned int cpu, unsigned long input,
224 */ 151 */
225unsigned long cpufreq_cooling_get_level(unsigned int cpu, unsigned int freq) 152unsigned long cpufreq_cooling_get_level(unsigned int cpu, unsigned int freq)
226{ 153{
227 unsigned int val; 154 struct cpufreq_cooling_device *cpufreq_dev;
228
229 if (get_property(cpu, (unsigned long)freq, &val, GET_LEVEL))
230 return THERMAL_CSTATE_INVALID;
231
232 return (unsigned long)val;
233}
234EXPORT_SYMBOL_GPL(cpufreq_cooling_get_level);
235
236/**
237 * get_cpu_frequency - get the absolute value of frequency from level.
238 * @cpu: cpu for which frequency is fetched.
239 * @level: cooling level
240 *
241 * This function matches cooling level with frequency. Based on a cooling level
242 * of frequency, equals cooling state of cpu cooling device, it will return
243 * the corresponding frequency.
244 * e.g level=0 --> 1st MAX FREQ, level=1 ---> 2nd MAX FREQ, .... etc
245 *
246 * Return: 0 on error, the corresponding frequency otherwise.
247 */
248static unsigned int get_cpu_frequency(unsigned int cpu, unsigned long level)
249{
250 int ret = 0;
251 unsigned int freq;
252
253 ret = get_property(cpu, level, &freq, GET_FREQ);
254 if (ret)
255 return 0;
256
257 return freq;
258}
259
260/**
261 * cpufreq_apply_cooling - function to apply frequency clipping.
262 * @cpufreq_device: cpufreq_cooling_device pointer containing frequency
263 * clipping data.
264 * @cooling_state: value of the cooling state.
265 *
266 * Function used to make sure the cpufreq layer is aware of current thermal
267 * limits. The limits are applied by updating the cpufreq policy.
268 *
269 * Return: 0 on success, an error code otherwise (-EINVAL in case wrong
270 * cooling state).
271 */
272static int cpufreq_apply_cooling(struct cpufreq_cooling_device *cpufreq_device,
273 unsigned long cooling_state)
274{
275 unsigned int cpuid, clip_freq;
276 struct cpumask *mask = &cpufreq_device->allowed_cpus;
277 unsigned int cpu = cpumask_any(mask);
278
279
280 /* Check if the old cooling action is same as new cooling action */
281 if (cpufreq_device->cpufreq_state == cooling_state)
282 return 0;
283
284 clip_freq = get_cpu_frequency(cpu, cooling_state);
285 if (!clip_freq)
286 return -EINVAL;
287
288 cpufreq_device->cpufreq_state = cooling_state;
289 cpufreq_device->cpufreq_val = clip_freq;
290 155
291 for_each_cpu(cpuid, mask) { 156 mutex_lock(&cooling_cpufreq_lock);
292 if (is_cpufreq_valid(cpuid)) 157 list_for_each_entry(cpufreq_dev, &cpufreq_dev_list, node) {
293 cpufreq_update_policy(cpuid); 158 if (cpumask_test_cpu(cpu, &cpufreq_dev->allowed_cpus)) {
159 mutex_unlock(&cooling_cpufreq_lock);
160 return get_level(cpufreq_dev, freq);
161 }
294 } 162 }
163 mutex_unlock(&cooling_cpufreq_lock);
295 164
296 return 0; 165 pr_err("%s: cpu:%d not part of any cooling device\n", __func__, cpu);
166 return THERMAL_CSTATE_INVALID;
297} 167}
168EXPORT_SYMBOL_GPL(cpufreq_cooling_get_level);
298 169
299/** 170/**
300 * cpufreq_thermal_notifier - notifier callback for cpufreq policy change. 171 * cpufreq_thermal_notifier - notifier callback for cpufreq policy change.
@@ -324,11 +195,6 @@ static int cpufreq_thermal_notifier(struct notifier_block *nb,
324 &cpufreq_dev->allowed_cpus)) 195 &cpufreq_dev->allowed_cpus))
325 continue; 196 continue;
326 197
327 if (!cpufreq_dev->cpufreq_val)
328 cpufreq_dev->cpufreq_val = get_cpu_frequency(
329 cpumask_any(&cpufreq_dev->allowed_cpus),
330 cpufreq_dev->cpufreq_state);
331
332 max_freq = cpufreq_dev->cpufreq_val; 198 max_freq = cpufreq_dev->cpufreq_val;
333 199
334 if (policy->max != max_freq) 200 if (policy->max != max_freq)
@@ -355,19 +221,9 @@ static int cpufreq_get_max_state(struct thermal_cooling_device *cdev,
355 unsigned long *state) 221 unsigned long *state)
356{ 222{
357 struct cpufreq_cooling_device *cpufreq_device = cdev->devdata; 223 struct cpufreq_cooling_device *cpufreq_device = cdev->devdata;
358 struct cpumask *mask = &cpufreq_device->allowed_cpus;
359 unsigned int cpu;
360 unsigned int count = 0;
361 int ret;
362
363 cpu = cpumask_any(mask);
364
365 ret = get_property(cpu, 0, &count, GET_MAXL);
366 224
367 if (count > 0) 225 *state = cpufreq_device->max_level;
368 *state = count; 226 return 0;
369
370 return ret;
371} 227}
372 228
373/** 229/**
@@ -404,8 +260,24 @@ static int cpufreq_set_cur_state(struct thermal_cooling_device *cdev,
404 unsigned long state) 260 unsigned long state)
405{ 261{
406 struct cpufreq_cooling_device *cpufreq_device = cdev->devdata; 262 struct cpufreq_cooling_device *cpufreq_device = cdev->devdata;
263 unsigned int cpu = cpumask_any(&cpufreq_device->allowed_cpus);
264 unsigned int clip_freq;
265
266 /* Request state should be less than max_level */
267 if (WARN_ON(state > cpufreq_device->max_level))
268 return -EINVAL;
269
270 /* Check if the old cooling action is same as new cooling action */
271 if (cpufreq_device->cpufreq_state == state)
272 return 0;
407 273
408 return cpufreq_apply_cooling(cpufreq_device, state); 274 clip_freq = cpufreq_device->freq_table[state];
275 cpufreq_device->cpufreq_state = state;
276 cpufreq_device->cpufreq_val = clip_freq;
277
278 cpufreq_update_policy(cpu);
279
280 return 0;
409} 281}
410 282
411/* Bind cpufreq callbacks to thermal cooling device ops */ 283/* Bind cpufreq callbacks to thermal cooling device ops */
@@ -420,10 +292,25 @@ static struct notifier_block thermal_cpufreq_notifier_block = {
420 .notifier_call = cpufreq_thermal_notifier, 292 .notifier_call = cpufreq_thermal_notifier,
421}; 293};
422 294
295static unsigned int find_next_max(struct cpufreq_frequency_table *table,
296 unsigned int prev_max)
297{
298 struct cpufreq_frequency_table *pos;
299 unsigned int max = 0;
300
301 cpufreq_for_each_valid_entry(pos, table) {
302 if (pos->frequency > max && pos->frequency < prev_max)
303 max = pos->frequency;
304 }
305
306 return max;
307}
308
423/** 309/**
424 * __cpufreq_cooling_register - helper function to create cpufreq cooling device 310 * __cpufreq_cooling_register - helper function to create cpufreq cooling device
425 * @np: a valid struct device_node to the cooling device device tree node 311 * @np: a valid struct device_node to the cooling device device tree node
426 * @clip_cpus: cpumask of cpus where the frequency constraints will happen. 312 * @clip_cpus: cpumask of cpus where the frequency constraints will happen.
313 * Normally this should be same as cpufreq policy->related_cpus.
427 * 314 *
428 * This interface function registers the cpufreq cooling device with the name 315 * This interface function registers the cpufreq cooling device with the name
429 * "thermal-cpufreq-%x". This api can support multiple instances of cpufreq 316 * "thermal-cpufreq-%x". This api can support multiple instances of cpufreq
@@ -438,37 +325,42 @@ __cpufreq_cooling_register(struct device_node *np,
438 const struct cpumask *clip_cpus) 325 const struct cpumask *clip_cpus)
439{ 326{
440 struct thermal_cooling_device *cool_dev; 327 struct thermal_cooling_device *cool_dev;
441 struct cpufreq_cooling_device *cpufreq_dev = NULL; 328 struct cpufreq_cooling_device *cpufreq_dev;
442 unsigned int min = 0, max = 0;
443 char dev_name[THERMAL_NAME_LENGTH]; 329 char dev_name[THERMAL_NAME_LENGTH];
444 int ret = 0, i; 330 struct cpufreq_frequency_table *pos, *table;
445 struct cpufreq_policy policy; 331 unsigned int freq, i;
332 int ret;
446 333
447 /* Verify that all the clip cpus have same freq_min, freq_max limit */ 334 table = cpufreq_frequency_get_table(cpumask_first(clip_cpus));
448 for_each_cpu(i, clip_cpus) { 335 if (!table) {
449 /* continue if cpufreq policy not found and not return error */ 336 pr_debug("%s: CPUFreq table not found\n", __func__);
450 if (!cpufreq_get_policy(&policy, i)) 337 return ERR_PTR(-EPROBE_DEFER);
451 continue;
452 if (min == 0 && max == 0) {
453 min = policy.cpuinfo.min_freq;
454 max = policy.cpuinfo.max_freq;
455 } else {
456 if (min != policy.cpuinfo.min_freq ||
457 max != policy.cpuinfo.max_freq)
458 return ERR_PTR(-EINVAL);
459 }
460 } 338 }
461 cpufreq_dev = kzalloc(sizeof(struct cpufreq_cooling_device), 339
462 GFP_KERNEL); 340 cpufreq_dev = kzalloc(sizeof(*cpufreq_dev), GFP_KERNEL);
463 if (!cpufreq_dev) 341 if (!cpufreq_dev)
464 return ERR_PTR(-ENOMEM); 342 return ERR_PTR(-ENOMEM);
465 343
344 /* Find max levels */
345 cpufreq_for_each_valid_entry(pos, table)
346 cpufreq_dev->max_level++;
347
348 cpufreq_dev->freq_table = kmalloc(sizeof(*cpufreq_dev->freq_table) *
349 cpufreq_dev->max_level, GFP_KERNEL);
350 if (!cpufreq_dev->freq_table) {
351 cool_dev = ERR_PTR(-ENOMEM);
352 goto free_cdev;
353 }
354
355 /* max_level is an index, not a counter */
356 cpufreq_dev->max_level--;
357
466 cpumask_copy(&cpufreq_dev->allowed_cpus, clip_cpus); 358 cpumask_copy(&cpufreq_dev->allowed_cpus, clip_cpus);
467 359
468 ret = get_idr(&cpufreq_idr, &cpufreq_dev->id); 360 ret = get_idr(&cpufreq_idr, &cpufreq_dev->id);
469 if (ret) { 361 if (ret) {
470 kfree(cpufreq_dev); 362 cool_dev = ERR_PTR(ret);
471 return ERR_PTR(-EINVAL); 363 goto free_table;
472 } 364 }
473 365
474 snprintf(dev_name, sizeof(dev_name), "thermal-cpufreq-%d", 366 snprintf(dev_name, sizeof(dev_name), "thermal-cpufreq-%d",
@@ -476,25 +368,44 @@ __cpufreq_cooling_register(struct device_node *np,
476 368
477 cool_dev = thermal_of_cooling_device_register(np, dev_name, cpufreq_dev, 369 cool_dev = thermal_of_cooling_device_register(np, dev_name, cpufreq_dev,
478 &cpufreq_cooling_ops); 370 &cpufreq_cooling_ops);
479 if (IS_ERR(cool_dev)) { 371 if (IS_ERR(cool_dev))
480 release_idr(&cpufreq_idr, cpufreq_dev->id); 372 goto remove_idr;
481 kfree(cpufreq_dev); 373
482 return cool_dev; 374 /* Fill freq-table in descending order of frequencies */
375 for (i = 0, freq = -1; i <= cpufreq_dev->max_level; i++) {
376 freq = find_next_max(table, freq);
377 cpufreq_dev->freq_table[i] = freq;
378
379 /* Warn for duplicate entries */
380 if (!freq)
381 pr_warn("%s: table has duplicate entries\n", __func__);
382 else
383 pr_debug("%s: freq:%u KHz\n", __func__, freq);
483 } 384 }
385
386 cpufreq_dev->cpufreq_val = cpufreq_dev->freq_table[0];
484 cpufreq_dev->cool_dev = cool_dev; 387 cpufreq_dev->cool_dev = cool_dev;
485 cpufreq_dev->cpufreq_state = 0; 388
486 mutex_lock(&cooling_cpufreq_lock); 389 mutex_lock(&cooling_cpufreq_lock);
487 390
488 /* Register the notifier for first cpufreq cooling device */ 391 /* Register the notifier for first cpufreq cooling device */
489 if (cpufreq_dev_count == 0) 392 if (list_empty(&cpufreq_dev_list))
490 cpufreq_register_notifier(&thermal_cpufreq_notifier_block, 393 cpufreq_register_notifier(&thermal_cpufreq_notifier_block,
491 CPUFREQ_POLICY_NOTIFIER); 394 CPUFREQ_POLICY_NOTIFIER);
492 cpufreq_dev_count++;
493 list_add(&cpufreq_dev->node, &cpufreq_dev_list); 395 list_add(&cpufreq_dev->node, &cpufreq_dev_list);
494 396
495 mutex_unlock(&cooling_cpufreq_lock); 397 mutex_unlock(&cooling_cpufreq_lock);
496 398
497 return cool_dev; 399 return cool_dev;
400
401remove_idr:
402 release_idr(&cpufreq_idr, cpufreq_dev->id);
403free_table:
404 kfree(cpufreq_dev->freq_table);
405free_cdev:
406 kfree(cpufreq_dev);
407
408 return cool_dev;
498} 409}
499 410
500/** 411/**
@@ -555,16 +466,16 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev)
555 cpufreq_dev = cdev->devdata; 466 cpufreq_dev = cdev->devdata;
556 mutex_lock(&cooling_cpufreq_lock); 467 mutex_lock(&cooling_cpufreq_lock);
557 list_del(&cpufreq_dev->node); 468 list_del(&cpufreq_dev->node);
558 cpufreq_dev_count--;
559 469
560 /* Unregister the notifier for the last cpufreq cooling device */ 470 /* Unregister the notifier for the last cpufreq cooling device */
561 if (cpufreq_dev_count == 0) 471 if (list_empty(&cpufreq_dev_list))
562 cpufreq_unregister_notifier(&thermal_cpufreq_notifier_block, 472 cpufreq_unregister_notifier(&thermal_cpufreq_notifier_block,
563 CPUFREQ_POLICY_NOTIFIER); 473 CPUFREQ_POLICY_NOTIFIER);
564 mutex_unlock(&cooling_cpufreq_lock); 474 mutex_unlock(&cooling_cpufreq_lock);
565 475
566 thermal_cooling_device_unregister(cpufreq_dev->cool_dev); 476 thermal_cooling_device_unregister(cpufreq_dev->cool_dev);
567 release_idr(&cpufreq_idr, cpufreq_dev->id); 477 release_idr(&cpufreq_idr, cpufreq_dev->id);
478 kfree(cpufreq_dev->freq_table);
568 kfree(cpufreq_dev); 479 kfree(cpufreq_dev);
569} 480}
570EXPORT_SYMBOL_GPL(cpufreq_cooling_unregister); 481EXPORT_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/int340x_thermal/Makefile b/drivers/thermal/int340x_thermal/Makefile
index ffe40bffaf1a..d4413698a85f 100644
--- a/drivers/thermal/int340x_thermal/Makefile
+++ b/drivers/thermal/int340x_thermal/Makefile
@@ -1,4 +1,5 @@
1obj-$(CONFIG_INT340X_THERMAL) += int3400_thermal.o 1obj-$(CONFIG_INT340X_THERMAL) += int3400_thermal.o
2obj-$(CONFIG_INT340X_THERMAL) += int3402_thermal.o 2obj-$(CONFIG_INT340X_THERMAL) += int3402_thermal.o
3obj-$(CONFIG_INT340X_THERMAL) += int3403_thermal.o 3obj-$(CONFIG_INT340X_THERMAL) += int3403_thermal.o
4obj-$(CONFIG_INT340X_THERMAL) += processor_thermal_device.o
4obj-$(CONFIG_ACPI_THERMAL_REL) += acpi_thermal_rel.o 5obj-$(CONFIG_ACPI_THERMAL_REL) += acpi_thermal_rel.o
diff --git a/drivers/thermal/int340x_thermal/acpi_thermal_rel.c b/drivers/thermal/int340x_thermal/acpi_thermal_rel.c
index e4e61b3fb11e..231cabc16e16 100644
--- a/drivers/thermal/int340x_thermal/acpi_thermal_rel.c
+++ b/drivers/thermal/int340x_thermal/acpi_thermal_rel.c
@@ -82,7 +82,7 @@ int acpi_parse_trt(acpi_handle handle, int *trt_count, struct trt **trtp,
82 struct acpi_buffer trt_format = { sizeof("RRNNNNNN"), "RRNNNNNN" }; 82 struct acpi_buffer trt_format = { sizeof("RRNNNNNN"), "RRNNNNNN" };
83 83
84 if (!acpi_has_method(handle, "_TRT")) 84 if (!acpi_has_method(handle, "_TRT"))
85 return 0; 85 return -ENODEV;
86 86
87 status = acpi_evaluate_object(handle, "_TRT", NULL, &buffer); 87 status = acpi_evaluate_object(handle, "_TRT", NULL, &buffer);
88 if (ACPI_FAILURE(status)) 88 if (ACPI_FAILURE(status))
@@ -167,7 +167,7 @@ int acpi_parse_art(acpi_handle handle, int *art_count, struct art **artp,
167 sizeof("RRNNNNNNNNNNN"), "RRNNNNNNNNNNN" }; 167 sizeof("RRNNNNNNNNNNN"), "RRNNNNNNNNNNN" };
168 168
169 if (!acpi_has_method(handle, "_ART")) 169 if (!acpi_has_method(handle, "_ART"))
170 return 0; 170 return -ENODEV;
171 171
172 status = acpi_evaluate_object(handle, "_ART", NULL, &buffer); 172 status = acpi_evaluate_object(handle, "_ART", NULL, &buffer);
173 if (ACPI_FAILURE(status)) 173 if (ACPI_FAILURE(status))
@@ -321,8 +321,8 @@ static long acpi_thermal_rel_ioctl(struct file *f, unsigned int cmd,
321 unsigned long length = 0; 321 unsigned long length = 0;
322 int count = 0; 322 int count = 0;
323 char __user *arg = (void __user *)__arg; 323 char __user *arg = (void __user *)__arg;
324 struct trt *trts; 324 struct trt *trts = NULL;
325 struct art *arts; 325 struct art *arts = NULL;
326 326
327 switch (cmd) { 327 switch (cmd) {
328 case ACPI_THERMAL_GET_TRT_COUNT: 328 case ACPI_THERMAL_GET_TRT_COUNT:
diff --git a/drivers/thermal/int340x_thermal/int3400_thermal.c b/drivers/thermal/int340x_thermal/int3400_thermal.c
index dcb306ea14a4..65a98a97df07 100644
--- a/drivers/thermal/int340x_thermal/int3400_thermal.c
+++ b/drivers/thermal/int340x_thermal/int3400_thermal.c
@@ -335,7 +335,6 @@ static struct platform_driver int3400_thermal_driver = {
335 .remove = int3400_thermal_remove, 335 .remove = int3400_thermal_remove,
336 .driver = { 336 .driver = {
337 .name = "int3400 thermal", 337 .name = "int3400 thermal",
338 .owner = THIS_MODULE,
339 .acpi_match_table = ACPI_PTR(int3400_thermal_match), 338 .acpi_match_table = ACPI_PTR(int3400_thermal_match),
340 }, 339 },
341}; 340};
diff --git a/drivers/thermal/int340x_thermal/int3402_thermal.c b/drivers/thermal/int340x_thermal/int3402_thermal.c
index a5d08c14ba24..c5cbc3af3a05 100644
--- a/drivers/thermal/int340x_thermal/int3402_thermal.c
+++ b/drivers/thermal/int340x_thermal/int3402_thermal.c
@@ -231,7 +231,6 @@ static struct platform_driver int3402_thermal_driver = {
231 .remove = int3402_thermal_remove, 231 .remove = int3402_thermal_remove,
232 .driver = { 232 .driver = {
233 .name = "int3402 thermal", 233 .name = "int3402 thermal",
234 .owner = THIS_MODULE,
235 .acpi_match_table = int3402_thermal_match, 234 .acpi_match_table = int3402_thermal_match,
236 }, 235 },
237}; 236};
diff --git a/drivers/thermal/int340x_thermal/int3403_thermal.c b/drivers/thermal/int340x_thermal/int3403_thermal.c
index 1bfa6a69e77a..0faf500d8a77 100644
--- a/drivers/thermal/int340x_thermal/int3403_thermal.c
+++ b/drivers/thermal/int340x_thermal/int3403_thermal.c
@@ -301,6 +301,8 @@ static int int3403_sensor_remove(struct int3403_priv *priv)
301{ 301{
302 struct int3403_sensor *obj = priv->priv; 302 struct int3403_sensor *obj = priv->priv;
303 303
304 acpi_remove_notify_handler(priv->adev->handle,
305 ACPI_DEVICE_NOTIFY, int3403_notify);
304 thermal_zone_device_unregister(obj->tzone); 306 thermal_zone_device_unregister(obj->tzone);
305 return 0; 307 return 0;
306} 308}
@@ -369,6 +371,7 @@ static int int3403_cdev_add(struct int3403_priv *priv)
369 p = buf.pointer; 371 p = buf.pointer;
370 if (!p || (p->type != ACPI_TYPE_PACKAGE)) { 372 if (!p || (p->type != ACPI_TYPE_PACKAGE)) {
371 printk(KERN_WARNING "Invalid PPSS data\n"); 373 printk(KERN_WARNING "Invalid PPSS data\n");
374 kfree(buf.pointer);
372 return -EFAULT; 375 return -EFAULT;
373 } 376 }
374 377
@@ -381,6 +384,7 @@ static int int3403_cdev_add(struct int3403_priv *priv)
381 384
382 priv->priv = obj; 385 priv->priv = obj;
383 386
387 kfree(buf.pointer);
384 /* TODO: add ACPI notification support */ 388 /* TODO: add ACPI notification support */
385 389
386 return result; 390 return result;
diff --git a/drivers/thermal/int340x_thermal/processor_thermal_device.c b/drivers/thermal/int340x_thermal/processor_thermal_device.c
new file mode 100644
index 000000000000..31bb553aac26
--- /dev/null
+++ b/drivers/thermal/int340x_thermal/processor_thermal_device.c
@@ -0,0 +1,309 @@
1/*
2 * processor_thermal_device.c
3 * Copyright (c) 2014, Intel Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 */
15#include <linux/kernel.h>
16#include <linux/module.h>
17#include <linux/init.h>
18#include <linux/pci.h>
19#include <linux/platform_device.h>
20#include <linux/acpi.h>
21
22/* Broadwell-U/HSB thermal reporting device */
23#define PCI_DEVICE_ID_PROC_BDW_THERMAL 0x1603
24#define PCI_DEVICE_ID_PROC_HSB_THERMAL 0x0A03
25
26/* Braswell thermal reporting device */
27#define PCI_DEVICE_ID_PROC_BSW_THERMAL 0x22DC
28
29struct power_config {
30 u32 index;
31 u32 min_uw;
32 u32 max_uw;
33 u32 tmin_us;
34 u32 tmax_us;
35 u32 step_uw;
36};
37
38struct proc_thermal_device {
39 struct device *dev;
40 struct acpi_device *adev;
41 struct power_config power_limits[2];
42};
43
44enum proc_thermal_emum_mode_type {
45 PROC_THERMAL_NONE,
46 PROC_THERMAL_PCI,
47 PROC_THERMAL_PLATFORM_DEV
48};
49
50/*
51 * We can have only one type of enumeration, PCI or Platform,
52 * not both. So we don't need instance specific data.
53 */
54static enum proc_thermal_emum_mode_type proc_thermal_emum_mode =
55 PROC_THERMAL_NONE;
56
57#define POWER_LIMIT_SHOW(index, suffix) \
58static ssize_t power_limit_##index##_##suffix##_show(struct device *dev, \
59 struct device_attribute *attr, \
60 char *buf) \
61{ \
62 struct pci_dev *pci_dev; \
63 struct platform_device *pdev; \
64 struct proc_thermal_device *proc_dev; \
65\
66 if (proc_thermal_emum_mode == PROC_THERMAL_PLATFORM_DEV) { \
67 pdev = to_platform_device(dev); \
68 proc_dev = platform_get_drvdata(pdev); \
69 } else { \
70 pci_dev = to_pci_dev(dev); \
71 proc_dev = pci_get_drvdata(pci_dev); \
72 } \
73 return sprintf(buf, "%lu\n",\
74 (unsigned long)proc_dev->power_limits[index].suffix * 1000); \
75}
76
77POWER_LIMIT_SHOW(0, min_uw)
78POWER_LIMIT_SHOW(0, max_uw)
79POWER_LIMIT_SHOW(0, step_uw)
80POWER_LIMIT_SHOW(0, tmin_us)
81POWER_LIMIT_SHOW(0, tmax_us)
82
83POWER_LIMIT_SHOW(1, min_uw)
84POWER_LIMIT_SHOW(1, max_uw)
85POWER_LIMIT_SHOW(1, step_uw)
86POWER_LIMIT_SHOW(1, tmin_us)
87POWER_LIMIT_SHOW(1, tmax_us)
88
89static DEVICE_ATTR_RO(power_limit_0_min_uw);
90static DEVICE_ATTR_RO(power_limit_0_max_uw);
91static DEVICE_ATTR_RO(power_limit_0_step_uw);
92static DEVICE_ATTR_RO(power_limit_0_tmin_us);
93static DEVICE_ATTR_RO(power_limit_0_tmax_us);
94
95static DEVICE_ATTR_RO(power_limit_1_min_uw);
96static DEVICE_ATTR_RO(power_limit_1_max_uw);
97static DEVICE_ATTR_RO(power_limit_1_step_uw);
98static DEVICE_ATTR_RO(power_limit_1_tmin_us);
99static DEVICE_ATTR_RO(power_limit_1_tmax_us);
100
101static struct attribute *power_limit_attrs[] = {
102 &dev_attr_power_limit_0_min_uw.attr,
103 &dev_attr_power_limit_1_min_uw.attr,
104 &dev_attr_power_limit_0_max_uw.attr,
105 &dev_attr_power_limit_1_max_uw.attr,
106 &dev_attr_power_limit_0_step_uw.attr,
107 &dev_attr_power_limit_1_step_uw.attr,
108 &dev_attr_power_limit_0_tmin_us.attr,
109 &dev_attr_power_limit_1_tmin_us.attr,
110 &dev_attr_power_limit_0_tmax_us.attr,
111 &dev_attr_power_limit_1_tmax_us.attr,
112 NULL
113};
114
115static struct attribute_group power_limit_attribute_group = {
116 .attrs = power_limit_attrs,
117 .name = "power_limits"
118};
119
120static int proc_thermal_add(struct device *dev,
121 struct proc_thermal_device **priv)
122{
123 struct proc_thermal_device *proc_priv;
124 struct acpi_device *adev;
125 acpi_status status;
126 struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL };
127 union acpi_object *elements, *ppcc;
128 union acpi_object *p;
129 int i;
130 int ret;
131
132 adev = ACPI_COMPANION(dev);
133
134 status = acpi_evaluate_object(adev->handle, "PPCC", NULL, &buf);
135 if (ACPI_FAILURE(status))
136 return -ENODEV;
137
138 p = buf.pointer;
139 if (!p || (p->type != ACPI_TYPE_PACKAGE)) {
140 dev_err(dev, "Invalid PPCC data\n");
141 ret = -EFAULT;
142 goto free_buffer;
143 }
144 if (!p->package.count) {
145 dev_err(dev, "Invalid PPCC package size\n");
146 ret = -EFAULT;
147 goto free_buffer;
148 }
149
150 proc_priv = devm_kzalloc(dev, sizeof(*proc_priv), GFP_KERNEL);
151 if (!proc_priv) {
152 ret = -ENOMEM;
153 goto free_buffer;
154 }
155
156 proc_priv->dev = dev;
157 proc_priv->adev = adev;
158
159 for (i = 0; i < min((int)p->package.count - 1, 2); ++i) {
160 elements = &(p->package.elements[i+1]);
161 if (elements->type != ACPI_TYPE_PACKAGE ||
162 elements->package.count != 6) {
163 ret = -EFAULT;
164 goto free_buffer;
165 }
166 ppcc = elements->package.elements;
167 proc_priv->power_limits[i].index = ppcc[0].integer.value;
168 proc_priv->power_limits[i].min_uw = ppcc[1].integer.value;
169 proc_priv->power_limits[i].max_uw = ppcc[2].integer.value;
170 proc_priv->power_limits[i].tmin_us = ppcc[3].integer.value;
171 proc_priv->power_limits[i].tmax_us = ppcc[4].integer.value;
172 proc_priv->power_limits[i].step_uw = ppcc[5].integer.value;
173 }
174
175 *priv = proc_priv;
176
177 ret = sysfs_create_group(&dev->kobj,
178 &power_limit_attribute_group);
179
180free_buffer:
181 kfree(buf.pointer);
182
183 return ret;
184}
185
186void proc_thermal_remove(struct proc_thermal_device *proc_priv)
187{
188 sysfs_remove_group(&proc_priv->dev->kobj,
189 &power_limit_attribute_group);
190}
191
192static int int3401_add(struct platform_device *pdev)
193{
194 struct proc_thermal_device *proc_priv;
195 int ret;
196
197 if (proc_thermal_emum_mode == PROC_THERMAL_PCI) {
198 dev_err(&pdev->dev, "error: enumerated as PCI dev\n");
199 return -ENODEV;
200 }
201
202 ret = proc_thermal_add(&pdev->dev, &proc_priv);
203 if (ret)
204 return ret;
205
206 platform_set_drvdata(pdev, proc_priv);
207 proc_thermal_emum_mode = PROC_THERMAL_PLATFORM_DEV;
208
209 return 0;
210}
211
212static int int3401_remove(struct platform_device *pdev)
213{
214 proc_thermal_remove(platform_get_drvdata(pdev));
215
216 return 0;
217}
218
219static int proc_thermal_pci_probe(struct pci_dev *pdev,
220 const struct pci_device_id *unused)
221{
222 struct proc_thermal_device *proc_priv;
223 int ret;
224
225 if (proc_thermal_emum_mode == PROC_THERMAL_PLATFORM_DEV) {
226 dev_err(&pdev->dev, "error: enumerated as platform dev\n");
227 return -ENODEV;
228 }
229
230 ret = pci_enable_device(pdev);
231 if (ret < 0) {
232 dev_err(&pdev->dev, "error: could not enable device\n");
233 return ret;
234 }
235
236 ret = proc_thermal_add(&pdev->dev, &proc_priv);
237 if (ret) {
238 pci_disable_device(pdev);
239 return ret;
240 }
241
242 pci_set_drvdata(pdev, proc_priv);
243 proc_thermal_emum_mode = PROC_THERMAL_PCI;
244
245 return 0;
246}
247
248static void proc_thermal_pci_remove(struct pci_dev *pdev)
249{
250 proc_thermal_remove(pci_get_drvdata(pdev));
251 pci_disable_device(pdev);
252}
253
254static const struct pci_device_id proc_thermal_pci_ids[] = {
255 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_BDW_THERMAL)},
256 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_HSB_THERMAL)},
257 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_BSW_THERMAL)},
258 { 0, },
259};
260
261MODULE_DEVICE_TABLE(pci, proc_thermal_pci_ids);
262
263static struct pci_driver proc_thermal_pci_driver = {
264 .name = "proc_thermal",
265 .probe = proc_thermal_pci_probe,
266 .remove = proc_thermal_pci_remove,
267 .id_table = proc_thermal_pci_ids,
268};
269
270static const struct acpi_device_id int3401_device_ids[] = {
271 {"INT3401", 0},
272 {"", 0},
273};
274MODULE_DEVICE_TABLE(acpi, int3401_device_ids);
275
276static struct platform_driver int3401_driver = {
277 .probe = int3401_add,
278 .remove = int3401_remove,
279 .driver = {
280 .name = "int3401 thermal",
281 .acpi_match_table = int3401_device_ids,
282 },
283};
284
285static int __init proc_thermal_init(void)
286{
287 int ret;
288
289 ret = platform_driver_register(&int3401_driver);
290 if (ret)
291 return ret;
292
293 ret = pci_register_driver(&proc_thermal_pci_driver);
294
295 return ret;
296}
297
298static void __exit proc_thermal_exit(void)
299{
300 platform_driver_unregister(&int3401_driver);
301 pci_unregister_driver(&proc_thermal_pci_driver);
302}
303
304module_init(proc_thermal_init);
305module_exit(proc_thermal_exit);
306
307MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
308MODULE_DESCRIPTION("Processor Thermal Reporting Device Driver");
309MODULE_LICENSE("GPL v2");
diff --git a/drivers/thermal/intel_powerclamp.c b/drivers/thermal/intel_powerclamp.c
index e98b4249187c..6ceebd659dd4 100644
--- a/drivers/thermal/intel_powerclamp.c
+++ b/drivers/thermal/intel_powerclamp.c
@@ -688,6 +688,7 @@ static const struct x86_cpu_id intel_powerclamp_ids[] = {
688 { X86_VENDOR_INTEL, 6, 0x45}, 688 { X86_VENDOR_INTEL, 6, 0x45},
689 { X86_VENDOR_INTEL, 6, 0x46}, 689 { X86_VENDOR_INTEL, 6, 0x46},
690 { X86_VENDOR_INTEL, 6, 0x4c}, 690 { X86_VENDOR_INTEL, 6, 0x4c},
691 { X86_VENDOR_INTEL, 6, 0x56},
691 {} 692 {}
692}; 693};
693MODULE_DEVICE_TABLE(x86cpu, intel_powerclamp_ids); 694MODULE_DEVICE_TABLE(x86cpu, intel_powerclamp_ids);
diff --git a/drivers/thermal/rockchip_thermal.c b/drivers/thermal/rockchip_thermal.c
index 1bcddfc60e91..9c6ce548e363 100644
--- a/drivers/thermal/rockchip_thermal.c
+++ b/drivers/thermal/rockchip_thermal.c
@@ -677,7 +677,6 @@ static SIMPLE_DEV_PM_OPS(rockchip_thermal_pm_ops,
677static struct platform_driver rockchip_thermal_driver = { 677static struct platform_driver rockchip_thermal_driver = {
678 .driver = { 678 .driver = {
679 .name = "rockchip-thermal", 679 .name = "rockchip-thermal",
680 .owner = THIS_MODULE,
681 .pm = &rockchip_thermal_pm_ops, 680 .pm = &rockchip_thermal_pm_ops,
682 .of_match_table = of_rockchip_thermal_match, 681 .of_match_table = of_rockchip_thermal_match,
683 }, 682 },
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