hwmon: (coretemp) Fix Atom CPUs support
authorRudolf Marek <r.marek@assembler.cz>
Wed, 23 Sep 2009 20:59:42 +0000 (22:59 +0200)
committerJean Delvare <khali@linux-fr.org>
Wed, 23 Sep 2009 20:59:42 +0000 (22:59 +0200)
Fix Atom CPUs support. Intel documents TjMax at 90 degrees C but
some Atoms may have 125 degrees C (this is undocumented speculation).

Signed-off-by: Rudolf Marek <r.marek@assembler.cz>
Cc: Huaxu Wan <huaxu.wan@linux.intel.com>
Cc: Kent Liu <kent.liu@linux.intel.com>
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Documentation/hwmon/coretemp
drivers/hwmon/Kconfig
drivers/hwmon/coretemp.c

index dbbe6c7..d3d79e6 100644 (file)
@@ -4,7 +4,7 @@ Kernel driver coretemp
 Supported chips:
   * All Intel Core family
     Prefix: 'coretemp'
-    CPUID: family 0x6, models 0xe, 0xf, 0x16, 0x17
+    CPUID: family 0x6, models 0xe, 0xf, 0x16, 0x17, 0x1c (Atom)
     Datasheet: Intel 64 and IA-32 Architectures Software Developer's Manual
                Volume 3A: System Programming Guide
                http://softwarecommunity.intel.com/Wiki/Mobility/720.htm
index 9d881f7..6857560 100644 (file)
@@ -373,12 +373,12 @@ config SENSORS_GL520SM
          will be called gl520sm.
 
 config SENSORS_CORETEMP
-       tristate "Intel Core (2) Duo/Solo temperature sensor"
+       tristate "Intel Core/Core2/Atom temperature sensor"
        depends on X86 && EXPERIMENTAL
        help
          If you say yes here you get support for the temperature
-         sensor inside your CPU. Supported all are all known variants
-         of Intel Core family.
+         sensor inside your CPU. Most of the family 6 CPUs
+         are supported. Check documentation/driver for details.
 
 config SENSORS_IBMAEM
        tristate "IBM Active Energy Manager temperature/power sensors and control"
index 972cf4b..4c15ed7 100644 (file)
@@ -157,17 +157,24 @@ static int __devinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *
        /* The 100C is default for both mobile and non mobile CPUs */
 
        int tjmax = 100000;
-       int ismobile = 1;
+       int usemsr_ee = 1;
        int err;
        u32 eax, edx;
 
        /* Early chips have no MSR for TjMax */
 
        if ((c->x86_model == 0xf) && (c->x86_mask < 4)) {
-               ismobile = 0;
+               usemsr_ee = 0;
        }
 
-       if ((c->x86_model > 0xe) && (ismobile)) {
+       /* Atoms seems to have TjMax at 90C */
+
+       if (c->x86_model == 0x1c) {
+               usemsr_ee = 0;
+               tjmax = 90000;
+       }
+
+       if ((c->x86_model > 0xe) && (usemsr_ee)) {
 
                /* Now we can detect the mobile CPU using Intel provided table
                   http://softwarecommunity.intel.com/Wiki/Mobility/720.htm
@@ -179,13 +186,13 @@ static int __devinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *
                        dev_warn(dev,
                                 "Unable to access MSR 0x17, assuming desktop"
                                 " CPU\n");
-                       ismobile = 0;
+                       usemsr_ee = 0;
                } else if (!(eax & 0x10000000)) {
-                       ismobile = 0;
+                       usemsr_ee = 0;
                }
        }
 
-       if (ismobile || c->x86_model == 0x1c) {
+       if (usemsr_ee) {
 
                err = rdmsr_safe_on_cpu(id, 0xee, &eax, &edx);
                if (err) {
@@ -195,7 +202,9 @@ static int __devinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *
                } else if (eax & 0x40000000) {
                        tjmax = 85000;
                }
-       } else {
+       /* if we dont use msr EE it means we are desktop CPU (with exeception
+          of Atom) */
+       } else if (tjmax == 100000) {
                dev_warn(dev, "Using relative temperature scale!\n");
        }
 
@@ -248,9 +257,9 @@ static int __devinit coretemp_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, data);
 
        /* read the still undocumented IA32_TEMPERATURE_TARGET it exists
-          on older CPUs but not in this register */
+          on older CPUs but not in this register, Atoms don't have it either */
 
-       if (c->x86_model > 0xe) {
+       if ((c->x86_model > 0xe) && (c->x86_model != 0x1c)) {
                err = rdmsr_safe_on_cpu(data->id, 0x1a2, &eax, &edx);
                if (err) {
                        dev_warn(&pdev->dev, "Unable to read"
@@ -413,7 +422,7 @@ static int __init coretemp_init(void)
        for_each_online_cpu(i) {
                struct cpuinfo_x86 *c = &cpu_data(i);
 
-               /* check if family 6, models 0xe, 0xf, 0x16, 0x17, 0x1A */
+               /* check if family 6, models 0xe, 0xf, 0x16, 0x17, 0x1A, 0x1c */
                if ((c->cpuid_level < 0) || (c->x86 != 0x6) ||
                    !((c->x86_model == 0xe) || (c->x86_model == 0xf) ||
                        (c->x86_model == 0x16) || (c->x86_model == 0x17) ||