Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/evalenti/linux...
[platform/kernel/linux-starfive.git] / drivers / thermal / of-thermal.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  *  of-thermal.c - Generic Thermal Management device tree support.
4  *
5  *  Copyright (C) 2013 Texas Instruments
6  *  Copyright (C) 2013 Eduardo Valentin <eduardo.valentin@ti.com>
7  */
8 #include <linux/thermal.h>
9 #include <linux/slab.h>
10 #include <linux/types.h>
11 #include <linux/of_device.h>
12 #include <linux/of_platform.h>
13 #include <linux/err.h>
14 #include <linux/export.h>
15 #include <linux/string.h>
16
17 #include "thermal_core.h"
18
19 /***   Private data structures to represent thermal device tree data ***/
20
21 /**
22  * struct __thermal_cooling_bind_param - a cooling device for a trip point
23  * @cooling_device: a pointer to identify the referred cooling device
24  * @min: minimum cooling state used at this trip point
25  * @max: maximum cooling state used at this trip point
26  */
27
28 struct __thermal_cooling_bind_param {
29         struct device_node *cooling_device;
30         unsigned long min;
31         unsigned long max;
32 };
33
34 /**
35  * struct __thermal_bind_param - a match between trip and cooling device
36  * @tcbp: a pointer to an array of cooling devices
37  * @count: number of elements in array
38  * @trip_id: the trip point index
39  * @usage: the percentage (from 0 to 100) of cooling contribution
40  */
41
42 struct __thermal_bind_params {
43         struct __thermal_cooling_bind_param *tcbp;
44         unsigned int count;
45         unsigned int trip_id;
46         unsigned int usage;
47 };
48
49 /**
50  * struct __thermal_zone - internal representation of a thermal zone
51  * @mode: current thermal zone device mode (enabled/disabled)
52  * @passive_delay: polling interval while passive cooling is activated
53  * @polling_delay: zone polling interval
54  * @slope: slope of the temperature adjustment curve
55  * @offset: offset of the temperature adjustment curve
56  * @ntrips: number of trip points
57  * @trips: an array of trip points (0..ntrips - 1)
58  * @num_tbps: number of thermal bind params
59  * @tbps: an array of thermal bind params (0..num_tbps - 1)
60  * @sensor_data: sensor private data used while reading temperature and trend
61  * @ops: set of callbacks to handle the thermal zone based on DT
62  */
63
64 struct __thermal_zone {
65         enum thermal_device_mode mode;
66         int passive_delay;
67         int polling_delay;
68         int slope;
69         int offset;
70
71         /* trip data */
72         int ntrips;
73         struct thermal_trip *trips;
74
75         /* cooling binding data */
76         int num_tbps;
77         struct __thermal_bind_params *tbps;
78
79         /* sensor interface */
80         void *sensor_data;
81         const struct thermal_zone_of_device_ops *ops;
82 };
83
84 /***   DT thermal zone device callbacks   ***/
85
86 static int of_thermal_get_temp(struct thermal_zone_device *tz,
87                                int *temp)
88 {
89         struct __thermal_zone *data = tz->devdata;
90
91         if (!data->ops->get_temp)
92                 return -EINVAL;
93
94         return data->ops->get_temp(data->sensor_data, temp);
95 }
96
97 static int of_thermal_set_trips(struct thermal_zone_device *tz,
98                                 int low, int high)
99 {
100         struct __thermal_zone *data = tz->devdata;
101
102         if (!data->ops || !data->ops->set_trips)
103                 return -EINVAL;
104
105         return data->ops->set_trips(data->sensor_data, low, high);
106 }
107
108 /**
109  * of_thermal_get_ntrips - function to export number of available trip
110  *                         points.
111  * @tz: pointer to a thermal zone
112  *
113  * This function is a globally visible wrapper to get number of trip points
114  * stored in the local struct __thermal_zone
115  *
116  * Return: number of available trip points, -ENODEV when data not available
117  */
118 int of_thermal_get_ntrips(struct thermal_zone_device *tz)
119 {
120         struct __thermal_zone *data = tz->devdata;
121
122         if (!data || IS_ERR(data))
123                 return -ENODEV;
124
125         return data->ntrips;
126 }
127 EXPORT_SYMBOL_GPL(of_thermal_get_ntrips);
128
129 /**
130  * of_thermal_is_trip_valid - function to check if trip point is valid
131  *
132  * @tz: pointer to a thermal zone
133  * @trip:       trip point to evaluate
134  *
135  * This function is responsible for checking if passed trip point is valid
136  *
137  * Return: true if trip point is valid, false otherwise
138  */
139 bool of_thermal_is_trip_valid(struct thermal_zone_device *tz, int trip)
140 {
141         struct __thermal_zone *data = tz->devdata;
142
143         if (!data || trip >= data->ntrips || trip < 0)
144                 return false;
145
146         return true;
147 }
148 EXPORT_SYMBOL_GPL(of_thermal_is_trip_valid);
149
150 /**
151  * of_thermal_get_trip_points - function to get access to a globally exported
152  *                              trip points
153  *
154  * @tz: pointer to a thermal zone
155  *
156  * This function provides a pointer to trip points table
157  *
158  * Return: pointer to trip points table, NULL otherwise
159  */
160 const struct thermal_trip *
161 of_thermal_get_trip_points(struct thermal_zone_device *tz)
162 {
163         struct __thermal_zone *data = tz->devdata;
164
165         if (!data)
166                 return NULL;
167
168         return data->trips;
169 }
170 EXPORT_SYMBOL_GPL(of_thermal_get_trip_points);
171
172 /**
173  * of_thermal_set_emul_temp - function to set emulated temperature
174  *
175  * @tz: pointer to a thermal zone
176  * @temp:       temperature to set
177  *
178  * This function gives the ability to set emulated value of temperature,
179  * which is handy for debugging
180  *
181  * Return: zero on success, error code otherwise
182  */
183 static int of_thermal_set_emul_temp(struct thermal_zone_device *tz,
184                                     int temp)
185 {
186         struct __thermal_zone *data = tz->devdata;
187
188         return data->ops->set_emul_temp(data->sensor_data, temp);
189 }
190
191 static int of_thermal_get_trend(struct thermal_zone_device *tz, int trip,
192                                 enum thermal_trend *trend)
193 {
194         struct __thermal_zone *data = tz->devdata;
195
196         if (!data->ops->get_trend)
197                 return -EINVAL;
198
199         return data->ops->get_trend(data->sensor_data, trip, trend);
200 }
201
202 static int of_thermal_bind(struct thermal_zone_device *thermal,
203                            struct thermal_cooling_device *cdev)
204 {
205         struct __thermal_zone *data = thermal->devdata;
206         struct __thermal_bind_params *tbp;
207         struct __thermal_cooling_bind_param *tcbp;
208         int i, j;
209
210         if (!data || IS_ERR(data))
211                 return -ENODEV;
212
213         /* find where to bind */
214         for (i = 0; i < data->num_tbps; i++) {
215                 tbp = data->tbps + i;
216
217                 for (j = 0; j < tbp->count; j++) {
218                         tcbp = tbp->tcbp + j;
219
220                         if (tcbp->cooling_device == cdev->np) {
221                                 int ret;
222
223                                 ret = thermal_zone_bind_cooling_device(thermal,
224                                                 tbp->trip_id, cdev,
225                                                 tcbp->max,
226                                                 tcbp->min,
227                                                 tbp->usage);
228                                 if (ret)
229                                         return ret;
230                         }
231                 }
232         }
233
234         return 0;
235 }
236
237 static int of_thermal_unbind(struct thermal_zone_device *thermal,
238                              struct thermal_cooling_device *cdev)
239 {
240         struct __thermal_zone *data = thermal->devdata;
241         struct __thermal_bind_params *tbp;
242         struct __thermal_cooling_bind_param *tcbp;
243         int i, j;
244
245         if (!data || IS_ERR(data))
246                 return -ENODEV;
247
248         /* find where to unbind */
249         for (i = 0; i < data->num_tbps; i++) {
250                 tbp = data->tbps + i;
251
252                 for (j = 0; j < tbp->count; j++) {
253                         tcbp = tbp->tcbp + j;
254
255                         if (tcbp->cooling_device == cdev->np) {
256                                 int ret;
257
258                                 ret = thermal_zone_unbind_cooling_device(thermal,
259                                                         tbp->trip_id, cdev);
260                                 if (ret)
261                                         return ret;
262                         }
263                 }
264         }
265
266         return 0;
267 }
268
269 static int of_thermal_get_mode(struct thermal_zone_device *tz,
270                                enum thermal_device_mode *mode)
271 {
272         struct __thermal_zone *data = tz->devdata;
273
274         *mode = data->mode;
275
276         return 0;
277 }
278
279 static int of_thermal_set_mode(struct thermal_zone_device *tz,
280                                enum thermal_device_mode mode)
281 {
282         struct __thermal_zone *data = tz->devdata;
283
284         mutex_lock(&tz->lock);
285
286         if (mode == THERMAL_DEVICE_ENABLED) {
287                 tz->polling_delay = data->polling_delay;
288                 tz->passive_delay = data->passive_delay;
289         } else {
290                 tz->polling_delay = 0;
291                 tz->passive_delay = 0;
292         }
293
294         mutex_unlock(&tz->lock);
295
296         data->mode = mode;
297         thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
298
299         return 0;
300 }
301
302 static int of_thermal_get_trip_type(struct thermal_zone_device *tz, int trip,
303                                     enum thermal_trip_type *type)
304 {
305         struct __thermal_zone *data = tz->devdata;
306
307         if (trip >= data->ntrips || trip < 0)
308                 return -EDOM;
309
310         *type = data->trips[trip].type;
311
312         return 0;
313 }
314
315 static int of_thermal_get_trip_temp(struct thermal_zone_device *tz, int trip,
316                                     int *temp)
317 {
318         struct __thermal_zone *data = tz->devdata;
319
320         if (trip >= data->ntrips || trip < 0)
321                 return -EDOM;
322
323         *temp = data->trips[trip].temperature;
324
325         return 0;
326 }
327
328 static int of_thermal_set_trip_temp(struct thermal_zone_device *tz, int trip,
329                                     int temp)
330 {
331         struct __thermal_zone *data = tz->devdata;
332
333         if (trip >= data->ntrips || trip < 0)
334                 return -EDOM;
335
336         if (data->ops->set_trip_temp) {
337                 int ret;
338
339                 ret = data->ops->set_trip_temp(data->sensor_data, trip, temp);
340                 if (ret)
341                         return ret;
342         }
343
344         /* thermal framework should take care of data->mask & (1 << trip) */
345         data->trips[trip].temperature = temp;
346
347         return 0;
348 }
349
350 static int of_thermal_get_trip_hyst(struct thermal_zone_device *tz, int trip,
351                                     int *hyst)
352 {
353         struct __thermal_zone *data = tz->devdata;
354
355         if (trip >= data->ntrips || trip < 0)
356                 return -EDOM;
357
358         *hyst = data->trips[trip].hysteresis;
359
360         return 0;
361 }
362
363 static int of_thermal_set_trip_hyst(struct thermal_zone_device *tz, int trip,
364                                     int hyst)
365 {
366         struct __thermal_zone *data = tz->devdata;
367
368         if (trip >= data->ntrips || trip < 0)
369                 return -EDOM;
370
371         /* thermal framework should take care of data->mask & (1 << trip) */
372         data->trips[trip].hysteresis = hyst;
373
374         return 0;
375 }
376
377 static int of_thermal_get_crit_temp(struct thermal_zone_device *tz,
378                                     int *temp)
379 {
380         struct __thermal_zone *data = tz->devdata;
381         int i;
382
383         for (i = 0; i < data->ntrips; i++)
384                 if (data->trips[i].type == THERMAL_TRIP_CRITICAL) {
385                         *temp = data->trips[i].temperature;
386                         return 0;
387                 }
388
389         return -EINVAL;
390 }
391
392 static struct thermal_zone_device_ops of_thermal_ops = {
393         .get_mode = of_thermal_get_mode,
394         .set_mode = of_thermal_set_mode,
395
396         .get_trip_type = of_thermal_get_trip_type,
397         .get_trip_temp = of_thermal_get_trip_temp,
398         .set_trip_temp = of_thermal_set_trip_temp,
399         .get_trip_hyst = of_thermal_get_trip_hyst,
400         .set_trip_hyst = of_thermal_set_trip_hyst,
401         .get_crit_temp = of_thermal_get_crit_temp,
402
403         .bind = of_thermal_bind,
404         .unbind = of_thermal_unbind,
405 };
406
407 /***   sensor API   ***/
408
409 static struct thermal_zone_device *
410 thermal_zone_of_add_sensor(struct device_node *zone,
411                            struct device_node *sensor, void *data,
412                            const struct thermal_zone_of_device_ops *ops)
413 {
414         struct thermal_zone_device *tzd;
415         struct __thermal_zone *tz;
416
417         tzd = thermal_zone_get_zone_by_name(zone->name);
418         if (IS_ERR(tzd))
419                 return ERR_PTR(-EPROBE_DEFER);
420
421         tz = tzd->devdata;
422
423         if (!ops)
424                 return ERR_PTR(-EINVAL);
425
426         mutex_lock(&tzd->lock);
427         tz->ops = ops;
428         tz->sensor_data = data;
429
430         tzd->ops->get_temp = of_thermal_get_temp;
431         tzd->ops->get_trend = of_thermal_get_trend;
432
433         /*
434          * The thermal zone core will calculate the window if they have set the
435          * optional set_trips pointer.
436          */
437         if (ops->set_trips)
438                 tzd->ops->set_trips = of_thermal_set_trips;
439
440         if (ops->set_emul_temp)
441                 tzd->ops->set_emul_temp = of_thermal_set_emul_temp;
442
443         mutex_unlock(&tzd->lock);
444
445         return tzd;
446 }
447
448 /**
449  * thermal_zone_of_sensor_register - registers a sensor to a DT thermal zone
450  * @dev: a valid struct device pointer of a sensor device. Must contain
451  *       a valid .of_node, for the sensor node.
452  * @sensor_id: a sensor identifier, in case the sensor IP has more
453  *             than one sensors
454  * @data: a private pointer (owned by the caller) that will be passed
455  *        back, when a temperature reading is needed.
456  * @ops: struct thermal_zone_of_device_ops *. Must contain at least .get_temp.
457  *
458  * This function will search the list of thermal zones described in device
459  * tree and look for the zone that refer to the sensor device pointed by
460  * @dev->of_node as temperature providers. For the zone pointing to the
461  * sensor node, the sensor will be added to the DT thermal zone device.
462  *
463  * The thermal zone temperature is provided by the @get_temp function
464  * pointer. When called, it will have the private pointer @data back.
465  *
466  * The thermal zone temperature trend is provided by the @get_trend function
467  * pointer. When called, it will have the private pointer @data back.
468  *
469  * TODO:
470  * 01 - This function must enqueue the new sensor instead of using
471  * it as the only source of temperature values.
472  *
473  * 02 - There must be a way to match the sensor with all thermal zones
474  * that refer to it.
475  *
476  * Return: On success returns a valid struct thermal_zone_device,
477  * otherwise, it returns a corresponding ERR_PTR(). Caller must
478  * check the return value with help of IS_ERR() helper.
479  */
480 struct thermal_zone_device *
481 thermal_zone_of_sensor_register(struct device *dev, int sensor_id, void *data,
482                                 const struct thermal_zone_of_device_ops *ops)
483 {
484         struct device_node *np, *child, *sensor_np;
485         struct thermal_zone_device *tzd = ERR_PTR(-ENODEV);
486
487         np = of_find_node_by_name(NULL, "thermal-zones");
488         if (!np)
489                 return ERR_PTR(-ENODEV);
490
491         if (!dev || !dev->of_node) {
492                 of_node_put(np);
493                 return ERR_PTR(-EINVAL);
494         }
495
496         sensor_np = of_node_get(dev->of_node);
497
498         for_each_available_child_of_node(np, child) {
499                 struct of_phandle_args sensor_specs;
500                 int ret, id;
501
502                 /* For now, thermal framework supports only 1 sensor per zone */
503                 ret = of_parse_phandle_with_args(child, "thermal-sensors",
504                                                  "#thermal-sensor-cells",
505                                                  0, &sensor_specs);
506                 if (ret)
507                         continue;
508
509                 if (sensor_specs.args_count >= 1) {
510                         id = sensor_specs.args[0];
511                         WARN(sensor_specs.args_count > 1,
512                              "%pOFn: too many cells in sensor specifier %d\n",
513                              sensor_specs.np, sensor_specs.args_count);
514                 } else {
515                         id = 0;
516                 }
517
518                 if (sensor_specs.np == sensor_np && id == sensor_id) {
519                         tzd = thermal_zone_of_add_sensor(child, sensor_np,
520                                                          data, ops);
521                         if (!IS_ERR(tzd))
522                                 tzd->ops->set_mode(tzd, THERMAL_DEVICE_ENABLED);
523
524                         of_node_put(sensor_specs.np);
525                         of_node_put(child);
526                         goto exit;
527                 }
528                 of_node_put(sensor_specs.np);
529         }
530 exit:
531         of_node_put(sensor_np);
532         of_node_put(np);
533
534         return tzd;
535 }
536 EXPORT_SYMBOL_GPL(thermal_zone_of_sensor_register);
537
538 /**
539  * thermal_zone_of_sensor_unregister - unregisters a sensor from a DT thermal zone
540  * @dev: a valid struct device pointer of a sensor device. Must contain
541  *       a valid .of_node, for the sensor node.
542  * @tzd: a pointer to struct thermal_zone_device where the sensor is registered.
543  *
544  * This function removes the sensor callbacks and private data from the
545  * thermal zone device registered with thermal_zone_of_sensor_register()
546  * API. It will also silent the zone by remove the .get_temp() and .get_trend()
547  * thermal zone device callbacks.
548  *
549  * TODO: When the support to several sensors per zone is added, this
550  * function must search the sensor list based on @dev parameter.
551  *
552  */
553 void thermal_zone_of_sensor_unregister(struct device *dev,
554                                        struct thermal_zone_device *tzd)
555 {
556         struct __thermal_zone *tz;
557
558         if (!dev || !tzd || !tzd->devdata)
559                 return;
560
561         tz = tzd->devdata;
562
563         /* no __thermal_zone, nothing to be done */
564         if (!tz)
565                 return;
566
567         mutex_lock(&tzd->lock);
568         tzd->ops->get_temp = NULL;
569         tzd->ops->get_trend = NULL;
570         tzd->ops->set_emul_temp = NULL;
571
572         tz->ops = NULL;
573         tz->sensor_data = NULL;
574         mutex_unlock(&tzd->lock);
575 }
576 EXPORT_SYMBOL_GPL(thermal_zone_of_sensor_unregister);
577
578 static void devm_thermal_zone_of_sensor_release(struct device *dev, void *res)
579 {
580         thermal_zone_of_sensor_unregister(dev,
581                                           *(struct thermal_zone_device **)res);
582 }
583
584 static int devm_thermal_zone_of_sensor_match(struct device *dev, void *res,
585                                              void *data)
586 {
587         struct thermal_zone_device **r = res;
588
589         if (WARN_ON(!r || !*r))
590                 return 0;
591
592         return *r == data;
593 }
594
595 /**
596  * devm_thermal_zone_of_sensor_register - Resource managed version of
597  *                              thermal_zone_of_sensor_register()
598  * @dev: a valid struct device pointer of a sensor device. Must contain
599  *       a valid .of_node, for the sensor node.
600  * @sensor_id: a sensor identifier, in case the sensor IP has more
601  *             than one sensors
602  * @data: a private pointer (owned by the caller) that will be passed
603  *        back, when a temperature reading is needed.
604  * @ops: struct thermal_zone_of_device_ops *. Must contain at least .get_temp.
605  *
606  * Refer thermal_zone_of_sensor_register() for more details.
607  *
608  * Return: On success returns a valid struct thermal_zone_device,
609  * otherwise, it returns a corresponding ERR_PTR(). Caller must
610  * check the return value with help of IS_ERR() helper.
611  * Registered thermal_zone_device device will automatically be
612  * released when device is unbounded.
613  */
614 struct thermal_zone_device *devm_thermal_zone_of_sensor_register(
615         struct device *dev, int sensor_id,
616         void *data, const struct thermal_zone_of_device_ops *ops)
617 {
618         struct thermal_zone_device **ptr, *tzd;
619
620         ptr = devres_alloc(devm_thermal_zone_of_sensor_release, sizeof(*ptr),
621                            GFP_KERNEL);
622         if (!ptr)
623                 return ERR_PTR(-ENOMEM);
624
625         tzd = thermal_zone_of_sensor_register(dev, sensor_id, data, ops);
626         if (IS_ERR(tzd)) {
627                 devres_free(ptr);
628                 return tzd;
629         }
630
631         *ptr = tzd;
632         devres_add(dev, ptr);
633
634         return tzd;
635 }
636 EXPORT_SYMBOL_GPL(devm_thermal_zone_of_sensor_register);
637
638 /**
639  * devm_thermal_zone_of_sensor_unregister - Resource managed version of
640  *                              thermal_zone_of_sensor_unregister().
641  * @dev: Device for which which resource was allocated.
642  * @tzd: a pointer to struct thermal_zone_device where the sensor is registered.
643  *
644  * This function removes the sensor callbacks and private data from the
645  * thermal zone device registered with devm_thermal_zone_of_sensor_register()
646  * API. It will also silent the zone by remove the .get_temp() and .get_trend()
647  * thermal zone device callbacks.
648  * Normally this function will not need to be called and the resource
649  * management code will ensure that the resource is freed.
650  */
651 void devm_thermal_zone_of_sensor_unregister(struct device *dev,
652                                             struct thermal_zone_device *tzd)
653 {
654         WARN_ON(devres_release(dev, devm_thermal_zone_of_sensor_release,
655                                devm_thermal_zone_of_sensor_match, tzd));
656 }
657 EXPORT_SYMBOL_GPL(devm_thermal_zone_of_sensor_unregister);
658
659 /***   functions parsing device tree nodes   ***/
660
661 /**
662  * thermal_of_populate_bind_params - parse and fill cooling map data
663  * @np: DT node containing a cooling-map node
664  * @__tbp: data structure to be filled with cooling map info
665  * @trips: array of thermal zone trip points
666  * @ntrips: number of trip points inside trips.
667  *
668  * This function parses a cooling-map type of node represented by
669  * @np parameter and fills the read data into @__tbp data structure.
670  * It needs the already parsed array of trip points of the thermal zone
671  * in consideration.
672  *
673  * Return: 0 on success, proper error code otherwise
674  */
675 static int thermal_of_populate_bind_params(struct device_node *np,
676                                            struct __thermal_bind_params *__tbp,
677                                            struct thermal_trip *trips,
678                                            int ntrips)
679 {
680         struct of_phandle_args cooling_spec;
681         struct __thermal_cooling_bind_param *__tcbp;
682         struct device_node *trip;
683         int ret, i, count;
684         u32 prop;
685
686         /* Default weight. Usage is optional */
687         __tbp->usage = THERMAL_WEIGHT_DEFAULT;
688         ret = of_property_read_u32(np, "contribution", &prop);
689         if (ret == 0)
690                 __tbp->usage = prop;
691
692         trip = of_parse_phandle(np, "trip", 0);
693         if (!trip) {
694                 pr_err("missing trip property\n");
695                 return -ENODEV;
696         }
697
698         /* match using device_node */
699         for (i = 0; i < ntrips; i++)
700                 if (trip == trips[i].np) {
701                         __tbp->trip_id = i;
702                         break;
703                 }
704
705         if (i == ntrips) {
706                 ret = -ENODEV;
707                 goto end;
708         }
709
710         count = of_count_phandle_with_args(np, "cooling-device",
711                                            "#cooling-cells");
712         if (!count) {
713                 pr_err("Add a cooling_device property with at least one device\n");
714                 goto end;
715         }
716
717         __tcbp = kcalloc(count, sizeof(*__tcbp), GFP_KERNEL);
718         if (!__tcbp)
719                 goto end;
720
721         for (i = 0; i < count; i++) {
722                 ret = of_parse_phandle_with_args(np, "cooling-device",
723                                 "#cooling-cells", i, &cooling_spec);
724                 if (ret < 0) {
725                         pr_err("Invalid cooling-device entry\n");
726                         goto free_tcbp;
727                 }
728
729                 __tcbp[i].cooling_device = cooling_spec.np;
730
731                 if (cooling_spec.args_count >= 2) { /* at least min and max */
732                         __tcbp[i].min = cooling_spec.args[0];
733                         __tcbp[i].max = cooling_spec.args[1];
734                 } else {
735                         pr_err("wrong reference to cooling device, missing limits\n");
736                 }
737         }
738
739         __tbp->tcbp = __tcbp;
740         __tbp->count = count;
741
742         goto end;
743
744 free_tcbp:
745         for (i = i - 1; i >= 0; i--)
746                 of_node_put(__tcbp[i].cooling_device);
747         kfree(__tcbp);
748 end:
749         of_node_put(trip);
750
751         return ret;
752 }
753
754 /**
755  * It maps 'enum thermal_trip_type' found in include/linux/thermal.h
756  * into the device tree binding of 'trip', property type.
757  */
758 static const char * const trip_types[] = {
759         [THERMAL_TRIP_ACTIVE]   = "active",
760         [THERMAL_TRIP_PASSIVE]  = "passive",
761         [THERMAL_TRIP_HOT]      = "hot",
762         [THERMAL_TRIP_CRITICAL] = "critical",
763 };
764
765 /**
766  * thermal_of_get_trip_type - Get phy mode for given device_node
767  * @np: Pointer to the given device_node
768  * @type: Pointer to resulting trip type
769  *
770  * The function gets trip type string from property 'type',
771  * and store its index in trip_types table in @type,
772  *
773  * Return: 0 on success, or errno in error case.
774  */
775 static int thermal_of_get_trip_type(struct device_node *np,
776                                     enum thermal_trip_type *type)
777 {
778         const char *t;
779         int err, i;
780
781         err = of_property_read_string(np, "type", &t);
782         if (err < 0)
783                 return err;
784
785         for (i = 0; i < ARRAY_SIZE(trip_types); i++)
786                 if (!strcasecmp(t, trip_types[i])) {
787                         *type = i;
788                         return 0;
789                 }
790
791         return -ENODEV;
792 }
793
794 /**
795  * thermal_of_populate_trip - parse and fill one trip point data
796  * @np: DT node containing a trip point node
797  * @trip: trip point data structure to be filled up
798  *
799  * This function parses a trip point type of node represented by
800  * @np parameter and fills the read data into @trip data structure.
801  *
802  * Return: 0 on success, proper error code otherwise
803  */
804 static int thermal_of_populate_trip(struct device_node *np,
805                                     struct thermal_trip *trip)
806 {
807         int prop;
808         int ret;
809
810         ret = of_property_read_u32(np, "temperature", &prop);
811         if (ret < 0) {
812                 pr_err("missing temperature property\n");
813                 return ret;
814         }
815         trip->temperature = prop;
816
817         ret = of_property_read_u32(np, "hysteresis", &prop);
818         if (ret < 0) {
819                 pr_err("missing hysteresis property\n");
820                 return ret;
821         }
822         trip->hysteresis = prop;
823
824         ret = thermal_of_get_trip_type(np, &trip->type);
825         if (ret < 0) {
826                 pr_err("wrong trip type property\n");
827                 return ret;
828         }
829
830         /* Required for cooling map matching */
831         trip->np = np;
832         of_node_get(np);
833
834         return 0;
835 }
836
837 /**
838  * thermal_of_build_thermal_zone - parse and fill one thermal zone data
839  * @np: DT node containing a thermal zone node
840  *
841  * This function parses a thermal zone type of node represented by
842  * @np parameter and fills the read data into a __thermal_zone data structure
843  * and return this pointer.
844  *
845  * TODO: Missing properties to parse: thermal-sensor-names
846  *
847  * Return: On success returns a valid struct __thermal_zone,
848  * otherwise, it returns a corresponding ERR_PTR(). Caller must
849  * check the return value with help of IS_ERR() helper.
850  */
851 static struct __thermal_zone
852 __init *thermal_of_build_thermal_zone(struct device_node *np)
853 {
854         struct device_node *child = NULL, *gchild;
855         struct __thermal_zone *tz;
856         int ret, i;
857         u32 prop, coef[2];
858
859         if (!np) {
860                 pr_err("no thermal zone np\n");
861                 return ERR_PTR(-EINVAL);
862         }
863
864         tz = kzalloc(sizeof(*tz), GFP_KERNEL);
865         if (!tz)
866                 return ERR_PTR(-ENOMEM);
867
868         ret = of_property_read_u32(np, "polling-delay-passive", &prop);
869         if (ret < 0) {
870                 pr_err("missing polling-delay-passive property\n");
871                 goto free_tz;
872         }
873         tz->passive_delay = prop;
874
875         ret = of_property_read_u32(np, "polling-delay", &prop);
876         if (ret < 0) {
877                 pr_err("missing polling-delay property\n");
878                 goto free_tz;
879         }
880         tz->polling_delay = prop;
881
882         /*
883          * REVIST: for now, the thermal framework supports only
884          * one sensor per thermal zone. Thus, we are considering
885          * only the first two values as slope and offset.
886          */
887         ret = of_property_read_u32_array(np, "coefficients", coef, 2);
888         if (ret == 0) {
889                 tz->slope = coef[0];
890                 tz->offset = coef[1];
891         } else {
892                 tz->slope = 1;
893                 tz->offset = 0;
894         }
895
896         /* trips */
897         child = of_get_child_by_name(np, "trips");
898
899         /* No trips provided */
900         if (!child)
901                 goto finish;
902
903         tz->ntrips = of_get_child_count(child);
904         if (tz->ntrips == 0) /* must have at least one child */
905                 goto finish;
906
907         tz->trips = kcalloc(tz->ntrips, sizeof(*tz->trips), GFP_KERNEL);
908         if (!tz->trips) {
909                 ret = -ENOMEM;
910                 goto free_tz;
911         }
912
913         i = 0;
914         for_each_child_of_node(child, gchild) {
915                 ret = thermal_of_populate_trip(gchild, &tz->trips[i++]);
916                 if (ret)
917                         goto free_trips;
918         }
919
920         of_node_put(child);
921
922         /* cooling-maps */
923         child = of_get_child_by_name(np, "cooling-maps");
924
925         /* cooling-maps not provided */
926         if (!child)
927                 goto finish;
928
929         tz->num_tbps = of_get_child_count(child);
930         if (tz->num_tbps == 0)
931                 goto finish;
932
933         tz->tbps = kcalloc(tz->num_tbps, sizeof(*tz->tbps), GFP_KERNEL);
934         if (!tz->tbps) {
935                 ret = -ENOMEM;
936                 goto free_trips;
937         }
938
939         i = 0;
940         for_each_child_of_node(child, gchild) {
941                 ret = thermal_of_populate_bind_params(gchild, &tz->tbps[i++],
942                                                       tz->trips, tz->ntrips);
943                 if (ret)
944                         goto free_tbps;
945         }
946
947 finish:
948         of_node_put(child);
949         tz->mode = THERMAL_DEVICE_DISABLED;
950
951         return tz;
952
953 free_tbps:
954         for (i = i - 1; i >= 0; i--) {
955                 struct __thermal_bind_params *tbp = tz->tbps + i;
956                 int j;
957
958                 for (j = 0; j < tbp->count; j++)
959                         of_node_put(tbp->tcbp[j].cooling_device);
960
961                 kfree(tbp->tcbp);
962         }
963
964         kfree(tz->tbps);
965 free_trips:
966         for (i = 0; i < tz->ntrips; i++)
967                 of_node_put(tz->trips[i].np);
968         kfree(tz->trips);
969         of_node_put(gchild);
970 free_tz:
971         kfree(tz);
972         of_node_put(child);
973
974         return ERR_PTR(ret);
975 }
976
977 static inline void of_thermal_free_zone(struct __thermal_zone *tz)
978 {
979         struct __thermal_bind_params *tbp;
980         int i, j;
981
982         for (i = 0; i < tz->num_tbps; i++) {
983                 tbp = tz->tbps + i;
984
985                 for (j = 0; j < tbp->count; j++)
986                         of_node_put(tbp->tcbp[j].cooling_device);
987
988                 kfree(tbp->tcbp);
989         }
990
991         kfree(tz->tbps);
992         for (i = 0; i < tz->ntrips; i++)
993                 of_node_put(tz->trips[i].np);
994         kfree(tz->trips);
995         kfree(tz);
996 }
997
998 /**
999  * of_parse_thermal_zones - parse device tree thermal data
1000  *
1001  * Initialization function that can be called by machine initialization
1002  * code to parse thermal data and populate the thermal framework
1003  * with hardware thermal zones info. This function only parses thermal zones.
1004  * Cooling devices and sensor devices nodes are supposed to be parsed
1005  * by their respective drivers.
1006  *
1007  * Return: 0 on success, proper error code otherwise
1008  *
1009  */
1010 int __init of_parse_thermal_zones(void)
1011 {
1012         struct device_node *np, *child;
1013         struct __thermal_zone *tz;
1014         struct thermal_zone_device_ops *ops;
1015
1016         np = of_find_node_by_name(NULL, "thermal-zones");
1017         if (!np) {
1018                 pr_debug("unable to find thermal zones\n");
1019                 return 0; /* Run successfully on systems without thermal DT */
1020         }
1021
1022         for_each_available_child_of_node(np, child) {
1023                 struct thermal_zone_device *zone;
1024                 struct thermal_zone_params *tzp;
1025                 int i, mask = 0;
1026                 u32 prop;
1027
1028                 tz = thermal_of_build_thermal_zone(child);
1029                 if (IS_ERR(tz)) {
1030                         pr_err("failed to build thermal zone %pOFn: %ld\n",
1031                                child,
1032                                PTR_ERR(tz));
1033                         continue;
1034                 }
1035
1036                 ops = kmemdup(&of_thermal_ops, sizeof(*ops), GFP_KERNEL);
1037                 if (!ops)
1038                         goto exit_free;
1039
1040                 tzp = kzalloc(sizeof(*tzp), GFP_KERNEL);
1041                 if (!tzp) {
1042                         kfree(ops);
1043                         goto exit_free;
1044                 }
1045
1046                 /* No hwmon because there might be hwmon drivers registering */
1047                 tzp->no_hwmon = true;
1048
1049                 if (!of_property_read_u32(child, "sustainable-power", &prop))
1050                         tzp->sustainable_power = prop;
1051
1052                 for (i = 0; i < tz->ntrips; i++)
1053                         mask |= 1 << i;
1054
1055                 /* these two are left for temperature drivers to use */
1056                 tzp->slope = tz->slope;
1057                 tzp->offset = tz->offset;
1058
1059                 zone = thermal_zone_device_register(child->name, tz->ntrips,
1060                                                     mask, tz,
1061                                                     ops, tzp,
1062                                                     tz->passive_delay,
1063                                                     tz->polling_delay);
1064                 if (IS_ERR(zone)) {
1065                         pr_err("Failed to build %pOFn zone %ld\n", child,
1066                                PTR_ERR(zone));
1067                         kfree(tzp);
1068                         kfree(ops);
1069                         of_thermal_free_zone(tz);
1070                         /* attempting to build remaining zones still */
1071                 }
1072         }
1073         of_node_put(np);
1074
1075         return 0;
1076
1077 exit_free:
1078         of_node_put(child);
1079         of_node_put(np);
1080         of_thermal_free_zone(tz);
1081
1082         /* no memory available, so free what we have built */
1083         of_thermal_destroy_zones();
1084
1085         return -ENOMEM;
1086 }
1087
1088 /**
1089  * of_thermal_destroy_zones - remove all zones parsed and allocated resources
1090  *
1091  * Finds all zones parsed and added to the thermal framework and remove them
1092  * from the system, together with their resources.
1093  *
1094  */
1095 void of_thermal_destroy_zones(void)
1096 {
1097         struct device_node *np, *child;
1098
1099         np = of_find_node_by_name(NULL, "thermal-zones");
1100         if (!np) {
1101                 pr_debug("unable to find thermal zones\n");
1102                 return;
1103         }
1104
1105         for_each_available_child_of_node(np, child) {
1106                 struct thermal_zone_device *zone;
1107
1108                 zone = thermal_zone_get_zone_by_name(child->name);
1109                 if (IS_ERR(zone))
1110                         continue;
1111
1112                 thermal_zone_device_unregister(zone);
1113                 kfree(zone->tzp);
1114                 kfree(zone->ops);
1115                 of_thermal_free_zone(zone->devdata);
1116         }
1117         of_node_put(np);
1118 }