KVM: MMU: invalidate and flush on spte small->large page size change
[safe/jmp/linux-2.6] / drivers / hwmon / smsc47m1.c
index bfef223..8fa462f 100644 (file)
@@ -136,11 +136,11 @@ struct smsc47m1_data {
 
 struct smsc47m1_sio_data {
        enum chips type;
+       u8 activate;            /* Remember initial device state */
 };
 
 
-static int smsc47m1_probe(struct platform_device *pdev);
-static int __devexit smsc47m1_remove(struct platform_device *pdev);
+static int __exit smsc47m1_remove(struct platform_device *pdev);
 static struct smsc47m1_data *smsc47m1_update_device(struct device *dev,
                int init);
 
@@ -160,8 +160,7 @@ static struct platform_driver smsc47m1_driver = {
                .owner  = THIS_MODULE,
                .name   = DRVNAME,
        },
-       .probe          = smsc47m1_probe,
-       .remove         = __devexit_p(smsc47m1_remove),
+       .remove         = __exit_p(smsc47m1_remove),
 };
 
 static ssize_t get_fan(struct device *dev, struct device_attribute
@@ -470,17 +469,38 @@ static int __init smsc47m1_find(unsigned short *addr,
        superio_select();
        *addr = (superio_inb(SUPERIO_REG_BASE) << 8)
              |  superio_inb(SUPERIO_REG_BASE + 1);
-       val = superio_inb(SUPERIO_REG_ACT);
-       if (*addr == 0 || (val & 0x01) == 0) {
-               pr_info(DRVNAME ": Device is disabled, will not use\n");
+       if (*addr == 0) {
+               pr_info(DRVNAME ": Device address not set, will not use\n");
                superio_exit();
                return -ENODEV;
        }
 
+       /* Enable only if address is set (needed at least on the
+        * Compaq Presario S4000NX) */
+       sio_data->activate = superio_inb(SUPERIO_REG_ACT);
+       if ((sio_data->activate & 0x01) == 0) {
+               pr_info(DRVNAME ": Enabling device\n");
+               superio_outb(SUPERIO_REG_ACT, sio_data->activate | 0x01);
+       }
+
        superio_exit();
        return 0;
 }
 
+/* Restore device to its initial state */
+static void smsc47m1_restore(const struct smsc47m1_sio_data *sio_data)
+{
+       if ((sio_data->activate & 0x01) == 0) {
+               superio_enter();
+               superio_select();
+
+               pr_info(DRVNAME ": Disabling device\n");
+               superio_outb(SUPERIO_REG_ACT, sio_data->activate);
+
+               superio_exit();
+       }
+}
+
 #define CHECK          1
 #define REQUEST                2
 #define RELEASE                3
@@ -562,7 +582,7 @@ static int smsc47m1_handle_resources(unsigned short address, enum chips type,
        return 0;
 }
 
-static int __devinit smsc47m1_probe(struct platform_device *pdev)
+static int __init smsc47m1_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
        struct smsc47m1_sio_data *sio_data = dev->platform_data;
@@ -720,7 +740,7 @@ error_release:
        return err;
 }
 
-static int __devexit smsc47m1_remove(struct platform_device *pdev)
+static int __exit smsc47m1_remove(struct platform_device *pdev)
 {
        struct smsc47m1_data *data = platform_get_drvdata(pdev);
        struct resource *res;
@@ -845,27 +865,29 @@ static int __init sm_smsc47m1_init(void)
        if (smsc47m1_find(&address, &sio_data))
                return -ENODEV;
 
-       err = platform_driver_register(&smsc47m1_driver);
+       /* Sets global pdev as a side effect */
+       err = smsc47m1_device_add(address, &sio_data);
        if (err)
                goto exit;
 
-       /* Sets global pdev as a side effect */
-       err = smsc47m1_device_add(address, &sio_data);
+       err = platform_driver_probe(&smsc47m1_driver, smsc47m1_probe);
        if (err)
-               goto exit_driver;
+               goto exit_device;
 
        return 0;
 
-exit_driver:
-       platform_driver_unregister(&smsc47m1_driver);
+exit_device:
+       platform_device_unregister(pdev);
+       smsc47m1_restore(&sio_data);
 exit:
        return err;
 }
 
 static void __exit sm_smsc47m1_exit(void)
 {
-       platform_device_unregister(pdev);
        platform_driver_unregister(&smsc47m1_driver);
+       smsc47m1_restore(pdev->dev.platform_data);
+       platform_device_unregister(pdev);
 }
 
 MODULE_AUTHOR("Mark D. Studebaker <mdsxyz123@yahoo.com>");