aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd
diff options
context:
space:
mode:
authorMisael Lopez Cruz <misael.lopez@ti.com>2012-04-11 13:54:17 -0500
committerZiyann <jaraidaniel@gmail.com>2014-10-01 12:58:20 +0200
commit94d05954c36b9b4e71ffd4cd1e660e7c8266b0d9 (patch)
tree325f3e122fc3244c952ea3569aec4da6e00be105 /drivers/mfd
parentd02c0a9afcb5b336482b471c79ad27476c6fbdbd (diff)
downloadkernel_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.c17
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,