diff options
Diffstat (limited to 'drivers/hwmon/coretemp.c')
-rw-r--r-- | drivers/hwmon/coretemp.c | 55 |
1 files changed, 35 insertions, 20 deletions
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index 2988da150ed..c070c9714cb 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c @@ -53,6 +53,7 @@ struct coretemp_data { struct mutex update_lock; const char *name; u32 id; + u16 core_id; char valid; /* zero until following fields are valid */ unsigned long last_updated; /* in jiffies */ int temp; @@ -75,7 +76,7 @@ static ssize_t show_name(struct device *dev, struct device_attribute if (attr->index == SHOW_NAME) ret = sprintf(buf, "%s\n", data->name); else /* show label */ - ret = sprintf(buf, "Core %d\n", data->id); + ret = sprintf(buf, "Core %d\n", data->core_id); return ret; } @@ -304,6 +305,9 @@ static int __devinit coretemp_probe(struct platform_device *pdev) } data->id = pdev->id; +#ifdef CONFIG_SMP + data->core_id = c->cpu_core_id; +#endif data->name = "coretemp"; mutex_init(&data->update_lock); @@ -405,6 +409,10 @@ struct pdev_entry { struct list_head list; struct platform_device *pdev; unsigned int cpu; +#ifdef CONFIG_SMP + u16 phys_proc_id; + u16 cpu_core_id; +#endif }; static LIST_HEAD(pdev_list); @@ -415,6 +423,22 @@ static int __cpuinit coretemp_device_add(unsigned int cpu) int err; struct platform_device *pdev; struct pdev_entry *pdev_entry; +#ifdef CONFIG_SMP + struct cpuinfo_x86 *c = &cpu_data(cpu); +#endif + + mutex_lock(&pdev_list_mutex); + +#ifdef CONFIG_SMP + /* Skip second HT entry of each core */ + list_for_each_entry(pdev_entry, &pdev_list, list) { + if (c->phys_proc_id == pdev_entry->phys_proc_id && + c->cpu_core_id == pdev_entry->cpu_core_id) { + err = 0; /* Not an error */ + goto exit; + } + } +#endif pdev = platform_device_alloc(DRVNAME, cpu); if (!pdev) { @@ -438,7 +462,10 @@ static int __cpuinit coretemp_device_add(unsigned int cpu) pdev_entry->pdev = pdev; pdev_entry->cpu = cpu; - mutex_lock(&pdev_list_mutex); +#ifdef CONFIG_SMP + pdev_entry->phys_proc_id = c->phys_proc_id; + pdev_entry->cpu_core_id = c->cpu_core_id; +#endif list_add_tail(&pdev_entry->list, &pdev_list); mutex_unlock(&pdev_list_mutex); @@ -449,10 +476,10 @@ exit_device_free: exit_device_put: platform_device_put(pdev); exit: + mutex_unlock(&pdev_list_mutex); return err; } -#ifdef CONFIG_HOTPLUG_CPU static void coretemp_device_remove(unsigned int cpu) { struct pdev_entry *p, *n; @@ -487,7 +514,6 @@ static int __cpuinit coretemp_cpu_callback(struct notifier_block *nfb, static struct notifier_block coretemp_cpu_notifier __refdata = { .notifier_call = coretemp_cpu_callback, }; -#endif /* !CONFIG_HOTPLUG_CPU */ static int __init coretemp_init(void) { @@ -509,12 +535,9 @@ static int __init coretemp_init(void) * sensors. We check this bit only, all the early CPUs * without thermal sensors will be filtered out. */ - if (c->cpuid_level >= 6 && (cpuid_eax(0x06) & 0x01)) { - err = coretemp_device_add(i); - if (err) - goto exit_devices_unreg; - - } else { + if (c->cpuid_level >= 6 && (cpuid_eax(0x06) & 0x01)) + coretemp_device_add(i); + else { printk(KERN_INFO DRVNAME ": CPU (model=0x%x)" " has no thermal sensor.\n", c->x86_model); } @@ -524,21 +547,13 @@ static int __init coretemp_init(void) goto exit_driver_unreg; } -#ifdef CONFIG_HOTPLUG_CPU register_hotcpu_notifier(&coretemp_cpu_notifier); -#endif return 0; -exit_devices_unreg: - mutex_lock(&pdev_list_mutex); - list_for_each_entry_safe(p, n, &pdev_list, list) { - platform_device_unregister(p->pdev); - list_del(&p->list); - kfree(p); - } - mutex_unlock(&pdev_list_mutex); exit_driver_unreg: +#ifndef CONFIG_HOTPLUG_CPU platform_driver_unregister(&coretemp_driver); +#endif exit: return err; } |