Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bb9a35f2 authored by Andreas Herrmann's avatar Andreas Herrmann Committed by Jean Delvare
Browse files

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: default avatarAndreas Herrmann <andreas.herrmann3@amd.com>
Signed-off-by: default avatarJean Delvare <khali@linux-fr.org>
parent 5393f780
Loading
Loading
Loading
Loading
+22 −7
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <asm/processor.h>

#define TEMP_FROM_REG(val)	(((((val) >> 16) & 0xff) - 49) * 1000)
#define REG_TEMP	0xe4
@@ -141,20 +142,34 @@ static int __devinit k8temp_probe(struct pci_dev *pdev,
	int err;
	u8 scfg;
	u32 temp;
	u8 model, stepping;
	struct k8temp_data *data;
	u32 cpuid = cpuid_eax(1);

	/* this feature should be available since SH-C0 core */
	if ((cpuid == 0xf40) || (cpuid == 0xf50) || (cpuid == 0xf51)) {
		err = -ENODEV;
		goto exit;
	}

	if (!(data = kzalloc(sizeof(struct k8temp_data), GFP_KERNEL))) {
		err = -ENOMEM;
		goto exit;
	}

	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;
		}

		if (model >= 0x40) {
			dev_warn(&pdev->dev, "Temperature readouts might be "
				 "wrong - check erratum #141\n");
		}

		break;
	}

	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);