Commit 77ed74da authored by Jean Delvare's avatar Jean Delvare Committed by Linus Torvalds

[PATCH] i2c: Prevent deadlock on i2c client registration

Delay the call to adapter->client_register() until after we are
certain that the client registration is a success. At this point the
client is fully initialized and we no longer hold the adapter->clist
mutex, so this should prevent the deadlocks if the client_register()
callback needs to take that mutex too, as is the case for the bttv
driver.

This fixes bug #7234.
Signed-off-by: default avatarJean Delvare <khali@linux-fr.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 5ffd1a6a
...@@ -420,14 +420,6 @@ int i2c_attach_client(struct i2c_client *client) ...@@ -420,14 +420,6 @@ int i2c_attach_client(struct i2c_client *client)
} }
list_add_tail(&client->list,&adapter->clients); list_add_tail(&client->list,&adapter->clients);
if (adapter->client_register) {
if (adapter->client_register(client)) {
dev_dbg(&adapter->dev, "client_register "
"failed for client [%s] at 0x%02x\n",
client->name, client->addr);
}
}
client->usage_count = 0; client->usage_count = 0;
client->dev.parent = &client->adapter->dev; client->dev.parent = &client->adapter->dev;
...@@ -445,10 +437,17 @@ int i2c_attach_client(struct i2c_client *client) ...@@ -445,10 +437,17 @@ int i2c_attach_client(struct i2c_client *client)
res = device_create_file(&client->dev, &dev_attr_client_name); res = device_create_file(&client->dev, &dev_attr_client_name);
if (res) if (res)
goto out_unregister; goto out_unregister;
out_unlock:
mutex_unlock(&adapter->clist_lock); mutex_unlock(&adapter->clist_lock);
return res;
if (adapter->client_register) {
if (adapter->client_register(client)) {
dev_dbg(&adapter->dev, "client_register "
"failed for client [%s] at 0x%02x\n",
client->name, client->addr);
}
}
return 0;
out_unregister: out_unregister:
init_completion(&client->released); /* Needed? */ init_completion(&client->released); /* Needed? */
...@@ -458,7 +457,9 @@ int i2c_attach_client(struct i2c_client *client) ...@@ -458,7 +457,9 @@ int i2c_attach_client(struct i2c_client *client)
list_del(&client->list); list_del(&client->list);
dev_err(&adapter->dev, "Failed to attach i2c client %s at 0x%02x " dev_err(&adapter->dev, "Failed to attach i2c client %s at 0x%02x "
"(%d)\n", client->name, client->addr, res); "(%d)\n", client->name, client->addr, res);
goto out_unlock; out_unlock:
mutex_unlock(&adapter->clist_lock);
return res;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment