diff options
-rw-r--r-- | drivers/thermal/ti-soc-thermal/ti-thermal-common.c | 77 |
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 | ||
49 | static void ti_thermal_work(struct work_struct *work) | 51 | static 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*/ |
78 | static inline int ti_thermal_get_temp(struct thermal_zone_device *thermal, | 80 | static 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 | ||
122 | static 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 */ |
122 | static int ti_thermal_bind(struct thermal_zone_device *thermal, | 131 | static 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 */ | 242 | static int __ti_thermal_get_trend(void *p, long *trend) |
234 | static 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 */ | ||
261 | static 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) | |||
350 | int ti_thermal_register_cpu_cooling(struct ti_bandgap *bgp, int id) | 386 | int 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 | } |