diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2022-08-08 14:29:00 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2022-08-08 14:29:00 -0700 |
commit | 507f811f205c17fd6f64e8d34d4bf91cd01b07a2 (patch) | |
tree | 72f4abfa45964c4cb4f06cdaaf463fd84e5e7581 /include | |
parent | 033c88d58b66a5bf61a9a4f0029c4fb771f0555e (diff) | |
parent | c3f834df191ac2e5e58c215b9110e7e19553100f (diff) |
Merge tag 'pm-5.20-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull more power management updates from Rafael Wysocki:
"These are ARM cpufreq updates and operating performance points (OPP)
updates plus one cpuidle update adding a new trace point.
Specifics:
- Fix return error code in mtk_cpu_dvfs_info_init (Yang Yingliang).
- Minor cleanups and support for new boards for Qcom cpufreq drivers
(Bryan O'Donoghue, Konrad Dybcio, Pierre Gondois, and Yicong Yang).
- Fix sparse warnings for Tegra cpufreq driver (Viresh Kumar).
- Make dev_pm_opp_set_regulators() accept NULL terminated list
(Viresh Kumar).
- Add dev_pm_opp_set_config() and friends and migrate other users and
helpers to using them (Viresh Kumar).
- Add support for multiple clocks for a device (Viresh Kumar and
Krzysztof Kozlowski).
- Configure resources before adding OPP table for Venus (Stanimir
Varbanov).
- Keep reference count up for opp->np and opp_table->np while they
are still in use (Liang He).
- Minor OPP cleanups (Viresh Kumar and Yang Li).
- Add a trace event for cpuidle to track missed (too deep or too
shallow) wakeups (Kajetan Puchalski)"
* tag 'pm-5.20-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (55 commits)
cpuidle: Add cpu_idle_miss trace event
venus: pm_helpers: Fix warning in OPP during probe
OPP: Don't drop opp->np reference while it is still in use
OPP: Don't drop opp_table->np reference while it is still in use
cpufreq: tegra194: Staticize struct tegra_cpufreq_soc instances
dt-bindings: cpufreq: cpufreq-qcom-hw: Add SM6375 compatible
dt-bindings: opp: Add msm8939 to the compatible list
dt-bindings: opp: Add missing compat devices
dt-bindings: opp: opp-v2-kryo-cpu: Fix example binding checks
cpufreq: Change order of online() CB and policy->cpus modification
cpufreq: qcom-hw: Remove deprecated irq_set_affinity_hint() call
cpufreq: qcom-hw: Disable LMH irq when disabling policy
cpufreq: qcom-hw: Reset cancel_throttle when policy is re-enabled
cpufreq: qcom-cpufreq-hw: use HZ_PER_KHZ macro in units.h
cpufreq: mediatek: fix error return code in mtk_cpu_dvfs_info_init()
OPP: Remove dev{m}_pm_opp_of_add_table_noclk()
PM / devfreq: tegra30: Register config_clks helper
OPP: Allow config_clks helper for single clk case
OPP: Provide a simple implementation to configure multiple clocks
OPP: Assert clk_count == 1 for single clk helpers
...
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/pm_opp.h | 322 | ||||
-rw-r--r-- | include/trace/events/power.h | 22 |
2 files changed, 216 insertions, 128 deletions
diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h index 6708b4ec244d..dc1fb5890792 100644 --- a/include/linux/pm_opp.h +++ b/include/linux/pm_opp.h @@ -57,37 +57,39 @@ struct dev_pm_opp_icc_bw { u32 peak; }; -/** - * struct dev_pm_opp_info - OPP freq/voltage/current values - * @rate: Target clk rate in hz - * @supplies: Array of voltage/current values for all power supplies - * - * This structure stores the freq/voltage/current values for a single OPP. - */ -struct dev_pm_opp_info { - unsigned long rate; - struct dev_pm_opp_supply *supplies; -}; +typedef int (*config_regulators_t)(struct device *dev, + struct dev_pm_opp *old_opp, struct dev_pm_opp *new_opp, + struct regulator **regulators, unsigned int count); + +typedef int (*config_clks_t)(struct device *dev, struct opp_table *opp_table, + struct dev_pm_opp *opp, void *data, bool scaling_down); /** - * struct dev_pm_set_opp_data - Set OPP data - * @old_opp: Old OPP info - * @new_opp: New OPP info - * @regulators: Array of regulator pointers - * @regulator_count: Number of regulators - * @clk: Pointer to clk - * @dev: Pointer to the struct device + * struct dev_pm_opp_config - Device OPP configuration values + * @clk_names: Clk names, NULL terminated array. + * @config_clks: Custom set clk helper. + * @prop_name: Name to postfix to properties. + * @config_regulators: Custom set regulator helper. + * @supported_hw: Array of hierarchy of versions to match. + * @supported_hw_count: Number of elements in the array. + * @regulator_names: Array of pointers to the names of the regulator, NULL terminated. + * @genpd_names: Null terminated array of pointers containing names of genpd to + * attach. + * @virt_devs: Pointer to return the array of virtual devices. * - * This structure contains all information required for setting an OPP. + * This structure contains platform specific OPP configurations for the device. */ -struct dev_pm_set_opp_data { - struct dev_pm_opp_info old_opp; - struct dev_pm_opp_info new_opp; - - struct regulator **regulators; - unsigned int regulator_count; - struct clk *clk; - struct device *dev; +struct dev_pm_opp_config { + /* NULL terminated */ + const char * const *clk_names; + config_clks_t config_clks; + const char *prop_name; + config_regulators_t config_regulators; + const unsigned int *supported_hw; + unsigned int supported_hw_count; + const char * const *regulator_names; + const char * const *genpd_names; + struct device ***virt_devs; }; #if defined(CONFIG_PM_OPP) @@ -97,6 +99,8 @@ void dev_pm_opp_put_opp_table(struct opp_table *opp_table); unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp); +int dev_pm_opp_get_supplies(struct dev_pm_opp *opp, struct dev_pm_opp_supply *supplies); + unsigned long dev_pm_opp_get_power(struct dev_pm_opp *opp); unsigned long dev_pm_opp_get_freq(struct dev_pm_opp *opp); @@ -119,8 +123,6 @@ struct dev_pm_opp *dev_pm_opp_find_freq_exact(struct device *dev, bool available); struct dev_pm_opp *dev_pm_opp_find_freq_floor(struct device *dev, unsigned long *freq); -struct dev_pm_opp *dev_pm_opp_find_freq_ceil_by_volt(struct device *dev, - unsigned long u_volt); struct dev_pm_opp *dev_pm_opp_find_level_exact(struct device *dev, unsigned int level); @@ -154,23 +156,13 @@ int dev_pm_opp_disable(struct device *dev, unsigned long freq); int dev_pm_opp_register_notifier(struct device *dev, struct notifier_block *nb); int dev_pm_opp_unregister_notifier(struct device *dev, struct notifier_block *nb); -struct opp_table *dev_pm_opp_set_supported_hw(struct device *dev, const u32 *versions, unsigned int count); -void dev_pm_opp_put_supported_hw(struct opp_table *opp_table); -int devm_pm_opp_set_supported_hw(struct device *dev, const u32 *versions, unsigned int count); -struct opp_table *dev_pm_opp_set_prop_name(struct device *dev, const char *name); -void dev_pm_opp_put_prop_name(struct opp_table *opp_table); -struct opp_table *dev_pm_opp_set_regulators(struct device *dev, const char * const names[], unsigned int count); -void dev_pm_opp_put_regulators(struct opp_table *opp_table); -int devm_pm_opp_set_regulators(struct device *dev, const char * const names[], unsigned int count); -struct opp_table *dev_pm_opp_set_clkname(struct device *dev, const char *name); -void dev_pm_opp_put_clkname(struct opp_table *opp_table); -int devm_pm_opp_set_clkname(struct device *dev, const char *name); -struct opp_table *dev_pm_opp_register_set_opp_helper(struct device *dev, int (*set_opp)(struct dev_pm_set_opp_data *data)); -void dev_pm_opp_unregister_set_opp_helper(struct opp_table *opp_table); -int devm_pm_opp_register_set_opp_helper(struct device *dev, int (*set_opp)(struct dev_pm_set_opp_data *data)); -struct opp_table *dev_pm_opp_attach_genpd(struct device *dev, const char * const *names, struct device ***virt_devs); -void dev_pm_opp_detach_genpd(struct opp_table *opp_table); -int devm_pm_opp_attach_genpd(struct device *dev, const char * const *names, struct device ***virt_devs); +int dev_pm_opp_set_config(struct device *dev, struct dev_pm_opp_config *config); +int devm_pm_opp_set_config(struct device *dev, struct dev_pm_opp_config *config); +void dev_pm_opp_clear_config(int token); +int dev_pm_opp_config_clks_simple(struct device *dev, + struct opp_table *opp_table, struct dev_pm_opp *opp, void *data, + bool scaling_down); + 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); int dev_pm_opp_xlate_performance_state(struct opp_table *src_table, struct opp_table *dst_table, unsigned int pstate); int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq); @@ -198,6 +190,11 @@ static inline unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp) return 0; } +static inline int dev_pm_opp_get_supplies(struct dev_pm_opp *opp, struct dev_pm_opp_supply *supplies) +{ + return -EOPNOTSUPP; +} + static inline unsigned long dev_pm_opp_get_power(struct dev_pm_opp *opp) { return 0; @@ -274,12 +271,6 @@ static inline struct dev_pm_opp *dev_pm_opp_find_freq_floor(struct device *dev, return ERR_PTR(-EOPNOTSUPP); } -static inline struct dev_pm_opp *dev_pm_opp_find_freq_ceil_by_volt(struct device *dev, - unsigned long u_volt) -{ - return ERR_PTR(-EOPNOTSUPP); -} - static inline struct dev_pm_opp *dev_pm_opp_find_freq_ceil(struct device *dev, unsigned long *freq) { @@ -342,79 +333,21 @@ static inline int dev_pm_opp_unregister_notifier(struct device *dev, struct noti return -EOPNOTSUPP; } -static inline struct opp_table *dev_pm_opp_set_supported_hw(struct device *dev, - const u32 *versions, - unsigned int count) -{ - return ERR_PTR(-EOPNOTSUPP); -} - -static inline void dev_pm_opp_put_supported_hw(struct opp_table *opp_table) {} - -static inline int devm_pm_opp_set_supported_hw(struct device *dev, - const u32 *versions, - unsigned int count) -{ - return -EOPNOTSUPP; -} - -static inline struct opp_table *dev_pm_opp_register_set_opp_helper(struct device *dev, - int (*set_opp)(struct dev_pm_set_opp_data *data)) -{ - return ERR_PTR(-EOPNOTSUPP); -} - -static inline void dev_pm_opp_unregister_set_opp_helper(struct opp_table *opp_table) {} - -static inline int devm_pm_opp_register_set_opp_helper(struct device *dev, - int (*set_opp)(struct dev_pm_set_opp_data *data)) -{ - return -EOPNOTSUPP; -} - -static inline struct opp_table *dev_pm_opp_set_prop_name(struct device *dev, const char *name) -{ - return ERR_PTR(-EOPNOTSUPP); -} - -static inline void dev_pm_opp_put_prop_name(struct opp_table *opp_table) {} - -static inline struct opp_table *dev_pm_opp_set_regulators(struct device *dev, const char * const names[], unsigned int count) -{ - return ERR_PTR(-EOPNOTSUPP); -} - -static inline void dev_pm_opp_put_regulators(struct opp_table *opp_table) {} - -static inline int devm_pm_opp_set_regulators(struct device *dev, - const char * const names[], - unsigned int count) +static inline int dev_pm_opp_set_config(struct device *dev, struct dev_pm_opp_config *config) { return -EOPNOTSUPP; } -static inline struct opp_table *dev_pm_opp_set_clkname(struct device *dev, const char *name) -{ - return ERR_PTR(-EOPNOTSUPP); -} - -static inline void dev_pm_opp_put_clkname(struct opp_table *opp_table) {} - -static inline int devm_pm_opp_set_clkname(struct device *dev, const char *name) +static inline int devm_pm_opp_set_config(struct device *dev, struct dev_pm_opp_config *config) { return -EOPNOTSUPP; } -static inline struct opp_table *dev_pm_opp_attach_genpd(struct device *dev, const char * const *names, struct device ***virt_devs) -{ - return ERR_PTR(-EOPNOTSUPP); -} - -static inline void dev_pm_opp_detach_genpd(struct opp_table *opp_table) {} +static inline void dev_pm_opp_clear_config(int token) {} -static inline int devm_pm_opp_attach_genpd(struct device *dev, - const char * const *names, - struct device ***virt_devs) +static inline int dev_pm_opp_config_clks_simple(struct device *dev, + struct opp_table *opp_table, struct dev_pm_opp *opp, void *data, + bool scaling_down) { return -EOPNOTSUPP; } @@ -469,8 +402,6 @@ static inline int dev_pm_opp_sync_regulators(struct device *dev) int dev_pm_opp_of_add_table(struct device *dev); int dev_pm_opp_of_add_table_indexed(struct device *dev, int index); int devm_pm_opp_of_add_table_indexed(struct device *dev, int index); -int dev_pm_opp_of_add_table_noclk(struct device *dev, int index); -int devm_pm_opp_of_add_table_noclk(struct device *dev, int index); void dev_pm_opp_of_remove_table(struct device *dev); int devm_pm_opp_of_add_table(struct device *dev); int dev_pm_opp_of_cpumask_add_table(const struct cpumask *cpumask); @@ -501,16 +432,6 @@ static inline int devm_pm_opp_of_add_table_indexed(struct device *dev, int index return -EOPNOTSUPP; } -static inline int dev_pm_opp_of_add_table_noclk(struct device *dev, int index) -{ - return -EOPNOTSUPP; -} - -static inline int devm_pm_opp_of_add_table_noclk(struct device *dev, int index) -{ - return -EOPNOTSUPP; -} - static inline void dev_pm_opp_of_remove_table(struct device *dev) { } @@ -565,4 +486,149 @@ static inline int dev_pm_opp_of_find_icc_paths(struct device *dev, struct opp_ta } #endif +/* OPP Configuration helpers */ + +/* Regulators helpers */ +static inline int dev_pm_opp_set_regulators(struct device *dev, + const char * const names[]) +{ + struct dev_pm_opp_config config = { + .regulator_names = names, + }; + + return dev_pm_opp_set_config(dev, &config); +} + +static inline void dev_pm_opp_put_regulators(int token) +{ + dev_pm_opp_clear_config(token); +} + +static inline int devm_pm_opp_set_regulators(struct device *dev, + const char * const names[]) +{ + struct dev_pm_opp_config config = { + .regulator_names = names, + }; + + return devm_pm_opp_set_config(dev, &config); +} + +/* Supported-hw helpers */ +static inline int dev_pm_opp_set_supported_hw(struct device *dev, + const u32 *versions, + unsigned int count) +{ + struct dev_pm_opp_config config = { + .supported_hw = versions, + .supported_hw_count = count, + }; + + return dev_pm_opp_set_config(dev, &config); +} + +static inline void dev_pm_opp_put_supported_hw(int token) +{ + dev_pm_opp_clear_config(token); +} + +static inline int devm_pm_opp_set_supported_hw(struct device *dev, + const u32 *versions, + unsigned int count) +{ + struct dev_pm_opp_config config = { + .supported_hw = versions, + .supported_hw_count = count, + }; + + return devm_pm_opp_set_config(dev, &config); +} + +/* clkname helpers */ +static inline int dev_pm_opp_set_clkname(struct device *dev, const char *name) +{ + const char *names[] = { name, NULL }; + struct dev_pm_opp_config config = { + .clk_names = names, + }; + + return dev_pm_opp_set_config(dev, &config); +} + +static inline void dev_pm_opp_put_clkname(int token) +{ + dev_pm_opp_clear_config(token); +} + +static inline int devm_pm_opp_set_clkname(struct device *dev, const char *name) +{ + const char *names[] = { name, NULL }; + struct dev_pm_opp_config config = { + .clk_names = names, + }; + + return devm_pm_opp_set_config(dev, &config); +} + +/* config-regulators helpers */ +static inline int dev_pm_opp_set_config_regulators(struct device *dev, + config_regulators_t helper) +{ + struct dev_pm_opp_config config = { + .config_regulators = helper, + }; + + return dev_pm_opp_set_config(dev, &config); +} + +static inline void dev_pm_opp_put_config_regulators(int token) +{ + dev_pm_opp_clear_config(token); +} + +/* genpd helpers */ +static inline int dev_pm_opp_attach_genpd(struct device *dev, + const char * const *names, + struct device ***virt_devs) +{ + struct dev_pm_opp_config config = { + .genpd_names = names, + .virt_devs = virt_devs, + }; + + return dev_pm_opp_set_config(dev, &config); +} + +static inline void dev_pm_opp_detach_genpd(int token) +{ + dev_pm_opp_clear_config(token); +} + +static inline int devm_pm_opp_attach_genpd(struct device *dev, + const char * const *names, + struct device ***virt_devs) +{ + struct dev_pm_opp_config config = { + .genpd_names = names, + .virt_devs = virt_devs, + }; + + return devm_pm_opp_set_config(dev, &config); +} + +/* prop-name helpers */ +static inline int dev_pm_opp_set_prop_name(struct device *dev, const char *name) +{ + struct dev_pm_opp_config config = { + .prop_name = name, + }; + + return dev_pm_opp_set_config(dev, &config); +} + +static inline void dev_pm_opp_put_prop_name(int token) +{ + dev_pm_opp_clear_config(token); +} + #endif /* __LINUX_OPP_H__ */ diff --git a/include/trace/events/power.h b/include/trace/events/power.h index c708521e4ed5..77f14f7a11d4 100644 --- a/include/trace/events/power.h +++ b/include/trace/events/power.h @@ -40,6 +40,28 @@ DEFINE_EVENT(cpu, cpu_idle, TP_ARGS(state, cpu_id) ); +TRACE_EVENT(cpu_idle_miss, + + TP_PROTO(unsigned int cpu_id, unsigned int state, bool below), + + TP_ARGS(cpu_id, state, below), + + TP_STRUCT__entry( + __field(u32, cpu_id) + __field(u32, state) + __field(bool, below) + ), + + TP_fast_assign( + __entry->cpu_id = cpu_id; + __entry->state = state; + __entry->below = below; + ), + + TP_printk("cpu_id=%lu state=%lu type=%s", (unsigned long)__entry->cpu_id, + (unsigned long)__entry->state, (__entry->below)?"below":"above") +); + TRACE_EVENT(powernv_throttle, TP_PROTO(int chip_id, const char *reason, int pmax), |