18 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
20 #include <linux/module.h>
22 #include <linux/types.h>
23 #include <linux/kernel.h>
28 #include <linux/watchdog.h>
30 #include <linux/reboot.h>
35 #define WATCHDOG_VERSION "1.00"
36 #define WATCHDOG_NAME "W83977F WDT"
38 #define IO_INDEX_PORT 0x3F0
39 #define IO_DATA_PORT (IO_INDEX_PORT+1)
41 #define UNLOCK_DATA 0x87
42 #define LOCK_DATA 0xAA
43 #define DEVICE_REGISTER 0x07
45 #define DEFAULT_TIMEOUT 45
49 static unsigned long timer_alive;
56 "Watchdog timeout in seconds (15..7635), default="
64 "Watchdog cannot be stopped once started (default="
71 static int wdt_start(
void)
131 spin_unlock_irqrestore(&
spinlock, flags);
142 static int wdt_stop(
void)
185 spin_unlock_irqrestore(&
spinlock, flags);
197 static int wdt_keepalive(
void)
216 spin_unlock_irqrestore(&
spinlock, flags);
225 static int wdt_set_timeout(
int t)
239 tmrval = ((t + 15) + 29) / 30;
249 timeout = (timeoutW * 30) - 15;
257 static int wdt_get_status(
int *
status)
277 spin_unlock_irqrestore(&
spinlock, flags);
304 static int wdt_release(
struct inode *inode,
struct file *file)
310 if (expect_close == 42) {
315 pr_crit(
"unexpected close, not stopping watchdog!\n");
333 size_t count, loff_t *ppos)
346 for (ofs = 0; ofs !=
count; ofs++) {
374 .firmware_version = 1,
378 static long wdt_ioctl(
struct file *file,
unsigned int cmd,
unsigned long arg)
388 uarg.i = (
int __user *)arg;
393 sizeof(ident)) ? -
EFAULT : 0;
396 wdt_get_status(&status);
426 if (wdt_set_timeout(new_timeout))
453 .unlocked_ioctl = wdt_ioctl,
455 .release = wdt_release,
465 .notifier_call = wdt_notify_sys,
468 static int __init w83977f_wdt_init(
void)
478 if (wdt_set_timeout(timeout)) {
480 pr_info(
"timeout value must be 15 <= timeout <= 7635, using %d\n",
492 pr_err(
"cannot register reboot notifier (err=%d)\n", rc);
498 pr_err(
"cannot register miscdev on minor=%d (err=%d)\n",
499 wdt_miscdev.
minor, rc);
503 pr_info(
"initialized. timeout=%d sec (nowayout=%d testmode=%d)\n",
504 timeout, nowayout, testmode);
516 static void __exit w83977f_wdt_exit(
void)