Skip to content

Commit

Permalink
Merge tag 'opp-updates-5.20-rc1' of git://git.kernel.org/pub/scm/linu…
Browse files Browse the repository at this point in the history
…x/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()
  ...
  • Loading branch information
Rafael J. Wysocki committed Aug 3, 2022
2 parents a771ea6 + 1d95af0 commit f6e0b46
Show file tree
Hide file tree
Showing 24 changed files with 1,356 additions and 1,274 deletions.
10 changes: 10 additions & 0 deletions Documentation/devicetree/bindings/opp/opp-v2-base.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,16 @@ patternProperties:
property to uniquely identify the OPP nodes exists. Devices like power
domains must have another (implementation dependent) property.

Entries for multiple clocks shall be provided in the same field, as
array of frequencies. The OPP binding doesn't provide any provisions
to relate the values to their clocks or the order in which the clocks
need to be configured and that is left for the implementation
specific binding.
minItems: 1
maxItems: 16
items:
maxItems: 1

opp-microvolt:
description: |
Voltage for the OPP
Expand Down
19 changes: 9 additions & 10 deletions drivers/cpufreq/cpufreq-dt.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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 */
Expand All @@ -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, &reg_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);
Expand Down Expand Up @@ -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;
Expand All @@ -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);
}
Expand Down
12 changes: 6 additions & 6 deletions drivers/cpufreq/imx-cpufreq-dt.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -153,17 +153,17 @@ 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;
}

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;
Expand All @@ -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);

Expand Down
109 changes: 28 additions & 81 deletions drivers/cpufreq/qcom-cpufreq-nvmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
Expand Down Expand Up @@ -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;
}
}
}
Expand All @@ -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);

Expand All @@ -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;
Expand Down
27 changes: 10 additions & 17 deletions drivers/cpufreq/sti-cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -210,21 +214,14 @@ static int sti_cpufreq_set_opp_info(void)

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",
Expand All @@ -233,10 +230,6 @@ static int sti_cpufreq_set_opp_info(void)
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)
Expand Down
Loading

0 comments on commit f6e0b46

Please sign in to comment.