aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/k8temp.c
diff options
context:
space:
mode:
authorAndreas Herrmann <andreas.herrmann3@amd.com>2009-01-15 16:27:46 -0500
committerJean Delvare <khali@linux-fr.org>2009-01-15 16:27:46 -0500
commitbb9a35f293a3c8b5d57253cdfe2f29fa2627e1b9 (patch)
tree41cf2f3ebc4736b0cc8cf92e1070ad3606a57d82 /drivers/hwmon/k8temp.c
parent5393f780277165f282a37ed82dd878159ec9dad5 (diff)
hwmon: (k8temp) Warn about fam F rev F errata
Add warning about wrong CPU temperature readouts on all fam F rev F. The allowed combinations of processors ensure that all processors in a multisocket system have similar characteristics, e.g. (1) provide temperature sensor interface (>=RevC && <RevF) (2) are affected by erratum #141 (>=RevF) Thus it is sufficient to check the revision of the boot CPU. For "mixed silicon support" refer to "Revision Guide for AMD Athlon 64 and AMD Opteron Processors" (RevA-E) and "Revision Guide for AMD NPT Family 0Fh Processors" (RefF-G). Cc: Rudolf Marek <r.marek@assembler.cz> Signed-off-by: Andreas Herrmann <andreas.herrmann3@amd.com> Signed-off-by: Jean Delvare <khali@linux-fr.org>
Diffstat (limited to 'drivers/hwmon/k8temp.c')
-rw-r--r--drivers/hwmon/k8temp.c29
1 files changed, 22 insertions, 7 deletions
diff --git a/drivers/hwmon/k8temp.c b/drivers/hwmon/k8temp.c
index bd2bde0ef95e..ca56f2e26fd1 100644
--- a/drivers/hwmon/k8temp.c
+++ b/drivers/hwmon/k8temp.c
@@ -31,6 +31,7 @@
31#include <linux/hwmon-sysfs.h> 31#include <linux/hwmon-sysfs.h>
32#include <linux/err.h> 32#include <linux/err.h>
33#include <linux/mutex.h> 33#include <linux/mutex.h>
34#include <asm/processor.h>
34 35
35#define TEMP_FROM_REG(val) (((((val) >> 16) & 0xff) - 49) * 1000) 36#define TEMP_FROM_REG(val) (((((val) >> 16) & 0xff) - 49) * 1000)
36#define REG_TEMP 0xe4 37#define REG_TEMP 0xe4
@@ -141,20 +142,34 @@ static int __devinit k8temp_probe(struct pci_dev *pdev,
141 int err; 142 int err;
142 u8 scfg; 143 u8 scfg;
143 u32 temp; 144 u32 temp;
145 u8 model, stepping;
144 struct k8temp_data *data; 146 struct k8temp_data *data;
145 u32 cpuid = cpuid_eax(1);
146
147 /* this feature should be available since SH-C0 core */
148 if ((cpuid == 0xf40) || (cpuid == 0xf50) || (cpuid == 0xf51)) {
149 err = -ENODEV;
150 goto exit;
151 }
152 147
153 if (!(data = kzalloc(sizeof(struct k8temp_data), GFP_KERNEL))) { 148 if (!(data = kzalloc(sizeof(struct k8temp_data), GFP_KERNEL))) {
154 err = -ENOMEM; 149 err = -ENOMEM;
155 goto exit; 150 goto exit;
156 } 151 }
157 152
153 model = boot_cpu_data.x86_model;
154 stepping = boot_cpu_data.x86_mask;
155
156 switch (boot_cpu_data.x86) {
157 case 0xf:
158 /* feature available since SH-C0, exclude older revisions */
159 if (((model == 4) && (stepping == 0)) ||
160 ((model == 5) && (stepping <= 1))) {
161 err = -ENODEV;
162 goto exit_free;
163 }
164
165 if (model >= 0x40) {
166 dev_warn(&pdev->dev, "Temperature readouts might be "
167 "wrong - check erratum #141\n");
168 }
169
170 break;
171 }
172
158 pci_read_config_byte(pdev, REG_TEMP, &scfg); 173 pci_read_config_byte(pdev, REG_TEMP, &scfg);
159 scfg &= ~(SEL_PLACE | SEL_CORE); /* Select sensor 0, core0 */ 174 scfg &= ~(SEL_PLACE | SEL_CORE); /* Select sensor 0, core0 */
160 pci_write_config_byte(pdev, REG_TEMP, scfg); 175 pci_write_config_byte(pdev, REG_TEMP, scfg);