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.c57
1 files changed, 33 insertions, 24 deletions
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c
index de8111114f46..a23b17a78ace 100644
--- a/drivers/hwmon/coretemp.c
+++ b/drivers/hwmon/coretemp.c
@@ -36,6 +36,7 @@
36#include <linux/pci.h> 36#include <linux/pci.h>
37#include <asm/msr.h> 37#include <asm/msr.h>
38#include <asm/processor.h> 38#include <asm/processor.h>
39#include <asm/smp.h>
39 40
40#define DRVNAME "coretemp" 41#define DRVNAME "coretemp"
41 42
@@ -423,9 +424,18 @@ static int __cpuinit coretemp_device_add(unsigned int cpu)
423 int err; 424 int err;
424 struct platform_device *pdev; 425 struct platform_device *pdev;
425 struct pdev_entry *pdev_entry; 426 struct pdev_entry *pdev_entry;
426#ifdef CONFIG_SMP
427 struct cpuinfo_x86 *c = &cpu_data(cpu); 427 struct cpuinfo_x86 *c = &cpu_data(cpu);
428#endif 428
429 /*
430 * CPUID.06H.EAX[0] indicates whether the CPU has thermal
431 * sensors. We check this bit only, all the early CPUs
432 * without thermal sensors will be filtered out.
433 */
434 if (!cpu_has(c, X86_FEATURE_DTS)) {
435 printk(KERN_INFO DRVNAME ": CPU (model=0x%x)"
436 " has no thermal sensor.\n", c->x86_model);
437 return 0;
438 }
429 439
430 mutex_lock(&pdev_list_mutex); 440 mutex_lock(&pdev_list_mutex);
431 441
@@ -482,14 +492,22 @@ exit:
482 492
483static void coretemp_device_remove(unsigned int cpu) 493static void coretemp_device_remove(unsigned int cpu)
484{ 494{
485 struct pdev_entry *p, *n; 495 struct pdev_entry *p;
496 unsigned int i;
497
486 mutex_lock(&pdev_list_mutex); 498 mutex_lock(&pdev_list_mutex);
487 list_for_each_entry_safe(p, n, &pdev_list, list) { 499 list_for_each_entry(p, &pdev_list, list) {
488 if (p->cpu == cpu) { 500 if (p->cpu != cpu)
489 platform_device_unregister(p->pdev); 501 continue;
490 list_del(&p->list); 502
491 kfree(p); 503 platform_device_unregister(p->pdev);
492 } 504 list_del(&p->list);
505 mutex_unlock(&pdev_list_mutex);
506 kfree(p);
507 for_each_cpu(i, cpu_sibling_mask(cpu))
508 if (i != cpu && !coretemp_device_add(i))
509 break;
510 return;
493 } 511 }
494 mutex_unlock(&pdev_list_mutex); 512 mutex_unlock(&pdev_list_mutex);
495} 513}
@@ -527,30 +545,21 @@ static int __init coretemp_init(void)
527 if (err) 545 if (err)
528 goto exit; 546 goto exit;
529 547
530 for_each_online_cpu(i) { 548 for_each_online_cpu(i)
531 struct cpuinfo_x86 *c = &cpu_data(i); 549 coretemp_device_add(i);
532 /* 550
533 * CPUID.06H.EAX[0] indicates whether the CPU has thermal 551#ifndef CONFIG_HOTPLUG_CPU
534 * sensors. We check this bit only, all the early CPUs
535 * without thermal sensors will be filtered out.
536 */
537 if (c->cpuid_level >= 6 && (cpuid_eax(0x06) & 0x01))
538 coretemp_device_add(i);
539 else {
540 printk(KERN_INFO DRVNAME ": CPU (model=0x%x)"
541 " has no thermal sensor.\n", c->x86_model);
542 }
543 }
544 if (list_empty(&pdev_list)) { 552 if (list_empty(&pdev_list)) {
545 err = -ENODEV; 553 err = -ENODEV;
546 goto exit_driver_unreg; 554 goto exit_driver_unreg;
547 } 555 }
556#endif
548 557
549 register_hotcpu_notifier(&coretemp_cpu_notifier); 558 register_hotcpu_notifier(&coretemp_cpu_notifier);
550 return 0; 559 return 0;
551 560
552exit_driver_unreg:
553#ifndef CONFIG_HOTPLUG_CPU 561#ifndef CONFIG_HOTPLUG_CPU
562exit_driver_unreg:
554 platform_driver_unregister(&coretemp_driver); 563 platform_driver_unregister(&coretemp_driver);
555#endif 564#endif
556exit: 565exit: