summaryrefslogtreecommitdiffstats
path: root/src/target/firmware/calypso
diff options
context:
space:
mode:
authorIngo Albrecht <prom@berlin.ccc.de>2010-03-07 09:34:36 +0100
committerHarald Welte <laforge@gnumonks.org>2010-03-15 00:15:04 +0800
commit83109b58f5865a99a9dd6b6fc6285f5f8e6851d7 (patch)
treeb3c2100b9587f998f78b304b4d5c362e9ec744c8 /src/target/firmware/calypso
parentf63cba07f3a65fe0b574ac64e0b3d33ea753e2da (diff)
firmware: watchdog-based system reset
Diffstat (limited to 'src/target/firmware/calypso')
-rw-r--r--src/target/firmware/calypso/timer.c33
1 files changed, 30 insertions, 3 deletions
diff --git a/src/target/firmware/calypso/timer.c b/src/target/firmware/calypso/timer.c
index 916839dd..1dd55f26 100644
--- a/src/target/firmware/calypso/timer.c
+++ b/src/target/firmware/calypso/timer.c
@@ -109,6 +109,19 @@ enum wdog_reg {
WD_MODE = 0x04,
};
+enum wdog_ctl {
+ WD_CTL_START = (1 << 7),
+ WD_CTL_AUTO_RELOAD = (1 << 8)
+};
+
+enum wdog_mode {
+ WD_MODE_DIS_ARM = 0xF5,
+ WD_MODE_DIS_CONFIRM = 0xA0,
+ WD_MODE_ENABLE = (1 << 15)
+};
+
+#define WD_CTL_PRESCALE(value) (((value)&0x07) << 9)
+
static void wdog_irq(__unused enum irq_nr nr)
{
puts("=> WATCHDOG\n");
@@ -120,10 +133,24 @@ void wdog_enable(int on)
irq_config(IRQ_WATCHDOG, 0, 0, 0);
irq_register_handler(IRQ_WATCHDOG, &wdog_irq);
irq_enable(IRQ_WATCHDOG);
- writew(0x8000, WDOG_REG(WD_MODE));
+ writew(WD_MODE_ENABLE, WDOG_REG(WD_MODE));
} else {
- writew(0xF5, WDOG_REG(WD_MODE));
- writew(0xA0, WDOG_REG(WD_MODE));
+ writew(WD_MODE_DIS_ARM, WDOG_REG(WD_MODE));
+ writew(WD_MODE_DIS_CONFIRM, WDOG_REG(WD_MODE));
}
}
+void wdog_reset(void)
+{
+#if 0
+ // XXX: this is supposed to reset immediately but does not seem to
+ writew(0xF5, WDOG_REG(WD_MODE));
+ writew(0xFF, WDOG_REG(WD_MODE));
+#else
+ // enable watchdog
+ writew(WD_MODE_ENABLE, WDOG_REG(WD_MODE));
+ // force expiration
+ writew(0x0000, WDOG_REG(WD_LOAD_TIMER));
+ writew(0x0000, WDOG_REG(WD_LOAD_TIMER));
+#endif
+}