diff options
author | Jean Delvare <khali@linux-fr.org> | 2008-07-16 19:30:05 +0200 |
---|---|---|
committer | Jean Delvare <khali@mahadeva.delvare> | 2008-07-16 19:30:05 +0200 |
commit | bd4bc3dbded9cd7b2bdca6bba1aecb4251a8039d (patch) | |
tree | 463f7b4283b3924abf504e4db020050bd2b55db5 /drivers/i2c | |
parent | 45158894d4d6704afbb4cefe55e5f6ca279fe12a (diff) |
i2c: Clear i2c_adapter.dev on adapter removal
Clear i2c_adapter.dev on adapter removal. This makes it possible to
re-add the adapter at a later point, which some drivers
(i2c-amd756-s4882, i2c-nforce2-s4985) actually do.
This fixes a bug reported by John Stultz here:
http://lkml.org/lkml/2008/7/15/720
and by Ingo Molar there:
http://lkml.org/lkml/2008/7/16/78
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Cc: John Stultz <johnstul@us.ibm.com>
Cc: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'drivers/i2c')
-rw-r--r-- | drivers/i2c/busses/i2c-amd756-s4882.c | 27 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-nforce2-s4985.c | 31 | ||||
-rw-r--r-- | drivers/i2c/i2c-core.c | 4 |
3 files changed, 32 insertions, 30 deletions
diff --git a/drivers/i2c/busses/i2c-amd756-s4882.c b/drivers/i2c/busses/i2c-amd756-s4882.c index 2f150e33c74..72872d1e63e 100644 --- a/drivers/i2c/busses/i2c-amd756-s4882.c +++ b/drivers/i2c/busses/i2c-amd756-s4882.c @@ -155,6 +155,16 @@ static int __init amd756_s4882_init(void) int i, error; union i2c_smbus_data ioconfig; + /* Configure the PCA9556 multiplexer */ + ioconfig.byte = 0x00; /* All I/O to output mode */ + error = i2c_smbus_xfer(&amd756_smbus, 0x18, 0, I2C_SMBUS_WRITE, 0x03, + I2C_SMBUS_BYTE_DATA, &ioconfig); + if (error) { + dev_err(&amd756_smbus.dev, "PCA9556 configuration failed\n"); + error = -EIO; + goto ERROR0; + } + /* Unregister physical bus */ error = i2c_del_adapter(&amd756_smbus); if (error) { @@ -198,22 +208,11 @@ static int __init amd756_s4882_init(void) s4882_algo[3].smbus_xfer = amd756_access_virt3; s4882_algo[4].smbus_xfer = amd756_access_virt4; - /* Configure the PCA9556 multiplexer */ - ioconfig.byte = 0x00; /* All I/O to output mode */ - error = amd756_smbus.algo->smbus_xfer(&amd756_smbus, 0x18, 0, - I2C_SMBUS_WRITE, 0x03, - I2C_SMBUS_BYTE_DATA, &ioconfig); - if (error) { - dev_err(&amd756_smbus.dev, "PCA9556 configuration failed\n"); - error = -EIO; - goto ERROR3; - } - /* Register virtual adapters */ for (i = 0; i < 5; i++) { error = i2c_add_adapter(s4882_adapter+i); if (error) { - dev_err(&amd756_smbus.dev, + printk(KERN_ERR "i2c-amd756-s4882: " "Virtual adapter %d registration " "failed, module not inserted\n", i); for (i--; i >= 0; i--) @@ -252,8 +251,8 @@ static void __exit amd756_s4882_exit(void) /* Restore physical bus */ if (i2c_add_adapter(&amd756_smbus)) - dev_err(&amd756_smbus.dev, "Physical bus restoration " - "failed\n"); + printk(KERN_ERR "i2c-amd756-s4882: " + "Physical bus restoration failed\n"); } MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>"); diff --git a/drivers/i2c/busses/i2c-nforce2-s4985.c b/drivers/i2c/busses/i2c-nforce2-s4985.c index 6a8995dfd0b..d1a4cbcf2aa 100644 --- a/drivers/i2c/busses/i2c-nforce2-s4985.c +++ b/drivers/i2c/busses/i2c-nforce2-s4985.c @@ -150,6 +150,16 @@ static int __init nforce2_s4985_init(void) int i, error; union i2c_smbus_data ioconfig; + /* Configure the PCA9556 multiplexer */ + ioconfig.byte = 0x00; /* All I/O to output mode */ + error = i2c_smbus_xfer(nforce2_smbus, 0x18, 0, I2C_SMBUS_WRITE, 0x03, + I2C_SMBUS_BYTE_DATA, &ioconfig); + if (error) { + dev_err(&nforce2_smbus->dev, "PCA9556 configuration failed\n"); + error = -EIO; + goto ERROR0; + } + /* Unregister physical bus */ if (!nforce2_smbus) return -ENODEV; @@ -191,24 +201,13 @@ static int __init nforce2_s4985_init(void) s4985_algo[3].smbus_xfer = nforce2_access_virt3; s4985_algo[4].smbus_xfer = nforce2_access_virt4; - /* Configure the PCA9556 multiplexer */ - ioconfig.byte = 0x00; /* All I/O to output mode */ - error = nforce2_smbus->algo->smbus_xfer(nforce2_smbus, 0x18, 0, - I2C_SMBUS_WRITE, 0x03, - I2C_SMBUS_BYTE_DATA, &ioconfig); - if (error) { - dev_err(&nforce2_smbus->dev, "PCA9556 configuration failed\n"); - error = -EIO; - goto ERROR3; - } - /* Register virtual adapters */ for (i = 0; i < 5; i++) { error = i2c_add_adapter(s4985_adapter + i); if (error) { - dev_err(&nforce2_smbus->dev, - "Virtual adapter %d registration " - "failed, module not inserted\n", i); + printk(KERN_ERR "i2c-nforce2-s4985: " + "Virtual adapter %d registration " + "failed, module not inserted\n", i); for (i--; i >= 0; i--) i2c_del_adapter(s4985_adapter + i); goto ERROR3; @@ -245,8 +244,8 @@ static void __exit nforce2_s4985_exit(void) /* Restore physical bus */ if (i2c_add_adapter(nforce2_smbus)) - dev_err(&nforce2_smbus->dev, "Physical bus restoration " - "failed\n"); + printk(KERN_ERR "i2c-nforce2-s4985: " + "Physical bus restoration failed\n"); } MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>"); diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 0a79f766101..7608df83d6d 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -654,6 +654,10 @@ int i2c_del_adapter(struct i2c_adapter *adap) dev_dbg(&adap->dev, "adapter [%s] unregistered\n", adap->name); + /* Clear the device structure in case this adapter is ever going to be + added again */ + memset(&adap->dev, 0, sizeof(adap->dev)); + out_unlock: mutex_unlock(&core_lock); return res; |