diff options
author | Charlie Mooney <charliemooney@chromium.org> | 2012-09-17 16:36:48 -0700 |
---|---|---|
committer | Gerrit <chrome-bot@google.com> | 2012-09-18 11:46:55 -0700 |
commit | 2249e4e1278dd6d434ce1612213afde4c77be362 (patch) | |
tree | c3202f1f1335b658989131572b00e0b038bd92c5 | |
parent | 72948eaf4e7829ee5af59f2d7e3edd0b983723ef (diff) | |
download | chrome-ec-2249e4e1278dd6d434ce1612213afde4c77be362.tar.gz |
Snow: Retry accesses to PMU before hard reset
Previously, after the first error when trying to reset the pmu over i2c,
the ec would immediately give up and force a hard reset. Since i2c can
be a little flaky from time to time, to prevent unneeded resets this
allows the EC 3 attempts to configure it nicely it before it forces the
whole system to reset.
BUG=chrome-os-partner:14156
TEST=Boot machine successfully multiple times. Add a line in to force a
failure whenever the pmu is accessed to simulate a total failure and
check the EC logs, it should try 3 times on startup and on shutdown
before finally resorting to a hard reset. If you add a fake failure that
only triggers once, the machine should still turn out without incident.
Without any fake failures, everything should work as normal.
BRANCH=snow
Change-Id: I1f453e9a6acc59d63e4cc80cffb58684f104ca6d
Signed-off-by: Charlie Mooney <charliemooney@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/33466
Reviewed-by: Simon Glass <sjg@chromium.org>
Reviewed-by: David Hendricks <dhendrix@chromium.org>
-rw-r--r-- | common/gaia_power.c | 9 | ||||
-rw-r--r-- | common/pmu_tps65090.c | 67 |
2 files changed, 45 insertions, 31 deletions
diff --git a/common/gaia_power.c b/common/gaia_power.c index 1b3cc61a2a..441f46f634 100644 --- a/common/gaia_power.c +++ b/common/gaia_power.c @@ -437,6 +437,8 @@ static int react_to_xpshold(unsigned int timeout_us) */ static void power_off(void) { + int pmu_shutdown_retries = 3; + /* Call hooks before we drop power rails */ hook_notify(HOOK_CHIPSET_SHUTDOWN, 0); /* switch off all rails */ @@ -449,7 +451,12 @@ static void power_off(void) lid_changed = 0; enable_sleep(SLEEP_MASK_AP_RUN); powerled_set_state(POWERLED_STATE_OFF); - if (pmu_shutdown()) + + while (--pmu_shutdown_retries >= 0) { + if (!pmu_shutdown()) + break; + } + if (pmu_shutdown_retries < 0) board_hard_reset(); CPUTS("Shutdown complete.\n"); } diff --git a/common/pmu_tps65090.c b/common/pmu_tps65090.c index 23027cd6a1..8d6d27a170 100644 --- a/common/pmu_tps65090.c +++ b/common/pmu_tps65090.c @@ -473,50 +473,57 @@ DECLARE_HOOK(HOOK_CHIPSET_PRE_INIT, pmu_init_registers, HOOK_PRIO_DEFAULT); void pmu_init(void) { - int failure = 0; + int failure = 0, retries_remaining = 3; + while (--retries_remaining >= 0) { + failure = 0; #ifdef CONFIG_PMU_BOARD_INIT - if (!failure) - failure = board_pmu_init(); + if (!failure) + failure = board_pmu_init(); #else - /* Init configuration - * Fast charge timer : 2 hours - * Charger : disable - * External pin control : enable - * - * TODO: move settings to battery pack specific init - */ - if (!failure) - failure = pmu_write(CG_CTRL0, 2); - /* Limit full charge current to 50% - * TODO: remove this temporary hack. - */ - if (!failure) - failure = pmu_write(CG_CTRL3, 0xbb); + /* Init configuration + * Fast charge timer : 2 hours + * Charger : disable + * External pin control : enable + * + * TODO: move settings to battery pack specific init + */ + if (!failure) + failure = pmu_write(CG_CTRL0, 2); + /* Limit full charge current to 50% + * TODO: remove this temporary hack. + */ + if (!failure) + failure = pmu_write(CG_CTRL3, 0xbb); #endif - /* Enable interrupts */ - if (!failure) { - failure = pmu_write(IRQ1MASK, + /* Enable interrupts */ + if (!failure) { + failure = pmu_write(IRQ1MASK, EVENT_VACG | /* AC voltage good */ EVENT_VSYSG | /* System voltage good */ EVENT_VBATG | /* Battery voltage good */ EVENT_CGACT | /* Charging status */ EVENT_CGCPL); /* Charging complete */ - } - if (!failure) - failure = pmu_write(IRQ2MASK, 0); - if (!failure) - failure = pmu_clear_irq(); + } + if (!failure) + failure = pmu_write(IRQ2MASK, 0); + if (!failure) + failure = pmu_clear_irq(); - /* Enable charger interrupt. */ - if (!failure) - failure = gpio_enable_interrupt(GPIO_CHARGER_INT); + /* Enable charger interrupt. */ + if (!failure) + failure = gpio_enable_interrupt(GPIO_CHARGER_INT); #ifdef CONFIG_AC_POWER_STATUS - if (!failure) - failure = gpio_set_flags(GPIO_AC_STATUS, GPIO_OUT_HIGH); + if (!failure) + failure = gpio_set_flags(GPIO_AC_STATUS, GPIO_OUT_HIGH); #endif + /* Exit the retry loop if there was no failure */ + if (!failure) + break; + } + if (failure) board_hard_reset(); } |