cpufreq: Create for_each_policy()
[cascardo/linux.git] / drivers / cpufreq / cpufreq.c
index 127cc6f..baa238f 100644 (file)
 #include <linux/tick.h>
 #include <trace/events/power.h>
 
+/* Macros to iterate over lists */
+/* Iterate over online CPUs policies */
+static LIST_HEAD(cpufreq_policy_list);
+#define for_each_policy(__policy)                              \
+       list_for_each_entry(__policy, &cpufreq_policy_list, policy_list)
+
 /**
  * The "cpufreq driver" - the arch- or hardware-dependent low
  * level driver of CPUFreq support, and its spinlock. This lock
@@ -41,7 +47,6 @@ static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data);
 static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data_fallback);
 static DEFINE_RWLOCK(cpufreq_driver_lock);
 DEFINE_MUTEX(cpufreq_governor_lock);
-static LIST_HEAD(cpufreq_policy_list);
 
 /* This one keeps track of the previously set governor of a removed CPU */
 static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor);
@@ -203,7 +208,7 @@ struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu)
        struct cpufreq_policy *policy = NULL;
        unsigned long flags;
 
-       if (cpufreq_disabled() || (cpu >= nr_cpu_ids))
+       if (cpu >= nr_cpu_ids)
                return NULL;
 
        if (!down_read_trylock(&cpufreq_rwsem))
@@ -230,9 +235,6 @@ EXPORT_SYMBOL_GPL(cpufreq_cpu_get);
 
 void cpufreq_cpu_put(struct cpufreq_policy *policy)
 {
-       if (cpufreq_disabled())
-               return;
-
        kobject_put(&policy->kobj);
        up_read(&cpufreq_rwsem);
 }
@@ -250,12 +252,12 @@ EXPORT_SYMBOL_GPL(cpufreq_cpu_put);
  * systems as each CPU might be scaled differently. So, use the arch
  * per-CPU loops_per_jiffy value wherever possible.
  */
-#ifndef CONFIG_SMP
-static unsigned long l_p_j_ref;
-static unsigned int l_p_j_ref_freq;
-
 static void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
 {
+#ifndef CONFIG_SMP
+       static unsigned long l_p_j_ref;
+       static unsigned int l_p_j_ref_freq;
+
        if (ci->flags & CPUFREQ_CONST_LOOPS)
                return;
 
@@ -271,13 +273,8 @@ static void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
                pr_debug("scaling loops_per_jiffy to %lu for frequency %u kHz\n",
                         loops_per_jiffy, ci->new);
        }
-}
-#else
-static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
-{
-       return;
-}
 #endif
+}
 
 static void __cpufreq_notify_transition(struct cpufreq_policy *policy,
                struct cpufreq_freqs *freqs, unsigned int state)
@@ -1031,6 +1028,8 @@ static struct cpufreq_policy *cpufreq_policy_alloc(void)
        init_rwsem(&policy->rwsem);
        spin_lock_init(&policy->transition_lock);
        init_waitqueue_head(&policy->transition_wait);
+       init_completion(&policy->kobj_unregister);
+       INIT_WORK(&policy->update, handle_update);
 
        return policy;
 
@@ -1089,15 +1088,9 @@ static int update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu,
        }
 
        down_write(&policy->rwsem);
-
-       policy->last_cpu = policy->cpu;
        policy->cpu = cpu;
-
        up_write(&policy->rwsem);
 
-       blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
-                       CPUFREQ_UPDATE_POLICY_CPU, policy);
-
        return 0;
 }
 
@@ -1116,18 +1109,16 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
 
        /* check whether a different CPU already registered this
         * CPU because it is in the same boat. */
-       policy = cpufreq_cpu_get(cpu);
-       if (unlikely(policy)) {
-               cpufreq_cpu_put(policy);
+       policy = cpufreq_cpu_get_raw(cpu);
+       if (unlikely(policy))
                return 0;
-       }
 
        if (!down_read_trylock(&cpufreq_rwsem))
                return 0;
 
        /* Check if this cpu was hot-unplugged earlier and has siblings */
        read_lock_irqsave(&cpufreq_driver_lock, flags);
