diff options
author | Andreas Herrmann <andreas.herrmann3@amd.com> | 2009-01-15 16:27:46 -0500 |
---|---|---|
committer | Jean Delvare <khali@linux-fr.org> | 2009-01-15 16:27:46 -0500 |
commit | bb9a35f293a3c8b5d57253cdfe2f29fa2627e1b9 (patch) | |
tree | 41cf2f3ebc4736b0cc8cf92e1070ad3606a57d82 /drivers | |
parent | 5393f780277165f282a37ed82dd878159ec9dad5 (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')
-rw-r--r-- | drivers/hwmon/k8temp.c | 29 |
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); |