vserver 1.9.5.x5
[linux-2.6.git] / drivers / i2c / busses / i2c-viapro.c
index 396b5eb..c872c28 100644 (file)
@@ -45,6 +45,8 @@
 #include <linux/init.h>
 #include <asm/io.h>
 
+static struct pci_dev *vt596_pdev;
+
 #define SMBBA1          0x90
 #define SMBBA2          0x80
 #define SMBBA3          0xD0
@@ -231,8 +233,8 @@ static s32 vt596_access(struct i2c_adapter *adap, u16 addr,
                        len = data->block[0];
                        if (len < 0)
                                len = 0;
-                       if (len > 32)
-                               len = 32;
+                       if (len > I2C_SMBUS_BLOCK_MAX)
+                               len = I2C_SMBUS_BLOCK_MAX;
                        outb_p(len, SMBHSTDAT0);
                        i = inb_p(SMBHSTCNT);   /* Reset SMBBLKDAT */
                        for (i = 1; i <= len; i++)
@@ -266,6 +268,8 @@ static s32 vt596_access(struct i2c_adapter *adap, u16 addr,
                break;
        case VT596_BLOCK_DATA:
                data->block[0] = inb_p(SMBHSTDAT0);
+               if (data->block[0] > I2C_SMBUS_BLOCK_MAX)
+                       data->block[0] = I2C_SMBUS_BLOCK_MAX;
                i = inb_p(SMBHSTCNT);   /* Reset SMBBLKDAT */
                for (i = 1; i <= data->block[0]; i++)
                        data->block[i] = inb_p(SMBBLKDAT);
@@ -381,95 +385,66 @@ static int __devinit vt596_probe(struct pci_dev *pdev,
        snprintf(vt596_adapter.name, I2C_NAME_SIZE,
                        "SMBus Via Pro adapter at %04x", vt596_smba);
        
-       return i2c_add_adapter(&vt596_adapter);
+       vt596_pdev = pci_dev_get(pdev);
+       if (i2c_add_adapter(&vt596_adapter)) {
+               pci_dev_put(vt596_pdev);
+               vt596_pdev = NULL;
+       }
+
+       /* Always return failure here.  This is to allow other drivers to bind
+        * to this pci device.  We don't really want to have control over the
+        * pci device, we only wanted to read as few register values from it.
+        */
+       return -ENODEV;
 
  release_region:
        release_region(vt596_smba, 8);
        return error;
 }
 
-static void __devexit vt596_remove(struct pci_dev *pdev)
-{
-       i2c_del_adapter(&vt596_adapter);
-       release_region(vt596_smba, 8);
-}
-
 static struct pci_device_id vt596_ids[] = {
-       {
-               .vendor         = PCI_VENDOR_ID_VIA,
-               .device         = PCI_DEVICE_ID_VIA_82C596_3,
-               .subvendor      = PCI_ANY_ID,
-               .subdevice      = PCI_ANY_ID,
-               .driver_data    = SMBBA1,
-       },
-       {
-               .vendor         = PCI_VENDOR_ID_VIA,
-               .device         = PCI_DEVICE_ID_VIA_82C596B_3,
-               .subvendor      = PCI_ANY_ID,
-               .subdevice      = PCI_ANY_ID,
-               .driver_data    = SMBBA1,
-       },
-       {
-               .vendor         = PCI_VENDOR_ID_VIA,
-               .device         = PCI_DEVICE_ID_VIA_82C686_4,
-               .subvendor      = PCI_ANY_ID,
-               .subdevice      = PCI_ANY_ID,
-               .driver_data    = SMBBA1,
-       },
-       {
-               .vendor         = PCI_VENDOR_ID_VIA,
-               .device         = PCI_DEVICE_ID_VIA_8233_0,
-               .subvendor      = PCI_ANY_ID,
-               .subdevice      = PCI_ANY_ID,
-               .driver_data    = SMBBA3
-       },
-       {
-               .vendor         = PCI_VENDOR_ID_VIA,
-               .device         = PCI_DEVICE_ID_VIA_8233A,
-               .subvendor      = PCI_ANY_ID,
-               .subdevice      = PCI_ANY_ID,
-               .driver_data    = SMBBA3,
-       },
-       {
-               .vendor         = PCI_VENDOR_ID_VIA,
-               .device         = PCI_DEVICE_ID_VIA_8235,
-               .subvendor      = PCI_ANY_ID,
-               .subdevice      = PCI_ANY_ID,
-               .driver_data    = SMBBA3
-       },
-       {
-               .vendor         = PCI_VENDOR_ID_VIA,
-               .device         = PCI_DEVICE_ID_VIA_8237,
-               .subvendor      = PCI_ANY_ID,
-               .subdevice      = PCI_ANY_ID,
-               .driver_data    = SMBBA3
-       },
-       {
-               .vendor         = PCI_VENDOR_ID_VIA,
-               .device         = PCI_DEVICE_ID_VIA_8231_4,
-               .subvendor      = PCI_ANY_ID,
-               .subdevice      = PCI_ANY_ID,
-               .driver_data    = SMBBA1,
-       },
+       { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C596_3),
+         .driver_data = SMBBA1 },
+       { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C596B_3),
+         .driver_data = SMBBA1 },
+       { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4),
+         .driver_data = SMBBA1 },
+       { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8233_0),
+         .driver_data = SMBBA3 },
+       { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8233A),
+         .driver_data = SMBBA3 },
+       { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235),
+         .driver_data = SMBBA3 },
+       { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237),
+         .driver_data = SMBBA3 },
+       { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231_4),
+         .driver_data = SMBBA1 },
        { 0, }
 };
 
+MODULE_DEVICE_TABLE (pci, vt596_ids);
+
 static struct pci_driver vt596_driver = {
        .name           = "vt596_smbus",
        .id_table       = vt596_ids,
        .probe          = vt596_probe,
-       .remove         = __devexit_p(vt596_remove),
 };
 
 static int __init i2c_vt596_init(void)
 {
-       return pci_module_init(&vt596_driver);
+       return pci_register_driver(&vt596_driver);
 }
 
 
 static void __exit i2c_vt596_exit(void)
 {
        pci_unregister_driver(&vt596_driver);
+       if (vt596_pdev != NULL) {
+               i2c_del_adapter(&vt596_adapter);
+               release_region(vt596_smba, 8);
+               pci_dev_put(vt596_pdev);
+               vt596_pdev = NULL;
+       }
 }
 
 MODULE_AUTHOR(