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