Merge tag 'hwmon-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck...
[linux-drm-fsl-dcu.git] / drivers / cpufreq / omap-cpufreq.c
index f31fcfcad514330ca856bcfd015aba3927de8241..a0acd0bfba40a361f3ea9eaafc42db928968dea7 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/io.h>
-#include <linux/opp.h>
+#include <linux/pm_opp.h>
 #include <linux/cpu.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
@@ -40,13 +40,6 @@ static struct clk *mpu_clk;
 static struct device *mpu_dev;
 static struct regulator *mpu_reg;
 
-static int omap_verify_speed(struct cpufreq_policy *policy)
-{
-       if (!freq_table)
-               return -EINVAL;
-       return cpufreq_frequency_table_verify(policy, freq_table);
-}
-
 static unsigned int omap_getspeed(unsigned int cpu)
 {
        unsigned long rate;
@@ -58,42 +51,17 @@ static unsigned int omap_getspeed(unsigned int cpu)
        return rate;
 }
 
-static int omap_target(struct cpufreq_policy *policy,
-                      unsigned int target_freq,
-                      unsigned int relation)
+static int omap_target(struct cpufreq_policy *policy, unsigned int index)
 {
-       unsigned int i;
-       int r, ret = 0;
-       struct cpufreq_freqs freqs;
-       struct opp *opp;
+       int r, ret;
+       struct dev_pm_opp *opp;
        unsigned long freq, volt = 0, volt_old = 0, tol = 0;
+       unsigned int old_freq, new_freq;
 
-       if (!freq_table) {
-               dev_err(mpu_dev, "%s: cpu%d: no freq table!\n", __func__,
-                               policy->cpu);
-               return -EINVAL;
-       }
+       old_freq = omap_getspeed(policy->cpu);
+       new_freq = freq_table[index].frequency;
 
-       ret = cpufreq_frequency_table_target(policy, freq_table, target_freq,
-                       relation, &i);
-       if (ret) {
-               dev_dbg(mpu_dev, "%s: cpu%d: no freq match for %d(ret=%d)\n",
-                       __func__, policy->cpu, target_freq, ret);
-               return ret;
-       }
-       freqs.new = freq_table[i].frequency;
-       if (!freqs.new) {
-               dev_err(mpu_dev, "%s: cpu%d: no match for freq %d\n", __func__,
-                       policy->cpu, target_freq);
-               return -EINVAL;
-       }
-
-       freqs.old = omap_getspeed(policy->cpu);
-
-       if (freqs.old == freqs.new && policy->cur == freqs.new)
-               return ret;
-
-       freq = freqs.new * 1000;
+       freq = new_freq * 1000;
        ret = clk_round_rate(mpu_clk, freq);
        if (IS_ERR_VALUE(ret)) {
                dev_warn(mpu_dev,
@@ -105,143 +73,103 @@ static int omap_target(struct cpufreq_policy *policy,
 
        if (mpu_reg) {
                rcu_read_lock();
-               opp = opp_find_freq_ceil(mpu_dev, &freq);
+               opp = dev_pm_opp_find_freq_ceil(mpu_dev, &freq);
                if (IS_ERR(opp)) {
                        rcu_read_unlock();
                        dev_err(mpu_dev, "%s: unable to find MPU OPP for %d\n",
-                               __func__, freqs.new);
+                               __func__, new_freq);
                        return -EINVAL;
                }
-               volt = opp_get_voltage(opp);
+               volt = dev_pm_opp_get_voltage(opp);
                rcu_read_unlock();
                tol = volt * OPP_TOLERANCE / 100;
                volt_old = regulator_get_voltage(mpu_reg);
        }
 
        dev_dbg(mpu_dev, "cpufreq-omap: %u MHz, %ld mV --> %u MHz, %ld mV\n", 
-               freqs.old / 1000, volt_old ? volt_old / 1000 : -1,
-               freqs.new / 1000, volt ? volt / 1000 : -1);
-
-       /* notifiers */
-       cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
+               old_freq / 1000, volt_old ? volt_old / 1000 : -1,
+               new_freq / 1000, volt ? volt / 1000 : -1);
 
        /* scaling up?  scale voltage before frequency */
-       if (mpu_reg && (freqs.new > freqs.old)) {
+       if (mpu_reg && (new_freq > old_freq)) {
                r = regulator_set_voltage(mpu_reg, volt - tol, volt + tol);
                if (r < 0) {
                        dev_warn(mpu_dev, "%s: unable to scale voltage up.\n",
                                 __func__);
-                       freqs.new = freqs.old;
-                       goto done;
+                       return r;
                }
        }
 
-       ret = clk_set_rate(mpu_clk, freqs.new * 1000);
+       ret = clk_set_rate(mpu_clk, new_freq * 1000);
 
        /* scaling down?  scale voltage after frequency */
-       if (mpu_reg && (freqs.new < freqs.old)) {
+       if (mpu_reg && (new_freq < old_freq)) {
                r = regulator_set_voltage(mpu_reg, volt - tol, volt + tol);
                if (r < 0) {
                        dev_warn(mpu_dev, "%s: unable to scale voltage down.\n",
                                 __func__);
-                       ret = clk_set_rate(mpu_clk, freqs.old * 1000);
-                       freqs.new = freqs.old;
-                       goto done;
+                       clk_set_rate(mpu_clk, old_freq * 1000);
+                       return r;
                }
        }
 
-       freqs.new = omap_getspeed(policy->cpu);
-
-done:
-       /* notifiers */
-       cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
-
        return ret;
 }
 
 static inline void freq_table_free(void)
 {
        if (atomic_dec_and_test(&freq_table_users))
-               opp_free_cpufreq_table(mpu_dev, &freq_table);
+               dev_pm_opp_free_cpufreq_table(mpu_dev, &freq_table);
 }
 
 static int omap_cpu_init(struct cpufreq_policy *policy)
 {
-       int result = 0;
+       int result;
 
        mpu_clk = clk_get(NULL, "cpufreq_ck");
        if (IS_ERR(mpu_clk))
                return PTR_ERR(mpu_clk);
 
-       if (policy->cpu >= NR_CPUS) {
-               result = -EINVAL;
-               goto fail_ck;
-       }
-
-       policy->cur = omap_getspeed(policy->cpu);
-
-       if (!freq_table)
-               result = opp_init_cpufreq_table(mpu_dev, &freq_table);
-
-       if (result) {
-               dev_err(mpu_dev, "%s: cpu%d: failed creating freq table[%d]\n",
+       if (!freq_table) {
+               result = dev_pm_opp_init_cpufreq_table(mpu_dev, &freq_table);
+               if (result) {
+                       dev_err(mpu_dev,
+                               "%s: cpu%d: failed creating freq table[%d]\n",
                                __func__, policy->cpu, result);
-               goto fail_ck;
+                       goto fail;
+               }
        }
 
        atomic_inc_return(&freq_table_users);
 
-       result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
-       if (result)
-               goto fail_table;
-
-       cpufreq_frequency_table_get_attr(freq_table, policy->cpu);
-
-       policy->cur = omap_getspeed(policy->cpu);
-
-       /*
-        * On OMAP SMP configuartion, both processors share the voltage
-        * and clock. So both CPUs needs to be scaled together and hence
-        * needs software co-ordination. Use cpufreq affected_cpus
-        * interface to handle this scenario. Additional is_smp() check
-        * is to keep SMP_ON_UP build working.
-        */
-       if (is_smp())
-               cpumask_setall(policy->cpus);
-
        /* FIXME: what's the actual transition time? */
-       policy->cpuinfo.transition_latency = 300 * 1000;
-
-       return 0;
+       result = cpufreq_generic_init(policy, freq_table, 300 * 1000);
+       if (!result)
+               return 0;
 
-fail_table:
        freq_table_free();
-fail_ck:
+fail:
        clk_put(mpu_clk);
        return result;
 }
 
 static int omap_cpu_exit(struct cpufreq_policy *policy)
 {
+       cpufreq_frequency_table_put_attr(policy->cpu);
        freq_table_free();
        clk_put(mpu_clk);
        return 0;
 }
 
-static struct freq_attr *omap_cpufreq_attr[] = {
-       &cpufreq_freq_attr_scaling_available_freqs,
-       NULL,
-};
-
 static struct cpufreq_driver omap_driver = {
        .flags          = CPUFREQ_STICKY,
-       .verify         = omap_verify_speed,
-       .target         = omap_target,
+       .verify         = cpufreq_generic_frequency_table_verify,
+       .target_index   = omap_target,
        .get            = omap_getspeed,
        .init           = omap_cpu_init,
        .exit           = omap_cpu_exit,
        .name           = "omap",
-       .attr           = omap_cpufreq_attr,
+       .attr           = cpufreq_generic_attr,
 };
 
 static int omap_cpufreq_probe(struct platform_device *pdev)