Merge ../powerpc-merge
[powerpc.git] / drivers / cpufreq / cpufreq.c
index 7a51147..9582de1 100644 (file)
@@ -35,8 +35,8 @@
  * level driver of CPUFreq support, and its spinlock. This lock
  * also protects the cpufreq_cpu_data array.
  */
-static struct cpufreq_driver           *cpufreq_driver;
-static struct cpufreq_policy   *cpufreq_cpu_data[NR_CPUS];
+static struct cpufreq_driver *cpufreq_driver;
+static struct cpufreq_policy *cpufreq_cpu_data[NR_CPUS];
 static DEFINE_SPINLOCK(cpufreq_driver_lock);
 
 /* internal prototypes */
@@ -50,15 +50,15 @@ static void handle_update(void *data);
  * changes to devices when the CPU clock speed changes.
  * The mutex locks both lists.
  */
-static struct notifier_block    *cpufreq_policy_notifier_list;
-static struct notifier_block    *cpufreq_transition_notifier_list;
-static DECLARE_RWSEM           (cpufreq_notifier_rwsem);
+static struct notifier_block *cpufreq_policy_notifier_list;
+static struct notifier_block *cpufreq_transition_notifier_list;
+static DECLARE_RWSEM (cpufreq_notifier_rwsem);
 
 
 static LIST_HEAD(cpufreq_governor_list);
-static DEFINE_MUTEX            (cpufreq_governor_mutex);
+static DEFINE_MUTEX (cpufreq_governor_mutex);
 
-struct cpufreq_policy * cpufreq_cpu_get(unsigned int cpu)
+struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu)
 {
        struct cpufreq_policy *data;
        unsigned long flags;
@@ -85,20 +85,19 @@ struct cpufreq_policy * cpufreq_cpu_get(unsigned int cpu)
        if (!kobject_get(&data->kobj))
                goto err_out_put_module;
 
-
        spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
-
        return data;
 
- err_out_put_module:
+err_out_put_module:
        module_put(cpufreq_driver->owner);
- err_out_unlock:
+err_out_unlock:
        spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
- err_out:
+err_out:
        return NULL;
 }
 EXPORT_SYMBOL_GPL(cpufreq_cpu_get);
 
