summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharlie Mooney <charliemooney@chromium.org>2012-09-17 16:36:48 -0700
committerCharlie Mooney <charliemooney@chromium.org>2012-09-18 15:21:15 -0700
commitcb1ed9dea0d4eb78b48f818661a8a5142eaa84aa (patch)
treed4e79434ab7c95911e2a17bc9d41f4f94343d746
parent833898a07c5da3145cd6c8157c1b7925c37cf5a6 (diff)
downloadchrome-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.c9
-rw-r--r--common/pmu_tps65090.c63
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();