diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-03-28 16:17:55 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-03-29 17:50:14 -0400 |
commit | e032b376551a61662b20a2c8544fbbc568ab2e7f (patch) | |
tree | c3a315be3598e387cd779f37455d75be1b5dd0bf /drivers/regulator | |
parent | 15c08f664d8ca4f4d0e202cbd4034422a706ef80 (diff) |
regulator: Fix deadlock on removal of regulators with supplies
If a regulator with a supply is being unregistered we will call
regulator_put() to release the supply with the regulator_list_mutex held
but this deadlocks as regulator_put() takes the same lock. Fix this by
releasing the supply before we take the mutex in regulator_unregister().
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'drivers/regulator')
-rw-r--r-- | drivers/regulator/core.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index e2f3afa71efb..4a5054ef9421 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c | |||
@@ -2992,14 +2992,14 @@ void regulator_unregister(struct regulator_dev *rdev) | |||
2992 | if (rdev == NULL) | 2992 | if (rdev == NULL) |
2993 | return; | 2993 | return; |
2994 | 2994 | ||
2995 | if (rdev->supply) | ||
2996 | regulator_put(rdev->supply); | ||
2995 | mutex_lock(®ulator_list_mutex); | 2997 | mutex_lock(®ulator_list_mutex); |
2996 | debugfs_remove_recursive(rdev->debugfs); | 2998 | debugfs_remove_recursive(rdev->debugfs); |
2997 | flush_work_sync(&rdev->disable_work.work); | 2999 | flush_work_sync(&rdev->disable_work.work); |
2998 | WARN_ON(rdev->open_count); | 3000 | WARN_ON(rdev->open_count); |
2999 | unset_regulator_supplies(rdev); | 3001 | unset_regulator_supplies(rdev); |
3000 | list_del(&rdev->list); | 3002 | list_del(&rdev->list); |
3001 | if (rdev->supply) | ||
3002 | regulator_put(rdev->supply); | ||
3003 | kfree(rdev->constraints); | 3003 | kfree(rdev->constraints); |
3004 | device_unregister(&rdev->dev); | 3004 | device_unregister(&rdev->dev); |
3005 | mutex_unlock(®ulator_list_mutex); | 3005 | mutex_unlock(®ulator_list_mutex); |