-       list_for_each_entry(policy, &cpufreq_policy_list, policy_list) {
+       for_each_policy(policy) {
                if (cpumask_test_cpu(cpu, policy->related_cpus)) {
                        read_unlock_irqrestore(&cpufreq_driver_lock, flags);
                        ret = cpufreq_add_policy_cpu(policy, cpu, dev);
@@ -1162,9 +1153,6 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
 
        cpumask_copy(policy->cpus, cpumask_of(cpu));
 
-       init_completion(&policy->kobj_unregister);
-       INIT_WORK(&policy->update, handle_update);
-
        /* call driver. From then on the cpufreq must be able
         * to accept all calls to ->verify and ->setpolicy for this CPU
         */
@@ -1406,9 +1394,10 @@ static int __cpufreq_remove_dev_finish(struct device *dev,
        unsigned long flags;
        struct cpufreq_policy *policy;
 
-       read_lock_irqsave(&cpufreq_driver_lock, flags);
+       write_lock_irqsave(&cpufreq_driver_lock, flags);
        policy = per_cpu(cpufreq_cpu_data, cpu);
-       read_unlock_irqrestore(&cpufreq_driver_lock, flags);
+       per_cpu(cpufreq_cpu_data, cpu) = NULL;
+       write_unlock_irqrestore(&cpufreq_driver_lock, flags);
 
        if (!policy) {
                pr_debug("%s: No cpu_data found\n", __func__);
@@ -1463,7 +1452,6 @@ static int __cpufreq_remove_dev_finish(struct device *dev,
                }
        }
 
-       per_cpu(cpufreq_cpu_data, cpu) = NULL;
        return 0;
 }
 
@@ -1664,7 +1652,7 @@ void cpufreq_suspend(void)
 
        pr_debug("%s: Suspending Governors\n", __func__);
 
-       list_for_each_entry(policy, &cpufreq_policy_list, policy_list) {
+       for_each_policy(policy) {
                if (__cpufreq_governor(policy, CPUFREQ_GOV_STOP))
                        pr_err("%s: Failed to stop governor for policy: %p\n",
                                __func__, policy);
@@ -1698,7 +1686,7 @@ void cpufreq_resume(void)
 
        pr_debug("%s: Resuming Governors\n", __func__);
 
-       list_for_each_entry(policy, &cpufreq_policy_list, policy_list) {
+       for_each_policy(policy) {
                if (cpufreq_driver->resume && cpufreq_driver->resume(policy))
                        pr_err("%s: Failed to resume driver: %p\n", __func__,
                                policy);
@@ -2341,7 +2329,7 @@ static int cpufreq_boost_set_sw(int state)
        struct cpufreq_policy *policy;
        int ret = -EINVAL;
 
-       list_for_each_entry(policy, &cpufreq_policy_list, policy_list) {
+       for_each_policy(policy) {
                freq_table = cpufreq_frequency_get_table(policy->cpu);
                if (freq_table) {
                        ret = cpufreq_frequency_table_cpuinfo(policy,
@@ -2462,23 +2450,12 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
        if (ret)
                goto err_boost_unreg;
 
-       if (!(cpufreq_driver->flags & CPUFREQ_STICKY)) {
-               int i;
-               ret = -ENODEV;
-
-               /* check for at least one working CPU */
-               for (i = 0; i < nr_cpu_ids; i++)
-                       if (cpu_possible(i) && per_cpu(cpufreq_cpu_data, i)) {
-                               ret = 0;
-                               break;
-                       }
-
+       if (!(cpufreq_driver->flags & CPUFREQ_STICKY) &&
+           list_empty(&cpufreq_policy_list)) {
                /* if all ->init() calls failed, unregister */
-               if (ret) {
-                       pr_debug("no CPU initialized for driver %s\n",
-                                driver_data->name);
-                       goto err_if_unreg;
-               }
+               pr_debug("%s: No CPU initialized for driver %s\n", __func__,
+                        driver_data->name);
+               goto err_if_unreg;
        }
 
        register_hotcpu_notifier(&cpufreq_cpu_notifier);