+
 void cpufreq_cpu_put(struct cpufreq_policy *data)
 {
        kobject_put(&data->kobj);
@@ -229,44 +228,53 @@ static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci) {
 
 
 /**
- * cpufreq_notify_transition - call notifier chain and adjust_jiffies on frequency transition
+ * cpufreq_notify_transition - call notifier chain and adjust_jiffies
+ * on frequency transition.
  *
- * This function calls the transition notifiers and the "adjust_jiffies" function. It is called
- * twice on all CPU frequency changes that have external effects. 
+ * This function calls the transition notifiers and the "adjust_jiffies"
+ * function. It is called twice on all CPU frequency changes that have
+ * external effects. 
  */
 void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state)
 {
+       struct cpufreq_policy *policy;
+
        BUG_ON(irqs_disabled());
 
        freqs->flags = cpufreq_driver->flags;
-       dprintk("notification %u of frequency transition to %u kHz\n", state, freqs->new);
+       dprintk("notification %u of frequency transition to %u kHz\n",
+               state, freqs->new);
 
        down_read(&cpufreq_notifier_rwsem);
+
+       policy = cpufreq_cpu_data[freqs->cpu];
        switch (state) {
+
        case CPUFREQ_PRECHANGE:
-               /* detect if the driver reported a value as "old frequency" which
-                * is not equal to what the cpufreq core thinks is "old frequency".
+               /* detect if the driver reported a value as "old frequency" 
+                * which is not equal to what the cpufreq core thinks is
+                * "old frequency".
                 */
                if (!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
-                       if ((likely(cpufreq_cpu_data[freqs->cpu])) &&
-                           (likely(cpufreq_cpu_data[freqs->cpu]->cpu == freqs->cpu)) &&
-                           (likely(cpufreq_cpu_data[freqs->cpu]->cur)) &&
-                           (unlikely(freqs->old != cpufreq_cpu_data[freqs->cpu]->cur)))
-                       {
-                               dprintk(KERN_WARNING "Warning: CPU frequency is %u, "
-                                      "cpufreq assumed %u kHz.\n", freqs->old, cpufreq_cpu_data[freqs->cpu]->cur);
-                               freqs->old = cpufreq_cpu_data[freqs->cpu]->cur;
+                       if ((policy) && (policy->cpu == freqs->cpu) &&
+                           (policy->cur) && (policy->cur != freqs->old)) {
+                               dprintk(KERN_WARNING "Warning: CPU frequency is"
+                                       " %u, cpufreq assumed %u kHz.\n",
+                                       freqs->old, policy->cur);
+                               freqs->old = policy->cur;
                        }
                }
-               notifier_call_chain(&cpufreq_transition_notifier_list, CPUFREQ_PRECHANGE, freqs);
+               notifier_call_chain(&cpufreq_transition_notifier_list,
+                                       CPUFREQ_PRECHANGE, freqs);
                adjust_jiffies(CPUFREQ_PRECHANGE, freqs);
                break;
+
        case CPUFREQ_POSTCHANGE:
                adjust_jiffies(CPUFREQ_POSTCHANGE, freqs);
-               notifier_call_chain(&cpufreq_transition_notifier_list, CPUFREQ_POSTCHANGE, freqs);
-               if ((likely(cpufreq_cpu_data[freqs->cpu])) && 
-                   (likely(cpufreq_cpu_data[freqs->cpu]->cpu == freqs->cpu)))
-                       cpufreq_cpu_data[freqs->cpu]->cur = freqs->new;
+               notifier_call_chain(&cpufreq_transition_notifier_list,
+                                       CPUFREQ_POSTCHANGE, freqs);
+               if (likely(policy) && likely(policy->cpu == freqs->cpu))
+                       policy->cur = freqs->new;
                break;
        }
        up_read(&cpufreq_notifier_rwsem);
@@ -308,7 +316,7 @@ static int cpufreq_parse_governor (char *str_governor, unsigned int *policy,
                                return 0;
                        }
                }
-       out:
+out:
                mutex_unlock(&cpufreq_governor_mutex);
        }
        return -EINVAL;
@@ -415,7 +423,6 @@ static ssize_t store_scaling_governor (struct cpufreq_policy * policy,
                return -EINVAL;
 
        ret = cpufreq_set_policy(&new_policy);
-
        return ret ? ret : count;
 }
 
@@ -446,7 +453,7 @@ static ssize_t show_scaling_available_governors (struct cpufreq_policy * policy,
                        goto out;
                i += scnprintf(&buf[i], CPUFREQ_NAME_LEN, "%s ", t->name);
        }
- out:
+out:
        i += sprintf(&buf[i], "\n");
        return i;
 }
@@ -789,7 +796,6 @@ static int cpufreq_remove_dev (struct sys_device * sys_dev)
        kfree(data);
 
        cpufreq_debug_enable_ratelimit();
-
        return 0;
 }
 
@@ -870,8 +876,7 @@ unsigned int cpufreq_get(unsigned int cpu)
 
        ret = cpufreq_driver->get(cpu);
 
