diff options
author | Ingo Albrecht <prom@berlin.ccc.de> | 2010-03-07 09:34:36 +0100 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2010-03-15 00:15:04 +0800 |
commit | 83109b58f5865a99a9dd6b6fc6285f5f8e6851d7 (patch) | |
tree | b3c2100b9587f998f78b304b4d5c362e9ec744c8 /src/target/firmware/calypso | |
parent | f63cba07f3a65fe0b574ac64e0b3d33ea753e2da (diff) |
firmware: watchdog-based system reset
Diffstat (limited to 'src/target/firmware/calypso')
-rw-r--r-- | src/target/firmware/calypso/timer.c | 33 |
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 +} |