Skip to content

Commit 99753a2

Browse files
vireshkAlex Shi
authored andcommitted
cpufreq: dt: Pass regulator name to the OPP core
OPP core can handle the regulators by itself, and but it needs to know the name of the regulator to fetch. Add support for that. Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> Reviewed-by: Stephen Boyd <sboyd@codeaurora.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> (cherry picked from commit 050794aaebbb9f2c2c50b340b6998273e7c64189) Signed-off-by: Alex Shi <alex.shi@linaro.org>
1 parent c9be304 commit 99753a2

1 file changed

Lines changed: 46 additions & 0 deletions

File tree

drivers/cpufreq/cpufreq-dt.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ struct private_data {
3434
struct regulator *cpu_reg;
3535
struct thermal_cooling_device *cdev;
3636
unsigned int voltage_tolerance; /* in percentage */
37+
const char *reg_name;
3738
};
3839

3940
static struct freq_attr *cpufreq_dt_attr[] = {
@@ -119,6 +120,30 @@ static int set_target(struct cpufreq_policy *policy, unsigned int index)
119120
return ret;
120121
}
121122

123+
/*
124+
* An earlier version of opp-v1 bindings used to name the regulator
125+
* "cpu0-supply", we still need to handle that for backwards compatibility.
126+
*/
127+
static const char *find_supply_name(struct device *dev, struct device_node *np)
128+
{
129+
struct property *pp;
130+
int cpu = dev->id;
131+
132+
/* Try "cpu0" for older DTs */
133+
if (!cpu) {
134+
pp = of_find_property(np, "cpu0-supply", NULL);
135+
if (pp)
136+
return "cpu0";
137+
}
138+
139+
pp = of_find_property(np, "cpu-supply", NULL);
140+
if (pp)
141+
return "cpu";
142+
143+
dev_dbg(dev, "no regulator for cpu%d\n", cpu);
144+
return NULL;
145+
}
146+
122147
static int allocate_resources(int cpu, struct device **cdev,
123148
struct regulator **creg, struct clk **cclk)
124149
{
@@ -200,6 +225,7 @@ static int cpufreq_init(struct cpufreq_policy *policy)
200225
unsigned long min_uV = ~0, max_uV = 0;
201226
unsigned int transition_latency;
202227
bool opp_v1 = false;
228+
const char *name;
203229
int ret;
204230

205231
ret = allocate_resources(policy->cpu, &cpu_dev, &cpu_reg, &cpu_clk);
@@ -228,6 +254,20 @@ static int cpufreq_init(struct cpufreq_policy *policy)
228254
goto out_node_put;
229255
}
230256

257+
/*
258+
* OPP layer will be taking care of regulators now, but it needs to know
259+
* the name of the regulator first.
260+
*/
261+
name = find_supply_name(cpu_dev, np);
262+
if (name) {
263+
ret = dev_pm_opp_set_regulator(cpu_dev, name);
264+
if (ret) {
265+
dev_err(cpu_dev, "Failed to set regulator for cpu%d: %d\n",
266+
policy->cpu, ret);
267+
goto out_node_put;
268+
}
269+
}
270+
231271
/*
232272
* Initialize OPP tables for all policy->cpus. They will be shared by
233273
* all CPUs which have marked their CPUs shared with OPP bindings.
@@ -273,6 +313,7 @@ static int cpufreq_init(struct cpufreq_policy *policy)
273313
goto out_free_opp;
274314
}
275315

316+
priv->reg_name = name;
276317
of_property_read_u32(np, "voltage-tolerance", &priv->voltage_tolerance);
277318

278319
transition_latency = dev_pm_opp_get_max_clock_latency(cpu_dev);
@@ -366,6 +407,8 @@ static int cpufreq_init(struct cpufreq_policy *policy)
366407
kfree(priv);
367408
out_free_opp:
368409
dev_pm_opp_of_cpumask_remove_table(policy->cpus);
410+
if (name)
411+
dev_pm_opp_put_regulator(cpu_dev);
369412
out_node_put:
370413
of_node_put(np);
371414
out_put_reg_clk:
@@ -383,6 +426,9 @@ static int cpufreq_exit(struct cpufreq_policy *policy)
383426
cpufreq_cooling_unregister(priv->cdev);
384427
dev_pm_opp_free_cpufreq_table(priv->cpu_dev, &policy->freq_table);
385428
dev_pm_opp_of_cpumask_remove_table(policy->related_cpus);
429+
if (priv->reg_name)
430+
dev_pm_opp_put_regulator(priv->cpu_dev);
431+
386432
clk_put(policy->clk);
387433
if (!IS_ERR(priv->cpu_reg))
388434
regulator_put(priv->cpu_reg);

0 commit comments

Comments
 (0)