diff options
author | Charlie Mooney <charliemooney@chromium.org> | 2012-09-17 16:36:48 -0700 |
---|---|---|
committer | Charlie Mooney <charliemooney@chromium.org> | 2012-09-18 15:21:15 -0700 |
commit | cb1ed9dea0d4eb78b48f818661a8a5142eaa84aa (patch) | |
tree | d4e79434ab7c95911e2a17bc9d41f4f94343d746 | |
parent | 833898a07c5da3145cd6c8157c1b7925c37cf5a6 (diff) | |
download | chrome-ec-cb1ed9dea0d4eb78b48f818661a8a5142eaa84aa.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
Original-Change-Id: I1f453e9a6acc59d63e4cc80cffb58684f104ca6d
Signed-off-by: Charlie Mooney <charliemooney@chromium.org>
Change-Id: If67283ab29d5e1193a0466309050b20a165498a6
Signed-off-by: Charlie Mooney <charliemooney@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/33549
Reviewed-by: Che-Liang Chiou <clchiou@chromium.org>
-rw-r--r-- | common/gaia_power.c | 9 | ||||
-rw-r--r-- | common/pmu_tps65090.c | 63 |
2 files changed, 43 insertions, 29 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 64babf46ff..59f913715b 100644 --- a/common/pmu_tps65090.c +++ b/common/pmu_tps65090.c @@ -404,44 +404,51 @@ 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); + + /* Exit the retry loop if there was no failure */ + if (!failure) + break; + } if (failure) board_hard_reset(); |