#include <linux/init.h>
#include <asm/io.h>
+static struct pci_dev *vt596_pdev;
+
#define SMBBA1 0x90
#define SMBBA2 0x80
#define SMBBA3 0xD0
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++)
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);
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(