-       if (ret && policy->cur && !(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) 
-       {
+       if (ret && policy->cur && !(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
                /* verify no discrepancy between actual and saved value exists */
                if (unlikely(ret != policy->cur)) {
                        cpufreq_out_of_sync(cpu, policy->cur, ret);
@@ -881,7 +886,7 @@ unsigned int cpufreq_get(unsigned int cpu)
 
        mutex_unlock(&policy->lock);
 
- out:
+out:
        cpufreq_cpu_put(policy);
 
        return (ret);
@@ -962,7 +967,7 @@ static int cpufreq_suspend(struct sys_device * sysdev, pm_message_t pmsg)
                cpu_policy->cur = cur_freq;
        }
 
- out:
+out:
        cpufreq_cpu_put(cpu_policy);
        return 0;
 }
@@ -1169,7 +1174,6 @@ int cpufreq_driver_target(struct cpufreq_policy *policy,
        mutex_unlock(&policy->lock);
 
        cpufreq_cpu_put(policy);
-
        return ret;
 }
 EXPORT_SYMBOL_GPL(cpufreq_driver_target);
@@ -1208,7 +1212,6 @@ int cpufreq_governor(unsigned int cpu, unsigned int event)
        mutex_unlock(&policy->lock);
 
        cpufreq_cpu_put(policy);
-
        return ret;
 }
 EXPORT_SYMBOL_GPL(cpufreq_governor);
@@ -1232,7 +1235,6 @@ int cpufreq_register_governor(struct cpufreq_governor *governor)
        list_add(&governor->governor_list, &cpufreq_governor_list);
 
        mutex_unlock(&cpufreq_governor_mutex);
-
        return 0;
 }
 EXPORT_SYMBOL_GPL(cpufreq_register_governor);
@@ -1277,7 +1279,6 @@ int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu)
        mutex_unlock(&cpu_policy->lock);
 
        cpufreq_cpu_put(cpu_policy);
-
        return 0;
 }
 EXPORT_SYMBOL(cpufreq_get_policy);
@@ -1291,9 +1292,7 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data, struct cpufreq_poli
        dprintk("setting new policy for CPU %u: %u - %u kHz\n", policy->cpu,
                policy->min, policy->max);
 
-       memcpy(&policy->cpuinfo, 
-              &data->cpuinfo, 
-              sizeof(struct cpufreq_cpuinfo));
+       memcpy(&policy->cpuinfo, &data->cpuinfo, sizeof(struct cpufreq_cpuinfo));
 
        /* verify the cpu speed can be set within this limit */
        ret = cpufreq_driver->verify(policy);
@@ -1324,8 +1323,8 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data, struct cpufreq_poli
 
        up_read(&cpufreq_notifier_rwsem);
 
-       data->min    = policy->min;
-       data->max    = policy->max;
+       data->min = policy->min;
+       data->max = policy->max;
 
        dprintk("new min and max freqs are %u - %u kHz\n", data->min, data->max);
 
@@ -1362,7 +1361,7 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data, struct cpufreq_poli
                __cpufreq_governor(data, CPUFREQ_GOV_LIMITS);
        }
 
- error_out:
+error_out:
        cpufreq_debug_enable_ratelimit();
        return ret;
 }
@@ -1421,9 +1420,7 @@ int cpufreq_update_policy(unsigned int cpu)
        mutex_lock(&data->lock);
 
        dprintk("updating policy for CPU %u\n", cpu);
-       memcpy(&policy, 
-              data,
-              sizeof(struct cpufreq_policy));
+       memcpy(&policy, data, sizeof(struct cpufreq_policy));
        policy.min = data->user_policy.min;
        policy.max = data->user_policy.max;
        policy.policy = data->user_policy.policy;
@@ -1433,8 +1430,13 @@ int cpufreq_update_policy(unsigned int cpu)
          -> ask driver for current freq and notify governors about a change */
        if (cpufreq_driver->get) {
                policy.cur = cpufreq_driver->get(cpu);
-               if (data->cur != policy.cur)
-                       cpufreq_out_of_sync(cpu, data->cur, policy.cur);
+               if (!data->cur) {
+                       dprintk("Driver did not initialize current freq");
+                       data->cur = policy.cur;
+               } else {
+                       if (data->cur != policy.cur)
+                               cpufreq_out_of_sync(cpu, data->cur, policy.cur);
+               }
        }
 
        ret = __cpufreq_set_policy(data, &policy);