|
@@ -636,6 +636,22 @@ static void i2c_adapter_dev_release(struct device *dev)
|
|
|
complete(&adap->dev_released);
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * This function is only needed for mutex_lock_nested, so it is never
|
|
|
+ * called unless locking correctness checking is enabled. Thus we
|
|
|
+ * make it inline to avoid a compiler warning. That's what gcc ends up
|
|
|
+ * doing anyway.
|
|
|
+ */
|
|
|
+static inline unsigned int i2c_adapter_depth(struct i2c_adapter *adapter)
|
|
|
+{
|
|
|
+ unsigned int depth = 0;
|
|
|
+
|
|
|
+ while ((adapter = i2c_parent_is_i2c_adapter(adapter)))
|
|
|
+ depth++;
|
|
|
+
|
|
|
+ return depth;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Let users instantiate I2C devices through sysfs. This can be used when
|
|
|
* platform initialization code doesn't contain the proper data for
|
|
@@ -726,7 +742,8 @@ i2c_sysfs_delete_device(struct device *dev, struct device_attribute *attr,
|
|
|
|
|
|
/* Make sure the device was added through sysfs */
|
|
|
res = -ENOENT;
|
|
|
- mutex_lock(&adap->userspace_clients_lock);
|
|
|
+ mutex_lock_nested(&adap->userspace_clients_lock,
|
|
|
+ i2c_adapter_depth(adap));
|
|
|
list_for_each_entry_safe(client, next, &adap->userspace_clients,
|
|
|
detected) {
|
|
|
if (client->addr == addr) {
|
|
@@ -1073,7 +1090,8 @@ int i2c_del_adapter(struct i2c_adapter *adap)
|
|
|
return res;
|
|
|
|
|
|
/* Remove devices instantiated from sysfs */
|
|
|
- mutex_lock(&adap->userspace_clients_lock);
|
|
|
+ mutex_lock_nested(&adap->userspace_clients_lock,
|
|
|
+ i2c_adapter_depth(adap));
|
|
|
list_for_each_entry_safe(client, next, &adap->userspace_clients,
|
|
|
detected) {
|
|
|
dev_dbg(&adap->dev, "Removing %s at 0x%x\n", client->name,
|