aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses/i2c-sis5595.c
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2007-07-12 08:12:30 -0400
committerJean Delvare <khali@hyperion.delvare>2007-07-12 08:12:30 -0400
commit7375cd822d600b4e8b83cbc025422e4267bf5fac (patch)
treea6b8b00e9a41924de9c37e4477f1045ea20e89b3 /drivers/i2c/busses/i2c-sis5595.c
parent7d13714650ec8868f999d2dc3d06e2723687d0c3 (diff)
i2c-sis5595: Resolve resource conflict with sis5595
Let the i2c-sis5595 driver release its PCI device after registering. This is to allow the sis5595 hardware monitoring driver to also access this PCI device. The same trick is already used in the i2c-viapro and via686a drivers to let them both load. Signed-off-by: Jean Delvare <khali@linux-fr.org>
Diffstat (limited to 'drivers/i2c/busses/i2c-sis5595.c')
-rw-r--r--drivers/i2c/busses/i2c-sis5595.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/drivers/i2c/busses/i2c-sis5595.c b/drivers/i2c/busses/i2c-sis5595.c
index a6feed449dbe..283769cecee2 100644
--- a/drivers/i2c/busses/i2c-sis5595.c
+++ b/drivers/i2c/busses/i2c-sis5595.c
@@ -129,6 +129,7 @@ MODULE_PARM_DESC(force_addr, "Initialize the base address of the i2c controller"
129 129
130static struct pci_driver sis5595_driver; 130static struct pci_driver sis5595_driver;
131static unsigned short sis5595_base; 131static unsigned short sis5595_base;
132static struct pci_dev *sis5595_pdev;
132 133
133static u8 sis5595_read(u8 reg) 134static u8 sis5595_read(u8 reg)
134{ 135{
@@ -379,6 +380,8 @@ MODULE_DEVICE_TABLE (pci, sis5595_ids);
379 380
380static int __devinit sis5595_probe(struct pci_dev *dev, const struct pci_device_id *id) 381static int __devinit sis5595_probe(struct pci_dev *dev, const struct pci_device_id *id)
381{ 382{
383 int err;
384
382 if (sis5595_setup(dev)) { 385 if (sis5595_setup(dev)) {
383 dev_err(&dev->dev, "SIS5595 not detected, module not inserted.\n"); 386 dev_err(&dev->dev, "SIS5595 not detected, module not inserted.\n");
384 return -ENODEV; 387 return -ENODEV;
@@ -389,20 +392,24 @@ static int __devinit sis5595_probe(struct pci_dev *dev, const struct pci_device_
389 392
390 sprintf(sis5595_adapter.name, "SMBus SIS5595 adapter at %04x", 393 sprintf(sis5595_adapter.name, "SMBus SIS5595 adapter at %04x",
391 sis5595_base + SMB_INDEX); 394 sis5595_base + SMB_INDEX);
392 return i2c_add_adapter(&sis5595_adapter); 395 err = i2c_add_adapter(&sis5595_adapter);
393} 396 if (err) {
397 release_region(sis5595_base + SMB_INDEX, 2);
398 return err;
399 }
394 400
395static void __devexit sis5595_remove(struct pci_dev *dev) 401 /* Always return failure here. This is to allow other drivers to bind
396{ 402 * to this pci device. We don't really want to have control over the
397 i2c_del_adapter(&sis5595_adapter); 403 * pci device, we only wanted to read as few register values from it.
398 release_region(sis5595_base + SMB_INDEX, 2); 404 */
405 sis5595_pdev = pci_dev_get(dev);
406 return -ENODEV;
399} 407}
400 408
401static struct pci_driver sis5595_driver = { 409static struct pci_driver sis5595_driver = {
402 .name = "sis5595_smbus", 410 .name = "sis5595_smbus",
403 .id_table = sis5595_ids, 411 .id_table = sis5595_ids,
404 .probe = sis5595_probe, 412 .probe = sis5595_probe,
405 .remove = __devexit_p(sis5595_remove),
406}; 413};
407 414
408static int __init i2c_sis5595_init(void) 415static int __init i2c_sis5595_init(void)
@@ -413,6 +420,12 @@ static int __init i2c_sis5595_init(void)
413static void __exit i2c_sis5595_exit(void) 420static void __exit i2c_sis5595_exit(void)
414{ 421{
415 pci_unregister_driver(&sis5595_driver); 422 pci_unregister_driver(&sis5595_driver);
423 if (sis5595_pdev) {
424 i2c_del_adapter(&sis5595_adapter);
425 release_region(sis5595_base + SMB_INDEX, 2);
426 pci_dev_put(sis5595_pdev);
427 sis5595_pdev = NULL;
428 }
416} 429}
417 430
418MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>"); 431MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");