]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c
[CPUFREQ] correct broken links and email addresses
[linux-2.6-omap-h63xx.git] / arch / x86 / kernel / cpu / cpufreq / speedstep-centrino.c
index 908dd347c67ec3dc29aa5ab8b3dcbae9a12e5e37..3b5f06423e7774f2801e31e811c631df90344e36 100644 (file)
 #include <asm/cpufeature.h>
 
 #define PFX            "speedstep-centrino: "
-#define MAINTAINER     "cpufreq@lists.linux.org.uk"
+#define MAINTAINER     "cpufreq@vger.kernel.org"
 
-#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "speedstep-centrino", msg)
+#define dprintk(msg...) \
+       cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "speedstep-centrino", msg)
 
 #define INTEL_MSR_RANGE        (0xffff)
 
@@ -66,11 +67,12 @@ struct cpu_model
 
        struct cpufreq_frequency_table *op_points; /* clock/voltage pairs */
 };
-static int centrino_verify_cpu_id(const struct cpuinfo_x86 *c, const struct cpu_id *x);
+static int centrino_verify_cpu_id(const struct cpuinfo_x86 *c,
+                                 const struct cpu_id *x);
 
 /* Operating points for current CPU */
-static struct cpu_model *centrino_model[NR_CPUS];
-static const struct cpu_id *centrino_cpu[NR_CPUS];
+static DEFINE_PER_CPU(struct cpu_model *, centrino_model);
+static DEFINE_PER_CPU(const struct cpu_id *, centrino_cpu);
 
 static struct cpufreq_driver centrino_driver;
 
@@ -255,7 +257,7 @@ static int centrino_cpu_init_table(struct cpufreq_policy *policy)
                return -ENOENT;
        }
 
-       centrino_model[policy->cpu] = model;
+       per_cpu(centrino_model, policy->cpu) = model;
 
        dprintk("found \"%s\": max frequency: %dkHz\n",
               model->model_name, model->max_freq);
@@ -264,10 +266,14 @@ static int centrino_cpu_init_table(struct cpufreq_policy *policy)
 }
 
 #else
-static inline int centrino_cpu_init_table(struct cpufreq_policy *policy) { return -ENODEV; }
+static inline int centrino_cpu_init_table(struct cpufreq_policy *policy)
+{
+       return -ENODEV;
+}
 #endif /* CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE */
 
