summaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/k8temp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon/k8temp.c')
-rw-r--r--drivers/hwmon/k8temp.c87
1 files changed, 55 insertions, 32 deletions
diff --git a/drivers/hwmon/k8temp.c b/drivers/hwmon/k8temp.c
index 8bdf80d91598..418496f13020 100644
--- a/drivers/hwmon/k8temp.c
+++ b/drivers/hwmon/k8temp.c
@@ -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);
@@ -252,12 +274,13 @@ static int __devinit k8temp_probe(struct pci_dev *pdev,
&sensor_dev_attr_temp3_input.dev_attr);
if (err)
goto exit_remove;
- if (data->sensorsp & SEL_PLACE)
+ if (data->sensorsp & SEL_PLACE) {
err = device_create_file(&pdev->dev,
&sensor_dev_attr_temp4_input.
dev_attr);
if (err)
goto exit_remove;
+ }
}
err = device_create_file(&pdev->dev, &dev_attr_name);