Merge back earlier cpufreq material for v4.8.
[cascardo/linux.git] / drivers / cpufreq / cpufreq.c
index 198416b..5918e95 100644 (file)
@@ -126,15 +126,6 @@ struct kobject *get_governor_parent_kobj(struct cpufreq_policy *policy)
 }
 EXPORT_SYMBOL_GPL(get_governor_parent_kobj);
 
-struct cpufreq_frequency_table *cpufreq_frequency_get_table(unsigned int cpu)
-{
-       struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu);
-
-       return policy && !policy_is_inactive(policy) ?
-               policy->freq_table : NULL;
-}
-EXPORT_SYMBOL_GPL(cpufreq_frequency_get_table);
-
 static inline u64 get_cpu_idle_time_jiffy(unsigned int cpu, u64 *wall)
 {
        u64 idle_time;
@@ -347,6 +338,7 @@ static void __cpufreq_notify_transition(struct cpufreq_policy *policy,
                pr_debug("FREQ: %lu - CPU: %lu\n",
                         (unsigned long)freqs->new, (unsigned long)freqs->cpu);
                trace_cpu_frequency(freqs->new, freqs->cpu);
+               cpufreq_stats_record_transition(policy, freqs->new);
                srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
                                CPUFREQ_POSTCHANGE, freqs);
                if (likely(policy) && likely(policy->cpu == freqs->cpu))
@@ -1108,6 +1100,7 @@ static void cpufreq_policy_put_kobj(struct cpufreq_policy *policy, bool notify)
                                             CPUFREQ_REMOVE_POLICY, policy);
 
        down_write(&policy->rwsem);
+       cpufreq_stats_free_table(policy);
        cpufreq_remove_dev_symlink(policy);
        kobj = &policy->kobj;
        cmp = &policy->kobj_unregister;
@@ -1262,6 +1255,8 @@ static int cpufreq_online(unsigned int cpu)
                ret = cpufreq_add_dev_interface(policy);
                if (ret)
                        goto out_exit_policy;
+
+               cpufreq_stats_create_table(policy);
                blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
                                CPUFREQ_CREATE_POLICY, policy);
 
@@ -1825,7 +1820,7 @@ EXPORT_SYMBOL(cpufreq_unregister_notifier);
 unsigned int cpufreq_driver_fast_switch(struct cpufreq_policy *policy,
                                        unsigned int target_freq)
 {
-       clamp_val(target_freq, policy->min, policy->max);
+       target_freq = clamp_val(target_freq, policy->min, policy->max);
 
        return cpufreq_driver->fast_switch(policy, target_freq);
 }
@@ -1857,14 +1852,17 @@ static int __target_intermediate(struct cpufreq_policy *policy,
        return ret;
 }
 
-static int __target_index(struct cpufreq_policy *policy,
-                         struct cpufreq_frequency_table *freq_table, int index)
+static int __target_index(struct cpufreq_policy *policy, int index)
 {
        struct cpufreq_freqs freqs = {.old = policy->cur, .flags = 0};
        unsigned int intermediate_freq = 0;
+       unsigned int newfreq = policy->freq_table[index].frequency;
        int retval = -EINVAL;
        bool notify;
 
+       if (newfreq == policy->cur)
+               return 0;
+
        notify = !(cpufreq_driver->flags & CPUFREQ_ASYNC_NOTIFICATION);
        if (notify) {
                /* Handle switching to intermediate frequency */
@@ -1879,7 +1877,7 @@ static int __target_index(struct cpufreq_policy *policy,
                                freqs.old = freqs.new;
                }
 
-               freqs.new = freq_table[index].frequency;
+               freqs.new = newfreq;
                pr_debug("%s: cpu: %d, oldfreq: %u, new freq: %u\n",
                         __func__, policy->cpu, freqs.old, freqs.new);
 
@@ -1916,8 +1914,7 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
                            unsigned int relation)
 {
        unsigned int old_target_freq = target_freq;
-       struct cpufreq_frequency_table *freq_table;
-       int index, retval;
+       int index;
 
        if (cpufreq_disabled())
                return -ENODEV;
@@ -1946,23 +1943,9 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
        if (!cpufreq_driver->target_index)
                return -EINVAL;
 
-       freq_table = cpufreq_frequency_get_table(policy->cpu);
-       if (unlikely(!freq_table)) {
-               pr_err("%s: Unable to find freq_table\n", __func__);
-               return -EINVAL;
-       }
+       index = cpufreq_frequency_table_target(policy, target_freq, relation);
 
-       retval = cpufreq_frequency_table_target(policy, freq_table, target_freq,
-                                               relation, &index);
-       if (unlikely(retval)) {
-               pr_err("%s: Unable to find matching freq\n", __func__);
-               return retval;
-       }
-
-       if (freq_table[index].frequency == policy->cur)
-               return 0;
-
-       return __target_index(policy, freq_table, index);
+       return __target_index(policy, index);
 }
 EXPORT_SYMBOL_GPL(__cpufreq_driver_target);
 
@@ -2297,6 +2280,10 @@ int cpufreq_update_policy(unsigned int cpu)
         * -> ask driver for current freq and notify governors about a change
         */
        if (cpufreq_driver->get && !cpufreq_driver->setpolicy) {
+               if (cpufreq_suspended) {
+                       ret = -EAGAIN;
+                       goto unlock;
+               }
                new_policy.cur = cpufreq_update_current_freq(policy);
                if (WARN_ON(!new_policy.cur)) {
                        ret = -EIO;
@@ -2341,26 +2328,25 @@ static struct notifier_block __refdata cpufreq_cpu_notifier = {
  *********************************************************************/
 static int cpufreq_boost_set_sw(int state)
 {
-       struct cpufreq_frequency_table *freq_table;
        struct cpufreq_policy *policy;
        int ret = -EINVAL;
 
        for_each_active_policy(policy) {
-               freq_table = cpufreq_frequency_get_table(policy->cpu);
-               if (freq_table) {
-                       ret = cpufreq_frequency_table_cpuinfo(policy,
-                                                       freq_table);
-                       if (ret) {
-                               pr_err("%s: Policy frequency update failed\n",
-                                      __func__);
-                               break;
-                       }
+               if (!policy->freq_table)
+                       continue;
 
-                       down_write(&policy->rwsem);
-                       policy->user_policy.max = policy->max;
-                       cpufreq_governor_limits(policy);
-                       up_write(&policy->rwsem);
+               ret = cpufreq_frequency_table_cpuinfo(policy,
+                                                     policy->freq_table);
+               if (ret) {
+                       pr_err("%s: Policy frequency update failed\n",
+                              __func__);
+                       break;
                }
+
+               down_write(&policy->rwsem);
+               policy->user_policy.max = policy->max;
+               cpufreq_governor_limits(policy);
+               up_write(&policy->rwsem);
        }
 
        return ret;