diff options
author | Jan Beulich <JBeulich@novell.com> | 2010-10-08 04:59:38 -0400 |
---|---|---|
committer | Guenter Roeck <guenter.roeck@ericsson.com> | 2010-10-25 14:11:21 -0700 |
commit | 3247800676c4a04352cde72b9935b57ffc72ce15 (patch) | |
tree | 5918c72fe4fbdf6f224f1e62661445870939e894 /drivers/hwmon/coretemp.c | |
parent | 17c10d61c750619324ee2a46c5a9e03a435fe212 (diff) | |
download | op-kernel-dev-3247800676c4a04352cde72b9935b57ffc72ce15.zip op-kernel-dev-3247800676c4a04352cde72b9935b57ffc72ce15.tar.gz |
hwmon: (coretemp) fix reading of microcode revision (v2)
According to the documentation, simply reading the respective MSR
isn't sufficient: It should be written with zeros, cpuid(1) be
executed, and then read (see arch/x86/kernel/cpu/intel.c for an
example).
v2: Fail probe when microcode revision cannot be determined, but is
needed to check for proper operation.
Signed-off-by: Jan Beulich <jbeulich@novell.com>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: Chen Gong <gong.chen@linux.intel.com>
Cc: Jean Delvare <khali@linux-fr.org>
Acked-by: Fenghua Yu <fenghua.yu@intel.com>
Signed-off-by: Guenter Roeck <guenter.roeck@ericsson.com>
Diffstat (limited to 'drivers/hwmon/coretemp.c')
-rw-r--r-- | drivers/hwmon/coretemp.c | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index 467488c..42de98d 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c @@ -289,6 +289,15 @@ static int __devinit get_tjmax(struct cpuinfo_x86 *c, u32 id, } } +static void __devinit get_ucode_rev_on_cpu(void *edx) +{ + u32 eax; + + wrmsr(MSR_IA32_UCODE_REV, 0, 0); + sync_core(); + rdmsr(MSR_IA32_UCODE_REV, eax, *(u32 *)edx); +} + static int __devinit coretemp_probe(struct platform_device *pdev) { struct coretemp_data *data; @@ -324,8 +333,15 @@ static int __devinit coretemp_probe(struct platform_device *pdev) if ((c->x86_model == 0xe) && (c->x86_mask < 0xc)) { /* check for microcode update */ - rdmsr_on_cpu(data->id, MSR_IA32_UCODE_REV, &eax, &edx); - if (edx < 0x39) { + err = smp_call_function_single(data->id, get_ucode_rev_on_cpu, + &edx, 1); + if (err) { + dev_err(&pdev->dev, + "Cannot determine microcode revision of " + "CPU#%u (%d)!\n", data->id, err); + err = -ENODEV; + goto exit_free; + } else if (edx < 0x39) { err = -ENODEV; dev_err(&pdev->dev, "Errata AE18 not fixed, update BIOS or " |