Skip to content

Commit f6e0b46

Browse files
committed
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() ...
2 parents a771ea6 + 1d95af0 commit f6e0b46

File tree

24 files changed

+1356
-1274
lines changed

24 files changed

+1356
-1274
lines changed

Documentation/devicetree/bindings/opp/opp-v2-base.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,16 @@ patternProperties:
5050
property to uniquely identify the OPP nodes exists. Devices like power
5151
domains must have another (implementation dependent) property.
5252

53+
Entries for multiple clocks shall be provided in the same field, as
54+
array of frequencies. The OPP binding doesn't provide any provisions
55+
to relate the values to their clocks or the order in which the clocks
56+
need to be configured and that is left for the implementation
57+
specific binding.
58+
minItems: 1
59+
maxItems: 16
60+
items:
61+
maxItems: 1
62+
5363
opp-microvolt:
5464
description: |
5565
Voltage for the OPP

drivers/cpufreq/cpufreq-dt.c

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ struct private_data {
2929

3030
cpumask_var_t cpus;
3131
struct device *cpu_dev;
32-
struct opp_table *opp_table;
3332
struct cpufreq_frequency_table *freq_table;
3433
bool have_static_opps;
34+
int opp_token;
3535
};
3636

3737
static LIST_HEAD(priv_list);
@@ -193,7 +193,7 @@ static int dt_cpufreq_early_init(struct device *dev, int cpu)
193193
struct private_data *priv;
194194
struct device *cpu_dev;
195195
bool fallback = false;
196-
const char *reg_name;
196+
const char *reg_name[] = { NULL, NULL };
197197
int ret;
198198

