diff options
Diffstat (limited to 'drivers/i2c/i2c-core.c')
-rw-r--r-- | drivers/i2c/i2c-core.c | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 2efa56c5ff2c..2091ae8f539a 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
@@ -637,6 +637,22 @@ static void i2c_adapter_dev_release(struct device *dev) | |||
637 | } | 637 | } |
638 | 638 | ||
639 | /* | 639 | /* |
640 | * This function is only needed for mutex_lock_nested, so it is never | ||
641 | * called unless locking correctness checking is enabled. Thus we | ||
642 | * make it inline to avoid a compiler warning. That's what gcc ends up | ||
643 | * doing anyway. | ||
644 | */ | ||
645 | static inline unsigned int i2c_adapter_depth(struct i2c_adapter *adapter) | ||
646 | { | ||
647 | unsigned int depth = 0; | ||
648 | |||
649 | while ((adapter = i2c_parent_is_i2c_adapter(adapter))) | ||
650 | depth++; | ||
651 | |||
652 | return depth; | ||
653 | } | ||
654 | |||
655 | /* | ||
640 | * Let users instantiate I2C devices through sysfs. This can be used when | 656 | * Let users instantiate I2C devices through sysfs. This can be used when |
641 | * platform initialization code doesn't contain the proper data for | 657 | * platform initialization code doesn't contain the proper data for |
642 | * whatever reason. Also useful for drivers that do device detection and | 658 | * whatever reason. Also useful for drivers that do device detection and |
@@ -726,7 +742,8 @@ i2c_sysfs_delete_device(struct device *dev, struct device_attribute *attr, | |||
726 | 742 | ||
727 | /* Make sure the device was added through sysfs */ | 743 | /* Make sure the device was added through sysfs */ |
728 | res = -ENOENT; | 744 | res = -ENOENT; |
729 | mutex_lock(&adap->userspace_clients_lock); | 745 | mutex_lock_nested(&adap->userspace_clients_lock, |
746 | i2c_adapter_depth(adap)); | ||
730 | list_for_each_entry_safe(client, next, &adap->userspace_clients, | 747 | list_for_each_entry_safe(client, next, &adap->userspace_clients, |
731 | detected) { | 748 | detected) { |
732 | if (client->addr == addr) { | 749 | if (client->addr == addr) { |
@@ -1073,7 +1090,8 @@ int i2c_del_adapter(struct i2c_adapter *adap) | |||
1073 | return res; | 1090 | return res; |
1074 | 1091 | ||
1075 | /* Remove devices instantiated from sysfs */ | 1092 | /* Remove devices instantiated from sysfs */ |
1076 | mutex_lock(&adap->userspace_clients_lock); | 1093 | mutex_lock_nested(&adap->userspace_clients_lock, |
1094 | i2c_adapter_depth(adap)); | ||
1077 | list_for_each_entry_safe(client, next, &adap->userspace_clients, | 1095 | list_for_each_entry_safe(client, next, &adap->userspace_clients, |
1078 | detected) { | 1096 | detected) { |
1079 | dev_dbg(&adap->dev, "Removing %s at 0x%x\n", client->name, | 1097 | dev_dbg(&adap->dev, "Removing %s at 0x%x\n", client->name, |