aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-01-24 20:13:49 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-01-24 20:13:49 -0500
commit91466574be1a3701fab4abf5ac1539b556575a81 (patch)
tree89373ef6b0c9e024a9688207b832552dfbcca666 /drivers/thermal/ti-soc-thermal/ti-thermal-common.c
parent09da8dfa98682d871987145ed11e3232accac860 (diff)
parentc698a4492f01127ca90fc28cd5157f3d616fe4ff (diff)
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux
Pull thermal management updates from Zhang Rui: "This time, the biggest change is the work of representing hardware thermal properties in device tree infrastructure. This work includes the introduction of a device tree bindings for describing the hardware thermal behavior and limits, and also a parser to read and interpret the data, and build thermal zones and thermal binding parameters. It also contains three examples on how to use the new representation on sensor devices, using three different drivers to accomplish it. One driver is in thermal subsystem, the TI SoC thermal, and the other two drivers are in hwmon subsystem. Actually, this would be the first step of the complete work because we still need to check other potential drivers to be converted and then validate the proposed API. But the reason why I include it in this pull request is that, first, this change does not hurt any others without using this approach, second, the principle and concept of this change would not break after converting the remaining drivers. BTW, as you can see, there are several points in this change that do not belong to thermal subsystem. Because it has been suggested by Guenter R that in such cases, it is recommended to send the complete series via one single subsystem. Specifics: - representing hardware thermal properties in device tree infrastructure - fix a regression that the imx thermal driver breaks system suspend. - introduce ACPI INT3403 thermal driver to retrieve temperature data from the INT3403 ACPI device object present on some systems. - introduce debug statement for thermal core and step_wise governor. - assorted fixes and cleanups for thermal core, cpu cooling, exynos thrmal, intel powerclamp and imx thermal driver" * 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux: (34 commits) thermal: remove const flag from .ops of imx thermal Thermal: update thermal zone device after setting emul_temp intel_powerclamp: Fix cstate counter detection. thermal: imx: add necessary clk operation Thermal cpu cooling: return error if no valid cpu frequency entry thermal: fix cpu_cooling max_level behavior thermal: rcar-thermal: Enable driver compilation with COMPILE_TEST thermal: debug: add debug statement for core and step_wise thermal: imx_thermal: add module device table drivers: thermal: Mark function as static in x86_pkg_temp_thermal.c thermal:samsung: fix compilation warning thermal: imx: correct suspend/resume flow thermal: exynos: fix error return code Thermal: ACPI INT3403 thermal driver MAINTAINERS: add thermal bindings entry in thermal domain arm: dts: make OMAP4460 bandgap node to belong to OCP arm: dts: make OMAP443x bandgap node to belong to OCP arm: dts: add cooling properties on omap5 cpu node arm: dts: add omap5 thermal data arm: dts: add omap5 CORE thermal data ...
Diffstat (limited to 'drivers/thermal/ti-soc-thermal/ti-thermal-common.c')
-rw-r--r--drivers/thermal/ti-soc-thermal/ti-thermal-common.c77
1 files changed, 62 insertions, 15 deletions
diff --git a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
index 5a47cc8c8f85..9eec26dc0448 100644
--- a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
+++ b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
@@ -31,6 +31,7 @@
31#include <linux/cpufreq.h> 31#include <linux/cpufreq.h>
32#include <linux/cpumask.h> 32#include <linux/cpumask.h>
33#include <linux/cpu_cooling.h> 33#include <linux/cpu_cooling.h>
34#include <linux/of.h>
34 35
35#include "ti-thermal.h" 36#include "ti-thermal.h"
36#include "ti-bandgap.h" 37#include "ti-bandgap.h"
@@ -44,6 +45,7 @@ struct ti_thermal_data {
44 enum thermal_device_mode mode; 45 enum thermal_device_mode mode;
45 struct work_struct thermal_wq; 46 struct work_struct thermal_wq;
46 int sensor_id; 47 int sensor_id;
48 bool our_zone;
47}; 49};
48 50
49static void ti_thermal_work(struct work_struct *work) 51static void ti_thermal_work(struct work_struct *work)
@@ -75,11 +77,10 @@ static inline int ti_thermal_hotspot_temperature(int t, int s, int c)
75 77
76/* thermal zone ops */ 78/* thermal zone ops */
77/* Get temperature callback function for thermal zone*/ 79/* Get temperature callback function for thermal zone*/
78static inline int ti_thermal_get_temp(struct thermal_zone_device *thermal, 80static inline int __ti_thermal_get_temp(void *devdata, long *temp)
79 unsigned long *temp)
80{ 81{
81 struct thermal_zone_device *pcb_tz = NULL; 82 struct thermal_zone_device *pcb_tz = NULL;
82 struct ti_thermal_data *data = thermal->devdata; 83 struct ti_thermal_data *data = devdata;
83 struct ti_bandgap *bgp; 84 struct ti_bandgap *bgp;
84 const struct ti_temp_sensor *s; 85 const struct ti_temp_sensor *s;
85 int ret, tmp, slope, constant; 86 int ret, tmp, slope, constant;
@@ -118,6 +119,14 @@ static inline int ti_thermal_get_temp(struct thermal_zone_device *thermal,
118 return ret; 119 return ret;
119} 120}
120 121
122static inline int ti_thermal_get_temp(struct thermal_zone_device *thermal,
123 unsigned long *temp)
124{
125 struct ti_thermal_data *data = thermal->devdata;
126
127 return __ti_thermal_get_temp(data, temp);
128}
129
121/* Bind callback functions for thermal zone */ 130/* Bind callback functions for thermal zone */
122static int ti_thermal_bind(struct thermal_zone_device *thermal, 131static int ti_thermal_bind(struct thermal_zone_device *thermal,
123 struct thermal_cooling_device *cdev) 132 struct thermal_cooling_device *cdev)
@@ -230,11 +239,9 @@ static int ti_thermal_get_trip_temp(struct thermal_zone_device *thermal,
230 return 0; 239 return 0;
231} 240}
232 241
233/* Get the temperature trend callback functions for thermal zone */ 242static int __ti_thermal_get_trend(void *p, long *trend)
234static int ti_thermal_get_trend(struct thermal_zone_device *thermal,
235 int trip, enum thermal_trend *trend)
236{ 243{
237 struct ti_thermal_data *data = thermal->devdata; 244 struct ti_thermal_data *data = p;
238 struct ti_bandgap *bgp; 245 struct ti_bandgap *bgp;
239 int id, tr, ret = 0; 246 int id, tr, ret = 0;
240 247
@@ -245,6 +252,22 @@ static int ti_thermal_get_trend(struct thermal_zone_device *thermal,
245 if (ret) 252 if (ret)
246 return ret; 253 return ret;
247 254
255 *trend = tr;
256
257 return 0;
258}
259
260/* Get the temperature trend callback functions for thermal zone */
261static int ti_thermal_get_trend(struct thermal_zone_device *thermal,
262 int trip, enum thermal_trend *trend)
263{
264 int ret;
265 long tr;
266
267 ret = __ti_thermal_get_trend(thermal->devdata, &tr);
268 if (ret)
269 return ret;
270
248 if (tr > 0) 271 if (tr > 0)
249 *trend = THERMAL_TREND_RAISING; 272 *trend = THERMAL_TREND_RAISING;
250 else if (tr < 0) 273 else if (tr < 0)
@@ -308,16 +331,23 @@ int ti_thermal_expose_sensor(struct ti_bandgap *bgp, int id,
308 if (!data) 331 if (!data)
309 return -EINVAL; 332 return -EINVAL;
310 333
311 /* Create thermal zone */ 334 /* in case this is specified by DT */
312 data->ti_thermal = thermal_zone_device_register(domain, 335 data->ti_thermal = thermal_zone_of_sensor_register(bgp->dev, id,
336 data, __ti_thermal_get_temp,
337 __ti_thermal_get_trend);
338 if (IS_ERR(data->ti_thermal)) {
339 /* Create thermal zone */
340 data->ti_thermal = thermal_zone_device_register(domain,
313 OMAP_TRIP_NUMBER, 0, data, &ti_thermal_ops, 341 OMAP_TRIP_NUMBER, 0, data, &ti_thermal_ops,
314 NULL, FAST_TEMP_MONITORING_RATE, 342 NULL, FAST_TEMP_MONITORING_RATE,
315 FAST_TEMP_MONITORING_RATE); 343 FAST_TEMP_MONITORING_RATE);
316 if (IS_ERR(data->ti_thermal)) { 344 if (IS_ERR(data->ti_thermal)) {
317 dev_err(bgp->dev, "thermal zone device is NULL\n"); 345 dev_err(bgp->dev, "thermal zone device is NULL\n");
318 return PTR_ERR(data->ti_thermal); 346 return PTR_ERR(data->ti_thermal);
347 }
348 data->ti_thermal->polling_delay = FAST_TEMP_MONITORING_RATE;
349 data->our_zone = true;
319 } 350 }
320 data->ti_thermal->polling_delay = FAST_TEMP_MONITORING_RATE;
321 ti_bandgap_set_sensor_data(bgp, id, data); 351 ti_bandgap_set_sensor_data(bgp, id, data);
322 ti_bandgap_write_update_interval(bgp, data->sensor_id, 352 ti_bandgap_write_update_interval(bgp, data->sensor_id,
323 data->ti_thermal->polling_delay); 353 data->ti_thermal->polling_delay);
@@ -331,7 +361,13 @@ int ti_thermal_remove_sensor(struct ti_bandgap *bgp, int id)
331 361
332 data = ti_bandgap_get_sensor_data(bgp, id); 362 data = ti_bandgap_get_sensor_data(bgp, id);
333 363
334 thermal_zone_device_unregister(data->ti_thermal); 364 if (data && data->ti_thermal) {
365 if (data->our_zone)
366 thermal_zone_device_unregister(data->ti_thermal);
367 else
368 thermal_zone_of_sensor_unregister(bgp->dev,
369 data->ti_thermal);
370 }
335 371
336 return 0; 372 return 0;
337} 373}
@@ -350,6 +386,15 @@ int ti_thermal_report_sensor_temperature(struct ti_bandgap *bgp, int id)
350int ti_thermal_register_cpu_cooling(struct ti_bandgap *bgp, int id) 386int ti_thermal_register_cpu_cooling(struct ti_bandgap *bgp, int id)
351{ 387{
352 struct ti_thermal_data *data; 388 struct ti_thermal_data *data;
389 struct device_node *np = bgp->dev->of_node;
390
391 /*
392 * We are assuming here that if one deploys the zone
393 * using DT, then it must be aware that the cooling device
394 * loading has to happen via cpufreq driver.
395 */
396 if (of_find_property(np, "#thermal-sensor-cells", NULL))
397 return 0;
353 398
354 data = ti_bandgap_get_sensor_data(bgp, id); 399 data = ti_bandgap_get_sensor_data(bgp, id);
355 if (!data || IS_ERR(data)) 400 if (!data || IS_ERR(data))
@@ -380,7 +425,9 @@ int ti_thermal_unregister_cpu_cooling(struct ti_bandgap *bgp, int id)
380 struct ti_thermal_data *data; 425 struct ti_thermal_data *data;
381 426
382 data = ti_bandgap_get_sensor_data(bgp, id); 427 data = ti_bandgap_get_sensor_data(bgp, id);
383 cpufreq_cooling_unregister(data->cool_dev); 428
429 if (data && data->cool_dev)
430 cpufreq_cooling_unregister(data->cool_dev);
384 431
385 return 0; 432 return 0;
386} 433}