aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-12-29 16:13:41 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-12-29 16:13:41 -0500
commit4c5d4995030c298db9fe0db00693a4641243cd9e (patch)
tree1d5fa84e5ee81cda90c32aa3a1be33506d09e45b
parent45f87de57f8fad59302fd263dd81ffa4843b5b24 (diff)
parent7429b1e0d00e62426c74a45195ba72149cb9ad64 (diff)
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux
Pull thermal management updates from Zhang Rui: "First of all, the most important change is the thermal cpu cooling fixes. The major fix here is to have proper sequencing between cpufreq layer and thermal cpu cooling registration. A take away of this fix is an improvement in the thermal drivers code. Thermal drivers that require cpu cooling do not need to check for cpufreq layer. The requirement now is to propagate the error code, if any, while registering cpu cooling device. Thanks to Viresh for implementing the required CPUfreq changes. Second, a new driver is introduced for int340x processor thermal device. Given that int340x thermal is disabled by default, and this processor thermal device is only available on limited platforms, plus the driver does nothing but exposes some thermal limitation information for user space to use, thus I think it is safe to include it in this pull request after missing 3.19-rc2. Specifics: - Thermal cpu cooling fixes and cleanups. - introduce INT340X processor thermal reporting device driver. - several small fixes and cleanups for int340x thermal drivers" * 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux: (43 commits) Thermal/int340x/int3403: Free acpi notification handler Thermal/int340x/processor_thermal: Fix memory leak Thermal/int340x/int3403: Fix memory leak thermal: int340x: Introduce processor reporting device thermal: int340x_thermal: drop owner assignment from platform_drivers thermal: drop owner assignment from platform_drivers thermal: cpu_cooling: document node in struct cpufreq_cooling_device thermal/powerclamp: add ids for future xeon cpus Thermal/int340x: Handle properly the case when _trt or _art acpi entry is missing thermal: cpu_cooling: return ERR_PTR() for !CPU_THERMAL or !THERMAL_OF thermal: cpu_cooling: small memory leak on error thermal: ti-soc-thermal: Do not print error message in the EPROBE_DEFER case thermal: db8500: Do not print error message in the EPROBE_DEFER case thermal: imx: Do not print error message in the EPROBE_DEFER case thermal: Fix cdev registration with THERMAL_NO_LIMIT on 64bit drivers: thermal: Remove ARCH_HAS_BANDGAP dependency for samsung thermal:core:fix: Check return code of the ->get_max_state() callback thermal: cpu_cooling: update copyright tags thermal: cpu_cooling: Use cpufreq_dev->freq_table for finding level/freq thermal: cpu_cooling: Store frequencies in descending order ...
-rw-r--r--drivers/thermal/cpu_cooling.c360
-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
-rw-r--r--include/dt-bindings/thermal/thermal.h2
-rw-r--r--include/linux/cpu_cooling.h6
-rw-r--r--include/linux/thermal.h2
19 files changed, 497 insertions, 276 deletions
diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c
index ad09e51ffae4..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,25 +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.
60 * @node: list_head to link all cpufreq_cooling_device together.
42 * 61 *
43 * This structure is required for keeping information of each 62 * This structure is required for keeping information of each registered
44 * cpufreq_cooling_device registered. In order to prevent corruption of this a 63 * cpufreq_cooling_device.
45 * mutex lock cooling_cpufreq_lock is used.
46 */ 64 */
47struct cpufreq_cooling_device { 65struct cpufreq_cooling_device {
48 int id; 66 int id;
49 struct thermal_cooling_device *cool_dev; 67 struct thermal_cooling_device *cool_dev;
50 unsigned int cpufreq_state; 68 unsigned int cpufreq_state;
51 unsigned int cpufreq_val; 69 unsigned int cpufreq_val;
70 unsigned int max_level;
71 unsigned int *freq_table; /* In descending order */
52 struct cpumask allowed_cpus; 72 struct cpumask allowed_cpus;
53 struct list_head node; 73 struct list_head node;
54}; 74};
55static DEFINE_IDR(cpufreq_idr); 75static DEFINE_IDR(cpufreq_idr);
56static DEFINE_MUTEX(cooling_cpufreq_lock); 76static DEFINE_MUTEX(cooling_cpufreq_lock);
57 77
58static unsigned int cpufreq_dev_count;
59
60static LIST_HEAD(cpufreq_dev_list); 78static LIST_HEAD(cpufreq_dev_list);
61 79
62/** 80/**
@@ -98,120 +116,30 @@ static void release_idr(struct idr *idr, int id)
98/* 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 */
99 117
100/** 118/**
101 * is_cpufreq_valid - function to check frequency transitioning capability. 119 * get_level: Find the level for a particular frequency
102 * @cpu: cpu for which check is needed. 120 * @cpufreq_dev: cpufreq_dev for which the property is required
121 * @freq: Frequency
103 * 122 *
104 * This function will check the current state of the system if 123 * 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 */ 124 */
110static int is_cpufreq_valid(int cpu) 125static unsigned long get_level(struct cpufreq_cooling_device *cpufreq_dev,
126 unsigned int freq)
111{ 127{
112 struct cpufreq_policy policy; 128 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 129
176 /* max_level is an index, not a counter */ 130 for (level = 0; level <= cpufreq_dev->max_level; level++) {
177 max_level--; 131 if (freq == cpufreq_dev->freq_table[level])
132 return level;
178 133
179 /* get max level */ 134 if (freq > cpufreq_dev->freq_table[level])
180 if (property == GET_MAXL) { 135 break;
181 *output = (unsigned int)max_level;
182 return 0;
183 } 136 }
184 137
185 if (property == GET_FREQ) 138 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} 139}
212 140
213/** 141/**
214 * 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.
215 * @cpu: cpu for which the level is required 143 * @cpu: cpu for which the level is required
216 * @freq: the frequency of interest 144 * @freq: the frequency of interest
217 * 145 *
@@ -223,77 +151,21 @@ static int get_property(unsigned int cpu, unsigned long input,
223 */ 151 */
224unsigned long cpufreq_cooling_get_level(unsigned int cpu, unsigned int freq) 152unsigned long cpufreq_cooling_get_level(unsigned int cpu, unsigned int freq)
225{ 153{
226 unsigned int val; 154 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 155
290 for_each_cpu(cpuid, mask) { 156 mutex_lock(&cooling_cpufreq_lock);
291 if (is_cpufreq_valid(cpuid)) 157 list_for_each_entry(cpufreq_dev, &cpufreq_dev_list, node) {
292 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 }
293 } 162 }
163 mutex_unlock(&cooling_cpufreq_lock);
294 164
295 return 0; 165 pr_err("%s: cpu:%d not part of any cooling device\n", __func__, cpu);
166 return THERMAL_CSTATE_INVALID;
296} 167}
168EXPORT_SYMBOL_GPL(cpufreq_cooling_get_level);
297 169
298/** 170/**
299 * cpufreq_thermal_notifier - notifier callback for cpufreq policy change. 171 * cpufreq_thermal_notifier - notifier callback for cpufreq policy change.
@@ -323,11 +195,6 @@ static int cpufreq_thermal_notifier(struct notifier_block *nb,
323 &cpufreq_dev->allowed_cpus)) 195 &cpufreq_dev->allowed_cpus))
324 continue; 196 continue;
325 197
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; 198 max_freq = cpufreq_dev->cpufreq_val;
332 199
333 if (policy->max != max_freq) 200 if (policy->max != max_freq)
@@ -354,19 +221,9 @@ static int cpufreq_get_max_state(struct thermal_cooling_device *cdev,
354 unsigned long *state) 221 unsigned long *state)
355{ 222{
356 struct cpufreq_cooling_device *cpufreq_device = cdev->devdata; 223 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 224
366 if (count > 0) 225 *state = cpufreq_device->max_level;
367 *state = count; 226 return 0;
368
369 return ret;
370} 227}
371 228
372/** 229/**
@@ -403,8 +260,24 @@ static int cpufreq_set_cur_state(struct thermal_cooling_device *cdev,
403 unsigned long state) 260 unsigned long state)
404{ 261{
405 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;
406 273
407 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;
408} 281}
409 282
410/* Bind cpufreq callbacks to thermal cooling device ops */ 283/* Bind cpufreq callbacks to thermal cooling device ops */
@@ -419,10 +292,25 @@ static struct notifier_block thermal_cpufreq_notifier_block = {
419 .notifier_call = cpufreq_thermal_notifier, 292 .notifier_call = cpufreq_thermal_notifier,
420}; 293};
421 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
422/** 309/**
423 * __cpufreq_cooling_register - helper function to create cpufreq cooling device 310 * __cpufreq_cooling_register - helper function to create cpufreq cooling device
424 * @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
425 * @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.
426 * 314 *
427 * This interface function registers the cpufreq cooling device with the name 315 * This interface function registers the cpufreq cooling device with the name
428 * "thermal-cpufreq-%x". This api can support multiple instances of cpufreq 316 * "thermal-cpufreq-%x". This api can support multiple instances of cpufreq
@@ -437,37 +325,42 @@ __cpufreq_cooling_register(struct device_node *np,
437 const struct cpumask *clip_cpus) 325 const struct cpumask *clip_cpus)
438{ 326{
439 struct thermal_cooling_device *cool_dev; 327 struct thermal_cooling_device *cool_dev;
440 struct cpufreq_cooling_device *cpufreq_dev = NULL; 328 struct cpufreq_cooling_device *cpufreq_dev;
441 unsigned int min = 0, max = 0;
442 char dev_name[THERMAL_NAME_LENGTH]; 329 char dev_name[THERMAL_NAME_LENGTH];
443 int ret = 0, i; 330 struct cpufreq_frequency_table *pos, *table;
444 struct cpufreq_policy policy; 331 unsigned int freq, i;
332 int ret;
445 333
446 /* Verify that all the clip cpus have same freq_min, freq_max limit */ 334 table = cpufreq_frequency_get_table(cpumask_first(clip_cpus));
447 for_each_cpu(i, clip_cpus) { 335 if (!table) {
448 /* continue if cpufreq policy not found and not return error */ 336 pr_debug("%s: CPUFreq table not found\n", __func__);
449 if (!cpufreq_get_policy(&policy, i)) 337 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 } 338 }
460 cpufreq_dev = kzalloc(sizeof(struct cpufreq_cooling_device), 339
461 GFP_KERNEL); 340 cpufreq_dev = kzalloc(sizeof(*cpufreq_dev), GFP_KERNEL);
462 if (!cpufreq_dev) 341 if (!cpufreq_dev)
463 return ERR_PTR(-ENOMEM); 342 return ERR_PTR(-ENOMEM);
464 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
465 cpumask_copy(&cpufreq_dev->allowed_cpus, clip_cpus); 358 cpumask_copy(&cpufreq_dev->allowed_cpus, clip_cpus);
466 359
467 ret = get_idr(&cpufreq_idr, &cpufreq_dev->id); 360 ret = get_idr(&cpufreq_idr, &cpufreq_dev->id);
468 if (ret) { 361 if (ret) {
469 kfree(cpufreq_dev); 362 cool_dev = ERR_PTR(ret);
470 return ERR_PTR(-EINVAL); 363 goto free_table;
471 } 364 }
472 365
473 snprintf(dev_name, sizeof(dev_name), "thermal-cpufreq-%d", 366 snprintf(dev_name, sizeof(dev_name), "thermal-cpufreq-%d",
@@ -475,25 +368,44 @@ __cpufreq_cooling_register(struct device_node *np,
475 368
476 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,
477 &cpufreq_cooling_ops); 370 &cpufreq_cooling_ops);
478 if (IS_ERR(cool_dev)) { 371 if (IS_ERR(cool_dev))
479 release_idr(&cpufreq_idr, cpufreq_dev->id); 372 goto remove_idr;
480 kfree(cpufreq_dev); 373
481 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);
482 } 384 }
385
386 cpufreq_dev->cpufreq_val = cpufreq_dev->freq_table[0];
483 cpufreq_dev->cool_dev = cool_dev; 387 cpufreq_dev->cool_dev = cool_dev;
484 cpufreq_dev->cpufreq_state = 0; 388
485 mutex_lock(&cooling_cpufreq_lock); 389 mutex_lock(&cooling_cpufreq_lock);
486 390
487 /* Register the notifier for first cpufreq cooling device */ 391 /* Register the notifier for first cpufreq cooling device */
488 if (cpufreq_dev_count == 0) 392 if (list_empty(&cpufreq_dev_list))
489 cpufreq_register_notifier(&thermal_cpufreq_notifier_block, 393 cpufreq_register_notifier(&thermal_cpufreq_notifier_block,
490 CPUFREQ_POLICY_NOTIFIER); 394 CPUFREQ_POLICY_NOTIFIER);
491 cpufreq_dev_count++;
492 list_add(&cpufreq_dev->node, &cpufreq_dev_list); 395 list_add(&cpufreq_dev->node, &cpufreq_dev_list);
493 396
494 mutex_unlock(&cooling_cpufreq_lock); 397 mutex_unlock(&cooling_cpufreq_lock);
495 398
496 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;
497} 409}
498 410
499/** 411/**
@@ -554,16 +466,16 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev)
554 cpufreq_dev = cdev->devdata; 466 cpufreq_dev = cdev->devdata;
555 mutex_lock(&cooling_cpufreq_lock); 467 mutex_lock(&cooling_cpufreq_lock);
556 list_del(&cpufreq_dev->node); 468 list_del(&cpufreq_dev->node);
557 cpufreq_dev_count--;
558 469
559 /* Unregister the notifier for the last cpufreq cooling device */ 470 /* Unregister the notifier for the last cpufreq cooling device */
560 if (cpufreq_dev_count == 0) 471 if (list_empty(&cpufreq_dev_list))
561 cpufreq_unregister_notifier(&thermal_cpufreq_notifier_block, 472 cpufreq_unregister_notifier(&thermal_cpufreq_notifier_block,
562 CPUFREQ_POLICY_NOTIFIER); 473 CPUFREQ_POLICY_NOTIFIER);
563 mutex_unlock(&cooling_cpufreq_lock); 474 mutex_unlock(&cooling_cpufreq_lock);
564 475
565 thermal_cooling_device_unregister(cpufreq_dev->cool_dev); 476 thermal_cooling_device_unregister(cpufreq_dev->cool_dev);
566 release_idr(&cpufreq_idr, cpufreq_dev->id); 477 release_idr(&cpufreq_idr, cpufreq_dev->id);
478 kfree(cpufreq_dev->freq_table);
567 kfree(cpufreq_dev); 479 kfree(cpufreq_dev);
568} 480}
569EXPORT_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
diff --git a/include/dt-bindings/thermal/thermal.h b/include/dt-bindings/thermal/thermal.h
index 59822a995858..b5e6b0069ac7 100644
--- a/include/dt-bindings/thermal/thermal.h
+++ b/include/dt-bindings/thermal/thermal.h
@@ -11,7 +11,7 @@
11#define _DT_BINDINGS_THERMAL_THERMAL_H 11#define _DT_BINDINGS_THERMAL_THERMAL_H
12 12
13/* On cooling devices upper and lower limits */ 13/* On cooling devices upper and lower limits */
14#define THERMAL_NO_LIMIT (-1UL) 14#define THERMAL_NO_LIMIT (~0)
15 15
16#endif 16#endif
17 17
diff --git a/include/linux/cpu_cooling.h b/include/linux/cpu_cooling.h
index c303d383def1..bd955270d5aa 100644
--- a/include/linux/cpu_cooling.h
+++ b/include/linux/cpu_cooling.h
@@ -50,7 +50,7 @@ static inline struct thermal_cooling_device *
50of_cpufreq_cooling_register(struct device_node *np, 50of_cpufreq_cooling_register(struct device_node *np,
51 const struct cpumask *clip_cpus) 51 const struct cpumask *clip_cpus)
52{ 52{
53 return NULL; 53 return ERR_PTR(-ENOSYS);
54} 54}
55#endif 55#endif
56 56
@@ -65,13 +65,13 @@ unsigned long cpufreq_cooling_get_level(unsigned int cpu, unsigned int freq);
65static inline struct thermal_cooling_device * 65static inline struct thermal_cooling_device *
66cpufreq_cooling_register(const struct cpumask *clip_cpus) 66cpufreq_cooling_register(const struct cpumask *clip_cpus)
67{ 67{
68 return NULL; 68 return ERR_PTR(-ENOSYS);
69} 69}
70static inline struct thermal_cooling_device * 70static inline struct thermal_cooling_device *
71of_cpufreq_cooling_register(struct device_node *np, 71of_cpufreq_cooling_register(struct device_node *np,
72 const struct cpumask *clip_cpus) 72 const struct cpumask *clip_cpus)
73{ 73{
74 return NULL; 74 return ERR_PTR(-ENOSYS);
75} 75}
76static inline 76static inline
77void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev) 77void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev)
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index c611a02fbc51..fc52e307efab 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -38,7 +38,7 @@
38#define THERMAL_CSTATE_INVALID -1UL 38#define THERMAL_CSTATE_INVALID -1UL
39 39
40/* No upper/lower limit requirement */ 40/* No upper/lower limit requirement */
41#define THERMAL_NO_LIMIT THERMAL_CSTATE_INVALID 41#define THERMAL_NO_LIMIT ((u32)~0)
42 42
43/* Unit conversion macros */ 43/* Unit conversion macros */
44#define KELVIN_TO_CELSIUS(t) (long)(((long)t-2732 >= 0) ? \ 44#define KELVIN_TO_CELSIUS(t) (long)(((long)t-2732 >= 0) ? \