aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2008-07-16 13:30:05 -0400
committerJean Delvare <khali@mahadeva.delvare>2008-07-16 13:30:05 -0400
commitbd4bc3dbded9cd7b2bdca6bba1aecb4251a8039d (patch)
tree463f7b4283b3924abf504e4db020050bd2b55db5
parent45158894d4d6704afbb4cefe55e5f6ca279fe12a (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>
-rw-r--r--drivers/i2c/busses/i2c-amd756-s4882.c27
-rw-r--r--drivers/i2c/busses/i2c-nforce2-s4985.c31
-rw-r--r--drivers/i2c/i2c-core.c4
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 2f150e33c74c..72872d1e63ef 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)
155 int i, error; 155 int i, error;
156 union i2c_smbus_data ioconfig; 156 union i2c_smbus_data ioconfig;
157 157
158 /* Configure the PCA9556 multiplexer */
159 ioconfig.byte = 0x00; /* All I/O to output mode */
160 error = i2c_smbus_xfer(&amd756_smbus, 0x18, 0, I2C_SMBUS_WRITE, 0x03,
161 I2C_SMBUS_BYTE_DATA, &ioconfig);
162 if (error) {
163 dev_err(&amd756_smbus.dev, "PCA9556 configuration failed\n");
164 error = -EIO;
165 goto ERROR0;
166 }
167
158 /* Unregister physical bus */ 168 /* Unregister physical bus */
159 error = i2c_del_adapter(&amd756_smbus); 169 error = i2c_del_adapter(&amd756_smbus);
160 if (error) { 170 if (error) {
@@ -198,22 +208,11 @@ static int __init amd756_s4882_init(void)
198 s4882_algo[3].smbus_xfer = amd756_access_virt3; 208 s4882_algo[3].smbus_xfer = amd756_access_virt3;
199 s4882_algo[4].smbus_xfer = amd756_access_virt4; 209 s4882_algo[4].smbus_xfer = amd756_access_virt4;
200 210
201 /* Configure the PCA9556 multiplexer */
202 ioconfig.byte = 0x00; /* All I/O to output mode */
203 error = amd756_smbus.algo->smbus_xfer(&amd756_smbus, 0x18, 0,
204 I2C_SMBUS_WRITE, 0x03,
205 I2C_SMBUS_BYTE_DATA, &ioconfig);
206 if (error) {
207 dev_err(&amd756_smbus.dev, "PCA9556 configuration failed\n");
208 error = -EIO;
209 goto ERROR3;
210 }
211
212 /* Register virtual adapters */ 211 /* Register virtual adapters */
213 for (i = 0; i < 5; i++) { 212 for (i = 0; i < 5; i++) {
214 error = i2c_add_adapter(s4882_adapter+i); 213 error = i2c_add_adapter(s4882_adapter+i);
215 if (error) { 214 if (error) {
216 dev_err(&amd756_smbus.dev, 215 printk(KERN_ERR "i2c-amd756-s4882: "
217 "Virtual adapter %d registration " 216 "Virtual adapter %d registration "
218 "failed, module not inserted\n", i); 217 "failed, module not inserted\n", i);
219 for (i--; i >= 0; i--) 218 for (i--; i >= 0; i--)
@@ -252,8 +251,8 @@ static void __exit amd756_s4882_exit(void)
252 251
253 /* Restore physical bus */ 252 /* Restore physical bus */
254 if (i2c_add_adapter(&amd756_smbus)) 253 if (i2c_add_adapter(&amd756_smbus))
255 dev_err(&amd756_smbus.dev, "Physical bus restoration " 254 printk(KERN_ERR "i2c-amd756-s4882: "
256 "failed\n"); 255 "Physical bus restoration failed\n");
257} 256}
258 257
259MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>"); 258MODULE_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 6a8995dfd0bb..d1a4cbcf2aa4 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)
150 int i, error; 150 int i, error;
151 union i2c_smbus_data ioconfig; 151 union i2c_smbus_data ioconfig;
152 152
153 /* Configure the PCA9556 multiplexer */
154 ioconfig.byte = 0x00; /* All I/O to output mode */
155 error = i2c_smbus_xfer(nforce2_smbus, 0x18, 0, I2C_SMBUS_WRITE, 0x03,
156 I2C_SMBUS_BYTE_DATA, &ioconfig);
157 if (error) {
158 dev_err(&nforce2_smbus->dev, "PCA9556 configuration failed\n");
159 error = -EIO;
160 goto ERROR0;
161 }
162
153 /* Unregister physical bus */ 163 /* Unregister physical bus */
154 if (!nforce2_smbus) 164 if (!nforce2_smbus)
155 return -ENODEV; 165 return -ENODEV;
@@ -191,24 +201,13 @@ static int __init nforce2_s4985_init(void)
191 s4985_algo[3].smbus_xfer = nforce2_access_virt3; 201 s4985_algo[3].smbus_xfer = nforce2_access_virt3;
192 s4985_algo[4].smbus_xfer = nforce2_access_virt4; 202 s4985_algo[4].smbus_xfer = nforce2_access_virt4;
193 203
194 /* Configure the PCA9556 multiplexer */
195 ioconfig.byte = 0x00; /* All I/O to output mode */
196 error = nforce2_smbus->algo->smbus_xfer(nforce2_smbus, 0x18, 0,
197 I2C_SMBUS_WRITE, 0x03,
198 I2C_SMBUS_BYTE_DATA, &ioconfig);
199 if (error) {
200 dev_err(&nforce2_smbus->dev, "PCA9556 configuration failed\n");
201 error = -EIO;
202 goto ERROR3;
203 }
204
205 /* Register virtual adapters */ 204 /* Register virtual adapters */
206 for (i = 0; i < 5; i++) { 205 for (i = 0; i < 5; i++) {
207 error = i2c_add_adapter(s4985_adapter + i); 206 error = i2c_add_adapter(s4985_adapter + i);
208 if (error) { 207 if (error) {
209 dev_err(&nforce2_smbus->dev, 208 printk(KERN_ERR "i2c-nforce2-s4985: "
210 "Virtual adapter %d registration " 209 "Virtual adapter %d registration "
211 "failed, module not inserted\n", i); 210 "failed, module not inserted\n", i);
212 for (i--; i >= 0; i--) 211 for (i--; i >= 0; i--)
213 i2c_del_adapter(s4985_adapter + i); 212 i2c_del_adapter(s4985_adapter + i);
214 goto ERROR3; 213 goto ERROR3;
@@ -245,8 +244,8 @@ static void __exit nforce2_s4985_exit(void)
245 244
246 /* Restore physical bus */ 245 /* Restore physical bus */
247 if (i2c_add_adapter(nforce2_smbus)) 246 if (i2c_add_adapter(nforce2_smbus))
248 dev_err(&nforce2_smbus->dev, "Physical bus restoration " 247 printk(KERN_ERR "i2c-nforce2-s4985: "
249 "failed\n"); 248 "Physical bus restoration failed\n");
250} 249}
251 250
252MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>"); 251MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 0a79f7661017..7608df83d6d1 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)
654 654
655 dev_dbg(&adap->dev, "adapter [%s] unregistered\n", adap->name); 655 dev_dbg(&adap->dev, "adapter [%s] unregistered\n", adap->name);
656 656
657 /* Clear the device structure in case this adapter is ever going to be
658 added again */
659 memset(&adap->dev, 0, sizeof(adap->dev));
660
657 out_unlock: 661 out_unlock:
658 mutex_unlock(&core_lock); 662 mutex_unlock(&core_lock);
659 return res; 663 return res;