-static int centrino_verify_cpu_id(const struct cpuinfo_x86 *c, const struct cpu_id *x)
+static int centrino_verify_cpu_id(const struct cpuinfo_x86 *c,
+                                 const struct cpu_id *x)
 {
        if ((c->x86 == x->x86) &&
            (c->x86_model == x->x86_model) &&
@@ -286,23 +292,28 @@ static unsigned extract_clock(unsigned msr, unsigned int cpu, int failsafe)
         * for centrino, as some DSDTs are buggy.
         * Ideally, this can be done using the acpi_data structure.
         */
-       if ((centrino_cpu[cpu] == &cpu_ids[CPU_BANIAS]) ||
-           (centrino_cpu[cpu] == &cpu_ids[CPU_DOTHAN_A1]) ||
-           (centrino_cpu[cpu] == &cpu_ids[CPU_DOTHAN_B0])) {
+       if ((per_cpu(centrino_cpu, cpu) == &cpu_ids[CPU_BANIAS]) ||
+           (per_cpu(centrino_cpu, cpu) == &cpu_ids[CPU_DOTHAN_A1]) ||
+           (per_cpu(centrino_cpu, cpu) == &cpu_ids[CPU_DOTHAN_B0])) {
                msr = (msr >> 8) & 0xff;
                return msr * 100000;
        }
 
-       if ((!centrino_model[cpu]) || (!centrino_model[cpu]->op_points))
+       if ((!per_cpu(centrino_model, cpu)) ||
+           (!per_cpu(centrino_model, cpu)->op_points))
                return 0;
 
        msr &= 0xffff;
-       for (i=0;centrino_model[cpu]->op_points[i].frequency != CPUFREQ_TABLE_END; i++) {
-               if (msr == centrino_model[cpu]->op_points[i].index)
-                       return centrino_model[cpu]->op_points[i].frequency;
+       for (i = 0;
+               per_cpu(centrino_model, cpu)->op_points[i].frequency
+                                                       != CPUFREQ_TABLE_END;
+            i++) {
+               if (msr == per_cpu(centrino_model, cpu)->op_points[i].index)
+                       return per_cpu(centrino_model, cpu)->
+                                                       op_points[i].frequency;
        }
        if (failsafe)
-               return centrino_model[cpu]->op_points[i-1].frequency;
+               return per_cpu(centrino_model, cpu)->op_points[i-1].frequency;
        else
                return 0;
 }
@@ -347,7 +358,8 @@ static int centrino_cpu_init(struct cpufreq_policy *policy)
        int i;
 
        /* Only Intel makes Enhanced Speedstep-capable CPUs */
-       if (cpu->x86_vendor != X86_VENDOR_INTEL || !cpu_has(cpu, X86_FEATURE_EST))
+       if (cpu->x86_vendor != X86_VENDOR_INTEL ||
+           !cpu_has(cpu, X86_FEATURE_EST))
                return -ENODEV;
 
        if (cpu_has(cpu, X86_FEATURE_CONSTANT_TSC))
@@ -361,9 +373,9 @@ static int centrino_cpu_init(struct cpufreq_policy *policy)
                        break;
 
        if (i != N_IDS)
-               centrino_cpu[policy->cpu] = &cpu_ids[i];
+               per_cpu(centrino_cpu, policy->cpu) = &cpu_ids[i];
 
-       if (!centrino_cpu[policy->cpu]) {
+       if (!per_cpu(centrino_cpu, policy->cpu)) {
                dprintk("found unsupported CPU with "
                "Enhanced SpeedStep: send /proc/cpuinfo to "
                MAINTAINER "\n");
@@ -386,23 +398,26 @@ static int centrino_cpu_init(struct cpufreq_policy *policy)
                /* check to see if it stuck */
                rdmsr(MSR_IA32_MISC_ENABLE, l, h);
                if (!(l & (1<<16))) {
-                       printk(KERN_INFO PFX "couldn't enable Enhanced SpeedStep\n");
+                       printk(KERN_INFO PFX
+                               "couldn't enable Enhanced SpeedStep\n");
                        return -ENODEV;
                }
        }
 
        freq = get_cur_freq(policy->cpu);
-
-       policy->cpuinfo.transition_latency = 10000; /* 10uS transition latency */
+       policy->cpuinfo.transition_latency = 10000;
+                                               /* 10uS transition latency */
        policy->cur = freq;
 
        dprintk("centrino_cpu_init: cur=%dkHz\n", policy->cur);
 
-       ret = cpufreq_frequency_table_cpuinfo(policy, centrino_model[policy->cpu]->op_points);
+       ret = cpufreq_frequency_table_cpuinfo(policy,
+               per_cpu(centrino_model, policy->cpu)->op_points);
        if (ret)
                return (ret);
 
-       cpufreq_frequency_table_get_attr(centrino_model[policy->cpu]->op_points, policy->cpu);
+       cpufreq_frequency_table_get_attr(
+               per_cpu(centrino_model, policy->cpu)->op_points, policy->cpu);
 
        return 0;
 }
@@ -411,12 +426,12 @@ static int centrino_cpu_exit(struct cpufreq_policy *policy)
 {
        unsigned int cpu = policy->cpu;
 
-       if (!centrino_model[cpu])
+       if (!per_cpu(centrino_model, cpu))
                return -ENODEV;
 
        cpufreq_frequency_table_put_attr(cpu);
 
-       centrino_model[cpu] = NULL;
+       per_cpu(centrino_model, cpu) = NULL;
 
        return 0;
 }
@@ -430,17 +445,26 @@ static int centrino_cpu_exit(struct cpufreq_policy *policy)
  */
 static int centrino_verify (struct cpufreq_policy *policy)
 {
-       return cpufreq_frequency_table_verify(policy, centrino_model[policy->cpu]->op_points);
+       return cpufreq_frequency_table_verify(policy,
+                       per_cpu(centrino_model, policy->cpu)->op_points);
 }
 
 /**
  * centrino_setpolicy - set a new CPUFreq policy
  * @policy: new policy
  * @target_freq: the target frequency
- * @relation: how that frequency relates to achieved frequency (CPUFREQ_RELATION_L or CPUFREQ_RELATION_H)
+ * @relation: how that frequency relates to achieved frequency
+ *     (CPUFREQ_RELATION_L or CPUFREQ_RELATION_H)
  *
  * Sets a new CPUFreq policy.
  */
+struct allmasks {
+       cpumask_t               online_policy_cpus;
+       cpumask_t               saved_mask;
+       cpumask_t               set_mask;
+       cpumask_t               covered_cpus;
+};
+
 static int centrino_target (struct cpufreq_policy *policy,
                            unsigned int target_freq,
                            unsigned int relation)
@@ -448,48 +472,55 @@ static int centrino_target (struct cpufreq_policy *policy,
        unsigned int    newstate = 0;
        unsigned int    msr, oldmsr = 0, h = 0, cpu = policy->cpu;
        struct cpufreq_freqs    freqs;
-       cpumask_t               online_policy_cpus;
-       cpumask_t               saved_mask;
-       cpumask_t               set_mask;
-       cpumask_t               covered_cpus;
        int                     retval = 0;
        unsigned int            j, k, first_cpu, tmp;
-
-       if (unlikely(centrino_model[cpu] == NULL))
-               return -ENODEV;
+       CPUMASK_ALLOC(allmasks);
+       CPUMASK_PTR(online_policy_cpus, allmasks);
+       CPUMASK_PTR(saved_mask, allmasks);
+       CPUMASK_PTR(set_mask, allmasks);
+       CPUMASK_PTR(covered_cpus, allmasks);
+
+       if (unlikely(allmasks == NULL))
+               return -ENOMEM;
+
+       if (unlikely(per_cpu(centrino_model, cpu) == NULL)) {
+               retval = -ENODEV;
+               goto out;
+       }
 
        if (unlikely(cpufreq_frequency_table_target(policy,
-                       centrino_model[cpu]->op_points,
+                       per_cpu(centrino_model, cpu)->op_points,
                        target_freq,
                        relation,
                        &newstate))) {
-               return -EINVAL;
+               retval = -EINVAL;
+               goto out;
        }
 
 #ifdef CONFIG_HOTPLUG_CPU
        /* cpufreq holds the hotplug lock, so we are safe from here on */
-       cpus_and(online_policy_cpus, cpu_online_map, policy->cpus);
+       cpus_and(*online_policy_cpus, cpu_online_map, policy->cpus);
 #else
-       online_policy_cpus = policy->cpus;
+       *online_policy_cpus = policy->cpus;
 #endif
 
-       saved_mask = current->cpus_allowed;
+       *saved_mask = current->cpus_allowed;
        first_cpu = 1;
-       cpus_clear(covered_cpus);
-       for_each_cpu_mask(j, online_policy_cpus) {
+       cpus_clear(*covered_cpus);
+       for_each_cpu_mask_nr(j, *online_policy_cpus) {
                /*
                 * Support for SMP systems.
                 * Make sure we are running on CPU that wants to change freq
                 */
-               cpus_clear(set_mask);
+               cpus_clear(*set_mask);
                if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY)
-                       cpus_or(set_mask, set_mask, online_policy_cpus);
+                       cpus_or(*set_mask, *set_mask, *online_policy_cpus);
                else
-                       cpu_set(j, set_mask);
+                       cpu_set(j, *set_mask);
 
-               set_cpus_allowed_ptr(current, &set_mask);
+               set_cpus_allowed_ptr(current, set_mask);
                preempt_disable();
-               if (unlikely(!cpu_isset(smp_processor_id(), set_mask))) {
+               if (unlikely(!cpu_isset(smp_processor_id(), *set_mask))) {
                        dprintk("couldn't limit to CPUs in this domain\n");
                        retval = -EAGAIN;
                        if (first_cpu) {
@@ -500,7 +531,7 @@ static int centrino_target (struct cpufreq_policy *policy,
                        break;
                }
 
-               msr = centrino_model[cpu]->op_points[newstate].index;
+               msr = per_cpu(centrino_model, cpu)->op_points[newstate].index;
 
                if (first_cpu) {
                        rdmsr(MSR_IA32_PERF_CTL, oldmsr, h);
@@ -517,7 +548,7 @@ static int centrino_target (struct cpufreq_policy *policy,
                        dprintk("target=%dkHz old=%d new=%d msr=%04x\n",
                                target_freq, freqs.old, freqs.new, msr);
 
-                       for_each_cpu_mask(k, online_policy_cpus) {
+                       for_each_cpu_mask_nr(k, *online_policy_cpus) {
                                freqs.cpu = k;
                                cpufreq_notify_transition(&freqs,
                                        CPUFREQ_PRECHANGE);
@@ -536,11 +567,11 @@ static int centrino_target (struct cpufreq_policy *policy,
                        break;
                }
 
-               cpu_set(j, covered_cpus);
+               cpu_set(j, *covered_cpus);
                preempt_enable();
        }
 
-       for_each_cpu_mask(k, online_policy_cpus) {
+       for_each_cpu_mask_nr(k, *online_policy_cpus) {
                freqs.cpu = k;
                cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
        }
@@ -553,30 +584,32 @@ static int centrino_target (struct cpufreq_policy *policy,
                 * Best effort undo..
                 */
 
-               if (!cpus_empty(covered_cpus)) {
-                       for_each_cpu_mask(j, covered_cpus) {
+               if (!cpus_empty(*covered_cpus))
+                       for_each_cpu_mask_nr(j, *covered_cpus) {
                                set_cpus_allowed_ptr(current,
                                                     &cpumask_of_cpu(j));
                                wrmsr(MSR_IA32_PERF_CTL, oldmsr, h);
                        }
-               }
 
                tmp = freqs.new;
                freqs.new = freqs.old;
                freqs.old = tmp;
-               for_each_cpu_mask(j, online_policy_cpus) {
+               for_each_cpu_mask_nr(j, *online_policy_cpus) {
                        freqs.cpu = j;
                        cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
                        cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
                }
        }
-       set_cpus_allowed_ptr(current, &saved_mask);
-       return 0;
+       set_cpus_allowed_ptr(current, saved_mask);
+       retval = 0;
+       goto out;
 
 migrate_end:
        preempt_enable();
-       set_cpus_allowed_ptr(current, &saved_mask);
-       return 0;
+       set_cpus_allowed_ptr(current, saved_mask);
+out:
+       CPUMASK_FREE(allmasks);
+       return retval;
 }
 
 static struct freq_attr* centrino_attr[] = {