Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Jean Delvare and committed by
Jean Delvare
bd4bc3db 45158894

+32 -30
+13 -14
drivers/i2c/busses/i2c-amd756-s4882.c
··· 155 155 int i, error; 156 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 168 /* Unregister physical bus */ 159 169 error = i2c_del_adapter(&amd756_smbus); 160 170 if (error) { ··· 208 198 s4882_algo[3].smbus_xfer = amd756_access_virt3; 209 199 s4882_algo[4].smbus_xfer = amd756_access_virt4; 210 200 211 - /* Configure the PCA9556 multiplexer */ 212 - ioconfig.byte = 0x00; /* All I/O to output mode */ 213 - error = amd756_smbus.algo->smbus_xfer(&amd756_smbus, 0x18, 0, 214 - I2C_SMBUS_WRITE, 0x03, 215 - I2C_SMBUS_BYTE_DATA, &ioconfig); 216 - if (error) { 217 - dev_err(&amd756_smbus.dev, "PCA9556 configuration failed\n"); 218 - error = -EIO; 219 - goto ERROR3; 220 - } 221 - 222 201 /* Register virtual adapters */ 223 202 for (i = 0; i < 5; i++) { 224 203 error = i2c_add_adapter(s4882_adapter+i); 225 204 if (error) { 226 - dev_err(&amd756_smbus.dev, 205 + printk(KERN_ERR "i2c-amd756-s4882: " 227 206 "Virtual adapter %d registration " 228 207 "failed, module not inserted\n", i); 229 208 for (i--; i >= 0; i--) ··· 251 252 252 253 /* Restore physical bus */ 253 254 if (i2c_add_adapter(&amd756_smbus)) 254 - dev_err(&amd756_smbus.dev, "Physical bus restoration " 255 - "failed\n"); 255 + printk(KERN_ERR "i2c-amd756-s4882: " 256 + "Physical bus restoration failed\n"); 256 257 } 257 258 258 259 MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
+15 -16
drivers/i2c/busses/i2c-nforce2-s4985.c
··· 150 150 int i, error; 151 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 163 /* Unregister physical bus */ 154 164 if (!nforce2_smbus) 155 165 return -ENODEV; ··· 201 191 s4985_algo[3].smbus_xfer = nforce2_access_virt3; 202 192 s4985_algo[4].smbus_xfer = nforce2_access_virt4; 203 193 204 - /* Configure the PCA9556 multiplexer */ 205 - ioconfig.byte = 0x00; /* All I/O to output mode */ 206 - error = nforce2_smbus->algo->smbus_xfer(nforce2_smbus, 0x18, 0, 207 - I2C_SMBUS_WRITE, 0x03, 208 - I2C_SMBUS_BYTE_DATA, &ioconfig); 209 - if (error) { 210 - dev_err(&nforce2_smbus->dev, "PCA9556 configuration failed\n"); 211 - error = -EIO; 212 - goto ERROR3; 213 - } 214 - 215 194 /* Register virtual adapters */ 216 195 for (i = 0; i < 5; i++) { 217 196 error = i2c_add_adapter(s4985_adapter + i); 218 197 if (error) { 219 - dev_err(&nforce2_smbus->dev, 220 - "Virtual adapter %d registration " 221 - "failed, module not inserted\n", i); 198 + printk(KERN_ERR "i2c-nforce2-s4985: " 199 + "Virtual adapter %d registration " 200 + "failed, module not inserted\n", i); 222 201 for (i--; i >= 0; i--) 223 202 i2c_del_adapter(s4985_adapter + i); 224 203 goto ERROR3; ··· 244 245 245 246 /* Restore physical bus */ 246 247 if (i2c_add_adapter(nforce2_smbus)) 247 - dev_err(&nforce2_smbus->dev, "Physical bus restoration " 248 - "failed\n"); 248 + printk(KERN_ERR "i2c-nforce2-s4985: " 249 + "Physical bus restoration failed\n"); 249 250 } 250 251 251 252 MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
+4
drivers/i2c/i2c-core.c
··· 654 654 655 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 661 out_unlock: 658 662 mutex_unlock(&core_lock); 659 663 return res;