diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2022-08-03 17:49:38 +0200 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2022-08-03 17:49:38 +0200 |
commit | f6e0b468dab97a9214c9713c298ed9e2dd62f97f (patch) | |
tree | 4ddebb6700fa629c1c6bc549b376dd539b5ca4ad /drivers/cpufreq | |
parent | a771ea6413c00cf4af0570745f2e27084d7e2376 (diff) | |
parent | 1d95af02f23031c2e1cca7607c514b86ce85bc6e (diff) |
Merge tag 'opp-updates-5.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm
Pull operating performance points (OPP) updates for 5.20-rc1 from 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/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 cleanups (Viresh Kumar and Yang Li)."
* tag 'opp-updates-5.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm: (43 commits)
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
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
OPP: Add key specific assert() method to key finding helpers
OPP: Compare bandwidths for all paths in _opp_compare_key()
OPP: Allow multiple clocks for a device
dt-bindings: opp: accept array of frequencies
OPP: Make dev_pm_opp_set_opp() independent of frequency
OPP: Reuse _opp_compare_key() in _opp_add_static_v2()
OPP: Remove rate_not_available parameter to _opp_add()
OPP: Use consistent names for OPP table instances
OPP: Use generic key finding helpers for bandwidth key
OPP: Use generic key finding helpers for level key
OPP: Add generic key finding helpers and use them for freq APIs
OPP: Remove dev_pm_opp_find_freq_ceil_by_volt()
...
Diffstat (limited to 'drivers/cpufreq')
-rw-r--r-- | drivers/cpufreq/cpufreq-dt.c | 19 | ||||
-rw-r--r-- | drivers/cpufreq/imx-cpufreq-dt.c | 12 | ||||
-rw-r--r-- | drivers/cpufreq/qcom-cpufreq-nvmem.c | 109 | ||||
-rw-r--r-- | drivers/cpufreq/sti-cpufreq.c | 27 | ||||
-rw-r--r-- | drivers/cpufreq/sun50i-cpufreq-nvmem.c | 31 | ||||
-rw-r--r-- | drivers/cpufreq/tegra20-cpufreq.c | 12 | ||||
-rw-r--r-- | drivers/cpufreq/ti-cpufreq.c | 42 |
7 files changed, 88 insertions, 164 deletions
diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c index 8fcaba541539..d69d13a26414 100644 --- a/drivers/cpufreq/cpufreq-dt.c +++ b/drivers/cpufreq/cpufreq-dt.c @@ -29,9 +29,9 @@ struct private_data { cpumask_var_t cpus; struct device *cpu_dev; - struct opp_table *opp_table; struct cpufreq_frequency_table *freq_table; bool have_static_opps; + int opp_token; }; static LIST_HEAD(priv_list); @@ -193,7 +193,7 @@ static int dt_cpufreq_early_init(struct device *dev, int cpu) struct private_data *priv; struct device *cpu_dev; bool fallback = false; - const char *reg_name; + const char *reg_name[] = { NULL, NULL }; int ret; /* Check if this CPU is already covered by some other policy */ @@ -218,12 +218,11 @@ static int dt_cpufreq_early_init(struct device *dev, int cpu) * OPP layer will be taking care of regulators now, but it needs to know * the name of the regulator first. */ - reg_name = find_supply_name(cpu_dev); - if (reg_name) { - priv->opp_table = dev_pm_opp_set_regulators(cpu_dev, ®_name, - 1); - if (IS_ERR(priv->opp_table)) { - ret = PTR_ERR(priv->opp_table); + reg_name[0] = find_supply_name(cpu_dev); + if (reg_name[0]) { + priv->opp_token = dev_pm_opp_set_regulators(cpu_dev, reg_name); + if (priv->opp_token < 0) { + ret = priv->opp_token; if (ret != -EPROBE_DEFER) dev_err(cpu_dev, "failed to set regulators: %d\n", ret); @@ -295,7 +294,7 @@ static int dt_cpufreq_early_init(struct device *dev, int cpu) out: if (priv->have_static_opps) dev_pm_opp_of_cpumask_remove_table(priv->cpus); - dev_pm_opp_put_regulators(priv->opp_table); + dev_pm_opp_put_regulators(priv->opp_token); free_cpumask: free_cpumask_var(priv->cpus); return ret; @@ -309,7 +308,7 @@ static void dt_cpufreq_release(void) dev_pm_opp_free_cpufreq_table(priv->cpu_dev, &priv->freq_table); if (priv->have_static_opps) dev_pm_opp_of_cpumask_remove_table(priv->cpus); - dev_pm_opp_put_regulators(priv->opp_table); + dev_pm_opp_put_regulators(priv->opp_token); free_cpumask_var(priv->cpus); list_del(&priv->node); } diff --git a/drivers/cpufreq/imx-cpufreq-dt.c b/drivers/cpufreq/imx-cpufreq-dt.c index 3fe9125156b4..76e553af2071 100644 --- a/drivers/cpufreq/imx-cpufreq-dt.c +++ b/drivers/cpufreq/imx-cpufreq-dt.c @@ -31,8 +31,8 @@ /* cpufreq-dt device registered by imx-cpufreq-dt */ static struct platform_device *cpufreq_dt_pdev; -static struct opp_table *cpufreq_opp_table; static struct device *cpu_dev; +static int cpufreq_opp_token; enum IMX7ULP_CPUFREQ_CLKS { ARM, @@ -153,9 +153,9 @@ static int imx_cpufreq_dt_probe(struct platform_device *pdev) dev_info(&pdev->dev, "cpu speed grade %d mkt segment %d supported-hw %#x %#x\n", speed_grade, mkt_segment, supported_hw[0], supported_hw[1]); - cpufreq_opp_table = dev_pm_opp_set_supported_hw(cpu_dev, supported_hw, 2); - if (IS_ERR(cpufreq_opp_table)) { - ret = PTR_ERR(cpufreq_opp_table); + cpufreq_opp_token = dev_pm_opp_set_supported_hw(cpu_dev, supported_hw, 2); + if (cpufreq_opp_token < 0) { + ret = cpufreq_opp_token; dev_err(&pdev->dev, "Failed to set supported opp: %d\n", ret); return ret; } @@ -163,7 +163,7 @@ static int imx_cpufreq_dt_probe(struct platform_device *pdev) cpufreq_dt_pdev = platform_device_register_data( &pdev->dev, "cpufreq-dt", -1, NULL, 0); if (IS_ERR(cpufreq_dt_pdev)) { - dev_pm_opp_put_supported_hw(cpufreq_opp_table); + dev_pm_opp_put_supported_hw(cpufreq_opp_token); ret = PTR_ERR(cpufreq_dt_pdev); dev_err(&pdev->dev, "Failed to register cpufreq-dt: %d\n", ret); return ret; @@ -176,7 +176,7 @@ static int imx_cpufreq_dt_remove(struct platform_device *pdev) { platform_device_unregister(cpufreq_dt_pdev); if (!of_machine_is_compatible("fsl,imx7ulp")) - dev_pm_opp_put_supported_hw(cpufreq_opp_table); + dev_pm_opp_put_supported_hw(cpufreq_opp_token); else clk_bulk_put(ARRAY_SIZE(imx7ulp_clks), imx7ulp_clks); 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; diff --git a/drivers/cpufreq/sti-cpufreq.c b/drivers/cpufreq/sti-cpufreq.c index fdb0a722d881..a67df90848c2 100644 --- a/drivers/cpufreq/sti-cpufreq.c +++ b/drivers/cpufreq/sti-cpufreq.c @@ -156,9 +156,13 @@ static int sti_cpufreq_set_opp_info(void) unsigned int hw_info_offset; unsigned int version[VERSION_ELEMENTS]; int pcode, substrate, major, minor; - int ret; + int opp_token, ret; char name[MAX_PCODE_NAME_LEN]; - struct opp_table *opp_table; + struct dev_pm_opp_config config = { + .supported_hw = version, + .supported_hw_count = ARRAY_SIZE(version), + .prop_name = name, + }; reg_fields = sti_cpufreq_match(); if (!reg_fields) { @@ -210,21 +214,14 @@ use_defaults: snprintf(name, MAX_PCODE_NAME_LEN, "pcode%d", pcode); - opp_table = dev_pm_opp_set_prop_name(dev, name); - if (IS_ERR(opp_table)) { - dev_err(dev, "Failed to set prop name\n"); - return PTR_ERR(opp_table); - } - version[0] = BIT(major); version[1] = BIT(minor); version[2] = BIT(substrate); - opp_table = dev_pm_opp_set_supported_hw(dev, version, VERSION_ELEMENTS); - if (IS_ERR(opp_table)) { - dev_err(dev, "Failed to set supported hardware\n"); - ret = PTR_ERR(opp_table); - goto err_put_prop_name; + opp_token = dev_pm_opp_set_config(dev, &config); + if (opp_token < 0) { + dev_err(dev, "Failed to set OPP config\n"); + return opp_token; } dev_dbg(dev, "pcode: %d major: %d minor: %d substrate: %d\n", @@ -233,10 +230,6 @@ use_defaults: version[0], version[1], version[2]); return 0; - -err_put_prop_name: - dev_pm_opp_put_prop_name(opp_table); - return ret; } static int sti_cpufreq_fetch_syscon_registers(void) diff --git a/drivers/cpufreq/sun50i-cpufreq-nvmem.c b/drivers/cpufreq/sun50i-cpufreq-nvmem.c index 75e1bf3a08f7..a4922580ce06 100644 --- a/drivers/cpufreq/sun50i-cpufreq-nvmem.c +++ b/drivers/cpufreq/sun50i-cpufreq-nvmem.c @@ -86,20 +86,20 @@ static int sun50i_cpufreq_get_efuse(u32 *versions) static int sun50i_cpufreq_nvmem_probe(struct platform_device *pdev) { - struct opp_table **opp_tables; + int *opp_tokens; char name[MAX_NAME_LEN]; unsigned int cpu; u32 speed = 0; int ret; - opp_tables = kcalloc(num_possible_cpus(), sizeof(*opp_tables), + opp_tokens = kcalloc(num_possible_cpus(), sizeof(*opp_tokens), GFP_KERNEL); - if (!opp_tables) + if (!opp_tokens) return -ENOMEM; ret = sun50i_cpufreq_get_efuse(&speed); if (ret) { - kfree(opp_tables); + kfree(opp_tokens); return ret; } @@ -113,9 +113,9 @@ static int sun50i_cpufreq_nvmem_probe(struct platform_device *pdev) goto free_opp; } - opp_tables[cpu] = dev_pm_opp_set_prop_name(cpu_dev, name); - if (IS_ERR(opp_tables[cpu])) { - ret = PTR_ERR(opp_tables[cpu]); + opp_tokens[cpu] = dev_pm_opp_set_prop_name(cpu_dev, name); + if (opp_tokens[cpu] < 0) { + ret = opp_tokens[cpu]; pr_err("Failed to set prop name\n"); goto free_opp; } @@ -124,7 +124,7 @@ static int sun50i_cpufreq_nvmem_probe(struct platform_device *pdev) cpufreq_dt_pdev = platform_device_register_simple("cpufreq-dt", -1, NULL, 0); if (!IS_ERR(cpufreq_dt_pdev)) { - platform_set_drvdata(pdev, opp_tables); + platform_set_drvdata(pdev, opp_tokens); return 0; } @@ -132,27 +132,24 @@ static int sun50i_cpufreq_nvmem_probe(struct platform_device *pdev) pr_err("Failed to register platform device\n"); free_opp: - for_each_possible_cpu(cpu) { - if (IS_ERR_OR_NULL(opp_tables[cpu])) - break; - dev_pm_opp_put_prop_name(opp_tables[cpu]); - } - kfree(opp_tables); + for_each_possible_cpu(cpu) + dev_pm_opp_put_prop_name(opp_tokens[cpu]); + kfree(opp_tokens); return ret; } static int sun50i_cpufreq_nvmem_remove(struct platform_device *pdev) { - struct opp_table **opp_tables = platform_get_drvdata(pdev); + int *opp_tokens = platform_get_drvdata(pdev); unsigned int cpu; platform_device_unregister(cpufreq_dt_pdev); for_each_possible_cpu(cpu) - dev_pm_opp_put_prop_name(opp_tables[cpu]); + dev_pm_opp_put_prop_name(opp_tokens[cpu]); - kfree(opp_tables); + kfree(opp_tokens); return 0; } diff --git a/drivers/cpufreq/tegra20-cpufreq.c b/drivers/cpufreq/tegra20-cpufreq.c index e8db3d75be25..ab7ac7df9e62 100644 --- a/drivers/cpufreq/tegra20-cpufreq.c +++ b/drivers/cpufreq/tegra20-cpufreq.c @@ -32,9 +32,9 @@ static bool cpu0_node_has_opp_v2_prop(void) return ret; } -static void tegra20_cpufreq_put_supported_hw(void *opp_table) +static void tegra20_cpufreq_put_supported_hw(void *opp_token) { - dev_pm_opp_put_supported_hw(opp_table); + dev_pm_opp_put_supported_hw((unsigned long) opp_token); } static void tegra20_cpufreq_dt_unregister(void *cpufreq_dt) @@ -45,7 +45,6 @@ static void tegra20_cpufreq_dt_unregister(void *cpufreq_dt) static int tegra20_cpufreq_probe(struct platform_device *pdev) { struct platform_device *cpufreq_dt; - struct opp_table *opp_table; struct device *cpu_dev; u32 versions[2]; int err; @@ -71,16 +70,15 @@ static int tegra20_cpufreq_probe(struct platform_device *pdev) if (WARN_ON(!cpu_dev)) return -ENODEV; - opp_table = dev_pm_opp_set_supported_hw(cpu_dev, versions, 2); - err = PTR_ERR_OR_ZERO(opp_table); - if (err) { + err = dev_pm_opp_set_supported_hw(cpu_dev, versions, 2); + if (err < 0) { dev_err(&pdev->dev, "failed to set supported hw: %d\n", err); return err; } err = devm_add_action_or_reset(&pdev->dev, tegra20_cpufreq_put_supported_hw, - opp_table); + (void *)((unsigned long) err)); if (err) return err; diff --git a/drivers/cpufreq/ti-cpufreq.c b/drivers/cpufreq/ti-cpufreq.c index 8f9fdd864391..df85a77d476b 100644 --- a/drivers/cpufreq/ti-cpufreq.c +++ b/drivers/cpufreq/ti-cpufreq.c @@ -60,7 +60,6 @@ struct ti_cpufreq_data { struct device_node *opp_node; struct regmap *syscon; const struct ti_cpufreq_soc_data *soc_data; - struct opp_table *opp_table; }; static unsigned long amx3_efuse_xlate(struct ti_cpufreq_data *opp_data, @@ -173,7 +172,7 @@ static struct ti_cpufreq_soc_data omap34xx_soc_data = { * seems to always read as 0). */ -static const char * const omap3_reg_names[] = {"cpu0", "vbb"}; +static const char * const omap3_reg_names[] = {"cpu0", "vbb", NULL}; static struct ti_cpufreq_soc_data omap36xx_soc_data = { .reg_names = omap3_reg_names, @@ -324,10 +323,13 @@ static int ti_cpufreq_probe(struct platform_device *pdev) { u32 version[VERSION_COUNT]; const struct of_device_id *match; - struct opp_table *ti_opp_table; struct ti_cpufreq_data *opp_data; - const char * const default_reg_names[] = {"vdd", "vbb"}; + const char * const default_reg_names[] = {"vdd", "vbb", NULL}; int ret; + struct dev_pm_opp_config config = { + .supported_hw = version, + .supported_hw_count = ARRAY_SIZE(version), + }; match = dev_get_platdata(&pdev->dev); if (!match) @@ -370,33 +372,21 @@ static int ti_cpufreq_probe(struct platform_device *pdev) if (ret) goto fail_put_node; - ti_opp_table = dev_pm_opp_set_supported_hw(opp_data->cpu_dev, - version, VERSION_COUNT); - if (IS_ERR(ti_opp_table)) { - dev_err(opp_data->cpu_dev, - "Failed to set supported hardware\n"); - ret = PTR_ERR(ti_opp_table); - goto fail_put_node; - } - - opp_data->opp_table = ti_opp_table; - if (opp_data->soc_data->multi_regulator) { - const char * const *reg_names = default_reg_names; - if (opp_data->soc_data->reg_names) - reg_names = opp_data->soc_data->reg_names; - ti_opp_table = dev_pm_opp_set_regulators(opp_data->cpu_dev, - reg_names, - ARRAY_SIZE(default_reg_names)); - if (IS_ERR(ti_opp_table)) { - dev_pm_opp_put_supported_hw(opp_data->opp_table); - ret = PTR_ERR(ti_opp_table); - goto fail_put_node; - } + config.regulator_names = opp_data->soc_data->reg_names; + else + config.regulator_names = default_reg_names; + } + + ret = dev_pm_opp_set_config(opp_data->cpu_dev, &config); + if (ret < 0) { + dev_err(opp_data->cpu_dev, "Failed to set OPP config\n"); + goto fail_put_node; } of_node_put(opp_data->opp_node); + register_cpufreq_dt: platform_device_register_simple("cpufreq-dt", -1, NULL, 0); |