1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
2 | /* |
3 | * devfreq: Generic Dynamic Voltage and Frequency Scaling (DVFS) Framework |
4 | * for Non-CPU Devices. |
5 | * |
6 | * Copyright (C) 2011 Samsung Electronics |
7 | * MyungJoo Ham <myungjoo.ham@samsung.com> |
8 | */ |
9 | |
10 | #ifndef __LINUX_DEVFREQ_H__ |
11 | #define __LINUX_DEVFREQ_H__ |
12 | |
13 | #include <linux/device.h> |
14 | #include <linux/notifier.h> |
15 | #include <linux/pm_opp.h> |
16 | #include <linux/pm_qos.h> |
17 | |
18 | /* DEVFREQ governor name */ |
19 | #define DEVFREQ_GOV_SIMPLE_ONDEMAND "simple_ondemand" |
20 | #define DEVFREQ_GOV_PERFORMANCE "performance" |
21 | #define DEVFREQ_GOV_POWERSAVE "powersave" |
22 | #define DEVFREQ_GOV_USERSPACE "userspace" |
23 | #define DEVFREQ_GOV_PASSIVE "passive" |
24 | |
25 | /* DEVFREQ notifier interface */ |
26 | #define DEVFREQ_TRANSITION_NOTIFIER (0) |
27 | |
28 | /* Transition notifiers of DEVFREQ_TRANSITION_NOTIFIER */ |
29 | #define DEVFREQ_PRECHANGE (0) |
30 | #define DEVFREQ_POSTCHANGE (1) |
31 | |
32 | /* DEVFREQ work timers */ |
33 | enum devfreq_timer { |
34 | DEVFREQ_TIMER_DEFERRABLE = 0, |
35 | DEVFREQ_TIMER_DELAYED, |
36 | DEVFREQ_TIMER_NUM, |
37 | }; |
38 | |
39 | struct devfreq; |
40 | struct devfreq_governor; |
41 | struct devfreq_cpu_data; |
42 | struct thermal_cooling_device; |
43 | |
44 | /** |
45 | * struct devfreq_dev_status - Data given from devfreq user device to |
46 | * governors. Represents the performance |
47 | * statistics. |
48 | * @total_time: The total time represented by this instance of |
49 | * devfreq_dev_status |
50 | * @busy_time: The time that the device was working among the |
51 | * total_time. |
52 | * @current_frequency: The operating frequency. |
53 | * @private_data: An entry not specified by the devfreq framework. |
54 | * A device and a specific governor may have their |
55 | * own protocol with private_data. However, because |
56 | * this is governor-specific, a governor using this |
57 | * will be only compatible with devices aware of it. |
58 | */ |
59 | struct devfreq_dev_status { |
60 | /* both since the last measure */ |
61 | unsigned long total_time; |
62 | unsigned long busy_time; |
63 | unsigned long current_frequency; |
64 | void *private_data; |
65 | }; |
66 | |
67 | /* |
68 | * The resulting frequency should be at most this. (this bound is the |
69 | * least upper bound; thus, the resulting freq should be lower or same) |
70 | * If the flag is not set, the resulting frequency should be at most the |
71 | * bound (greatest lower bound) |
72 | */ |
73 | #define DEVFREQ_FLAG_LEAST_UPPER_BOUND 0x1 |
74 | |
75 | /** |
76 | * struct devfreq_dev_profile - Devfreq's user device profile |
77 | * @initial_freq: The operating frequency when devfreq_add_device() is |
78 | * called. |
79 | * @polling_ms: The polling interval in ms. 0 disables polling. |
80 | * @timer: Timer type is either deferrable or delayed timer. |
81 | * @target: The device should set its operating frequency at |
82 | * freq or lowest-upper-than-freq value. If freq is |
83 | * higher than any operable frequency, set maximum. |
84 | * Before returning, target function should set |
85 | * freq at the current frequency. |
86 | * The "flags" parameter's possible values are |
87 | * explained above with "DEVFREQ_FLAG_*" macros. |
88 | * @get_dev_status: The device should provide the current performance |
89 | * status to devfreq. Governors are recommended not to |
90 | * use this directly. Instead, governors are recommended |
91 | * to use devfreq_update_stats() along with |
92 | * devfreq.last_status. |
93 | * @get_cur_freq: The device should provide the current frequency |
94 | * at which it is operating. |
95 | * @exit: An optional callback that is called when devfreq |
96 | * is removing the devfreq object due to error or |
97 | * from devfreq_remove_device() call. If the user |
98 | * has registered devfreq->nb at a notifier-head, |
99 | * this is the time to unregister it. |
100 | * @freq_table: Optional list of frequencies to support statistics |
101 | * and freq_table must be generated in ascending order. |
102 | * @max_state: The size of freq_table. |
103 | * |
104 | * @is_cooling_device: A self-explanatory boolean giving the device a |
105 | * cooling effect property. |
106 | */ |
107 | struct devfreq_dev_profile { |
108 | unsigned long initial_freq; |
109 | unsigned int polling_ms; |
110 | enum devfreq_timer timer; |
111 | |
112 | int (*target)(struct device *dev, unsigned long *freq, u32 flags); |
113 | int (*get_dev_status)(struct device *dev, |
114 | struct devfreq_dev_status *stat); |
115 | int (*get_cur_freq)(struct device *dev, unsigned long *freq); |
116 | void (*exit)(struct device *dev); |
117 | |
118 | unsigned long *freq_table; |
119 | unsigned int max_state; |
120 | |
121 | bool is_cooling_device; |
122 | }; |
123 | |
124 | /** |
125 | * struct devfreq_stats - Statistics of devfreq device behavior |
126 | * @total_trans: Number of devfreq transitions. |
127 | * @trans_table: Statistics of devfreq transitions. |
128 | * @time_in_state: Statistics of devfreq states. |
129 | * @last_update: The last time stats were updated. |
130 | */ |
131 | struct devfreq_stats { |
132 | unsigned int total_trans; |
133 | unsigned int *trans_table; |
134 | u64 *time_in_state; |
135 | u64 last_update; |
136 | }; |
137 | |
138 | /** |
139 | * struct devfreq - Device devfreq structure |
140 | * @node: list node - contains the devices with devfreq that have been |
141 | * registered. |
142 | * @lock: a mutex to protect accessing devfreq. |
143 | * @dev: device registered by devfreq class. dev.parent is the device |
144 | * using devfreq. |
145 | * @profile: device-specific devfreq profile |
146 | * @governor: method how to choose frequency based on the usage. |
147 | * @opp_table: Reference to OPP table of dev.parent, if one exists. |
148 | * @nb: notifier block used to notify devfreq object that it should |
149 | * reevaluate operable frequencies. Devfreq users may use |
150 | * devfreq.nb to the corresponding register notifier call chain. |
151 | * @work: delayed work for load monitoring. |
152 | * @freq_table: current frequency table used by the devfreq driver. |
153 | * @max_state: count of entry present in the frequency table. |
154 | * @previous_freq: previously configured frequency value. |
155 | * @last_status: devfreq user device info, performance statistics |
156 | * @data: devfreq driver pass to governors, governor should not change it. |
157 | * @governor_data: private data for governors, devfreq core doesn't touch it. |
158 | * @user_min_freq_req: PM QoS minimum frequency request from user (via sysfs) |
159 | * @user_max_freq_req: PM QoS maximum frequency request from user (via sysfs) |
160 | * @scaling_min_freq: Limit minimum frequency requested by OPP interface |
161 | * @scaling_max_freq: Limit maximum frequency requested by OPP interface |
162 | * @stop_polling: devfreq polling status of a device. |
163 | * @suspend_freq: frequency of a device set during suspend phase. |
164 | * @resume_freq: frequency of a device set in resume phase. |
165 | * @suspend_count: suspend requests counter for a device. |
166 | * @stats: Statistics of devfreq device behavior |
167 | * @transition_notifier_list: list head of DEVFREQ_TRANSITION_NOTIFIER notifier |
168 | * @cdev: Cooling device pointer if the devfreq has cooling property |
169 | * @nb_min: Notifier block for DEV_PM_QOS_MIN_FREQUENCY |
170 | * @nb_max: Notifier block for DEV_PM_QOS_MAX_FREQUENCY |
171 | * |
172 | * This structure stores the devfreq information for a given device. |
173 | * |
174 | * Note that when a governor accesses entries in struct devfreq in its |
175 | * functions except for the context of callbacks defined in struct |
176 | * devfreq_governor, the governor should protect its access with the |
177 | * struct mutex lock in struct devfreq. A governor may use this mutex |
178 | * to protect its own private data in ``void *data`` as well. |
179 | */ |
180 | struct devfreq { |
181 | struct list_head node; |
182 | |
183 | struct mutex lock; |
184 | struct device dev; |
185 | struct devfreq_dev_profile *profile; |
186 | const struct devfreq_governor *governor; |
187 | struct opp_table *opp_table; |
188 | struct notifier_block nb; |
189 | struct delayed_work work; |
190 | |
191 | unsigned long *freq_table; |
192 | unsigned int max_state; |
193 | |
194 | unsigned long previous_freq; |
195 | struct devfreq_dev_status last_status; |
196 | |
197 | void *data; |
198 | void *governor_data; |
199 | |
200 | struct dev_pm_qos_request user_min_freq_req; |
201 | struct dev_pm_qos_request user_max_freq_req; |
202 | unsigned long scaling_min_freq; |
203 | unsigned long scaling_max_freq; |
204 | bool stop_polling; |
205 | |
206 | unsigned long suspend_freq; |
207 | unsigned long resume_freq; |
208 | atomic_t suspend_count; |
209 | |
210 | /* information for device frequency transitions */ |
211 | struct devfreq_stats stats; |
212 | |
213 | struct srcu_notifier_head transition_notifier_list; |
214 | |
215 | /* Pointer to the cooling device if used for thermal mitigation */ |
216 | struct thermal_cooling_device *cdev; |
217 | |
218 | struct notifier_block nb_min; |
219 | struct notifier_block nb_max; |
220 | }; |
221 | |
222 | struct devfreq_freqs { |
223 | unsigned long old; |
224 | unsigned long new; |
225 | }; |
226 | |
227 | #if defined(CONFIG_PM_DEVFREQ) |
228 | struct devfreq *devfreq_add_device(struct device *dev, |
229 | struct devfreq_dev_profile *profile, |
230 | const char *governor_name, |
231 | void *data); |
232 | int devfreq_remove_device(struct devfreq *devfreq); |
233 | struct devfreq *devm_devfreq_add_device(struct device *dev, |
234 | struct devfreq_dev_profile *profile, |
235 | const char *governor_name, |
236 | void *data); |
237 | void devm_devfreq_remove_device(struct device *dev, struct devfreq *devfreq); |
238 | |
239 | /* Supposed to be called by PM callbacks */ |
240 | int devfreq_suspend_device(struct devfreq *devfreq); |
241 | int devfreq_resume_device(struct devfreq *devfreq); |
242 | |
243 | void devfreq_suspend(void); |
244 | void devfreq_resume(void); |
245 | |
246 | /* update_devfreq() - Reevaluate the device and configure frequency */ |
247 | int update_devfreq(struct devfreq *devfreq); |
248 | |
249 | /* Helper functions for devfreq user device driver with OPP. */ |
250 | struct dev_pm_opp *devfreq_recommended_opp(struct device *dev, |
251 | unsigned long *freq, u32 flags); |
252 | int devfreq_register_opp_notifier(struct device *dev, |
253 | struct devfreq *devfreq); |
254 | int devfreq_unregister_opp_notifier(struct device *dev, |
255 | struct devfreq *devfreq); |
256 | int devm_devfreq_register_opp_notifier(struct device *dev, |
257 | struct devfreq *devfreq); |
258 | void devm_devfreq_unregister_opp_notifier(struct device *dev, |
259 | struct devfreq *devfreq); |
260 | int devfreq_register_notifier(struct devfreq *devfreq, |
261 | struct notifier_block *nb, |
262 | unsigned int list); |
263 | int devfreq_unregister_notifier(struct devfreq *devfreq, |
264 | struct notifier_block *nb, |
265 | unsigned int list); |
266 | int devm_devfreq_register_notifier(struct device *dev, |
267 | struct devfreq *devfreq, |
268 | struct notifier_block *nb, |
269 | unsigned int list); |
270 | void devm_devfreq_unregister_notifier(struct device *dev, |
271 | struct devfreq *devfreq, |
272 | struct notifier_block *nb, |
273 | unsigned int list); |
274 | struct devfreq *devfreq_get_devfreq_by_node(struct device_node *node); |
275 | struct devfreq *devfreq_get_devfreq_by_phandle(struct device *dev, |
276 | const char *phandle_name, int index); |
277 | #endif /* CONFIG_PM_DEVFREQ */ |
278 | |
279 | /** |
280 | * struct devfreq_simple_ondemand_data - ``void *data`` fed to struct devfreq |
281 | * and devfreq_add_device |
282 | * @upthreshold: If the load is over this value, the frequency jumps. |
283 | * Specify 0 to use the default. Valid value = 0 to 100. |
284 | * @downdifferential: If the load is under upthreshold - downdifferential, |
285 | * the governor may consider slowing the frequency down. |
286 | * Specify 0 to use the default. Valid value = 0 to 100. |
287 | * downdifferential < upthreshold must hold. |
288 | * |
289 | * If the fed devfreq_simple_ondemand_data pointer is NULL to the governor, |
290 | * the governor uses the default values. |
291 | */ |
292 | struct devfreq_simple_ondemand_data { |
293 | unsigned int upthreshold; |
294 | unsigned int downdifferential; |
295 | }; |
296 | |
297 | enum devfreq_parent_dev_type { |
298 | DEVFREQ_PARENT_DEV, |
299 | CPUFREQ_PARENT_DEV, |
300 | }; |
301 | |
302 | /** |
303 | * struct devfreq_passive_data - ``void *data`` fed to struct devfreq |
304 | * and devfreq_add_device |
305 | * @parent: the devfreq instance of parent device. |
306 | * @get_target_freq: Optional callback, Returns desired operating frequency |
307 | * for the device using passive governor. That is called |
308 | * when passive governor should decide the next frequency |
309 | * by using the new frequency of parent devfreq device |
310 | * using governors except for passive governor. |
311 | * If the devfreq device has the specific method to decide |
312 | * the next frequency, should use this callback. |
313 | * @parent_type: the parent type of the device. |
314 | * @this: the devfreq instance of own device. |
315 | * @nb: the notifier block for DEVFREQ_TRANSITION_NOTIFIER or |
316 | * CPUFREQ_TRANSITION_NOTIFIER list. |
317 | * @cpu_data_list: the list of cpu frequency data for all cpufreq_policy. |
318 | * |
319 | * The devfreq_passive_data have to set the devfreq instance of parent |
320 | * device with governors except for the passive governor. But, don't need to |
321 | * initialize the 'this' and 'nb' field because the devfreq core will handle |
322 | * them. |
323 | */ |
324 | struct devfreq_passive_data { |
325 | /* Should set the devfreq instance of parent device */ |
326 | struct devfreq *parent; |
327 | |
328 | /* Optional callback to decide the next frequency of passvice device */ |
329 | int (*get_target_freq)(struct devfreq *this, unsigned long *freq); |
330 | |
331 | /* Should set the type of parent device */ |
332 | enum devfreq_parent_dev_type parent_type; |
333 | |
334 | /* For passive governor's internal use. Don't need to set them */ |
335 | struct devfreq *this; |
336 | struct notifier_block nb; |
337 | struct list_head cpu_data_list; |
338 | }; |
339 | |
340 | #if !defined(CONFIG_PM_DEVFREQ) |
341 | static inline struct devfreq *devfreq_add_device(struct device *dev, |
342 | struct devfreq_dev_profile *profile, |
343 | const char *governor_name, |
344 | void *data) |
345 | { |
346 | return ERR_PTR(-ENOSYS); |
347 | } |
348 | |
349 | static inline int devfreq_remove_device(struct devfreq *devfreq) |
350 | { |
351 | return 0; |
352 | } |
353 | |
354 | static inline struct devfreq *devm_devfreq_add_device(struct device *dev, |
355 | struct devfreq_dev_profile *profile, |
356 | const char *governor_name, |
357 | void *data) |
358 | { |
359 | return ERR_PTR(-ENOSYS); |
360 | } |
361 | |
362 | static inline void devm_devfreq_remove_device(struct device *dev, |
363 | struct devfreq *devfreq) |
364 | { |
365 | } |
366 | |
367 | static inline int devfreq_suspend_device(struct devfreq *devfreq) |
368 | { |
369 | return 0; |
370 | } |
371 | |
372 | static inline int devfreq_resume_device(struct devfreq *devfreq) |
373 | { |
374 | return 0; |
375 | } |
376 | |
377 | static inline void devfreq_suspend(void) {} |
378 | static inline void devfreq_resume(void) {} |
379 | |
380 | static inline struct dev_pm_opp *devfreq_recommended_opp(struct device *dev, |
381 | unsigned long *freq, u32 flags) |
382 | { |
383 | return ERR_PTR(-EINVAL); |
384 | } |
385 | |
386 | static inline int devfreq_register_opp_notifier(struct device *dev, |
387 | struct devfreq *devfreq) |
388 | { |
389 | return -EINVAL; |
390 | } |
391 | |
392 | static inline int devfreq_unregister_opp_notifier(struct device *dev, |
393 | struct devfreq *devfreq) |
394 | { |
395 | return -EINVAL; |
396 | } |
397 | |
398 | static inline int devm_devfreq_register_opp_notifier(struct device *dev, |
399 | struct devfreq *devfreq) |
400 | { |
401 | return -EINVAL; |
402 | } |
403 | |
404 | static inline void devm_devfreq_unregister_opp_notifier(struct device *dev, |
405 | struct devfreq *devfreq) |
406 | { |
407 | } |
408 | |
409 | static inline int devfreq_register_notifier(struct devfreq *devfreq, |
410 | struct notifier_block *nb, |
411 | unsigned int list) |
412 | { |
413 | return 0; |
414 | } |
415 | |
416 | static inline int devfreq_unregister_notifier(struct devfreq *devfreq, |
417 | struct notifier_block *nb, |
418 | unsigned int list) |
419 | { |
420 | return 0; |
421 | } |
422 | |
423 | static inline int devm_devfreq_register_notifier(struct device *dev, |
424 | struct devfreq *devfreq, |
425 | struct notifier_block *nb, |
426 | unsigned int list) |
427 | { |
428 | return 0; |
429 | } |
430 | |
431 | static inline void devm_devfreq_unregister_notifier(struct device *dev, |
432 | struct devfreq *devfreq, |
433 | struct notifier_block *nb, |
434 | unsigned int list) |
435 | { |
436 | } |
437 | |
438 | static inline struct devfreq *devfreq_get_devfreq_by_node(struct device_node *node) |
439 | { |
440 | return ERR_PTR(-ENODEV); |
441 | } |
442 | |
443 | static inline struct devfreq *devfreq_get_devfreq_by_phandle(struct device *dev, |
444 | const char *phandle_name, int index) |
445 | { |
446 | return ERR_PTR(-ENODEV); |
447 | } |
448 | |
449 | static inline int devfreq_update_stats(struct devfreq *df) |
450 | { |
451 | return -EINVAL; |
452 | } |
453 | #endif /* CONFIG_PM_DEVFREQ */ |
454 | |
455 | #endif /* __LINUX_DEVFREQ_H__ */ |
456 | |