Skip to content

Commit

Permalink
i2c: Clear i2c_adapter.dev on adapter removal
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Jean Delvare authored and Jean Delvare committed Jul 16, 2008
1 parent 4515889 commit bd4bc3d
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 30 deletions.
27 changes: 13 additions & 14 deletions drivers/i2c/busses/i2c-amd756-s4882.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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--)
Expand Down Expand Up @@ -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>");
Expand Down
31 changes: 15 additions & 16 deletions drivers/i2c/busses/i2c-nforce2-s4985.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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>");
Expand Down
4 changes: 4 additions & 0 deletions drivers/i2c/i2c-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit bd4bc3d

Please sign in to comment.