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