diff options
Diffstat (limited to 'drivers/hwmon')
-rw-r--r-- | drivers/hwmon/Kconfig | 2 | ||||
-rw-r--r-- | drivers/hwmon/coretemp.c | 57 | ||||
-rw-r--r-- | drivers/hwmon/f71882fg.c | 32 | ||||
-rw-r--r-- | drivers/hwmon/lis3lv02d.c | 4 | ||||
-rw-r--r-- | drivers/hwmon/pkgtemp.c | 23 |
5 files changed, 66 insertions, 52 deletions
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 4d4d09bdec0a..97499d00615a 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -409,7 +409,7 @@ config SENSORS_CORETEMP | |||
409 | 409 | ||
410 | config SENSORS_PKGTEMP | 410 | config SENSORS_PKGTEMP |
411 | tristate "Intel processor package temperature sensor" | 411 | tristate "Intel processor package temperature sensor" |
412 | depends on X86 && PCI && EXPERIMENTAL | 412 | depends on X86 && EXPERIMENTAL |
413 | help | 413 | help |
414 | If you say yes here you get support for the package level temperature | 414 | If you say yes here you get support for the package level temperature |
415 | sensor inside your CPU. Check documentation/driver for details. | 415 | sensor inside your CPU. Check documentation/driver for details. |
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 | ||
483 | static void coretemp_device_remove(unsigned int cpu) | 493 | static 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 | ||
552 | exit_driver_unreg: | ||
553 | #ifndef CONFIG_HOTPLUG_CPU | 561 | #ifndef CONFIG_HOTPLUG_CPU |
562 | exit_driver_unreg: | ||
554 | platform_driver_unregister(&coretemp_driver); | 563 | platform_driver_unregister(&coretemp_driver); |
555 | #endif | 564 | #endif |
556 | exit: | 565 | exit: |
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c index 537841ef44b9..75afb3b0e076 100644 --- a/drivers/hwmon/f71882fg.c +++ b/drivers/hwmon/f71882fg.c | |||
@@ -111,7 +111,7 @@ static struct platform_device *f71882fg_pdev; | |||
111 | /* Super-I/O Function prototypes */ | 111 | /* Super-I/O Function prototypes */ |
112 | static inline int superio_inb(int base, int reg); | 112 | static inline int superio_inb(int base, int reg); |
113 | static inline int superio_inw(int base, int reg); | 113 | static inline int superio_inw(int base, int reg); |
114 | static inline void superio_enter(int base); | 114 | static inline int superio_enter(int base); |
115 | static inline void superio_select(int base, int ld); | 115 | static inline void superio_select(int base, int ld); |
116 | static inline void superio_exit(int base); | 116 | static inline void superio_exit(int base); |
117 | 117 | ||
@@ -861,11 +861,20 @@ static int superio_inw(int base, int reg) | |||
861 | return val; | 861 | return val; |
862 | } | 862 | } |
863 | 863 | ||
864 | static inline void superio_enter(int base) | 864 | static inline int superio_enter(int base) |
865 | { | 865 | { |
866 | /* Don't step on other drivers' I/O space by accident */ | ||
867 | if (!request_muxed_region(base, 2, DRVNAME)) { | ||
868 | printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n", | ||
869 | base); | ||
870 | return -EBUSY; | ||
871 | } | ||
872 | |||
866 | /* according to the datasheet the key must be send twice! */ | 873 | /* according to the datasheet the key must be send twice! */ |
867 | outb(SIO_UNLOCK_KEY, base); | 874 | outb(SIO_UNLOCK_KEY, base); |
868 | outb(SIO_UNLOCK_KEY, base); | 875 | outb(SIO_UNLOCK_KEY, base); |
876 | |||
877 | return 0; | ||
869 | } | 878 | } |
870 | 879 | ||
871 | static inline void superio_select(int base, int ld) | 880 | static inline void superio_select(int base, int ld) |
@@ -877,6 +886,7 @@ static inline void superio_select(int base, int ld) | |||
877 | static inline void superio_exit(int base) | 886 | static inline void superio_exit(int base) |
878 | { | 887 | { |
879 | outb(SIO_LOCK_KEY, base); | 888 | outb(SIO_LOCK_KEY, base); |
889 | release_region(base, 2); | ||
880 | } | 890 | } |
881 | 891 | ||
882 | static inline int fan_from_reg(u16 reg) | 892 | static inline int fan_from_reg(u16 reg) |
@@ -2175,21 +2185,15 @@ static int f71882fg_remove(struct platform_device *pdev) | |||
2175 | static int __init f71882fg_find(int sioaddr, unsigned short *address, | 2185 | static int __init f71882fg_find(int sioaddr, unsigned short *address, |
2176 | struct f71882fg_sio_data *sio_data) | 2186 | struct f71882fg_sio_data *sio_data) |
2177 | { | 2187 | { |
2178 | int err = -ENODEV; | ||
2179 | u16 devid; | 2188 | u16 devid; |
2180 | 2189 | int err = superio_enter(sioaddr); | |
2181 | /* Don't step on other drivers' I/O space by accident */ | 2190 | if (err) |
2182 | if (!request_region(sioaddr, 2, DRVNAME)) { | 2191 | return err; |
2183 | printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n", | ||
2184 | (int)sioaddr); | ||
2185 | return -EBUSY; | ||
2186 | } | ||
2187 | |||
2188 | superio_enter(sioaddr); | ||
2189 | 2192 | ||
2190 | devid = superio_inw(sioaddr, SIO_REG_MANID); | 2193 | devid = superio_inw(sioaddr, SIO_REG_MANID); |
2191 | if (devid != SIO_FINTEK_ID) { | 2194 | if (devid != SIO_FINTEK_ID) { |
2192 | pr_debug(DRVNAME ": Not a Fintek device\n"); | 2195 | pr_debug(DRVNAME ": Not a Fintek device\n"); |
2196 | err = -ENODEV; | ||
2193 | goto exit; | 2197 | goto exit; |
2194 | } | 2198 | } |
2195 | 2199 | ||
@@ -2213,6 +2217,7 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address, | |||
2213 | default: | 2217 | default: |
2214 | printk(KERN_INFO DRVNAME ": Unsupported Fintek device: %04x\n", | 2218 | printk(KERN_INFO DRVNAME ": Unsupported Fintek device: %04x\n", |
2215 | (unsigned int)devid); | 2219 | (unsigned int)devid); |
2220 | err = -ENODEV; | ||
2216 | goto exit; | 2221 | goto exit; |
2217 | } | 2222 | } |
2218 | 2223 | ||
@@ -2223,12 +2228,14 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address, | |||
2223 | 2228 | ||
2224 | if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) { | 2229 | if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) { |
2225 | printk(KERN_WARNING DRVNAME ": Device not activated\n"); | 2230 | printk(KERN_WARNING DRVNAME ": Device not activated\n"); |
2231 | err = -ENODEV; | ||
2226 | goto exit; | 2232 | goto exit; |
2227 | } | 2233 | } |
2228 | 2234 | ||
2229 | *address = superio_inw(sioaddr, SIO_REG_ADDR); | 2235 | *address = superio_inw(sioaddr, SIO_REG_ADDR); |
2230 | if (*address == 0) { | 2236 | if (*address == 0) { |
2231 | printk(KERN_WARNING DRVNAME ": Base address not set\n"); | 2237 | printk(KERN_WARNING DRVNAME ": Base address not set\n"); |
2238 | err = -ENODEV; | ||
2232 | goto exit; | 2239 | goto exit; |
2233 | } | 2240 | } |
2234 | *address &= ~(REGION_LENGTH - 1); /* Ignore 3 LSB */ | 2241 | *address &= ~(REGION_LENGTH - 1); /* Ignore 3 LSB */ |
@@ -2239,7 +2246,6 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address, | |||
2239 | (int)superio_inb(sioaddr, SIO_REG_DEVREV)); | 2246 | (int)superio_inb(sioaddr, SIO_REG_DEVREV)); |
2240 | exit: | 2247 | exit: |
2241 | superio_exit(sioaddr); | 2248 | superio_exit(sioaddr); |
2242 | release_region(sioaddr, 2); | ||
2243 | return err; | 2249 | return err; |
2244 | } | 2250 | } |
2245 | 2251 | ||
diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c index 6138f036b159..fc591ae53107 100644 --- a/drivers/hwmon/lis3lv02d.c +++ b/drivers/hwmon/lis3lv02d.c | |||
@@ -277,7 +277,7 @@ static irqreturn_t lis302dl_interrupt(int irq, void *dummy) | |||
277 | wake_up_interruptible(&lis3_dev.misc_wait); | 277 | wake_up_interruptible(&lis3_dev.misc_wait); |
278 | kill_fasync(&lis3_dev.async_queue, SIGIO, POLL_IN); | 278 | kill_fasync(&lis3_dev.async_queue, SIGIO, POLL_IN); |
279 | out: | 279 | out: |
280 | if (lis3_dev.whoami == WAI_8B && lis3_dev.idev && | 280 | if (lis3_dev.pdata && lis3_dev.whoami == WAI_8B && lis3_dev.idev && |
281 | lis3_dev.idev->input->users) | 281 | lis3_dev.idev->input->users) |
282 | return IRQ_WAKE_THREAD; | 282 | return IRQ_WAKE_THREAD; |
283 | return IRQ_HANDLED; | 283 | return IRQ_HANDLED; |
@@ -718,7 +718,7 @@ int lis3lv02d_init_device(struct lis3lv02d *dev) | |||
718 | * io-apic is not configurable (and generates a warning) but I keep it | 718 | * io-apic is not configurable (and generates a warning) but I keep it |
719 | * in case of support for other hardware. | 719 | * in case of support for other hardware. |
720 | */ | 720 | */ |
721 | if (dev->whoami == WAI_8B) | 721 | if (dev->pdata && dev->whoami == WAI_8B) |
722 | thread_fn = lis302dl_interrupt_thread1_8b; | 722 | thread_fn = lis302dl_interrupt_thread1_8b; |
723 | else | 723 | else |
724 | thread_fn = NULL; | 724 | thread_fn = NULL; |
diff --git a/drivers/hwmon/pkgtemp.c b/drivers/hwmon/pkgtemp.c index 74157fcda6ed..f11903936c8b 100644 --- a/drivers/hwmon/pkgtemp.c +++ b/drivers/hwmon/pkgtemp.c | |||
@@ -33,7 +33,6 @@ | |||
33 | #include <linux/list.h> | 33 | #include <linux/list.h> |
34 | #include <linux/platform_device.h> | 34 | #include <linux/platform_device.h> |
35 | #include <linux/cpu.h> | 35 | #include <linux/cpu.h> |
36 | #include <linux/pci.h> | ||
37 | #include <asm/msr.h> | 36 | #include <asm/msr.h> |
38 | #include <asm/processor.h> | 37 | #include <asm/processor.h> |
39 | 38 | ||
@@ -224,7 +223,7 @@ static int __devinit pkgtemp_probe(struct platform_device *pdev) | |||
224 | 223 | ||
225 | err = sysfs_create_group(&pdev->dev.kobj, &pkgtemp_group); | 224 | err = sysfs_create_group(&pdev->dev.kobj, &pkgtemp_group); |
226 | if (err) | 225 | if (err) |
227 | goto exit_free; | 226 | goto exit_dev; |
228 | 227 | ||
229 | data->hwmon_dev = hwmon_device_register(&pdev->dev); | 228 | data->hwmon_dev = hwmon_device_register(&pdev->dev); |
230 | if (IS_ERR(data->hwmon_dev)) { | 229 | if (IS_ERR(data->hwmon_dev)) { |
@@ -238,6 +237,8 @@ static int __devinit pkgtemp_probe(struct platform_device *pdev) | |||
238 | 237 | ||
239 | exit_class: | 238 | exit_class: |
240 | sysfs_remove_group(&pdev->dev.kobj, &pkgtemp_group); | 239 | sysfs_remove_group(&pdev->dev.kobj, &pkgtemp_group); |
240 | exit_dev: | ||
241 | device_remove_file(&pdev->dev, &sensor_dev_attr_temp1_max.dev_attr); | ||
241 | exit_free: | 242 | exit_free: |
242 | kfree(data); | 243 | kfree(data); |
243 | exit: | 244 | exit: |
@@ -250,6 +251,7 @@ static int __devexit pkgtemp_remove(struct platform_device *pdev) | |||
250 | 251 | ||
251 | hwmon_device_unregister(data->hwmon_dev); | 252 | hwmon_device_unregister(data->hwmon_dev); |
252 | sysfs_remove_group(&pdev->dev.kobj, &pkgtemp_group); | 253 | sysfs_remove_group(&pdev->dev.kobj, &pkgtemp_group); |
254 | device_remove_file(&pdev->dev, &sensor_dev_attr_temp1_max.dev_attr); | ||
253 | platform_set_drvdata(pdev, NULL); | 255 | platform_set_drvdata(pdev, NULL); |
254 | kfree(data); | 256 | kfree(data); |
255 | return 0; | 257 | return 0; |
@@ -281,9 +283,10 @@ static int __cpuinit pkgtemp_device_add(unsigned int cpu) | |||
281 | int err; | 283 | int err; |
282 | struct platform_device *pdev; | 284 | struct platform_device *pdev; |
283 | struct pdev_entry *pdev_entry; | 285 | struct pdev_entry *pdev_entry; |
284 | #ifdef CONFIG_SMP | ||
285 | struct cpuinfo_x86 *c = &cpu_data(cpu); | 286 | struct cpuinfo_x86 *c = &cpu_data(cpu); |
286 | #endif | 287 | |
288 | if (!cpu_has(c, X86_FEATURE_PTS)) | ||
289 | return 0; | ||
287 | 290 | ||
288 | mutex_lock(&pdev_list_mutex); | 291 | mutex_lock(&pdev_list_mutex); |
289 | 292 | ||
@@ -339,17 +342,18 @@ exit: | |||
339 | #ifdef CONFIG_HOTPLUG_CPU | 342 | #ifdef CONFIG_HOTPLUG_CPU |
340 | static void pkgtemp_device_remove(unsigned int cpu) | 343 | static void pkgtemp_device_remove(unsigned int cpu) |
341 | { | 344 | { |
342 | struct pdev_entry *p, *n; | 345 | struct pdev_entry *p; |
343 | unsigned int i; | 346 | unsigned int i; |
344 | int err; | 347 | int err; |
345 | 348 | ||
346 | mutex_lock(&pdev_list_mutex); | 349 | mutex_lock(&pdev_list_mutex); |
347 | list_for_each_entry_safe(p, n, &pdev_list, list) { | 350 | list_for_each_entry(p, &pdev_list, list) { |
348 | if (p->cpu != cpu) | 351 | if (p->cpu != cpu) |
349 | continue; | 352 | continue; |
350 | 353 | ||
351 | platform_device_unregister(p->pdev); | 354 | platform_device_unregister(p->pdev); |
352 | list_del(&p->list); | 355 | list_del(&p->list); |
356 | mutex_unlock(&pdev_list_mutex); | ||
353 | kfree(p); | 357 | kfree(p); |
354 | for_each_cpu(i, cpu_core_mask(cpu)) { | 358 | for_each_cpu(i, cpu_core_mask(cpu)) { |
355 | if (i != cpu) { | 359 | if (i != cpu) { |
@@ -358,7 +362,7 @@ static void pkgtemp_device_remove(unsigned int cpu) | |||
358 | break; | 362 | break; |
359 | } | 363 | } |
360 | } | 364 | } |
361 | break; | 365 | return; |
362 | } | 366 | } |
363 | mutex_unlock(&pdev_list_mutex); | 367 | mutex_unlock(&pdev_list_mutex); |
364 | } | 368 | } |
@@ -399,11 +403,6 @@ static int __init pkgtemp_init(void) | |||
399 | goto exit; | 403 | goto exit; |
400 | 404 | ||
401 | for_each_online_cpu(i) { | 405 | for_each_online_cpu(i) { |
402 | struct cpuinfo_x86 *c = &cpu_data(i); | ||
403 | |||
404 | if (!cpu_has(c, X86_FEATURE_PTS)) | ||
405 | continue; | ||
406 | |||
407 | err = pkgtemp_device_add(i); | 406 | err = pkgtemp_device_add(i); |
408 | if (err) | 407 | if (err) |
409 | goto exit_devices_unreg; | 408 | goto exit_devices_unreg; |