[CPUFREQ] reduce scope of ACPI_PSS_BIOS_BUG_MSG[]
[safe/jmp/linux-2.6] / arch / x86 / kernel / cpu / cpufreq / powernow-k8.c
index feef10c..2709b3c 100644 (file)
@@ -1,3 +1,4 @@
+
 /*
  *   (c) 2003-2006 Advanced Micro Devices, Inc.
  *  Your use of this code is subject to the terms and conditions of the
@@ -649,6 +650,20 @@ static void print_basics(struct powernow_k8_data *data)
                                data->batps);
 }
 
+static u32 freq_from_fid_did(u32 fid, u32 did)
+{
+       u32 mhz = 0;
+
+       if (boot_cpu_data.x86 == 0x10)
+               mhz = (100 * (fid + 0x10)) >> did;
+       else if (boot_cpu_data.x86 == 0x11)
+               mhz = (100 * (fid + 8)) >> did;
+       else
+               BUG();
+
+       return mhz * 1000;
+}
+
 static int fill_powernow_table(struct powernow_k8_data *data,
                struct pst_s *pst, u8 maxvid)
 {
@@ -809,19 +824,20 @@ static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data,
        if (!data->acpi_data.state_count || (cpu_family == CPU_HW_PSTATE))
                return;
 
-       control = data->acpi_data.states[index].control; data->irt = (control
-                       >> IRT_SHIFT) & IRT_MASK; data->rvo = (control >>
-                               RVO_SHIFT) & RVO_MASK; data->exttype = (control
-                                       >> EXT_TYPE_SHIFT) & EXT_TYPE_MASK;
-       data->plllock = (control >> PLL_L_SHIFT) & PLL_L_MASK; data->vidmvs = 1
-               << ((control >> MVS_SHIFT) & MVS_MASK); data->vstable =
-               (control >> VST_SHIFT) & VST_MASK; }
+       control = data->acpi_data.states[index].control;
+       data->irt = (control >> IRT_SHIFT) & IRT_MASK;
+       data->rvo = (control >> RVO_SHIFT) & RVO_MASK;
+       data->exttype = (control >> EXT_TYPE_SHIFT) & EXT_TYPE_MASK;
+       data->plllock = (control >> PLL_L_SHIFT) & PLL_L_MASK;
+       data->vidmvs = 1 << ((control >> MVS_SHIFT) & MVS_MASK);
+       data->vstable = (control >> VST_SHIFT) & VST_MASK;
+}
 
 static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
 {
        struct cpufreq_frequency_table *powernow_table;
        int ret_val = -ENODEV;
-       acpi_integer space_id;
+       acpi_integer control, status;
 
        if (acpi_processor_register_performance(&data->acpi_data, data->cpu)) {
                dprintk("register performance failed: bad ACPI data\n");
@@ -834,12 +850,13 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
                goto err_out;
        }
 
-       space_id = data->acpi_data.control_register.space_id;
-       if ((space_id != ACPI_ADR_SPACE_FIXED_HARDWARE) ||
-               (space_id != ACPI_ADR_SPACE_FIXED_HARDWARE)) {
+       control = data->acpi_data.control_register.space_id;
+       status = data->acpi_data.status_register.space_id;
+
+       if ((control != ACPI_ADR_SPACE_FIXED_HARDWARE) ||
+           (status != ACPI_ADR_SPACE_FIXED_HARDWARE)) {
                dprintk("Invalid control/status registers (%x - %x)\n",
-                       data->acpi_data.control_register.space_id,
-                       space_id);
+                       control, status);
                goto err_out;
        }
 
@@ -872,7 +889,7 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
        /* notify BIOS that we exist */
        acpi_processor_notify_smm(THIS_MODULE);
 
-       if (!alloc_cpumask_var(&data->acpi_data.shared_cpu_map, GFP_KERNEL)) {
+       if (!zalloc_cpumask_var(&data->acpi_data.shared_cpu_map, GFP_KERNEL)) {
                printk(KERN_ERR PFX
                                "unable to alloc powernow_k8_data cpumask\n");
                ret_val = -ENOMEM;
@@ -923,8 +940,13 @@ static int fill_powernow_table_pstate(struct powernow_k8_data *data,
 
                powernow_table[i].index = index;
 
-               powernow_table[i].frequency =
-                       data->acpi_data.states[i].core_frequency * 1000;
+               /* Frequency may be rounded for these */
+               if (boot_cpu_data.x86 == 0x10 || boot_cpu_data.x86 == 0x11) {
+                       powernow_table[i].frequency =
+                               freq_from_fid_did(lo & 0x3f, (lo >> 6) & 7);
+               } else
+                       powernow_table[i].frequency =
+                               data->acpi_data.states[i].core_frequency * 1000;
        }
        return 0;
 }
@@ -1026,6 +1048,19 @@ static int get_transition_latency(struct powernow_k8_data *data)
                if (cur_latency > max_latency)
                        max_latency = cur_latency;
        }
+       if (max_latency == 0) {
+               /*
+                * Fam 11h always returns 0 as transition latency.
+                * This is intended and means "very fast". While cpufreq core
+                * and governors currently can handle that gracefully, better
+                * set it to 1 to avoid problems in the future.
+                * For all others it's a BIOS bug.
+                */
+               if (!boot_cpu_data.x86 == 0x11)
+                       printk(KERN_ERR FW_WARN PFX "Invalid zero transition "
+                               "latency\n");
+               max_latency = 1;
+       }
        /* value in usecs, needs to be in nanoseconds */
        return 1000 * max_latency;
 }
@@ -1215,13 +1250,12 @@ static int powernowk8_verify(struct cpufreq_policy *pol)
        return cpufreq_frequency_table_verify(pol, data->powernow_table);
 }
 
-static const char ACPI_PSS_BIOS_BUG_MSG[] =
-       KERN_ERR FW_BUG PFX "No compatible ACPI _PSS objects found.\n"
-       KERN_ERR FW_BUG PFX "Try again with latest BIOS.\n";
-
 /* per CPU init entry point to the driver */
 static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
 {
+       static const char ACPI_PSS_BIOS_BUG_MSG[] =
+               KERN_ERR FW_BUG PFX "No compatible ACPI _PSS objects found.\n"
+               KERN_ERR FW_BUG PFX "Try again with latest BIOS.\n";
        struct powernow_k8_data *data;
        cpumask_t oldmask;
        int rc;