summaryrefslogtreecommitdiff
path: root/chip/lm4/watchdog.c
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2012-04-12 12:01:02 -0700
committerRandall Spangler <rspangler@chromium.org>2012-04-12 12:04:37 -0700
commitf411bbbe19b91ee8fa22fa3c04468127d85e46e1 (patch)
treecf9782e7f127d2fcaa9da03cb50f99f15983e0d7 /chip/lm4/watchdog.c
parent20fdc57a351998f4a43731249f57bb262d610f72 (diff)
downloadchrome-ec-f411bbbe19b91ee8fa22fa3c04468127d85e46e1.tar.gz
Re-enable watchdog in watchdog_reload()
Signed-off-by: Randall Spangler <rspangler@chromium.org> BUG=chrome-os-partner:8971 TEST=manual waitms 1500 (see watchdog trace) waitms 1500 (should see watchdog trace again) waitms 3000 (should see trace, then system should reboot) Change-Id: Ieb5009d7a7bc9e1ed795e58efb0cb44a1eeb2706
Diffstat (limited to 'chip/lm4/watchdog.c')
-rw-r--r--chip/lm4/watchdog.c35
1 files changed, 21 insertions, 14 deletions
diff --git a/chip/lm4/watchdog.c b/chip/lm4/watchdog.c
index 248d895369..65c5ad2d2a 100644
--- a/chip/lm4/watchdog.c
+++ b/chip/lm4/watchdog.c
@@ -25,6 +25,9 @@
#define LM4_WATCHDOG_MAGIC_WORD 0x1ACCE551
#define WATCHDOG_PERIOD_MS 1100 /* Watchdog period in ms */
+#define WATCHDOG_RELOAD_MS 500 /* Interval in ms between reloads of the
+ * watchdog timer. Should be less than half
+ * of the watchdog period. */
static uint32_t watchdog_period; /* Watchdog counter initial value */
@@ -93,20 +96,24 @@ void watchdog_reload(void)
{
uint32_t status = LM4_WATCHDOG_RIS(0);
- /* unlock watchdog registers */
+ /* Unlock watchdog registers */
LM4_WATCHDOG_LOCK(0) = LM4_WATCHDOG_MAGIC_WORD;
- /* As we reboot only on the second time-out,
- * if we have already reached 1 time-out
- * we need to reset the interrupt bit.
- */
- if (status)
+ /* As we reboot only on the second timeout, if we have already reached
+ * the first timeout we need to reset the interrupt bit. */
+ if (status) {
LM4_WATCHDOG_ICR(0) = status;
+ /* That doesn't seem to unpend the watchdog interrupt (even if
+ * we do dummy writes to force the write to be committed), so
+ * explicitly unpend the interrupt before re-enabling it. */
+ task_clear_pending_irq(LM4_IRQ_WATCHDOG);
+ task_enable_irq(LM4_IRQ_WATCHDOG);
+ }
- /* reload the watchdog counter */
+ /* Reload the watchdog counter */
LM4_WATCHDOG_LOAD(0) = watchdog_period;
- /* re-lock watchdog registers */
+ /* Re-lock watchdog registers */
LM4_WATCHDOG_LOCK(0) = 0xdeaddead;
}
@@ -134,12 +141,11 @@ int watchdog_init(void)
watchdog_clock_changed(clock_get_freq());
LM4_WATCHDOG_LOAD(0) = watchdog_period;
- /* de-activate the watchdog when the JTAG stops the CPU */
+ /* De-activate the watchdog when the JTAG stops the CPU */
LM4_WATCHDOG_TEST(0) |= 1 << 8;
- /* reset after 2 time-out,
- * activate the watchdog and lock the control register
- */
+ /* Reset after 2 time-out, activate the watchdog and lock the control
+ * register. */
LM4_WATCHDOG_CTL(0) = 0x3;
/* Reset watchdog interrupt bits */
@@ -154,6 +160,7 @@ int watchdog_init(void)
return EC_SUCCESS;
}
+
/* Low priority task to reload the watchdog */
void watchdog_task(void)
{
@@ -166,12 +173,12 @@ void watchdog_task(void)
#ifdef BOARD_bds
gpio_set_level(GPIO_DEBUG_LED, 1);
#endif
- usleep(500000);
+ usleep(WATCHDOG_RELOAD_MS * 1000);
watchdog_reload();
#ifdef BOARD_bds
gpio_set_level(GPIO_DEBUG_LED, 0);
#endif
- usleep(500000);
+ usleep(WATCHDOG_RELOAD_MS * 1000);
watchdog_reload();
}
}