| From 8bff8426ecaa0abeb683b12c825d649078745275 Mon Sep 17 00:00:00 2001 |
| From: Carsten Emde <C.Emde@osadl.org> |
| Date: Mon, 24 May 2010 14:33:41 -0700 |
| Subject: [PATCH] drivers/hwmon/coretemp.c: get TjMax value from MSR |
| |
| commit ab774e8960b7eb5aec4ccaa2fd09b49fbb368d1a in tip. |
| |
| The MSR IA32_TEMPERATURE_TARGET contains the TjMax value in the newer |
| Intel processors. |
| |
| [ upstream commit a321cedb12904114e2ba5041a3673ca24deb09c9 ] |
| |
| Signed-off-by: Huaxu Wan <huaxu.wan@linux.intel.com> |
| Signed-off-by: Carsten Emde <C.Emde@osadl.org> |
| Cc: Jean Delvare <khali@linux-fr.org> |
| Cc: Valdis Kletnieks <valdis.kletnieks@vt.edu> |
| Cc: Henrique de Moraes Holschuh <hmh@hmh.eng.br> |
| Cc: Yong Wang <yong.y.wang@linux.intel.com> |
| Cc: Rudolf Marek <r.marek@assembler.cz> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| Signed-off-by: Thomas Gleixner <tglx@linutronix.de> |
| |
| diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h |
| index 1cd58cd..1f0002d 100644 |
| --- a/arch/x86/include/asm/msr-index.h |
| +++ b/arch/x86/include/asm/msr-index.h |
| @@ -230,6 +230,8 @@ |
| |
| #define MSR_IA32_MISC_ENABLE 0x000001a0 |
| |
| +#define MSR_IA32_TEMPERATURE_TARGET 0x000001a2 |
| + |
| /* MISC_ENABLE bits: architectural */ |
| #define MSR_IA32_MISC_ENABLE_FAST_STRING (1ULL << 0) |
| #define MSR_IA32_MISC_ENABLE_TCC (1ULL << 1) |
| diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c |
| index 915dff5..be2cf9b 100644 |
| --- a/drivers/hwmon/coretemp.c |
| +++ b/drivers/hwmon/coretemp.c |
| @@ -241,6 +241,55 @@ static int __devinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device * |
| return tjmax; |
| } |
| |
| +static int __devinit get_tjmax(struct cpuinfo_x86 *c, u32 id, |
| + struct device *dev) |
| +{ |
| + /* The 100C is default for both mobile and non mobile CPUs */ |
| + int err; |
| + u32 eax, edx; |
| + u32 val; |
| + |
| + /* A new feature of current Intel(R) processors, the |
| + IA32_TEMPERATURE_TARGET contains the TjMax value */ |
| + err = rdmsr_safe_on_cpu(id, MSR_IA32_TEMPERATURE_TARGET, &eax, &edx); |
| + if (err) { |
| + dev_warn(dev, "Unable to read TjMax from CPU.\n"); |
| + } else { |
| + val = (eax >> 16) & 0xff; |
| + /* |
| + * If the TjMax is not plausible, an assumption |
| + * will be used |
| + */ |
| + if ((val > 80) && (val < 120)) { |
| + dev_info(dev, "TjMax is %d C.\n", val); |
| + return val * 1000; |
| + } |
| + } |
| + |
| + /* |
| + * An assumption is made for early CPUs and unreadable MSR. |
| + * NOTE: the given value may not be correct. |
| + */ |
| + |
| + switch (c->x86_model) { |
| + case 0xe: |
| + case 0xf: |
| + case 0x16: |
| + case 0x1a: |
| + dev_warn(dev, "TjMax is assumed as 100 C!\n"); |
| + return 100000; |
| + break; |
| + case 0x17: |
| + case 0x1c: /* Atom CPUs */ |
| + return adjust_tjmax(c, id, dev); |
| + break; |
| + default: |
| + dev_warn(dev, "CPU (model=0x%x) is not supported yet," |
| + " using default TjMax of 100C.\n", c->x86_model); |
| + return 100000; |
| + } |
| +} |
| + |
| static int __devinit coretemp_probe(struct platform_device *pdev) |
| { |
| struct coretemp_data *data; |
| @@ -283,14 +332,18 @@ static int __devinit coretemp_probe(struct platform_device *pdev) |
| } |
| } |
| |
| - data->tjmax = adjust_tjmax(c, data->id, &pdev->dev); |
| + data->tjmax = get_tjmax(c, data->id, &pdev->dev); |
| platform_set_drvdata(pdev, data); |
| |
| - /* read the still undocumented IA32_TEMPERATURE_TARGET it exists |
| - on older CPUs but not in this register, Atoms don't have it either */ |
| + /* |
| + * read the still undocumented IA32_TEMPERATURE_TARGET. It exists |
| + * on older CPUs but not in this register, |
| + * Atoms don't have it either. |
| + */ |
| |
| if ((c->x86_model > 0xe) && (c->x86_model != 0x1c)) { |
| - err = rdmsr_safe_on_cpu(data->id, 0x1a2, &eax, &edx); |
| + err = rdmsr_safe_on_cpu(data->id, MSR_IA32_TEMPERATURE_TARGET, |
| + &eax, &edx); |
| if (err) { |
| dev_warn(&pdev->dev, "Unable to read" |
| " IA32_TEMPERATURE_TARGET MSR\n"); |
| -- |
| 1.7.1.1 |
| |