diff options
author | Randall Spangler <rspangler@chromium.org> | 2012-05-29 10:18:43 -0700 |
---|---|---|
committer | Randall Spangler <rspangler@chromium.org> | 2012-05-29 10:21:36 -0700 |
commit | e31d9a6660317760a96e19007f5f858456c22576 (patch) | |
tree | f2ba5b2d5c4645827b5c3da93f70bf42552ea90b | |
parent | 7f66786b76464298a8fc92b2b2377d3652fda914 (diff) | |
download | chrome-ec-e31d9a6660317760a96e19007f5f858456c22576.tar.gz |
Jump to RAM before entering hibernate
Works around LM4 errata where EEPROM access is unstable while powering down.
Signed-off-by: Randall Spangler <rspangler@chromium.org>
BUG=chrome-os-partner:9996
TEST=hibernate 1
Change-Id: I99d21ec8ab5a06fb0972edebec3cc58ca9f60fa9
-rw-r--r-- | chip/lm4/system.c | 25 |
1 files changed, 18 insertions, 7 deletions
diff --git a/chip/lm4/system.c b/chip/lm4/system.c index af6ac11add..ca1098da21 100644 --- a/chip/lm4/system.c +++ b/chip/lm4/system.c @@ -66,6 +66,19 @@ static void check_reset_cause(void) } +/* A3 and earlier chip stepping has a problem accessing flash during shutdown. + * To work around that, we jump to RAM before hibernating. This function must + * live in RAM. It must be called with interrupts disabled, cannot call other + * functions, and can't be declared static (or else the compiler optimizes it + * into the main hibernate function. */ +void __attribute__((section(".iram.text"))) __enter_hibernate(int hibctl) +{ + LM4_HIBERNATE_HIBCTL = hibctl; + while (1) + ; +} + + void system_hibernate(uint32_t seconds, uint32_t microseconds) { /* clear pending interrupt */ @@ -86,17 +99,14 @@ void system_hibernate(uint32_t seconds, uint32_t microseconds) #ifdef BOARD_link if (system_get_board_version() == BOARD_VERSION_PROTO1) { /* Need VDD3ON because we can't drop VDD externally */ - LM4_HIBERNATE_HIBCTL = 0x15B; + __enter_hibernate(0x15B); } else { /* EVT+ can drop VDD */ - LM4_HIBERNATE_HIBCTL = 0x5B; + __enter_hibernate(0x5B); } #else - LM4_HIBERNATE_HIBCTL = 0x5B; + __enter_hibernate(0x5B); #endif - - /* we are going to hibernate ... */ - while (1) ; } @@ -165,7 +175,8 @@ void system_reset(int is_hard) } /* Spin and wait for reboot; should never return */ - while (1) {} + while (1) + ; } |