Commit | Line | Data |
---|---|---|
7e3c0381 | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
203d3d4a ZR |
2 | /* |
3 | * thermal.h ($Revision: 0 $) | |
4 | * | |
5 | * Copyright (C) 2008 Intel Corp | |
6 | * Copyright (C) 2008 Zhang Rui <rui.zhang@intel.com> | |
7 | * Copyright (C) 2008 Sujith Thomas <sujith.thomas@intel.com> | |
203d3d4a ZR |
8 | */ |
9 | ||
10 | #ifndef __THERMAL_H__ | |
11 | #define __THERMAL_H__ | |
12 | ||
a116b5d4 | 13 | #include <linux/of.h> |
203d3d4a ZR |
14 | #include <linux/idr.h> |
15 | #include <linux/device.h> | |
4d0fe749 | 16 | #include <linux/sysfs.h> |
b1569e99 | 17 | #include <linux/workqueue.h> |
af6c9f16 | 18 | #include <uapi/linux/thermal.h> |
203d3d4a | 19 | |
57df8106 ZR |
20 | /* invalid cooling state */ |
21 | #define THERMAL_CSTATE_INVALID -1UL | |
22 | ||
23064088 | 23 | /* No upper/lower limit requirement */ |
a940cb34 | 24 | #define THERMAL_NO_LIMIT ((u32)~0) |
23064088 | 25 | |
6cd9e9f6 KS |
26 | /* Default weight of a bound cooling device */ |
27 | #define THERMAL_WEIGHT_DEFAULT 0 | |
28 | ||
bb431ba2 ZR |
29 | /* use value, which < 0K, to indicate an invalid/uninitialized temperature */ |
30 | #define THERMAL_TEMP_INVALID -274000 | |
31 | ||
203d3d4a ZR |
32 | struct thermal_zone_device; |
33 | struct thermal_cooling_device; | |
35b11d2e | 34 | struct thermal_instance; |
755113d7 | 35 | struct thermal_debugfs; |
c68df440 | 36 | struct thermal_attr; |
203d3d4a | 37 | |
601f3d42 ZR |
38 | enum thermal_trend { |
39 | THERMAL_TREND_STABLE, /* temperature is stable */ | |
40 | THERMAL_TREND_RAISING, /* temperature is raising */ | |
41 | THERMAL_TREND_DROPPING, /* temperature is dropping */ | |
42 | }; | |
43 | ||
0e70f466 SP |
44 | /* Thermal notification reason */ |
45 | enum thermal_notify_event { | |
46 | THERMAL_EVENT_UNSPECIFIED, /* Unspecified event */ | |
47 | THERMAL_EVENT_TEMP_SAMPLE, /* New Temperature sample */ | |
48 | THERMAL_TRIP_VIOLATED, /* TRIP Point violation */ | |
49 | THERMAL_TRIP_CHANGED, /* TRIP Point temperature changed */ | |
50 | THERMAL_DEVICE_DOWN, /* Thermal device is down */ | |
51 | THERMAL_DEVICE_UP, /* Thermal device is up after a down event */ | |
52 | THERMAL_DEVICE_POWER_CAPABILITY_CHANGED, /* power capability changed */ | |
38e44da5 | 53 | THERMAL_TABLE_CHANGED, /* Thermal table(s) changed */ |
88052319 | 54 | THERMAL_EVENT_KEEP_ALIVE, /* Request for user space handler to respond */ |
a8c95940 LL |
55 | THERMAL_TZ_BIND_CDEV, /* Cooling dev is bind to the thermal zone */ |
56 | THERMAL_TZ_UNBIND_CDEV, /* Cooling dev is unbind from the thermal zone */ | |
bfc57bd1 | 57 | THERMAL_INSTANCE_WEIGHT_CHANGED, /* Thermal instance weight changed */ |
6e6f58a1 | 58 | THERMAL_TZ_RESUME, /* Thermal zone is resuming after system sleep */ |
0e70f466 SP |
59 | }; |
60 | ||
8289d810 RW |
61 | /** |
62 | * struct thermal_trip - representation of a point in temperature domain | |
63 | * @temperature: temperature value in miliCelsius | |
64 | * @hysteresis: relative hysteresis in miliCelsius | |
65 | * @type: trip point type | |
66 | * @priv: pointer to driver data associated with this trip | |
5340f764 | 67 | * @flags: flags representing binary properties of the trip |
8289d810 RW |
68 | */ |
69 | struct thermal_trip { | |
70 | int temperature; | |
71 | int hysteresis; | |
72 | enum thermal_trip_type type; | |
5340f764 | 73 | u8 flags; |
8289d810 RW |
74 | void *priv; |
75 | }; | |
76 | ||
5340f764 RW |
77 | #define THERMAL_TRIP_FLAG_RW_TEMP BIT(0) |
78 | #define THERMAL_TRIP_FLAG_RW_HYST BIT(1) | |
79 | ||
80 | #define THERMAL_TRIP_FLAG_RW (THERMAL_TRIP_FLAG_RW_TEMP | \ | |
81 | THERMAL_TRIP_FLAG_RW_HYST) | |
82 | ||
d1fbf18a RW |
83 | #define THERMAL_TRIP_PRIV_TO_INT(_val_) (uintptr_t)(_val_) |
84 | #define THERMAL_INT_TO_TRIP_PRIV(_val_) (void *)(uintptr_t)(_val_) | |
85 | ||
b1ae92dc RW |
86 | struct thermal_zone_device; |
87 | ||
aa35e56a RW |
88 | struct cooling_spec { |
89 | unsigned long upper; /* Highest cooling state */ | |
90 | unsigned long lower; /* Lowest cooling state */ | |
91 | unsigned int weight; /* Cooling device weight */ | |
92 | }; | |
93 | ||
203d3d4a | 94 | struct thermal_zone_device_ops { |
aa35e56a RW |
95 | bool (*should_bind) (struct thermal_zone_device *, |
96 | const struct thermal_trip *, | |
97 | struct thermal_cooling_device *, | |
98 | struct cooling_spec *); | |
17e8351a | 99 | int (*get_temp) (struct thermal_zone_device *, int *); |
060c034a | 100 | int (*set_trips) (struct thermal_zone_device *, int, int); |
f5e50bf4 | 101 | int (*change_mode) (struct thermal_zone_device *, |
6503e5df | 102 | enum thermal_device_mode); |
0728c810 RW |
103 | int (*set_trip_temp) (struct thermal_zone_device *, |
104 | const struct thermal_trip *, int); | |
17e8351a SH |
105 | int (*get_crit_temp) (struct thermal_zone_device *, int *); |
106 | int (*set_emul_temp) (struct thermal_zone_device *, int); | |
ebc7abb3 RW |
107 | int (*get_trend) (struct thermal_zone_device *, |
108 | const struct thermal_trip *, enum thermal_trend *); | |
d7203eed DL |
109 | void (*hot)(struct thermal_zone_device *); |
110 | void (*critical)(struct thermal_zone_device *); | |
203d3d4a ZR |
111 | }; |
112 | ||
113 | struct thermal_cooling_device_ops { | |
6503e5df MG |
114 | int (*get_max_state) (struct thermal_cooling_device *, unsigned long *); |
115 | int (*get_cur_state) (struct thermal_cooling_device *, unsigned long *); | |
116 | int (*set_cur_state) (struct thermal_cooling_device *, unsigned long); | |
ecd1d2a3 | 117 | int (*get_requested_power)(struct thermal_cooling_device *, u32 *); |
118 | int (*state2power)(struct thermal_cooling_device *, unsigned long, u32 *); | |
119 | int (*power2state)(struct thermal_cooling_device *, u32, unsigned long *); | |
203d3d4a ZR |
120 | }; |
121 | ||
203d3d4a ZR |
122 | struct thermal_cooling_device { |
123 | int id; | |
57a427c8 | 124 | const char *type; |
c408b3d1 | 125 | unsigned long max_state; |
203d3d4a | 126 | struct device device; |
4e5e4705 | 127 | struct device_node *np; |
203d3d4a | 128 | void *devdata; |
8ea22951 | 129 | void *stats; |
5b275ce2 | 130 | const struct thermal_cooling_device_ops *ops; |
ce119f83 | 131 | bool updated; /* true if the cooling device does not need update */ |
f4a821ce | 132 | struct mutex lock; /* protect thermal_instances list */ |
b5e4ae62 | 133 | struct list_head thermal_instances; |
203d3d4a | 134 | struct list_head node; |
755113d7 DL |
135 | #ifdef CONFIG_THERMAL_DEBUGFS |
136 | struct thermal_debugfs *debugfs; | |
137 | #endif | |
203d3d4a ZR |
138 | }; |
139 | ||
ef873947 D |
140 | /* Structure to define Thermal Zone parameters */ |
141 | struct thermal_zone_params { | |
b377252e | 142 | const char *governor_name; |
ccba4ffd EV |
143 | |
144 | /* | |
145 | * a boolean to indicate if the thermal to hwmon sysfs interface | |
146 | * is required. when no_hwmon == false, a hwmon sysfs interface | |
147 | * will be created. when no_hwmon == true, nothing will be done | |
148 | */ | |
149 | bool no_hwmon; | |
150 | ||
6b775e87 JM |
151 | /* |
152 | * Sustainable power (heat) that this thermal zone can dissipate in | |
153 | * mW | |
154 | */ | |
155 | u32 sustainable_power; | |
156 | ||
157 | /* | |
158 | * Proportional parameter of the PID controller when | |
159 | * overshooting (i.e., when temperature is below the target) | |
160 | */ | |
161 | s32 k_po; | |
162 | ||
163 | /* | |
164 | * Proportional parameter of the PID controller when | |
165 | * undershooting | |
166 | */ | |
167 | s32 k_pu; | |
168 | ||
169 | /* Integral parameter of the PID controller */ | |
170 | s32 k_i; | |
171 | ||
172 | /* Derivative parameter of the PID controller */ | |
173 | s32 k_d; | |
174 | ||
175 | /* threshold below which the error is no longer accumulated */ | |
176 | s32 integral_cutoff; | |
9d0be7f4 EV |
177 | |
178 | /* | |
179 | * @slope: slope of a linear temperature adjustment curve. | |
180 | * Used by thermal zone drivers. | |
181 | */ | |
182 | int slope; | |
183 | /* | |
184 | * @offset: offset of a linear temperature adjustment curve. | |
185 | * Used by thermal zone drivers (default 0). | |
186 | */ | |
187 | int offset; | |
ef873947 D |
188 | }; |
189 | ||
23064088 | 190 | /* Function declarations */ |
4e5e4705 | 191 | #ifdef CONFIG_THERMAL_OF |
3fd6d6e2 DL |
192 | struct thermal_zone_device *devm_thermal_of_zone_register(struct device *dev, int id, void *data, |
193 | const struct thermal_zone_device_ops *ops); | |
194 | ||
3fd6d6e2 DL |
195 | void devm_thermal_of_zone_unregister(struct device *dev, struct thermal_zone_device *tz); |
196 | ||
4e5e4705 | 197 | #else |
4e5e4705 | 198 | |
f59ac19b DL |
199 | static inline |
200 | struct thermal_zone_device *devm_thermal_of_zone_register(struct device *dev, int id, void *data, | |
201 | const struct thermal_zone_device_ops *ops) | |
e498b498 | 202 | { |
f59ac19b | 203 | return ERR_PTR(-ENOTSUPP); |
e498b498 LD |
204 | } |
205 | ||
f59ac19b DL |
206 | static inline void devm_thermal_of_zone_unregister(struct device *dev, |
207 | struct thermal_zone_device *tz) | |
3fd6d6e2 DL |
208 | { |
209 | } | |
4e5e4705 | 210 | #endif |
12ca7188 | 211 | |
96b8b436 RW |
212 | int for_each_thermal_trip(struct thermal_zone_device *tz, |
213 | int (*cb)(struct thermal_trip *, void *), | |
214 | void *data); | |
a56cc0a8 RW |
215 | int thermal_zone_for_each_trip(struct thermal_zone_device *tz, |
216 | int (*cb)(struct thermal_trip *, void *), | |
217 | void *data); | |
bdc22c8d RW |
218 | void thermal_zone_set_trip_temp(struct thermal_zone_device *tz, |
219 | struct thermal_trip *trip, int temp); | |
7c3d5c20 DL |
220 | |
221 | int thermal_zone_get_crit_temp(struct thermal_zone_device *tz, int *temp); | |
222 | ||
60518260 | 223 | #ifdef CONFIG_THERMAL |
9ffa7b92 RW |
224 | struct thermal_zone_device *thermal_zone_device_register_with_trips( |
225 | const char *type, | |
9b0a6275 | 226 | const struct thermal_trip *trips, |
4a62d588 | 227 | int num_trips, void *devdata, |
698a1eb1 | 228 | const struct thermal_zone_device_ops *ops, |
9ffa7b92 | 229 | const struct thermal_zone_params *tzp, |
d05374de RW |
230 | unsigned int passive_delay, |
231 | unsigned int polling_delay); | |
9ffa7b92 | 232 | |
d332db8f RW |
233 | struct thermal_zone_device *thermal_tripless_zone_device_register( |
234 | const char *type, | |
235 | void *devdata, | |
698a1eb1 | 236 | const struct thermal_zone_device_ops *ops, |
d332db8f RW |
237 | const struct thermal_zone_params *tzp); |
238 | ||
9ffa7b92 | 239 | void thermal_zone_device_unregister(struct thermal_zone_device *tz); |
fae11de5 | 240 | |
a6ff3c00 | 241 | void *thermal_zone_device_priv(struct thermal_zone_device *tzd); |
072e35c9 | 242 | const char *thermal_zone_device_type(struct thermal_zone_device *tzd); |
3034f859 | 243 | int thermal_zone_device_id(struct thermal_zone_device *tzd); |
7cefbaf0 | 244 | struct device *thermal_zone_device(struct thermal_zone_device *tzd); |
a6ff3c00 | 245 | |
0e70f466 SP |
246 | void thermal_zone_device_update(struct thermal_zone_device *, |
247 | enum thermal_notify_event); | |
23064088 | 248 | |
f991de53 JFD |
249 | struct thermal_cooling_device *thermal_cooling_device_register(const char *, |
250 | void *, const struct thermal_cooling_device_ops *); | |
a116b5d4 | 251 | struct thermal_cooling_device * |
f991de53 | 252 | thermal_of_cooling_device_register(struct device_node *np, const char *, void *, |
a116b5d4 | 253 | const struct thermal_cooling_device_ops *); |
b4ab114c GR |
254 | struct thermal_cooling_device * |
255 | devm_thermal_of_cooling_device_register(struct device *dev, | |
256 | struct device_node *np, | |
4acab508 | 257 | const char *type, void *devdata, |
b4ab114c | 258 | const struct thermal_cooling_device_ops *ops); |
790930f4 | 259 | void thermal_cooling_device_update(struct thermal_cooling_device *); |
203d3d4a | 260 | void thermal_cooling_device_unregister(struct thermal_cooling_device *); |
63c4d919 | 261 | struct thermal_zone_device *thermal_zone_get_zone_by_name(const char *name); |
17e8351a | 262 | int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp); |
4a7069a3 RN |
263 | int thermal_zone_get_slope(struct thermal_zone_device *tz); |
264 | int thermal_zone_get_offset(struct thermal_zone_device *tz); | |
463b86fe RW |
265 | bool thermal_trip_is_bound_to_cdev(struct thermal_zone_device *tz, |
266 | const struct thermal_trip *trip, | |
267 | struct thermal_cooling_device *cdev); | |
af06216a | 268 | |
ac5d9ecc AP |
269 | int thermal_zone_device_enable(struct thermal_zone_device *tz); |
270 | int thermal_zone_device_disable(struct thermal_zone_device *tz); | |
d7203eed | 271 | void thermal_zone_device_critical(struct thermal_zone_device *tz); |
12ca7188 | 272 | #else |
9ffa7b92 RW |
273 | static inline struct thermal_zone_device *thermal_zone_device_register_with_trips( |
274 | const char *type, | |
9b0a6275 | 275 | const struct thermal_trip *trips, |
4a62d588 | 276 | int num_trips, void *devdata, |
698a1eb1 | 277 | const struct thermal_zone_device_ops *ops, |
9ffa7b92 RW |
278 | const struct thermal_zone_params *tzp, |
279 | int passive_delay, int polling_delay) | |
12ca7188 | 280 | { return ERR_PTR(-ENODEV); } |
9ffa7b92 | 281 | |
d332db8f RW |
282 | static inline struct thermal_zone_device *thermal_tripless_zone_device_register( |
283 | const char *type, | |
284 | void *devdata, | |
285 | struct thermal_zone_device_ops *ops, | |
286 | const struct thermal_zone_params *tzp) | |
287 | { return ERR_PTR(-ENODEV); } | |
288 | ||
9ffa7b92 | 289 | static inline void thermal_zone_device_unregister(struct thermal_zone_device *tz) |
12ca7188 | 290 | { } |
9ffa7b92 | 291 | |
12ca7188 | 292 | static inline struct thermal_cooling_device * |
fb836107 | 293 | thermal_cooling_device_register(const char *type, void *devdata, |
12ca7188 NM |
294 | const struct thermal_cooling_device_ops *ops) |
295 | { return ERR_PTR(-ENODEV); } | |
296 | static inline struct thermal_cooling_device * | |
297 | thermal_of_cooling_device_register(struct device_node *np, | |
fb836107 AB |
298 | const char *type, void *devdata, |
299 | const struct thermal_cooling_device_ops *ops) | |
12ca7188 | 300 | { return ERR_PTR(-ENODEV); } |
b4ab114c GR |
301 | static inline struct thermal_cooling_device * |
302 | devm_thermal_of_cooling_device_register(struct device *dev, | |
303 | struct device_node *np, | |
4acab508 | 304 | const char *type, void *devdata, |
b4ab114c GR |
305 | const struct thermal_cooling_device_ops *ops) |
306 | { | |
307 | return ERR_PTR(-ENODEV); | |
308 | } | |
12ca7188 NM |
309 | static inline void thermal_cooling_device_unregister( |
310 | struct thermal_cooling_device *cdev) | |
311 | { } | |
312 | static inline struct thermal_zone_device *thermal_zone_get_zone_by_name( | |
313 | const char *name) | |
314 | { return ERR_PTR(-ENODEV); } | |
315 | static inline int thermal_zone_get_temp( | |
17e8351a | 316 | struct thermal_zone_device *tz, int *temp) |
12ca7188 | 317 | { return -ENODEV; } |
4a7069a3 RN |
318 | static inline int thermal_zone_get_slope( |
319 | struct thermal_zone_device *tz) | |
320 | { return -ENODEV; } | |
321 | static inline int thermal_zone_get_offset( | |
322 | struct thermal_zone_device *tz) | |
323 | { return -ENODEV; } | |
f0129c23 | 324 | |
a6ff3c00 DL |
325 | static inline void *thermal_zone_device_priv(struct thermal_zone_device *tz) |
326 | { | |
327 | return NULL; | |
328 | } | |
329 | ||
072e35c9 DL |
330 | static inline const char *thermal_zone_device_type(struct thermal_zone_device *tzd) |
331 | { | |
332 | return NULL; | |
333 | } | |
334 | ||
3034f859 DL |
335 | static inline int thermal_zone_device_id(struct thermal_zone_device *tzd) |
336 | { | |
337 | return -ENODEV; | |
338 | } | |
339 | ||
ac5d9ecc AP |
340 | static inline int thermal_zone_device_enable(struct thermal_zone_device *tz) |
341 | { return -ENODEV; } | |
342 | ||
343 | static inline int thermal_zone_device_disable(struct thermal_zone_device *tz) | |
344 | { return -ENODEV; } | |
12ca7188 NM |
345 | #endif /* CONFIG_THERMAL */ |
346 | ||
a0dd25b2 | 347 | #endif /* __THERMAL_H__ */ |