diff -rNu linux.vanilla/Documentation/Configure.help linux/Documentation/Configure.help --- linux.vanilla/Documentation/Configure.help Fri Apr 7 02:50:33 2000 +++ linux/Documentation/Configure.help Fri Apr 7 02:28:15 2000 @@ -9335,6 +9335,25 @@ module, say M here and read Documentation/modules.txt. Most people will say N. +SBC-60XX Watchdog Timer +CONFIG_60XX_WDT + This driver can be used with the watchdog timer found on some + single board computers, namely the 6020 PII based computer. + It may well work with other cards. It reads port 0x443 to enable + and re-set the watchdog timer, and reads port 0x45 to disable + the watchdog. If you have a card that behave in similar ways, + you can probably make this driver work with your card as well. + + Unlike the other watchdog drivers, this driver does *NOT* use + /dev/watchdog for watchdog input. Instead this driver uses + a kernel timer to pulse the watchdog. This is because the + watchdog on this card has a 1 second timeout (default setting) + and relying on a user-space application to _always_ respond + within one second is unwise. + + You can compile this driver directly into the kernel, or use + it as a module. The module will be called sbc60xxwdt.o. + Enhanced Real Time Clock Support CONFIG_RTC If you say Y here and create a character special file /dev/rtc with diff -rNu linux.vanilla/drivers/char/Config.in linux/drivers/char/Config.in --- linux.vanilla/drivers/char/Config.in Fri Apr 7 02:50:33 2000 +++ linux/drivers/char/Config.in Fri Apr 7 02:28:15 2000 @@ -109,6 +109,7 @@ tristate ' Software Watchdog' CONFIG_SOFT_WATCHDOG tristate ' Berkshire Products PC Watchdog' CONFIG_PCWATCHDOG tristate ' Acquire SBC Watchdog Timer' CONFIG_ACQUIRE_WDT + tristate ' SBC-60XX Watchdog Timer' CONFIG_60XX_WDT tristate ' Mixcom Watchdog' CONFIG_MIXCOMWD endmenu fi diff -rNu linux.vanilla/drivers/char/Makefile linux/drivers/char/Makefile --- linux.vanilla/drivers/char/Makefile Fri Apr 7 02:50:33 2000 +++ linux/drivers/char/Makefile Fri Apr 7 02:28:15 2000 @@ -299,6 +299,14 @@ endif endif +ifeq ($(CONFIG_60XX_WDT),y) +L_OBJS += sbc60xxwdt.o +else + ifeq ($(CONFIG_60XX_WDT),m) + M_OBJS += sbc60xxwdt.o + endif +endif + ifeq ($(CONFIG_MIXCOMWD),y) L_OBJS += mixcomwd.o else diff -rNu linux.vanilla/drivers/char/misc.c linux/drivers/char/misc.c --- linux.vanilla/drivers/char/misc.c Fri Apr 7 02:50:33 2000 +++ linux/drivers/char/misc.c Fri Apr 7 02:46:11 2000 @@ -73,6 +73,7 @@ extern void watchdog_init(void); extern void wdt_init(void); extern void acq_init(void); +extern void wdt60xx_init(void); extern void dtlk_init(void); extern void pcwatchdog_init(void); extern int rtc_init(void); @@ -228,6 +229,9 @@ #endif #ifdef CONFIG_ACQUIRE_WDT acq_init(); +#endif +#ifdef CONFIG_60XX_WDT + sbc60xxwdt_init(); #endif #ifdef CONFIG_SOFT_WATCHDOG watchdog_init(); diff -rNu linux.vanilla/drivers/char/sbc60xxwdt.c linux/drivers/char/sbc60xxwdt.c --- linux.vanilla/drivers/char/sbc60xxwdt.c Thu Jan 1 01:00:00 1970 +++ linux/drivers/char/sbc60xxwdt.c Fri Apr 7 02:47:37 2000 @@ -0,0 +1,131 @@ +/* + * 60xx Single Board Computer Watchdog Timer driver for Linux 2.2.x + * + * Based on acquirewdt.c by Alan Cox. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * The author does NOT admit liability nor provide warranty for + * any of this software. This material is provided "AS-IS" in + * the hope that it may be useful for others. + * + * (c) Copyright 2000 Jakob Oestergaard + * [Initial revision] + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * You must set these - The driver cannot probe for the settings + */ + +#define WDT_STOP 0x45 +#define WDT_START 0x443 + +/* + * The 60xx board can use watchdog timeout values from one second + * to several minutes. The default is one second, so if we reset + * the watchdog every ~250ms we should be safe. + */ + +#define WDT_INTERVAL (HZ/4+1) + +static void wdt_timer_ping(unsigned long); +static struct timer_list timer = { 0, 0, WDT_INTERVAL, 0, wdt_timer_ping }; + +/* + * Kernel methods. + */ + +static void wdt_timer_ping(unsigned long data) +{ + /* Ping the WDT by reading from WDT_START */ + inb_p(WDT_START); + /* Re-set the timer interval */ + timer.expires = jiffies + WDT_INTERVAL; + add_timer(&timer); +} + +/* + * Notifier for system down + */ + +static int wdt_notify_sys(struct notifier_block *this, unsigned long code, + void *unused) +{ + if(code==SYS_DOWN || code==SYS_HALT) + { + /* Stop the timer */ + del_timer(&timer); + /* Turn off the WDT */ + inb_p(WDT_STOP); + } + return NOTIFY_DONE; +} + +/* + * The WDT needs to learn about soft shutdowns in order to + * turn the timebomb registers off. + */ + +static struct notifier_block wdt_notifier= +{ + wdt_notify_sys, + 0, + 0 +}; + +#ifdef MODULE + +#define sbc60xxwdt_init init_module + +void cleanup_module(void) +{ + /* Stop the timer */ + del_timer(&timer); + inb_p(WDT_STOP); + printk("Watchdog timer is now disabled...\n"); + + /* Deregister */ + unregister_reboot_notifier(&wdt_notifier); + release_region(WDT_STOP,1); + release_region(WDT_START,1); +} + +#endif + +__initfunc(int sbc60xxwdt_init(void)) +{ + printk("WDT driver for 60XX single board computer initialising.\n"); + + request_region(WDT_STOP, 1, "Acquire WDT"); + request_region(WDT_START, 1, "Acquire WDT"); + register_reboot_notifier(&wdt_notifier); + + /* Start the timer */ + timer.expires = jiffies + WDT_INTERVAL; + add_timer(&timer); + printk("Watchdog timer is now enabled.\n"); + + return 0; +} +