xref: /linux/tools/lib/thermal/thermal.c (revision 364eeb79a213fcf9164208b53764223ad522d6b3)
1 // SPDX-License-Identifier: LGPL-2.1+
2 // Copyright (C) 2022, Linaro Ltd - Daniel Lezcano <daniel.lezcano@linaro.org>
3 #include <stdio.h>
4 #include <limits.h>
5 #include <thermal.h>
6 
7 #include "thermal_nl.h"
8 
9 int for_each_thermal_threshold(struct thermal_threshold *th, cb_th_t cb, void *arg)
10 {
11 	int i, ret = 0;
12 
13 	if (!th)
14 		return 0;
15 
16 	for (i = 0; th[i].temperature != INT_MAX; i++)
17 		ret |= cb(&th[i], arg);
18 
19 	return ret;
20 }
21 
22 int for_each_thermal_cdev(struct thermal_cdev *cdev, cb_tc_t cb, void *arg)
23 {
24 	int i, ret = 0;
25 
26 	if (!cdev)
27 		return 0;
28 
29 	for (i = 0; cdev[i].id != -1; i++)
30 		ret |= cb(&cdev[i], arg);
31 
32 	return ret;
33 }
34 
35 int for_each_thermal_trip(struct thermal_trip *tt, cb_tt_t cb, void *arg)
36 {
37 	int i, ret = 0;
38 
39 	if (!tt)
40 		return 0;
41 
42 	for (i = 0; tt[i].id != -1; i++)
43 		ret |= cb(&tt[i], arg);
44 
45 	return ret;
46 }
47 
48 int for_each_thermal_zone(struct thermal_zone *tz, cb_tz_t cb, void *arg)
49 {
50 	int i, ret = 0;
51 
52 	if (!tz)
53 		return 0;
54 
55 	for (i = 0; tz[i].id != -1; i++)
56 		ret |= cb(&tz[i], arg);
57 
58 	return ret;
59 }
60 
61 struct thermal_zone *thermal_zone_find_by_name(struct thermal_zone *tz,
62 					       const char *name)
63 {
64 	int i;
65 
66 	if (!tz || !name)
67 		return NULL;
68 
69 	for (i = 0; tz[i].id != -1; i++) {
70 		if (!strcmp(tz[i].name, name))
71 			return &tz[i];
72 	}
73 
74 	return NULL;
75 }
76 
77 struct thermal_zone *thermal_zone_find_by_id(struct thermal_zone *tz, int id)
78 {
79 	int i;
80 
81 	if (!tz || id < 0)
82 		return NULL;
83 
84 	for (i = 0; tz[i].id != -1; i++) {
85 		if (tz[i].id == id)
86 			return &tz[i];
87 	}
88 
89 	return NULL;
90 }
91 
92 static int __thermal_zone_discover(struct thermal_zone *tz, void *th)
93 {
94 	if (thermal_cmd_get_trip(th, tz) < 0)
95 		return -1;
96 
97 	if (thermal_cmd_threshold_get(th, tz))
98 		return -1;
99 
100 	if (thermal_cmd_get_governor(th, tz))
101 		return -1;
102 
103 	return 0;
104 }
105 
106 struct thermal_zone *thermal_zone_discover(struct thermal_handler *th)
107 {
108 	struct thermal_zone *tz;
109 
110 	if (thermal_cmd_get_tz(th, &tz) < 0)
111 		return NULL;
112 
113 	if (for_each_thermal_zone(tz, __thermal_zone_discover, th))
114 		return NULL;
115 
116 	return tz;
117 }
118 
119 void thermal_exit(struct thermal_handler *th)
120 {
121 	thermal_cmd_exit(th);
122 	thermal_events_exit(th);
123 	thermal_sampling_exit(th);
124 
125 	free(th);
126 }
127 
128 struct thermal_handler *thermal_init(struct thermal_ops *ops)
129 {
130 	struct thermal_handler *th;
131 
132 	th = malloc(sizeof(*th));
133 	if (!th)
134 		return NULL;
135 	th->ops = ops;
136 
137 	if (thermal_events_init(th))
138 		goto out_free;
139 
140 	if (thermal_sampling_init(th))
141 		goto out_free;
142 
143 	if (thermal_cmd_init(th))
144 		goto out_free;
145 
146 	return th;
147 
148 out_free:
149 	free(th);
150 
151 	return NULL;
152 }
153