diff options
author | Stephen Boyd <sboyd@codeaurora.org> | 2012-07-02 22:21:06 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-07-03 15:25:58 -0400 |
commit | d92d95b6bf2722ffa0fefa7651c51bf336743dd7 (patch) | |
tree | 61177e0b126a1a467b6a9fd219fe6e48d74ea76a /drivers/regulator | |
parent | 6887a4131da3adaab011613776d865f4bcfb5678 (diff) |
regulator: Fix recursive mutex lockdep warning
A recursive lockdep warning occurs if you call
regulator_set_optimum_mode() on a regulator with a supply because
there is no nesting annotation for the rdev->mutex. To avoid this
warning, get the supply's load before locking the regulator's
mutex to avoid grabbing the same class of lock twice.
=============================================
[ INFO: possible recursive locking detected ]
3.4.0 #3257 Tainted: G W
---------------------------------------------
swapper/0/1 is trying to acquire lock:
(&rdev->mutex){+.+.+.}, at: [<c036e9e0>] regulator_get_voltage+0x18/0x38
but task is already holding lock:
(&rdev->mutex){+.+.+.}, at: [<c036ef38>] regulator_set_optimum_mode+0x24/0x224
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0
----
lock(&rdev->mutex);
lock(&rdev->mutex);
*** DEADLOCK ***
May be due to missing lock nesting notation
3 locks held by swapper/0/1:
#0: (&__lockdep_no_validate__){......}, at: [<c03dbb48>] __driver_attach+0x40/0x8c
#1: (&__lockdep_no_validate__){......}, at: [<c03dbb58>] __driver_attach+0x50/0x8c
#2: (&rdev->mutex){+.+.+.}, at: [<c036ef38>] regulator_set_optimum_mode+0x24/0x224
stack backtrace:
[<c001521c>] (unwind_backtrace+0x0/0x12c) from [<c00cc4d4>] (validate_chain+0x760/0x1080)
[<c00cc4d4>] (validate_chain+0x760/0x1080) from [<c00cd744>] (__lock_acquire+0x950/0xa10)
[<c00cd744>] (__lock_acquire+0x950/0xa10) from [<c00cd990>] (lock_acquire+0x18c/0x1e8)
[<c00cd990>] (lock_acquire+0x18c/0x1e8) from [<c080c248>] (mutex_lock_nested+0x68/0x3c4)
[<c080c248>] (mutex_lock_nested+0x68/0x3c4) from [<c036e9e0>] (regulator_get_voltage+0x18/0x38)
[<c036e9e0>] (regulator_get_voltage+0x18/0x38) from [<c036efb8>] (regulator_set_optimum_mode+0xa4/0x224)
...
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'drivers/regulator')
-rw-r--r-- | drivers/regulator/core.c | 10 |
1 files changed, 5 insertions, 5 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 09a737c868b5..8b4b3829d9e7 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c | |||
@@ -2519,9 +2519,12 @@ int regulator_set_optimum_mode(struct regulator *regulator, int uA_load) | |||
2519 | { | 2519 | { |
2520 | struct regulator_dev *rdev = regulator->rdev; | 2520 | struct regulator_dev *rdev = regulator->rdev; |
2521 | struct regulator *consumer; | 2521 | struct regulator *consumer; |
2522 | int ret, output_uV, input_uV, total_uA_load = 0; | 2522 | int ret, output_uV, input_uV = 0, total_uA_load = 0; |
2523 | unsigned int mode; | 2523 | unsigned int mode; |
2524 | 2524 | ||
2525 | if (rdev->supply) | ||
2526 | input_uV = regulator_get_voltage(rdev->supply); | ||
2527 | |||
2525 | mutex_lock(&rdev->mutex); | 2528 | mutex_lock(&rdev->mutex); |
2526 | 2529 | ||
2527 | /* | 2530 | /* |
@@ -2554,10 +2557,7 @@ int regulator_set_optimum_mode(struct regulator *regulator, int uA_load) | |||
2554 | goto out; | 2557 | goto out; |
2555 | } | 2558 | } |
2556 | 2559 | ||
2557 | /* get input voltage */ | 2560 | /* No supply? Use constraint voltage */ |
2558 | input_uV = 0; | ||
2559 | if (rdev->supply) | ||
2560 | input_uV = regulator_get_voltage(rdev->supply); | ||
2561 | if (input_uV <= 0) | 2561 | if (input_uV <= 0) |
2562 | input_uV = rdev->constraints->input_uV; | 2562 | input_uV = rdev->constraints->input_uV; |
2563 | if (input_uV <= 0) { | 2563 | if (input_uV <= 0) { |