summaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq/qcom-cpufreq-nvmem.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2022-08-08 14:29:00 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2022-08-08 14:29:00 -0700
commit507f811f205c17fd6f64e8d34d4bf91cd01b07a2 (patch)
tree72f4abfa45964c4cb4f06cdaaf463fd84e5e7581 /drivers/cpufreq/qcom-cpufreq-nvmem.c
parent033c88d58b66a5bf61a9a4f0029c4fb771f0555e (diff)
parentc3f834df191ac2e5e58c215b9110e7e19553100f (diff)
downloadlinux-507f811f205c17fd6f64e8d34d4bf91cd01b07a2.tar.bz2
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 'drivers/cpufreq/qcom-cpufreq-nvmem.c')
-rw-r--r--drivers/cpufreq/qcom-cpufreq-nvmem.c109
1 files changed, 28 insertions, 81 deletions
diff --git a/drivers/cpufreq/qcom-cpufreq-nvmem.c b/drivers/cpufreq/qcom-cpufreq-nvmem.c
index 6dfa86971a75..863548f59c3e 100644
--- a/drivers/cpufreq/qcom-cpufreq-nvmem.c
+++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c
@@ -55,9 +55,7 @@ struct qcom_cpufreq_match_data {
};
struct qcom_cpufreq_drv {
- struct opp_table **names_opp_tables;
- struct opp_table **hw_opp_tables;
- struct opp_table **genpd_opp_tables;
+ int *opp_tokens;
u32 versions;
const struct qcom_cpufreq_match_data *data;
};
@@ -315,72 +313,43 @@ static int qcom_cpufreq_probe(struct platform_device *pdev)
}
of_node_put(np);
- drv->names_opp_tables = kcalloc(num_possible_cpus(),
- sizeof(*drv->names_opp_tables),
+ drv->opp_tokens = kcalloc(num_possible_cpus(), sizeof(*drv->opp_tokens),
GFP_KERNEL);
- if (!drv->names_opp_tables) {
+ if (!drv->opp_tokens) {
ret = -ENOMEM;
goto free_drv;
}
- drv->hw_opp_tables = kcalloc(num_possible_cpus(),
- sizeof(*drv->hw_opp_tables),
- GFP_KERNEL);
- if (!drv->hw_opp_tables) {
- ret = -ENOMEM;
- goto free_opp_names;
- }
-
- drv->genpd_opp_tables = kcalloc(num_possible_cpus(),
- sizeof(*drv->genpd_opp_tables),
- GFP_KERNEL);
- if (!drv->genpd_opp_tables) {
- ret = -ENOMEM;
- goto free_opp;
- }
for_each_possible_cpu(cpu) {
+ struct dev_pm_opp_config config = {
+ .supported_hw = NULL,
+ };
+
cpu_dev = get_cpu_device(cpu);
if (NULL == cpu_dev) {
ret = -ENODEV;
- goto free_genpd_opp;
+ goto free_opp;
}
if (drv->data->get_version) {
+ config.supported_hw = &drv->versions;
+ config.supported_hw_count = 1;
- if (pvs_name) {
- drv->names_opp_tables[cpu] = dev_pm_opp_set_prop_name(
- cpu_dev,
- pvs_name);
- if (IS_ERR(drv->names_opp_tables[cpu])) {
- ret = PTR_ERR(drv->names_opp_tables[cpu]);
- dev_err(cpu_dev, "Failed to add OPP name %s\n",
- pvs_name);
- goto free_opp;
- }
- }
-
- drv->hw_opp_tables[cpu] = dev_pm_opp_set_supported_hw(
- cpu_dev, &drv->versions, 1);
- if (IS_ERR(drv->hw_opp_tables[cpu])) {
- ret = PTR_ERR(drv->hw_opp_tables[cpu]);
- dev_err(cpu_dev,
- "Failed to set supported hardware\n");
- goto free_genpd_opp;
- }
+ if (pvs_name)
+ config.prop_name = pvs_name;
}
if (drv->data->genpd_names) {
- drv->genpd_opp_tables[cpu] =
- dev_pm_opp_attach_genpd(cpu_dev,
- drv->data->genpd_names,
- NULL);
- if (IS_ERR(drv->genpd_opp_tables[cpu])) {
- ret = PTR_ERR(drv->genpd_opp_tables[cpu]);
- if (ret != -EPROBE_DEFER)
- dev_err(cpu_dev,
- "Could not attach to pm_domain: %d\n",
- ret);
- goto free_genpd_opp;
+ config.genpd_names = drv->data->genpd_names;
+ config.virt_devs = NULL;
+ }
+
+ if (config.supported_hw || config.genpd_names) {
+ drv->opp_tokens[cpu] = dev_pm_opp_set_config(cpu_dev, &config);
+ if (drv->opp_tokens[cpu] < 0) {
+ ret = drv->opp_tokens[cpu];
+ dev_err(cpu_dev, "Failed to set OPP config\n");
+ goto free_opp;
}
}
}
@@ -395,27 +364,10 @@ static int qcom_cpufreq_probe(struct platform_device *pdev)
ret = PTR_ERR(cpufreq_dt_pdev);
dev_err(cpu_dev, "Failed to register platform device\n");
-free_genpd_opp:
- for_each_possible_cpu(cpu) {
- if (IS_ERR(drv->genpd_opp_tables[cpu]))
- break;
- dev_pm_opp_detach_genpd(drv->genpd_opp_tables[cpu]);
- }
- kfree(drv->genpd_opp_tables);
free_opp:
- for_each_possible_cpu(cpu) {
- if (IS_ERR(drv->names_opp_tables[cpu]))
- break;
- dev_pm_opp_put_prop_name(drv->names_opp_tables[cpu]);
- }
- for_each_possible_cpu(cpu) {
- if (IS_ERR(drv->hw_opp_tables[cpu]))
- break;
- dev_pm_opp_put_supported_hw(drv->hw_opp_tables[cpu]);
- }
- kfree(drv->hw_opp_tables);
-free_opp_names:
- kfree(drv->names_opp_tables);
+ for_each_possible_cpu(cpu)
+ dev_pm_opp_clear_config(drv->opp_tokens[cpu]);
+ kfree(drv->opp_tokens);
free_drv:
kfree(drv);
@@ -429,15 +381,10 @@ static int qcom_cpufreq_remove(struct platform_device *pdev)
platform_device_unregister(cpufreq_dt_pdev);
- for_each_possible_cpu(cpu) {
- dev_pm_opp_put_supported_hw(drv->names_opp_tables[cpu]);
- dev_pm_opp_put_supported_hw(drv->hw_opp_tables[cpu]);
- dev_pm_opp_detach_genpd(drv->genpd_opp_tables[cpu]);
- }
+ for_each_possible_cpu(cpu)
+ dev_pm_opp_clear_config(drv->opp_tokens[cpu]);
- kfree(drv->names_opp_tables);
- kfree(drv->hw_opp_tables);
- kfree(drv->genpd_opp_tables);
+ kfree(drv->opp_tokens);
kfree(drv);
return 0;