diff options
author | Carsten Emde <C.Emde@osadl.org> | 2010-05-24 17:33:41 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-25 11:07:07 -0400 |
commit | a321cedb12904114e2ba5041a3673ca24deb09c9 (patch) | |
tree | 43481f2751380094a9873b3b474ae6e7e0019167 /drivers/hwmon/coretemp.c | |
parent | 5db47b009d17d69a2f8d84357e7b24c3e3c2edec (diff) |
drivers/hwmon/coretemp.c: get TjMax value from MSR
The MSR IA32_TEMPERATURE_TARGET contains the TjMax value in the newer
Intel processors.
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: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/hwmon/coretemp.c')
-rw-r--r-- | drivers/hwmon/coretemp.c | 61 |
1 files changed, 57 insertions, 4 deletions
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index 9fae7cbc5d76..2988da150ed6 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 * | |||
241 | return tjmax; | 241 | return tjmax; |
242 | } | 242 | } |
243 | 243 | ||
244 | static int __devinit get_tjmax(struct cpuinfo_x86 *c, u32 id, | ||
245 | struct device *dev) | ||
246 | { | ||
247 | /* The 100C is default for both mobile and non mobile CPUs */ | ||
248 | int err; | ||
249 | u32 eax, edx; | ||
250 | u32 val; | ||
251 | |||
252 | /* A new feature of current Intel(R) processors, the | ||
253 | IA32_TEMPERATURE_TARGET contains the TjMax value */ | ||
254 | err = rdmsr_safe_on_cpu(id, MSR_IA32_TEMPERATURE_TARGET, &eax, &edx); | ||
255 | if (err) { | ||
256 | dev_warn(dev, "Unable to read TjMax from CPU.\n"); | ||
257 | } else { | ||
258 | val = (eax >> 16) & 0xff; | ||
259 | /* | ||
260 | * If the TjMax is not plausible, an assumption | ||
261 | * will be used | ||
262 | */ | ||
263 | if ((val > 80) && (val < 120)) { | ||
264 | dev_info(dev, "TjMax is %d C.\n", val); | ||
265 | return val * 1000; | ||
266 | } | ||
267 | } | ||
268 | |||
269 | /* | ||
270 | * An assumption is made for early CPUs and unreadable MSR. | ||
271 | * NOTE: the given value may not be correct. | ||
272 | */ | ||
273 | |||
274 | switch (c->x86_model) { | ||
275 | case 0xe: | ||
276 | case 0xf: | ||
277 | case 0x16: | ||
278 | case 0x1a: | ||
279 | dev_warn(dev, "TjMax is assumed as 100 C!\n"); | ||
280 | return 100000; | ||
281 | break; | ||
282 | case 0x17: | ||
283 | case 0x1c: /* Atom CPUs */ | ||
284 | return adjust_tjmax(c, id, dev); | ||
285 | break; | ||
286 | default: | ||
287 | dev_warn(dev, "CPU (model=0x%x) is not supported yet," | ||
288 | " using default TjMax of 100C.\n", c->x86_model); | ||
289 | return 100000; | ||
290 | } | ||
291 | } | ||
292 | |||
244 | static int __devinit coretemp_probe(struct platform_device *pdev) | 293 | static int __devinit coretemp_probe(struct platform_device *pdev) |
245 | { | 294 | { |
246 | struct coretemp_data *data; | 295 | struct coretemp_data *data; |
@@ -283,14 +332,18 @@ static int __devinit coretemp_probe(struct platform_device *pdev) | |||
283 | } | 332 | } |
284 | } | 333 | } |
285 | 334 | ||
286 | data->tjmax = adjust_tjmax(c, data->id, &pdev->dev); | 335 | data->tjmax = get_tjmax(c, data->id, &pdev->dev); |
287 | platform_set_drvdata(pdev, data); | 336 | platform_set_drvdata(pdev, data); |
288 | 337 | ||
289 | /* read the still undocumented IA32_TEMPERATURE_TARGET it exists | 338 | /* |
290 | on older CPUs but not in this register, Atoms don't have it either */ | 339 | * read the still undocumented IA32_TEMPERATURE_TARGET. It exists |
340 | * on older CPUs but not in this register, | ||
341 | * Atoms don't have it either. | ||
342 | */ | ||
291 | 343 | ||
292 | if ((c->x86_model > 0xe) && (c->x86_model != 0x1c)) { | 344 | if ((c->x86_model > 0xe) && (c->x86_model != 0x1c)) { |
293 | err = rdmsr_safe_on_cpu(data->id, 0x1a2, &eax, &edx); | 345 | err = rdmsr_safe_on_cpu(data->id, MSR_IA32_TEMPERATURE_TARGET, |
346 | &eax, &edx); | ||
294 | if (err) { | 347 | if (err) { |
295 | dev_warn(&pdev->dev, "Unable to read" | 348 | dev_warn(&pdev->dev, "Unable to read" |
296 | " IA32_TEMPERATURE_TARGET MSR\n"); | 349 | " IA32_TEMPERATURE_TARGET MSR\n"); |