i2c-core: Fix for lockdep validator
If kernel is compiled with CONFIG_PROVE_LOCKING the validator raises an error when a multiplexer is removed via sysfs and sub-clients are connected to it. This is a false positive. Documentation/lockdep-design.txt recommends to handle this via calls to mutex_lock_nested(). Based on an earlier fix from Michael Lawnick. Note that the extra code resolves to nothing unless CONFIG_DEBUG_LOCK_ALLOC=y. Signed-off-by: Jean Delvare <khali@linux-fr.org> Cc: Michael Lawnick <ml.lawnick@gmx.de>
This commit is contained in:
Родитель
e68bb91baa
Коммит
390946b172
|
@ -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,
|
||||
|
|
Загрузка…
Ссылка в новой задаче