diff options
author | Jean Delvare <khali@linux-fr.org> | 2010-08-11 12:21:01 -0400 |
---|---|---|
committer | Jean Delvare <khali@linux-fr.org> | 2010-08-11 12:21:01 -0400 |
commit | dafc50d141c27959dbd3a1cfe9857a86d23402a7 (patch) | |
tree | 565aea94308f40813540f06d7bbcb322ae92eeed /drivers/i2c | |
parent | 8031d79baedabd44590d047d97a310eb0e0e4e0c (diff) |
i2c: Use a separate mutex for userspace client lists
Moving userspace-instantiated clients to separate lists wasn't nearly
enough to avoid deadlocks in multiplexed bus cases. We also want to
have a dedicated mutex to protect each list.
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Cc: Michael Lawnick <ml.lawnick@gmx.de>
Diffstat (limited to 'drivers/i2c')
-rw-r--r-- | drivers/i2c/i2c-core.c | 13 |
1 files changed, 7 insertions, 6 deletions
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index ba86af63f5cf..97f96b66653c 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
@@ -662,9 +662,9 @@ i2c_sysfs_new_device(struct device *dev, struct device_attribute *attr, | |||
662 | return -EINVAL; | 662 | return -EINVAL; |
663 | 663 | ||
664 | /* Keep track of the added device */ | 664 | /* Keep track of the added device */ |
665 | i2c_lock_adapter(adap); | 665 | mutex_lock(&adap->userspace_clients_lock); |
666 | list_add_tail(&client->detected, &adap->userspace_clients); | 666 | list_add_tail(&client->detected, &adap->userspace_clients); |
667 | i2c_unlock_adapter(adap); | 667 | mutex_unlock(&adap->userspace_clients_lock); |
668 | dev_info(dev, "%s: Instantiated device %s at 0x%02hx\n", "new_device", | 668 | dev_info(dev, "%s: Instantiated device %s at 0x%02hx\n", "new_device", |
669 | info.type, info.addr); | 669 | info.type, info.addr); |
670 | 670 | ||
@@ -703,7 +703,7 @@ i2c_sysfs_delete_device(struct device *dev, struct device_attribute *attr, | |||
703 | 703 | ||
704 | /* Make sure the device was added through sysfs */ | 704 | /* Make sure the device was added through sysfs */ |
705 | res = -ENOENT; | 705 | res = -ENOENT; |
706 | i2c_lock_adapter(adap); | 706 | mutex_lock(&adap->userspace_clients_lock); |
707 | list_for_each_entry_safe(client, next, &adap->userspace_clients, | 707 | list_for_each_entry_safe(client, next, &adap->userspace_clients, |
708 | detected) { | 708 | detected) { |
709 | if (client->addr == addr) { | 709 | if (client->addr == addr) { |
@@ -716,7 +716,7 @@ i2c_sysfs_delete_device(struct device *dev, struct device_attribute *attr, | |||
716 | break; | 716 | break; |
717 | } | 717 | } |
718 | } | 718 | } |
719 | i2c_unlock_adapter(adap); | 719 | mutex_unlock(&adap->userspace_clients_lock); |
720 | 720 | ||
721 | if (res < 0) | 721 | if (res < 0) |
722 | dev_err(dev, "%s: Can't find device in list\n", | 722 | dev_err(dev, "%s: Can't find device in list\n", |
@@ -798,6 +798,7 @@ static int i2c_register_adapter(struct i2c_adapter *adap) | |||
798 | } | 798 | } |
799 | 799 | ||
800 | rt_mutex_init(&adap->bus_lock); | 800 | rt_mutex_init(&adap->bus_lock); |
801 | mutex_init(&adap->userspace_clients_lock); | ||
801 | INIT_LIST_HEAD(&adap->userspace_clients); | 802 | INIT_LIST_HEAD(&adap->userspace_clients); |
802 | 803 | ||
803 | /* Set default timeout to 1 second if not already set */ | 804 | /* Set default timeout to 1 second if not already set */ |
@@ -1003,7 +1004,7 @@ int i2c_del_adapter(struct i2c_adapter *adap) | |||
1003 | return res; | 1004 | return res; |
1004 | 1005 | ||
1005 | /* Remove devices instantiated from sysfs */ | 1006 | /* Remove devices instantiated from sysfs */ |
1006 | i2c_lock_adapter(adap); | 1007 | mutex_lock(&adap->userspace_clients_lock); |
1007 | list_for_each_entry_safe(client, next, &adap->userspace_clients, | 1008 | list_for_each_entry_safe(client, next, &adap->userspace_clients, |
1008 | detected) { | 1009 | detected) { |
1009 | dev_dbg(&adap->dev, "Removing %s at 0x%x\n", client->name, | 1010 | dev_dbg(&adap->dev, "Removing %s at 0x%x\n", client->name, |
@@ -1011,7 +1012,7 @@ int i2c_del_adapter(struct i2c_adapter *adap) | |||
1011 | list_del(&client->detected); | 1012 | list_del(&client->detected); |
1012 | i2c_unregister_device(client); | 1013 | i2c_unregister_device(client); |
1013 | } | 1014 | } |
1014 | i2c_unlock_adapter(adap); | 1015 | mutex_unlock(&adap->userspace_clients_lock); |
1015 | 1016 | ||
1016 | /* Detach any active clients. This can't fail, thus we do not | 1017 | /* Detach any active clients. This can't fail, thus we do not |
1017 | checking the returned value. */ | 1018 | checking the returned value. */ |