+ struct notifier_block opp_nb;
+ struct mutex lock;
+ unsigned long opp_freq;
+ bool have_static_opps;
};
- static struct freq_attr *cpufreq_dt_attr[] = {
-@@ -43,9 +46,16 @@ static struct freq_attr *cpufreq_dt_attr
+@@ -44,9 +47,16 @@ static struct freq_attr *cpufreq_dt_attr
static int set_target(struct cpufreq_policy *policy, unsigned int index)
{
struct private_data *priv = policy->driver_data;
}
/*
-@@ -86,6 +96,39 @@ node_put:
+@@ -87,6 +97,39 @@ node_put:
return name;
}
static int resources_available(void)
{
struct device *cpu_dev;
-@@ -152,6 +195,7 @@ static int cpufreq_init(struct cpufreq_p
+@@ -153,6 +196,7 @@ static int cpufreq_init(struct cpufreq_p
bool fallback = false;
const char *name;
int ret;
cpu_dev = get_cpu_device(policy->cpu);
if (!cpu_dev) {
-@@ -241,13 +285,16 @@ static int cpufreq_init(struct cpufreq_p
- goto out_free_opp;
+@@ -246,10 +290,13 @@ static int cpufreq_init(struct cpufreq_p
+ __func__, ret);
}
+ mutex_init(&priv->lock);
+ dev_pm_opp_register_notifier(cpu_dev, &priv->opp_nb);
+
- 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;
+ goto out_unregister_nb;
}
priv->cpu_dev = cpu_dev;
-@@ -283,6 +330,8 @@ static int cpufreq_init(struct cpufreq_p
+@@ -285,6 +332,8 @@ static int cpufreq_init(struct cpufreq_p
out_free_cpufreq_table:
dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);
+out_unregister_nb:
+ dev_pm_opp_unregister_notifier(cpu_dev, &priv->opp_nb);
- out_free_priv:
- kfree(priv);
out_free_opp:
+ if (priv->have_static_opps)
+ dev_pm_opp_of_cpumask_remove_table(policy->cpus);