aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/coretemp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon/coretemp.c')
-rw-r--r--drivers/hwmon/coretemp.c93
1 files changed, 69 insertions, 24 deletions
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c
index e9b7fbc5a447..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
244static 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
244static int __devinit coretemp_probe(struct platform_device *pdev) 293static 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");
@@ -451,28 +504,20 @@ static int __init coretemp_init(void)
451 504
452 for_each_online_cpu(i) { 505 for_each_online_cpu(i) {
453 struct cpuinfo_x86 *c = &cpu_data(i); 506 struct cpuinfo_x86 *c = &cpu_data(i);
507 /*
508 * CPUID.06H.EAX[0] indicates whether the CPU has thermal
509 * sensors. We check this bit only, all the early CPUs
510 * without thermal sensors will be filtered out.
511 */
512 if (c->cpuid_level >= 6 && (cpuid_eax(0x06) & 0x01)) {
513 err = coretemp_device_add(i);
514 if (err)
515 goto exit_devices_unreg;
454 516
455 /* check if family 6, models 0xe (Pentium M DC), 517 } else {
456 0xf (Core 2 DC 65nm), 0x16 (Core 2 SC 65nm), 518 printk(KERN_INFO DRVNAME ": CPU (model=0x%x)"
457 0x17 (Penryn 45nm), 0x1a (Nehalem), 0x1c (Atom), 519 " has no thermal sensor.\n", c->x86_model);
458 0x1e (Lynnfield) */
459 if ((c->cpuid_level < 0) || (c->x86 != 0x6) ||
460 !((c->x86_model == 0xe) || (c->x86_model == 0xf) ||
461 (c->x86_model == 0x16) || (c->x86_model == 0x17) ||
462 (c->x86_model == 0x1a) || (c->x86_model == 0x1c) ||
463 (c->x86_model == 0x1e))) {
464
465 /* supported CPU not found, but report the unknown
466 family 6 CPU */
467 if ((c->x86 == 0x6) && (c->x86_model > 0xf))
468 printk(KERN_WARNING DRVNAME ": Unknown CPU "
469 "model 0x%x\n", c->x86_model);
470 continue;
471 } 520 }
472
473 err = coretemp_device_add(i);
474 if (err)
475 goto exit_devices_unreg;
476 } 521 }
477 if (list_empty(&pdev_list)) { 522 if (list_empty(&pdev_list)) {
478 err = -ENODEV; 523 err = -ENODEV;