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