1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
2 | /* |
3 | * Generic OPP Interface |
4 | * |
5 | * Copyright (C) 2009-2010 Texas Instruments Incorporated. |
6 | * Nishanth Menon |
7 | * Romit Dasgupta |
8 | * Kevin Hilman |
9 | */ |
10 | |
11 | #ifndef __LINUX_OPP_H__ |
12 | #define __LINUX_OPP_H__ |
13 | |
14 | #include <linux/energy_model.h> |
15 | #include <linux/err.h> |
16 | #include <linux/notifier.h> |
17 | |
18 | struct clk; |
19 | struct regulator; |
20 | struct dev_pm_opp; |
21 | struct device; |
22 | struct opp_table; |
23 | |
24 | enum dev_pm_opp_event { |
25 | OPP_EVENT_ADD, OPP_EVENT_REMOVE, OPP_EVENT_ENABLE, OPP_EVENT_DISABLE, |
26 | OPP_EVENT_ADJUST_VOLTAGE, |
27 | }; |
28 | |
29 | /** |
30 | * struct dev_pm_opp_supply - Power supply voltage/current values |
31 | * @u_volt: Target voltage in microvolts corresponding to this OPP |
32 | * @u_volt_min: Minimum voltage in microvolts corresponding to this OPP |
33 | * @u_volt_max: Maximum voltage in microvolts corresponding to this OPP |
34 | * @u_amp: Maximum current drawn by the device in microamperes |
35 | * @u_watt: Power used by the device in microwatts |
36 | * |
37 | * This structure stores the voltage/current/power values for a single power |
38 | * supply. |
39 | */ |
40 | struct dev_pm_opp_supply { |
41 | unsigned long u_volt; |
42 | unsigned long u_volt_min; |
43 | unsigned long u_volt_max; |
44 | unsigned long u_amp; |
45 | unsigned long u_watt; |
46 | }; |
47 | |
48 | /** |
49 | * struct dev_pm_opp_icc_bw - Interconnect bandwidth values |
50 | * @avg: Average bandwidth corresponding to this OPP (in icc units) |
51 | * @peak: Peak bandwidth corresponding to this OPP (in icc units) |
52 | * |
53 | * This structure stores the bandwidth values for a single interconnect path. |
54 | */ |
55 | struct dev_pm_opp_icc_bw { |
56 | u32 avg; |
57 | u32 peak; |
58 | }; |
59 | |
60 | typedef int (*config_regulators_t)(struct device *dev, |
61 | struct dev_pm_opp *old_opp, struct dev_pm_opp *new_opp, |
62 | struct regulator **regulators, unsigned int count); |
63 | |
64 | typedef int (*config_clks_t)(struct device *dev, struct opp_table *opp_table, |
65 | struct dev_pm_opp *opp, void *data, bool scaling_down); |
66 | |
67 | /** |
68 | * struct dev_pm_opp_config - Device OPP configuration values |
69 | * @clk_names: Clk names, NULL terminated array. |
70 | * @config_clks: Custom set clk helper. |
71 | * @prop_name: Name to postfix to properties. |
72 | * @config_regulators: Custom set regulator helper. |
73 | * @supported_hw: Array of hierarchy of versions to match. |
74 | * @supported_hw_count: Number of elements in the array. |
75 | * @regulator_names: Array of pointers to the names of the regulator, NULL terminated. |
76 | * @genpd_names: Null terminated array of pointers containing names of genpd to |
77 | * attach. |
78 | * @virt_devs: Pointer to return the array of virtual devices. |
79 | * |
80 | * This structure contains platform specific OPP configurations for the device. |
81 | */ |
82 | struct dev_pm_opp_config { |
83 | /* NULL terminated */ |
84 | const char * const *clk_names; |
85 | config_clks_t config_clks; |
86 | const char *prop_name; |
87 | config_regulators_t config_regulators; |
88 | const unsigned int *supported_hw; |
89 | unsigned int supported_hw_count; |
90 | const char * const *regulator_names; |
91 | const char * const *genpd_names; |
92 | struct device ***virt_devs; |
93 | }; |
94 | |
95 | /** |
96 | * struct dev_pm_opp_data - The data to use to initialize an OPP. |
97 | * @level: The performance level for the OPP. |
98 | * @freq: The clock rate in Hz for the OPP. |
99 | * @u_volt: The voltage in uV for the OPP. |
100 | */ |
101 | struct dev_pm_opp_data { |
102 | unsigned int level; |
103 | unsigned long freq; |
104 | unsigned long u_volt; |
105 | }; |
106 | |
107 | #if defined(CONFIG_PM_OPP) |
108 | |
109 | struct opp_table *dev_pm_opp_get_opp_table(struct device *dev); |
110 | void dev_pm_opp_put_opp_table(struct opp_table *opp_table); |
111 | |
112 | unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp); |
113 | |
114 | int dev_pm_opp_get_supplies(struct dev_pm_opp *opp, struct dev_pm_opp_supply *supplies); |
115 | |
116 | unsigned long dev_pm_opp_get_power(struct dev_pm_opp *opp); |
117 | |
118 | unsigned long dev_pm_opp_get_freq_indexed(struct dev_pm_opp *opp, u32 index); |
119 | |
120 | unsigned int dev_pm_opp_get_level(struct dev_pm_opp *opp); |
121 | |
122 | unsigned int dev_pm_opp_get_required_pstate(struct dev_pm_opp *opp, |
123 | unsigned int index); |
124 | |
125 | bool dev_pm_opp_is_turbo(struct dev_pm_opp *opp); |
126 | |
127 | int dev_pm_opp_get_opp_count(struct device *dev); |
128 | unsigned long dev_pm_opp_get_max_clock_latency(struct device *dev); |
129 | unsigned long dev_pm_opp_get_max_volt_latency(struct device *dev); |
130 | unsigned long dev_pm_opp_get_max_transition_latency(struct device *dev); |
131 | unsigned long dev_pm_opp_get_suspend_opp_freq(struct device *dev); |
132 | |
133 | struct dev_pm_opp *dev_pm_opp_find_freq_exact(struct device *dev, |
134 | unsigned long freq, |
135 | bool available); |
136 | |
137 | struct dev_pm_opp * |
138 | dev_pm_opp_find_freq_exact_indexed(struct device *dev, unsigned long freq, |
139 | u32 index, bool available); |
140 | |
141 | struct dev_pm_opp *dev_pm_opp_find_freq_floor(struct device *dev, |
142 | unsigned long *freq); |
143 | |
144 | struct dev_pm_opp *dev_pm_opp_find_freq_floor_indexed(struct device *dev, |
145 | unsigned long *freq, u32 index); |
146 | |
147 | struct dev_pm_opp *dev_pm_opp_find_freq_ceil(struct device *dev, |
148 | unsigned long *freq); |
149 | |
150 | struct dev_pm_opp *dev_pm_opp_find_freq_ceil_indexed(struct device *dev, |
151 | unsigned long *freq, u32 index); |
152 | |
153 | struct dev_pm_opp *dev_pm_opp_find_level_exact(struct device *dev, |
154 | unsigned int level); |
155 | |
156 | struct dev_pm_opp *dev_pm_opp_find_level_ceil(struct device *dev, |
157 | unsigned int *level); |
158 | |
159 | struct dev_pm_opp *dev_pm_opp_find_level_floor(struct device *dev, |
160 | unsigned long *level); |
161 | |
162 | struct dev_pm_opp *dev_pm_opp_find_bw_ceil(struct device *dev, |
163 | unsigned int *bw, int index); |
164 | |
165 | struct dev_pm_opp *dev_pm_opp_find_bw_floor(struct device *dev, |
166 | unsigned int *bw, int index); |
167 | |
168 | void dev_pm_opp_put(struct dev_pm_opp *opp); |
169 | |
170 | int dev_pm_opp_add_dynamic(struct device *dev, struct dev_pm_opp_data *opp); |
171 | |
172 | void dev_pm_opp_remove(struct device *dev, unsigned long freq); |
173 | void dev_pm_opp_remove_all_dynamic(struct device *dev); |
174 | |
175 | int dev_pm_opp_adjust_voltage(struct device *dev, unsigned long freq, |
176 | unsigned long u_volt, unsigned long u_volt_min, |
177 | unsigned long u_volt_max); |
178 | |
179 | int dev_pm_opp_enable(struct device *dev, unsigned long freq); |
180 | |
181 | int dev_pm_opp_disable(struct device *dev, unsigned long freq); |
182 | |
183 | int dev_pm_opp_register_notifier(struct device *dev, struct notifier_block *nb); |
184 | int dev_pm_opp_unregister_notifier(struct device *dev, struct notifier_block *nb); |
185 | |
186 | int dev_pm_opp_set_config(struct device *dev, struct dev_pm_opp_config *config); |
187 | int devm_pm_opp_set_config(struct device *dev, struct dev_pm_opp_config *config); |
188 | void dev_pm_opp_clear_config(int token); |
189 | int dev_pm_opp_config_clks_simple(struct device *dev, |
190 | struct opp_table *opp_table, struct dev_pm_opp *opp, void *data, |
191 | bool scaling_down); |
192 | |
193 | struct dev_pm_opp *dev_pm_opp_xlate_required_opp(struct opp_table *src_table, struct opp_table *dst_table, struct dev_pm_opp *src_opp); |
194 | int dev_pm_opp_xlate_performance_state(struct opp_table *src_table, struct opp_table *dst_table, unsigned int pstate); |
195 | int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq); |
196 | int dev_pm_opp_set_opp(struct device *dev, struct dev_pm_opp *opp); |
197 | int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev, const struct cpumask *cpumask); |
198 | int dev_pm_opp_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask); |
199 | void dev_pm_opp_remove_table(struct device *dev); |
200 | void dev_pm_opp_cpumask_remove_table(const struct cpumask *cpumask); |
201 | int dev_pm_opp_sync_regulators(struct device *dev); |
202 | #else |
203 | static inline struct opp_table *dev_pm_opp_get_opp_table(struct device *dev) |
204 | { |
205 | return ERR_PTR(-EOPNOTSUPP); |
206 | } |
207 | |
208 | static inline struct opp_table *dev_pm_opp_get_opp_table_indexed(struct device *dev, int index) |
209 | { |
210 | return ERR_PTR(-EOPNOTSUPP); |
211 | } |
212 | |
213 | static inline void dev_pm_opp_put_opp_table(struct opp_table *opp_table) {} |
214 | |
215 | static inline unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp) |
216 | { |
217 | return 0; |
218 | } |
219 | |
220 | static inline int dev_pm_opp_get_supplies(struct dev_pm_opp *opp, struct dev_pm_opp_supply *supplies) |
221 | { |
222 | return -EOPNOTSUPP; |
223 | } |
224 | |
225 | static inline unsigned long dev_pm_opp_get_power(struct dev_pm_opp *opp) |
226 | { |
227 | return 0; |
228 | } |
229 | |
230 | static inline unsigned long dev_pm_opp_get_freq_indexed(struct dev_pm_opp *opp, u32 index) |
231 | { |
232 | return 0; |
233 | } |
234 | |
235 | static inline unsigned int dev_pm_opp_get_level(struct dev_pm_opp *opp) |
236 | { |
237 | return 0; |
238 | } |
239 | |
240 | static inline |
241 | unsigned int dev_pm_opp_get_required_pstate(struct dev_pm_opp *opp, |
242 | unsigned int index) |
243 | { |
244 | return 0; |
245 | } |
246 | |
247 | static inline bool dev_pm_opp_is_turbo(struct dev_pm_opp *opp) |
248 | { |
249 | return false; |
250 | } |
251 | |
252 | static inline int dev_pm_opp_get_opp_count(struct device *dev) |
253 | { |
254 | return 0; |
255 | } |
256 | |
257 | static inline unsigned long dev_pm_opp_get_max_clock_latency(struct device *dev) |
258 | { |
259 | return 0; |
260 | } |
261 | |
262 | static inline unsigned long dev_pm_opp_get_max_volt_latency(struct device *dev) |
263 | { |
264 | return 0; |
265 | } |
266 | |
267 | static inline unsigned long dev_pm_opp_get_max_transition_latency(struct device *dev) |
268 | { |
269 | return 0; |
270 | } |
271 | |
272 | static inline unsigned long dev_pm_opp_get_suspend_opp_freq(struct device *dev) |
273 | { |
274 | return 0; |
275 | } |
276 | |
277 | static inline struct dev_pm_opp *dev_pm_opp_find_freq_exact(struct device *dev, |
278 | unsigned long freq, bool available) |
279 | { |
280 | return ERR_PTR(-EOPNOTSUPP); |
281 | } |
282 | |
283 | static inline struct dev_pm_opp * |
284 | dev_pm_opp_find_freq_exact_indexed(struct device *dev, unsigned long freq, |
285 | u32 index, bool available) |
286 | { |
287 | return ERR_PTR(-EOPNOTSUPP); |
288 | } |
289 | |
290 | static inline struct dev_pm_opp *dev_pm_opp_find_freq_floor(struct device *dev, |
291 | unsigned long *freq) |
292 | { |
293 | return ERR_PTR(-EOPNOTSUPP); |
294 | } |
295 | |
296 | static inline struct dev_pm_opp * |
297 | dev_pm_opp_find_freq_floor_indexed(struct device *dev, unsigned long *freq, u32 index) |
298 | { |
299 | return ERR_PTR(-EOPNOTSUPP); |
300 | } |
301 | |
302 | static inline struct dev_pm_opp *dev_pm_opp_find_freq_ceil(struct device *dev, |
303 | unsigned long *freq) |
304 | { |
305 | return ERR_PTR(-EOPNOTSUPP); |
306 | } |
307 | |
308 | static inline struct dev_pm_opp * |
309 | dev_pm_opp_find_freq_ceil_indexed(struct device *dev, unsigned long *freq, u32 index) |
310 | { |
311 | return ERR_PTR(-EOPNOTSUPP); |
312 | } |
313 | |
314 | static inline struct dev_pm_opp *dev_pm_opp_find_level_exact(struct device *dev, |
315 | unsigned int level) |
316 | { |
317 | return ERR_PTR(-EOPNOTSUPP); |
318 | } |
319 | |
320 | static inline struct dev_pm_opp *dev_pm_opp_find_level_ceil(struct device *dev, |
321 | unsigned int *level) |
322 | { |
323 | return ERR_PTR(-EOPNOTSUPP); |
324 | } |
325 | |
326 | static inline struct dev_pm_opp *dev_pm_opp_find_level_floor(struct device *dev, |
327 | unsigned long *level) |
328 | { |
329 | return ERR_PTR(-EOPNOTSUPP); |
330 | } |
331 | |
332 | static inline struct dev_pm_opp *dev_pm_opp_find_bw_ceil(struct device *dev, |
333 | unsigned int *bw, int index) |
334 | { |
335 | return ERR_PTR(-EOPNOTSUPP); |
336 | } |
337 | |
338 | static inline struct dev_pm_opp *dev_pm_opp_find_bw_floor(struct device *dev, |
339 | unsigned int *bw, int index) |
340 | { |
341 | return ERR_PTR(-EOPNOTSUPP); |
342 | } |
343 | |
344 | static inline void dev_pm_opp_put(struct dev_pm_opp *opp) {} |
345 | |
346 | static inline int |
347 | dev_pm_opp_add_dynamic(struct device *dev, struct dev_pm_opp_data *opp) |
348 | { |
349 | return -EOPNOTSUPP; |
350 | } |
351 | |
352 | static inline void dev_pm_opp_remove(struct device *dev, unsigned long freq) |
353 | { |
354 | } |
355 | |
356 | static inline void dev_pm_opp_remove_all_dynamic(struct device *dev) |
357 | { |
358 | } |
359 | |
360 | static inline int |
361 | dev_pm_opp_adjust_voltage(struct device *dev, unsigned long freq, |
362 | unsigned long u_volt, unsigned long u_volt_min, |
363 | unsigned long u_volt_max) |
364 | { |
365 | return 0; |
366 | } |
367 | |
368 | static inline int dev_pm_opp_enable(struct device *dev, unsigned long freq) |
369 | { |
370 | return 0; |
371 | } |
372 | |
373 | static inline int dev_pm_opp_disable(struct device *dev, unsigned long freq) |
374 | { |
375 | return 0; |
376 | } |
377 | |
378 | static inline int dev_pm_opp_register_notifier(struct device *dev, struct notifier_block *nb) |
379 | { |
380 | return -EOPNOTSUPP; |
381 | } |
382 | |
383 | static inline int dev_pm_opp_unregister_notifier(struct device *dev, struct notifier_block *nb) |
384 | { |
385 | return -EOPNOTSUPP; |
386 | } |
387 | |
388 | static inline int dev_pm_opp_set_config(struct device *dev, struct dev_pm_opp_config *config) |
389 | { |
390 | return -EOPNOTSUPP; |
391 | } |
392 | |
393 | static inline int devm_pm_opp_set_config(struct device *dev, struct dev_pm_opp_config *config) |
394 | { |
395 | return -EOPNOTSUPP; |
396 | } |
397 | |
398 | static inline void dev_pm_opp_clear_config(int token) {} |
399 | |
400 | static inline int dev_pm_opp_config_clks_simple(struct device *dev, |
401 | struct opp_table *opp_table, struct dev_pm_opp *opp, void *data, |
402 | bool scaling_down) |
403 | { |
404 | return -EOPNOTSUPP; |
405 | } |
406 | |
407 | static inline struct dev_pm_opp *dev_pm_opp_xlate_required_opp(struct opp_table *src_table, |
408 | struct opp_table *dst_table, struct dev_pm_opp *src_opp) |
409 | { |
410 | return ERR_PTR(-EOPNOTSUPP); |
411 | } |
412 | |
413 | static inline int dev_pm_opp_xlate_performance_state(struct opp_table *src_table, struct opp_table *dst_table, unsigned int pstate) |
414 | { |
415 | return -EOPNOTSUPP; |
416 | } |
417 | |
418 | static inline int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq) |
419 | { |
420 | return -EOPNOTSUPP; |
421 | } |
422 | |
423 | static inline int dev_pm_opp_set_opp(struct device *dev, struct dev_pm_opp *opp) |
424 | { |
425 | return -EOPNOTSUPP; |
426 | } |
427 | |
428 | static inline int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev, const struct cpumask *cpumask) |
429 | { |
430 | return -EOPNOTSUPP; |
431 | } |
432 | |
433 | static inline int dev_pm_opp_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask) |
434 | { |
435 | return -EINVAL; |
436 | } |
437 | |
438 | static inline void dev_pm_opp_remove_table(struct device *dev) |
439 | { |
440 | } |
441 | |
442 | static inline void dev_pm_opp_cpumask_remove_table(const struct cpumask *cpumask) |
443 | { |
444 | } |
445 | |
446 | static inline int dev_pm_opp_sync_regulators(struct device *dev) |
447 | { |
448 | return -EOPNOTSUPP; |
449 | } |
450 | |
451 | #endif /* CONFIG_PM_OPP */ |
452 | |
453 | #if defined(CONFIG_PM_OPP) && defined(CONFIG_OF) |
454 | int dev_pm_opp_of_add_table(struct device *dev); |
455 | int dev_pm_opp_of_add_table_indexed(struct device *dev, int index); |
456 | int devm_pm_opp_of_add_table_indexed(struct device *dev, int index); |
457 | void dev_pm_opp_of_remove_table(struct device *dev); |
458 | int devm_pm_opp_of_add_table(struct device *dev); |
459 | int dev_pm_opp_of_cpumask_add_table(const struct cpumask *cpumask); |
460 | void dev_pm_opp_of_cpumask_remove_table(const struct cpumask *cpumask); |
461 | int dev_pm_opp_of_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask); |
462 | struct device_node *dev_pm_opp_of_get_opp_desc_node(struct device *dev); |
463 | struct device_node *dev_pm_opp_get_of_node(struct dev_pm_opp *opp); |
464 | int of_get_required_opp_performance_state(struct device_node *np, int index); |
465 | int dev_pm_opp_of_find_icc_paths(struct device *dev, struct opp_table *opp_table); |
466 | int dev_pm_opp_of_register_em(struct device *dev, struct cpumask *cpus); |
467 | static inline void dev_pm_opp_of_unregister_em(struct device *dev) |
468 | { |
469 | em_dev_unregister_perf_domain(dev); |
470 | } |
471 | #else |
472 | static inline int dev_pm_opp_of_add_table(struct device *dev) |
473 | { |
474 | return -EOPNOTSUPP; |
475 | } |
476 | |
477 | static inline int dev_pm_opp_of_add_table_indexed(struct device *dev, int index) |
478 | { |
479 | return -EOPNOTSUPP; |
480 | } |
481 | |
482 | static inline int devm_pm_opp_of_add_table_indexed(struct device *dev, int index) |
483 | { |
484 | return -EOPNOTSUPP; |
485 | } |
486 | |
487 | static inline void dev_pm_opp_of_remove_table(struct device *dev) |
488 | { |
489 | } |
490 | |
491 | static inline int devm_pm_opp_of_add_table(struct device *dev) |
492 | { |
493 | return -EOPNOTSUPP; |
494 | } |
495 | |
496 | static inline int dev_pm_opp_of_cpumask_add_table(const struct cpumask *cpumask) |
497 | { |
498 | return -EOPNOTSUPP; |
499 | } |
500 | |
501 | static inline void dev_pm_opp_of_cpumask_remove_table(const struct cpumask *cpumask) |
502 | { |
503 | } |
504 | |
505 | static inline int dev_pm_opp_of_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask) |
506 | { |
507 | return -EOPNOTSUPP; |
508 | } |
509 | |
510 | static inline struct device_node *dev_pm_opp_of_get_opp_desc_node(struct device *dev) |
511 | { |
512 | return NULL; |
513 | } |
514 | |
515 | static inline struct device_node *dev_pm_opp_get_of_node(struct dev_pm_opp *opp) |
516 | { |
517 | return NULL; |
518 | } |
519 | |
520 | static inline int dev_pm_opp_of_register_em(struct device *dev, |
521 | struct cpumask *cpus) |
522 | { |
523 | return -EOPNOTSUPP; |
524 | } |
525 | |
526 | static inline void dev_pm_opp_of_unregister_em(struct device *dev) |
527 | { |
528 | } |
529 | |
530 | static inline int of_get_required_opp_performance_state(struct device_node *np, int index) |
531 | { |
532 | return -EOPNOTSUPP; |
533 | } |
534 | |
535 | static inline int dev_pm_opp_of_find_icc_paths(struct device *dev, struct opp_table *opp_table) |
536 | { |
537 | return -EOPNOTSUPP; |
538 | } |
539 | #endif |
540 | |
541 | /* OPP Configuration helpers */ |
542 | |
543 | static inline int dev_pm_opp_add(struct device *dev, unsigned long freq, |
544 | unsigned long u_volt) |
545 | { |
546 | struct dev_pm_opp_data data = { |
547 | .freq = freq, |
548 | .u_volt = u_volt, |
549 | }; |
550 | |
551 | return dev_pm_opp_add_dynamic(dev, opp: &data); |
552 | } |
553 | |
554 | /* Regulators helpers */ |
555 | static inline int dev_pm_opp_set_regulators(struct device *dev, |
556 | const char * const names[]) |
557 | { |
558 | struct dev_pm_opp_config config = { |
559 | .regulator_names = names, |
560 | }; |
561 | |
562 | return dev_pm_opp_set_config(dev, config: &config); |
563 | } |
564 | |
565 | static inline void dev_pm_opp_put_regulators(int token) |
566 | { |
567 | dev_pm_opp_clear_config(token); |
568 | } |
569 | |
570 | static inline int devm_pm_opp_set_regulators(struct device *dev, |
571 | const char * const names[]) |
572 | { |
573 | struct dev_pm_opp_config config = { |
574 | .regulator_names = names, |
575 | }; |
576 | |
577 | return devm_pm_opp_set_config(dev, config: &config); |
578 | } |
579 | |
580 | /* Supported-hw helpers */ |
581 | static inline int dev_pm_opp_set_supported_hw(struct device *dev, |
582 | const u32 *versions, |
583 | unsigned int count) |
584 | { |
585 | struct dev_pm_opp_config config = { |
586 | .supported_hw = versions, |
587 | .supported_hw_count = count, |
588 | }; |
589 | |
590 | return dev_pm_opp_set_config(dev, config: &config); |
591 | } |
592 | |
593 | static inline void dev_pm_opp_put_supported_hw(int token) |
594 | { |
595 | dev_pm_opp_clear_config(token); |
596 | } |
597 | |
598 | static inline int devm_pm_opp_set_supported_hw(struct device *dev, |
599 | const u32 *versions, |
600 | unsigned int count) |
601 | { |
602 | struct dev_pm_opp_config config = { |
603 | .supported_hw = versions, |
604 | .supported_hw_count = count, |
605 | }; |
606 | |
607 | return devm_pm_opp_set_config(dev, config: &config); |
608 | } |
609 | |
610 | /* clkname helpers */ |
611 | static inline int dev_pm_opp_set_clkname(struct device *dev, const char *name) |
612 | { |
613 | const char *names[] = { name, NULL }; |
614 | struct dev_pm_opp_config config = { |
615 | .clk_names = names, |
616 | }; |
617 | |
618 | return dev_pm_opp_set_config(dev, config: &config); |
619 | } |
620 | |
621 | static inline void dev_pm_opp_put_clkname(int token) |
622 | { |
623 | dev_pm_opp_clear_config(token); |
624 | } |
625 | |
626 | static inline int devm_pm_opp_set_clkname(struct device *dev, const char *name) |
627 | { |
628 | const char *names[] = { name, NULL }; |
629 | struct dev_pm_opp_config config = { |
630 | .clk_names = names, |
631 | }; |
632 | |
633 | return devm_pm_opp_set_config(dev, config: &config); |
634 | } |
635 | |
636 | /* config-regulators helpers */ |
637 | static inline int dev_pm_opp_set_config_regulators(struct device *dev, |
638 | config_regulators_t helper) |
639 | { |
640 | struct dev_pm_opp_config config = { |
641 | .config_regulators = helper, |
642 | }; |
643 | |
644 | return dev_pm_opp_set_config(dev, config: &config); |
645 | } |
646 | |
647 | static inline void dev_pm_opp_put_config_regulators(int token) |
648 | { |
649 | dev_pm_opp_clear_config(token); |
650 | } |
651 | |
652 | /* genpd helpers */ |
653 | static inline int dev_pm_opp_attach_genpd(struct device *dev, |
654 | const char * const *names, |
655 | struct device ***virt_devs) |
656 | { |
657 | struct dev_pm_opp_config config = { |
658 | .genpd_names = names, |
659 | .virt_devs = virt_devs, |
660 | }; |
661 | |
662 | return dev_pm_opp_set_config(dev, config: &config); |
663 | } |
664 | |
665 | static inline void dev_pm_opp_detach_genpd(int token) |
666 | { |
667 | dev_pm_opp_clear_config(token); |
668 | } |
669 | |
670 | static inline int devm_pm_opp_attach_genpd(struct device *dev, |
671 | const char * const *names, |
672 | struct device ***virt_devs) |
673 | { |
674 | struct dev_pm_opp_config config = { |
675 | .genpd_names = names, |
676 | .virt_devs = virt_devs, |
677 | }; |
678 | |
679 | return devm_pm_opp_set_config(dev, config: &config); |
680 | } |
681 | |
682 | /* prop-name helpers */ |
683 | static inline int dev_pm_opp_set_prop_name(struct device *dev, const char *name) |
684 | { |
685 | struct dev_pm_opp_config config = { |
686 | .prop_name = name, |
687 | }; |
688 | |
689 | return dev_pm_opp_set_config(dev, config: &config); |
690 | } |
691 | |
692 | static inline void dev_pm_opp_put_prop_name(int token) |
693 | { |
694 | dev_pm_opp_clear_config(token); |
695 | } |
696 | |
697 | static inline unsigned long dev_pm_opp_get_freq(struct dev_pm_opp *opp) |
698 | { |
699 | return dev_pm_opp_get_freq_indexed(opp, index: 0); |
700 | } |
701 | |
702 | #endif /* __LINUX_OPP_H__ */ |
703 | |