199199
/* 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)
218218
* OPP layer will be taking care of regulators now, but it needs to know
219219
* the name of the regulator first.
220220
*/
221-
reg_name = find_supply_name(cpu_dev);
222-
if (reg_name) {
223-
priv->opp_table = dev_pm_opp_set_regulators(cpu_dev, &reg_name,
224-
1);
225-
if (IS_ERR(priv->opp_table)) {
226-
ret = PTR_ERR(priv->opp_table);
221+
reg_name[0] = find_supply_name(cpu_dev);
222+
if (reg_name[0]) {
223+
priv->opp_token = dev_pm_opp_set_regulators(cpu_dev, reg_name);
224+
if (priv->opp_token < 0) {
225+
ret = priv->opp_token;
227226
if (ret != -EPROBE_DEFER)
228227
dev_err(cpu_dev, "failed to set regulators: %d\n",
229228
ret);
@@ -295,7 +294,7 @@ static int dt_cpufreq_early_init(struct device *dev, int cpu)
295294
out:
296295
if (priv->have_static_opps)
297296
dev_pm_opp_of_cpumask_remove_table(priv->cpus);
298-
dev_pm_opp_put_regulators(priv->opp_table);
297+
dev_pm_opp_put_regulators(priv->opp_token);
299298
free_cpumask:
300299
free_cpumask_var(priv->cpus);
301300
return ret;
@@ -309,7 +308,7 @@ static void dt_cpufreq_release(void)
309308
dev_pm_opp_free_cpufreq_table(priv->cpu_dev, &priv->freq_table);
310309
if (priv->have_static_opps)
311310
dev_pm_opp_of_cpumask_remove_table(priv->cpus);
312-
dev_pm_opp_put_regulators(priv->opp_table);
311+
dev_pm_opp_put_regulators(priv->opp_token);
313312
free_cpumask_var(priv->cpus);
314313
list_del(&priv->node);
315314
}

drivers/cpufreq/imx-cpufreq-dt.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@
3131

3232
/* cpufreq-dt device registered by imx-cpufreq-dt */
3333
static struct platform_device *cpufreq_dt_pdev;
34-
static struct opp_table *cpufreq_opp_table;
3534
static struct device *cpu_dev;
35+
static int cpufreq_opp_token;
3636

3737
enum IMX7ULP_CPUFREQ_CLKS {
3838
ARM,
@@ -153,17 +153,17 @@ static int imx_cpufreq_dt_probe(struct platform_device *pdev)
153153
dev_info(&pdev->dev, "cpu speed grade %d mkt segment %d supported-hw %#x %#x\n",
154154
speed_grade, mkt_segment, supported_hw[0], supported_hw[1]);
155155

156-
cpufreq_opp_table = dev_pm_opp_set_supported_hw(cpu_dev, supported_hw, 2);
157-
if (IS_ERR(cpufreq_opp_table)) {
158-
ret = PTR_ERR(cpufreq_opp_table);
156+
cpufreq_opp_token = dev_pm_opp_set_supported_hw(cpu_dev, supported_hw, 2);
157+
if (cpufreq_opp_token < 0) {
158+
ret = cpufreq_opp_token;
159159
dev_err(&pdev->dev, "Failed to set supported opp: %d\n", ret);
160160
return ret;
161161
}
162162

163163
cpufreq_dt_pdev = platform_device_register_data(
164164
&pdev->dev, "cpufreq-dt", -1, NULL, 0);
165165
if (IS_ERR(cpufreq_dt_pdev)) {
166-
dev_pm_opp_put_supported_hw(cpufreq_opp_table);
166+
dev_pm_opp_put_supported_hw(cpufreq_opp_token);
167167
ret = PTR_ERR(cpufreq_dt_pdev);
168168
dev_err(&pdev->dev, "Failed to register cpufreq-dt: %d\n", ret);
169169
return ret;
@@ -176,7 +176,7 @@ static int imx_cpufreq_dt_remove(struct platform_device *pdev)
176176
{
177177
platform_device_unregister(cpufreq_dt_pdev);
178178
if (!of_machine_is_compatible("fsl,imx7ulp"))
179-
dev_pm_opp_put_supported_hw(cpufreq_opp_table);
179+
dev_pm_opp_put_supported_hw(cpufreq_opp_token);
180180
else
181181
clk_bulk_put(ARRAY_SIZE(imx7ulp_clks), imx7ulp_clks);
182182

drivers/cpufreq/qcom-cpufreq-nvmem.c

Lines changed: 28 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,7 @@ struct qcom_cpufreq_match_data {
5555
};
5656

5757
struct qcom_cpufreq_drv {
58-
struct opp_table **names_opp_tables;
59-
struct opp_table **hw_opp_tables;
60-
struct opp_table **genpd_opp_tables;
58+
int *opp_tokens;
6159
u32 versions;
6260
const struct qcom_cpufreq_match_data *data;
6361
};
@@ -315,72 +313,43 @@ static int qcom_cpufreq_probe(struct platform_device *pdev)
315313
}
316314
of_node_put(np);
317315

318-
drv->names_opp_tables = kcalloc(num_possible_cpus(),
319-
sizeof(*drv->names_opp_tables),
316+
drv->opp_tokens = kcalloc(num_possible_cpus(), sizeof(*drv->opp_tokens),
320317
GFP_KERNEL);
321-
if (!drv->names_opp_tables) {
318+
if (!drv->opp_tokens) {
322319
ret = -ENOMEM;
323320
goto free_drv;
324321
}
325-
drv->hw_opp_tables = kcalloc(num_possible_cpus(),
326-
sizeof(*drv->hw_opp_tables),
327-
GFP_KERNEL);
328-
if (!drv->hw_opp_tables) {
329-
ret = -ENOMEM;
330-
goto free_opp_names;
331-
}
332-
333-
drv->genpd_opp_tables = kcalloc(num_possible_cpus(),
334-
sizeof(*drv->genpd_opp_tables),
335-
GFP_KERNEL);
336-
if (!drv->genpd_opp_tables) {
337-
ret = -ENOMEM;
338-
goto free_opp;
339-
}
340322

341323
for_each_possible_cpu(cpu) {
324+
struct dev_pm_opp_config config = {
325+
.supported_hw = NULL,
326+
};
327+
342328
cpu_dev = get_cpu_device(cpu);
343329
if (NULL == cpu_dev) {
344330
ret = -ENODEV;
345-
goto free_genpd_opp;
331+
goto free_opp;
346332
}
347333

348334
if (drv->data->get_version) {
335+
config.supported_hw = &drv->versions;
336+
config.supported_hw_count = 1;
349337

350-
if (pvs_name) {
351-
drv->names_opp_tables[cpu] = dev_pm_opp_set_prop_name(
352-
cpu_dev,
353-
pvs_name);
354-
if (IS_ERR(drv->names_opp_tables[cpu])) {
355-
ret = PTR_ERR(drv->names_opp_tables[cpu]);
356-
dev_err(cpu_dev, "Failed to add OPP name %s\n",
357-
pvs_name);
358-
goto free_opp;
359-
}
360-
}
361-
362-
drv->hw_opp_tables[cpu] = dev_pm_opp_set_supported_hw(
363-
cpu_dev, &drv->versions, 1);
364-
if (IS_ERR(drv->hw_opp_tables[cpu])) {
365-
ret = PTR_ERR(drv->hw_opp_tables[cpu]);
366-
dev_err(cpu_dev,
367-
"Failed to set supported hardware\n");
368-
goto free_genpd_opp;
369-
}
338+
if (pvs_name)
339+
config.prop_name = pvs_name;
370340
}
371341

372342
if (drv->data->genpd_names) {
373-
drv->genpd_opp_tables[cpu] =
374-
dev_pm_opp_attach_genpd(cpu_dev,
375-
drv->data->genpd_names,
376-
NULL);
377-
if (IS_ERR(drv->genpd_opp_tables[cpu])) {
378-
ret = PTR_ERR(drv->genpd_opp_tables[cpu]);
379-
if (ret != -EPROBE_DEFER)
380-
dev_err(cpu_dev,
381-
"Could not attach to pm_domain: %d\n",
382-
ret);
383-
goto free_genpd_opp;
343+
config.genpd_names = drv->data->genpd_names;
344+
config.virt_devs = NULL;
345+
}
346+
347+
if (config.supported_hw || config.genpd_names) {
348+
drv->opp_tokens[cpu] = dev_pm_opp_set_config(cpu_dev, &config);
349+
if (drv->opp_tokens[cpu] < 0) {
350+
ret = drv->opp_tokens[cpu];
351+
dev_err(cpu_dev, "Failed to set OPP config\n");
352+
goto free_opp;
384353
}
385354
}
386355
}
@@ -395,27 +364,10 @@ static int qcom_cpufreq_probe(struct platform_device *pdev)
395364
ret = PTR_ERR(cpufreq_dt_pdev);
396365
dev_err(cpu_dev, "Failed to register platform device\n");
397366

398-
free_genpd_opp:
399-
for_each_possible_cpu(cpu) {
400-
if (IS_ERR(drv->genpd_opp_tables[cpu]))
401-
break;
402-
dev_pm_opp_detach_genpd(drv->genpd_opp_tables[cpu]);
403-
}
404-
kfree(drv->genpd_opp_tables);
405367
free_opp:
406-
for_each_possible_cpu(cpu) {
407-
if (IS_ERR(drv->names_opp_tables[cpu]))
408-
break;
409-
dev_pm_opp_put_prop_name(drv->names_opp_tables[cpu]);
410-
}
411-
for_each_possible_cpu(cpu) {
412-
if (IS_ERR(drv->hw_opp_tables[cpu]))
413-
break;
414-
dev_pm_opp_put_supported_hw(drv->hw_opp_tables[cpu]);
415-
}
416-
kfree(drv->hw_opp_tables);
417-
free_opp_names:
418-
kfree(drv->names_opp_tables);
368+
for_each_possible_cpu(cpu)
369+
dev_pm_opp_clear_config(drv->opp_tokens[cpu]);
370+
kfree(drv->opp_tokens);
419371
free_drv:
420372
kfree(drv);
421373

@@ -429,15 +381,10 @@ static int qcom_cpufreq_remove(struct platform_device *pdev)
429381

430382
platform_device_unregister(cpufreq_dt_pdev);
431383

432-
for_each_possible_cpu(cpu) {
433-
dev_pm_opp_put_supported_hw(drv->names_opp_tables[cpu]);
434-
dev_pm_opp_put_supported_hw(drv->hw_opp_tables[cpu]);
435-
dev_pm_opp_detach_genpd(drv->genpd_opp_tables[cpu]);
436-
}
384+
for_each_possible_cpu(cpu)
385+
dev_pm_opp_clear_config(drv->opp_tokens[cpu]);
437386

438-
kfree(drv->names_opp_tables);
439-
kfree(drv->hw_opp_tables);
440-
kfree(drv->genpd_opp_tables);
387+
kfree(drv->opp_tokens);
441388
kfree(drv);
442389

443390
return 0;

drivers/cpufreq/sti-cpufreq.c

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,13 @@ static int sti_cpufreq_set_opp_info(void)
156156
unsigned int hw_info_offset;
157157
unsigned int version[VERSION_ELEMENTS];
158158
int pcode, substrate, major, minor;
159-
int ret;
159+
int opp_token, ret;
160160
char name[MAX_PCODE_NAME_LEN];
161-
struct opp_table *opp_table;
161+
struct dev_pm_opp_config config = {
162+
.supported_hw = version,
163+
.supported_hw_count = ARRAY_SIZE(version),
164+
.prop_name = name,
165+
};
162166

163167
reg_fields = sti_cpufreq_match();
164168
if (!reg_fields) {
@@ -210,21 +214,14 @@ static int sti_cpufreq_set_opp_info(void)
210214

211215
snprintf(name, MAX_PCODE_NAME_LEN, "pcode%d", pcode);
212216

213-
opp_table = dev_pm_opp_set_prop_name(dev, name);
214-
if (IS_ERR(opp_table)) {
215-
dev_err(dev, "Failed to set prop name\n");
216-
return PTR_ERR(opp_table);
217-
}
218-
219217
version[0] = BIT(major);
220218
version[1] = BIT(minor);
221219
version[2] = BIT(substrate);
222220

223-
opp_table = dev_pm_opp_set_supported_hw(dev, version, VERSION_ELEMENTS);
224-
if (IS_ERR(opp_table)) {
225-
dev_err(dev, "Failed to set supported hardware\n");
226-
ret = PTR_ERR(opp_table);
227-
goto err_put_prop_name;
221+
opp_token = dev_pm_opp_set_config(dev, &config);
222+
if (opp_token < 0) {
223+
dev_err(dev, "Failed to set OPP config\n");
224+
return opp_token;
228225
}
229226

230227
dev_dbg(dev, "pcode: %d major: %d minor: %d substrate: %d\n",
@@ -233,10 +230,6 @@ static int sti_cpufreq_set_opp_info(void)
233230
version[0], version[1], version[2]);
234231

235232
return 0;
236-
237-
err_put_prop_name:
238-
dev_pm_opp_put_prop_name(opp_table);
239-
return ret;
240233
}
241234

242235
static int sti_cpufreq_fetch_syscon_registers(void)

0 commit comments

Comments
 (0)