Merge branch 'hwmon-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelv...
[pandora-kernel.git] / drivers / hwmon / k8temp.c
index b9bb3e0..418496f 100644 (file)
@@ -143,6 +143,37 @@ static const struct pci_device_id k8temp_ids[] = {
 
 MODULE_DEVICE_TABLE(pci, k8temp_ids);
 
+static int __devinit is_rev_g_desktop(u8 model)
+{
+       u32 brandidx;
+
+       if (model < 0x69)
+               return 0;
+
+       if (model == 0xc1 || model == 0x6c || model == 0x7c)
+               return 0;
+
+       /*
+        * Differentiate between AM2 and ASB1.
+        * See "Constructing the processor Name String" in "Revision
+        * Guide for AMD NPT Family 0Fh Processors" (33610).
+        */
+       brandidx = cpuid_ebx(0x80000001);
+       brandidx = (brandidx >> 9) & 0x1f;
+
+       /* Single core */
+       if ((model == 0x6f || model == 0x7f) &&
+           (brandidx == 0x7 || brandidx == 0x9 || brandidx == 0xc))
+               return 0;
+
+       /* Dual core */
+       if (model == 0x6b &&
+           (brandidx == 0xb || brandidx == 0xc))
+               return 0;
+
+       return 1;
+}
+
 static int __devinit k8temp_probe(struct pci_dev *pdev,
                                  const struct pci_device_id *id)
 {
@@ -160,40 +191,31 @@ static int __devinit k8temp_probe(struct pci_dev *pdev,
        model = boot_cpu_data.x86_model;
        stepping = boot_cpu_data.x86_mask;
 
-       switch (boot_cpu_data.x86) {
-       case 0xf:
-               /* feature available since SH-C0, exclude older revisions */
-               if (((model == 4) && (stepping == 0)) ||
-                   ((model == 5) && (stepping <= 1))) {
-                       err = -ENODEV;
-                       goto exit_free;
-               }
-
-               /*
-                * AMD NPT family 0fh, i.e. RevF and RevG:
-                * meaning of SEL_CORE bit is inverted
-                */
-               if (model >= 0x40) {
-                       data->swap_core_select = 1;
-                       dev_warn(&pdev->dev, "Temperature readouts might be "
-                                "wrong - check erratum #141\n");
-               }
-
-               if ((model >= 0x69) &&
-                   !(model == 0xc1 || model == 0x6c || model == 0x7c ||
-                     model == 0x6b || model == 0x6f || model == 0x7f)) {
-                       /*
-                        * RevG desktop CPUs (i.e. no socket S1G1 or
-                        * ASB1 parts) need additional offset,
-                        * otherwise reported temperature is below
-                        * ambient temperature
-                        */
-                       data->temp_offset = 21000;
-               }
+       /* feature available since SH-C0, exclude older revisions */
+       if (((model == 4) && (stepping == 0)) ||
+           ((model == 5) && (stepping <= 1))) {
+               err = -ENODEV;
+               goto exit_free;
+       }
 
-               break;
+       /*
+        * AMD NPT family 0fh, i.e. RevF and RevG:
+        * meaning of SEL_CORE bit is inverted
+        */
+       if (model >= 0x40) {
+               data->swap_core_select = 1;
+               dev_warn(&pdev->dev, "Temperature readouts might be wrong - "
+                        "check erratum #141\n");
        }
 
+       /*
+        * RevG desktop CPUs (i.e. no socket S1G1 or ASB1 parts) need
+        * additional offset, otherwise reported temperature is below
+        * ambient temperature
+        */
+       if (is_rev_g_desktop(model))
+               data->temp_offset = 21000;
+
        pci_read_config_byte(pdev, REG_TEMP, &scfg);
        scfg &= ~(SEL_PLACE | SEL_CORE);                /* Select sensor 0, core0 */
        pci_write_config_byte(pdev, REG_TEMP, scfg);