Skip to content

Commit

Permalink
cpufreq: dt: Add support for operating-points-v2 bindings
Browse files Browse the repository at this point in the history
Support for parsing operating-points-v2 bindings is in place now, lets
modify cpufreq-dt driver to use them.

For backward compatibility we will continue to support earlier bindings.
Special handling for that is required, to make sure OPPs are initialized
for all the CPUs.

Reviewed-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
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>
  • Loading branch information
Viresh Kumar authored and Rafael J. Wysocki committed Aug 7, 2015
1 parent 44139ed commit 2e02d87
Showing 1 changed file with 46 additions and 10 deletions.
56 changes: 46 additions & 10 deletions drivers/cpufreq/cpufreq-dt.c
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,6 @@ static int allocate_resources(int cpu, struct device **cdev,

static int cpufreq_init(struct cpufreq_policy *policy)
{
struct cpufreq_dt_platform_data *pd;
struct cpufreq_frequency_table *freq_table;
struct device_node *np;
struct private_data *priv;
Expand All @@ -193,6 +192,7 @@ static int cpufreq_init(struct cpufreq_policy *policy)
struct clk *cpu_clk;
unsigned long min_uV = ~0, max_uV = 0;
unsigned int transition_latency;
bool need_update = false;
int ret;

ret = allocate_resources(policy->cpu, &cpu_dev, &cpu_reg, &cpu_clk);
Expand All @@ -208,8 +208,47 @@ static int cpufreq_init(struct cpufreq_policy *policy)
goto out_put_reg_clk;
}

/* OPPs might be populated at runtime, don't check for error here */
of_init_opp_table(cpu_dev);
/* Get OPP-sharing information from "operating-points-v2" bindings */
ret = of_get_cpus_sharing_opps(cpu_dev, policy->cpus);
if (ret) {
/*
* operating-points-v2 not supported, fallback to old method of
* finding shared-OPPs for backward compatibility.
*/
if (ret == -ENOENT)
need_update = true;
else
goto out_node_put;
}

/*
* Initialize OPP tables for all policy->cpus. They will be shared by
* all CPUs which have marked their CPUs shared with OPP bindings.
*
* For platforms not using operating-points-v2 bindings, we do this
* before updating policy->cpus. Otherwise, we will end up creating
* duplicate OPPs for policy->cpus.
*
* OPPs might be populated at runtime, don't check for error here
*/
of_cpumask_init_opp_table(policy->cpus);

if (need_update) {
struct cpufreq_dt_platform_data *pd = cpufreq_get_driver_data();

if (!pd || !pd->independent_clocks)
cpumask_setall(policy->cpus);

/*
* OPP tables are initialized only for policy->cpu, do it for
* others as well.
*/
set_cpus_sharing_opps(cpu_dev, policy->cpus);

of_property_read_u32(np, "clock-latency", &transition_latency);
} else {
transition_latency = dev_pm_opp_get_max_clock_latency(cpu_dev);
}

/*
* But we need OPP table to function so if it is not there let's
Expand All @@ -230,7 +269,7 @@ static int cpufreq_init(struct cpufreq_policy *policy)

of_property_read_u32(np, "voltage-tolerance", &priv->voltage_tolerance);

if (of_property_read_u32(np, "clock-latency", &transition_latency))
if (!transition_latency)
transition_latency = CPUFREQ_ETERNAL;

if (!IS_ERR(cpu_reg)) {
Expand Down Expand Up @@ -293,10 +332,6 @@ static int cpufreq_init(struct cpufreq_policy *policy)

policy->cpuinfo.transition_latency = transition_latency;

pd = cpufreq_get_driver_data();
if (!pd || !pd->independent_clocks)
cpumask_setall(policy->cpus);

of_node_put(np);

return 0;
Expand All @@ -306,7 +341,8 @@ static int cpufreq_init(struct cpufreq_policy *policy)
out_free_priv:
kfree(priv);
out_free_opp:
of_free_opp_table(cpu_dev);
of_cpumask_free_opp_table(policy->cpus);
out_node_put:
of_node_put(np);
out_put_reg_clk:
clk_put(cpu_clk);
Expand All @@ -322,7 +358,7 @@ static int cpufreq_exit(struct cpufreq_policy *policy)

cpufreq_cooling_unregister(priv->cdev);
dev_pm_opp_free_cpufreq_table(priv->cpu_dev, &policy->freq_table);
of_free_opp_table(priv->cpu_dev);
of_cpumask_free_opp_table(policy->related_cpus);
clk_put(policy->clk);
if (!IS_ERR(priv->cpu_reg))
regulator_put(priv->cpu_reg);
Expand Down

0 comments on commit 2e02d87

Please sign in to comment.