diff options
author | Misael Lopez Cruz <misael.lopez@ti.com> | 2012-04-11 13:54:17 -0500 |
---|---|---|
committer | Ziyann <jaraidaniel@gmail.com> | 2014-10-01 12:58:20 +0200 |
commit | 94d05954c36b9b4e71ffd4cd1e660e7c8266b0d9 (patch) | |
tree | 325f3e122fc3244c952ea3569aec4da6e00be105 /drivers/mfd | |
parent | d02c0a9afcb5b336482b471c79ad27476c6fbdbd (diff) | |
download | kernel_samsung_tuna-94d05954c36b9b4e71ffd4cd1e660e7c8266b0d9.tar.gz kernel_samsung_tuna-94d05954c36b9b4e71ffd4cd1e660e7c8266b0d9.tar.bz2 kernel_samsung_tuna-94d05954c36b9b4e71ffd4cd1e660e7c8266b0d9.zip |
MFD: twl6040-codec: Change power-up verification policy
Automatic power-up completion result can be affected by race
conditions between the completion task itself and the READYINT
handler, leading to false power-up failures as the completion
timeout may expire before READYINT handler gets executed and
marks completion.
Instead, the first verification for a successful power-up sequence
is the expected state of NCPCTL, LDOCTL and LPPLLCTL registers.
These registers will have specific values after automatic power-up
sequence has completed.
False power-up success is still checked, this is the case where
the READYINT is received but the hardware state is not consistent
with what is known/expected after a successful sequence. Under these
circumstances, we retry automatic power-up.
Change-Id: I9f85d67a10e84564a38f7d97a78345be06ac3b16
Signed-off-by: Misael Lopez Cruz <misael.lopez@ti.com>
Diffstat (limited to 'drivers/mfd')
-rw-r--r-- | drivers/mfd/twl6040-codec.c | 17 |
1 files changed, 9 insertions, 8 deletions
diff --git a/drivers/mfd/twl6040-codec.c b/drivers/mfd/twl6040-codec.c index 0e7ed8cdf9c..3488fec11b8 100644 --- a/drivers/mfd/twl6040-codec.c +++ b/drivers/mfd/twl6040-codec.c @@ -582,6 +582,10 @@ static int twl6040_power_up_completion(struct twl6040 *twl6040, gpio_set_value(twl6040->audpwron, 1); time_left = wait_for_completion_timeout(&twl6040->ready, msecs_to_jiffies(700)); + + if (twl6040_is_powered(twl6040)) + return 0; + if (!time_left) { intid = twl6040_reg_read(twl6040, TWL6040_REG_INTID); if (!(intid & TWL6040_READYINT)) { @@ -590,17 +594,14 @@ static int twl6040_power_up_completion(struct twl6040 *twl6040, return -ETIMEDOUT; } } + /* * Power on seemingly completed. - * Look for clues that the twl6040 might be still booting. + * READYINT received, but not in expected state, retry. */ - if (!twl6040_is_powered(twl6040)) { - round++; - gpio_set_value(twl6040->audpwron, 0); - usleep_range(1000, 1500); - continue; - } - } while (round && (round < 3)); + gpio_set_value(twl6040->audpwron, 0); + usleep_range(1000, 1500); + } while (round++ < 3); if (round >= 3) { dev_err(twl6040->dev, |