[i2c] [patch 2.6.21-rc3-git +i2c 2/5] i2c stack can remove()
Jean Delvare
khali at linux-fr.org
Tue Mar 13 20:01:29 CET 2007
Hi David,
On Mon, 12 Mar 2007 08:49:25 -0800, David Brownell wrote:
> More update for new style driver support: add a remove() method, and
> use it in the relevant code paths.
>
> Again, nothing will use this yet since there's nothing to create devices
> feeding this infrastructure.
>
> Signed-off-by: David Brownell <dbrownell at users.sourceforge.net>
>
> ---
> UPDATED: address the del_driver() issue, don't add separate interface
> to unregister newstyle drivers, add and use is_newstyle_driver() for
> better internal consistency
I've been converting i2c-parport + lm90 to experiment with the new
model, but I'm hitting a bug in i2c_unregister_device. I converted lm90
to the new-style of i2c device driver, then modified i2c-parport to
instantiate an lm90 device. Loading the drivers work fine, lm90 is
loaded automatically as expected. If I unload lm90 first and
i2c-parport second, it works OK. However, if I unload i2c-parport
first, the lm90 driver's remove function ends up being called
_twice_ for the i2c device, with the consequences you can imagine.
I added a stack dump in i2c_device_remove to figure out what was going
on, and here is what I obtained:
First call:
[<d98a61f6>] i2c_device_remove+0x76/0x90 [i2c_core]
[<d98a63a4>] i2c_unregister_device+0x34/0x150 [i2c_core]
[<c02b247b>] __mutex_lock_interruptible_slowpath+0xfb/0x290
[<d9a976b5>] i2c_parport_detach+0xf5/0x120 [i2c_parport]
[<d88651a5>] parport_unregister_driver+0x35/0x60 [parport]
[<c0136109>] sys_delete_module+0x129/0x140
Second call:
[<d98a61f6>] i2c_device_remove+0x76/0x90 [i2c_core]
[<c0235c24>] __device_release_driver+0x94/0xb0
[<c0235c5d>] device_release_driver+0x1d/0x40
[<c0234f72>] bus_remove_device+0x52/0x70
[<c023389c>] device_del+0x5c/0x1f0
[<c0233a38>] device_unregister+0x8/0x10
[<d98a6fdc>] i2c_detach_client+0x6c/0xf0 [i2c_core]
[<d98a61fb>] i2c_device_remove+0x7b/0x90 [i2c_core]
[<d98a63b5>] i2c_unregister_device+0x45/0x150 [i2c_core]
[<c02b247b>] __mutex_lock_interruptible_slowpath+0xfb/0x290
[<d9a976b5>] i2c_parport_detach+0xf5/0x120 [i2c_parport]
[<d88651a5>] parport_unregister_driver+0x35/0x60 [parport]
[<c0136109>] sys_delete_module+0x129/0x140
As you can see, i2c_device_remove is indeed called twice, once by this
part of i2c_unregister_device:
/* unbind driver */
if (driver) {
/* REVISIT driver model core would handle this for us, and
* once i2c_detach_client() stops updating lists, it should.
*/
status = i2c_device_remove(&client->dev);
if (status < 0) {
dev_err(&client->dev, "unbind failed (%d)\n", status);
return;
}
}
And a second time by the part right after:
/* now remove the device, and free its memory */
status = i2c_detach_client(client);
if (status < 0)
dev_err(&adap->dev, "detach failed (%d) for client [%s] "
"at address 0x%02x\n",
status, client->name, client->addr);
else
put_device(&client->dev);
It's obviously not correct to call i2c_device_remove explicitly and
then have i2c_detach_client call it again, but I am a bit confused on
how to fix it. Why do we need this explicit call to i2c_device_remove
in the first place, as it appears that i2c_detach_client does it just
fine? If we really want to do that, then I guess we need to set
client->dev.driver to NULL between the two blocks so that the second
call to i2c_device_remove takes the quick exit?
Thanks,
--
Jean Delvare
More information about the i2c
mailing list