aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2009-12-16 15:38:27 -0500
committerJean Delvare <khali@linux-fr.org>2009-12-16 15:38:27 -0500
commitfa0bff02239abdad446effef22e5db281cf3d562 (patch)
treeb6bc68dd9e32660a73b2155ad209919040b80195
parent3ecf44b312758d10be20539b06b2df5d77d59cdb (diff)
hwmon: (smsc47m1) Enable device if needed
If the address is set but the device isn't enabled, attempt to enable it. If it won't work for any reason (resource conflict, no function enabled) the initial state is restored. The initial state is also restored on module unloading. Signed-off-by: Jean Delvare <khali@linux-fr.org> Tested-by: Sean Fidler <fidlersean@gmail.com>
-rw-r--r--drivers/hwmon/smsc47m1.c30
1 files changed, 27 insertions, 3 deletions
diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c
index 92cca512b38..9ca97818bd4 100644
--- a/drivers/hwmon/smsc47m1.c
+++ b/drivers/hwmon/smsc47m1.c
@@ -136,6 +136,7 @@ struct smsc47m1_data {
136 136
137struct smsc47m1_sio_data { 137struct smsc47m1_sio_data {
138 enum chips type; 138 enum chips type;
139 u8 activate; /* Remember initial device state */
139}; 140};
140 141
141 142
@@ -468,17 +469,38 @@ static int __init smsc47m1_find(unsigned short *addr,
468 superio_select(); 469 superio_select();
469 *addr = (superio_inb(SUPERIO_REG_BASE) << 8) 470 *addr = (superio_inb(SUPERIO_REG_BASE) << 8)
470 | superio_inb(SUPERIO_REG_BASE + 1); 471 | superio_inb(SUPERIO_REG_BASE + 1);
471 val = superio_inb(SUPERIO_REG_ACT); 472 if (*addr == 0) {
472 if (*addr == 0 || (val & 0x01) == 0) { 473 pr_info(DRVNAME ": Device address not set, will not use\n");
473 pr_info(DRVNAME ": Device is disabled, will not use\n");
474 superio_exit(); 474 superio_exit();
475 return -ENODEV; 475 return -ENODEV;
476 } 476 }
477 477
478 /* Enable only if address is set (needed at least on the
479 * Compaq Presario S4000NX) */
480 sio_data->activate = superio_inb(SUPERIO_REG_ACT);
481 if ((sio_data->activate & 0x01) == 0) {
482 pr_info(DRVNAME ": Enabling device\n");
483 superio_outb(SUPERIO_REG_ACT, sio_data->activate | 0x01);
484 }
485
478 superio_exit(); 486 superio_exit();
479 return 0; 487 return 0;
480} 488}
481 489
490/* Restore device to its initial state */
491static void __init smsc47m1_restore(const struct smsc47m1_sio_data *sio_data)
492{
493 if ((sio_data->activate & 0x01) == 0) {
494 superio_enter();
495 superio_select();
496
497 pr_info(DRVNAME ": Disabling device\n");
498 superio_outb(SUPERIO_REG_ACT, sio_data->activate);
499
500 superio_exit();
501 }
502}
503
482#define CHECK 1 504#define CHECK 1
483#define REQUEST 2 505#define REQUEST 2
484#define RELEASE 3 506#define RELEASE 3
@@ -856,6 +878,7 @@ static int __init sm_smsc47m1_init(void)
856 878
857exit_device: 879exit_device:
858 platform_device_unregister(pdev); 880 platform_device_unregister(pdev);
881 smsc47m1_restore(&sio_data);
859exit: 882exit:
860 return err; 883 return err;
861} 884}
@@ -863,6 +886,7 @@ exit:
863static void __exit sm_smsc47m1_exit(void) 886static void __exit sm_smsc47m1_exit(void)
864{ 887{
865 platform_driver_unregister(&smsc47m1_driver); 888 platform_driver_unregister(&smsc47m1_driver);
889 smsc47m1_restore(pdev->dev.platform_data);
866 platform_device_unregister(pdev); 890 platform_device_unregister(pdev);
867} 891}
868 892