@@ -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
3940static 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+
122147static 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 );
367408out_free_opp :
368409 dev_pm_opp_of_cpumask_remove_table (policy -> cpus );
410+ if (name )
411+ dev_pm_opp_put_regulator (cpu_dev );
369412out_node_put :
370413 of_node_put (np );
371414out_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