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