|
@@ -32,6 +32,7 @@ struct private_data {
|
|
|
struct device *cpu_dev;
|
|
|
struct thermal_cooling_device *cdev;
|
|
|
const char *reg_name;
|
|
|
+ bool have_static_opps;
|
|
|
};
|
|
|
|
|
|
static struct freq_attr *cpufreq_dt_attr[] = {
|
|
@@ -204,6 +205,15 @@ static int cpufreq_init(struct cpufreq_policy *policy)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
|
|
|
+ if (!priv) {
|
|
|
+ ret = -ENOMEM;
|
|
|
+ goto out_put_regulator;
|
|
|
+ }
|
|
|
+
|
|
|
+ priv->reg_name = name;
|
|
|
+ priv->opp_table = opp_table;
|
|
|
+
|
|
|
/*
|
|
|
* Initialize OPP tables for all policy->cpus. They will be shared by
|
|
|
* all CPUs which have marked their CPUs shared with OPP bindings.
|
|
@@ -214,7 +224,8 @@ static int cpufreq_init(struct cpufreq_policy *policy)
|
|
|
*
|
|
|
* OPPs might be populated at runtime, don't check for error here
|
|
|
*/
|
|
|
- dev_pm_opp_of_cpumask_add_table(policy->cpus);
|
|
|
+ if (!dev_pm_opp_of_cpumask_add_table(policy->cpus))
|
|
|
+ priv->have_static_opps = true;
|
|
|
|
|
|
/*
|
|
|
* But we need OPP table to function so if it is not there let's
|
|
@@ -240,19 +251,10 @@ static int cpufreq_init(struct cpufreq_policy *policy)
|
|
|
__func__, ret);
|
|
|
}
|
|
|
|
|
|
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
|
|
|
- if (!priv) {
|
|
|
- ret = -ENOMEM;
|
|
|
- goto out_free_opp;
|
|
|
- }
|
|
|
-
|
|
|
- priv->reg_name = name;
|
|
|
- priv->opp_table = opp_table;
|
|
|
-
|
|
|
ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table);
|
|
|
if (ret) {
|
|
|
dev_err(cpu_dev, "failed to init cpufreq table: %d\n", ret);
|
|
|
- goto out_free_priv;
|
|
|
+ goto out_free_opp;
|
|
|
}
|
|
|
|
|
|
priv->cpu_dev = cpu_dev;
|
|
@@ -282,10 +284,11 @@ static int cpufreq_init(struct cpufreq_policy *policy)
|
|
|
|
|
|
out_free_cpufreq_table:
|
|
|
dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);
|
|
|
-out_free_priv:
|
|
|
- kfree(priv);
|
|
|
out_free_opp:
|
|
|
- dev_pm_opp_of_cpumask_remove_table(policy->cpus);
|
|
|
+ if (priv->have_static_opps)
|
|
|
+ dev_pm_opp_of_cpumask_remove_table(policy->cpus);
|
|
|
+ kfree(priv);
|
|
|
+out_put_regulator:
|
|
|
if (name)
|
|
|
dev_pm_opp_put_regulators(opp_table);
|
|
|
out_put_clk:
|
|
@@ -300,7 +303,8 @@ 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);
|
|
|
- dev_pm_opp_of_cpumask_remove_table(policy->related_cpus);
|
|
|
+ if (priv->have_static_opps)
|
|
|
+ dev_pm_opp_of_cpumask_remove_table(policy->related_cpus);
|
|
|
if (priv->reg_name)
|
|
|
dev_pm_opp_put_regulators(priv->opp_table);
|
|
|
|