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>
This commit is contained in:
parent
45158894d4
commit
bd4bc3dbde
|
@ -155,6 +155,16 @@ static int __init amd756_s4882_init(void)
|
||||||
int i, error;
|
int i, error;
|
||||||
union i2c_smbus_data ioconfig;
|
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 */
|
/* Unregister physical bus */
|
||||||
error = i2c_del_adapter(&amd756_smbus);
|
error = i2c_del_adapter(&amd756_smbus);
|
||||||
if (error) {
|
if (error) {
|
||||||
|
@ -198,22 +208,11 @@ static int __init amd756_s4882_init(void)
|
||||||
s4882_algo[3].smbus_xfer = amd756_access_virt3;
|
s4882_algo[3].smbus_xfer = amd756_access_virt3;
|
||||||
s4882_algo[4].smbus_xfer = amd756_access_virt4;
|
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 */
|
/* Register virtual adapters */
|
||||||
for (i = 0; i < 5; i++) {
|
for (i = 0; i < 5; i++) {
|
||||||
error = i2c_add_adapter(s4882_adapter+i);
|
error = i2c_add_adapter(s4882_adapter+i);
|
||||||
if (error) {
|
if (error) {
|
||||||
dev_err(&amd756_smbus.dev,
|
printk(KERN_ERR "i2c-amd756-s4882: "
|
||||||
"Virtual adapter %d registration "
|
"Virtual adapter %d registration "
|
||||||
"failed, module not inserted\n", i);
|
"failed, module not inserted\n", i);
|
||||||
for (i--; i >= 0; i--)
|
for (i--; i >= 0; i--)
|
||||||
|
@ -252,8 +251,8 @@ static void __exit amd756_s4882_exit(void)
|
||||||
|
|
||||||
/* Restore physical bus */
|
/* Restore physical bus */
|
||||||
if (i2c_add_adapter(&amd756_smbus))
|
if (i2c_add_adapter(&amd756_smbus))
|
||||||
dev_err(&amd756_smbus.dev, "Physical bus restoration "
|
printk(KERN_ERR "i2c-amd756-s4882: "
|
||||||
"failed\n");
|
"Physical bus restoration failed\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
|
MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
|
||||||
|
|
|
@ -150,6 +150,16 @@ static int __init nforce2_s4985_init(void)
|
||||||
int i, error;
|
int i, error;
|
||||||
union i2c_smbus_data ioconfig;
|
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 */
|
/* Unregister physical bus */
|
||||||
if (!nforce2_smbus)
|
if (!nforce2_smbus)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
@ -191,22 +201,11 @@ static int __init nforce2_s4985_init(void)
|
||||||
s4985_algo[3].smbus_xfer = nforce2_access_virt3;
|
s4985_algo[3].smbus_xfer = nforce2_access_virt3;
|
||||||
s4985_algo[4].smbus_xfer = nforce2_access_virt4;
|
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 */
|
/* Register virtual adapters */
|
||||||
for (i = 0; i < 5; i++) {
|
for (i = 0; i < 5; i++) {
|
||||||
error = i2c_add_adapter(s4985_adapter + i);
|
error = i2c_add_adapter(s4985_adapter + i);
|
||||||
if (error) {
|
if (error) {
|
||||||
dev_err(&nforce2_smbus->dev,
|
printk(KERN_ERR "i2c-nforce2-s4985: "
|
||||||
"Virtual adapter %d registration "
|
"Virtual adapter %d registration "
|
||||||
"failed, module not inserted\n", i);
|
"failed, module not inserted\n", i);
|
||||||
for (i--; i >= 0; i--)
|
for (i--; i >= 0; i--)
|
||||||
|
@ -245,8 +244,8 @@ static void __exit nforce2_s4985_exit(void)
|
||||||
|
|
||||||
/* Restore physical bus */
|
/* Restore physical bus */
|
||||||
if (i2c_add_adapter(nforce2_smbus))
|
if (i2c_add_adapter(nforce2_smbus))
|
||||||
dev_err(&nforce2_smbus->dev, "Physical bus restoration "
|
printk(KERN_ERR "i2c-nforce2-s4985: "
|
||||||
"failed\n");
|
"Physical bus restoration failed\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
|
MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
|
||||||
|
|
|
@ -654,6 +654,10 @@ int i2c_del_adapter(struct i2c_adapter *adap)
|
||||||
|
|
||||||
dev_dbg(&adap->dev, "adapter [%s] unregistered\n", adap->name);
|
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:
|
out_unlock:
|
||||||
mutex_unlock(&core_lock);
|
mutex_unlock(&core_lock);
|
||||||
return res;
|
return res;
|
||||||
|
|
Loading…
Reference in New Issue