summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2012-05-29 10:18:43 -0700
committerRandall Spangler <rspangler@chromium.org>2012-05-29 10:21:36 -0700
commite31d9a6660317760a96e19007f5f858456c22576 (patch)
treef2ba5b2d5c4645827b5c3da93f70bf42552ea90b
parent7f66786b76464298a8fc92b2b2377d3652fda914 (diff)
downloadchrome-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.c25
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)
+ ;
}