33 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
35 #include <linux/module.h>
37 #include <linux/types.h>
38 #include <linux/kernel.h>
43 #include <linux/watchdog.h>
45 #include <linux/reboot.h>
50 #define WATCHDOG_VERSION "1.14"
51 #define WATCHDOG_NAME "IT87 WDT"
52 #define DRIVER_VERSION WATCHDOG_NAME " driver, v" WATCHDOG_VERSION "\n"
56 #define DEFAULT_NOGAMEPORT 0
57 #define DEFAULT_EXCLUSIVE 1
58 #define DEFAULT_TIMEOUT 60
59 #define DEFAULT_TESTMODE 0
60 #define DEFAULT_NOWAYOUT WATCHDOG_NOWAYOUT
79 #define NO_DEV_ID 0xffff
80 #define IT8702_ID 0x8702
81 #define IT8705_ID 0x8705
82 #define IT8712_ID 0x8712
83 #define IT8716_ID 0x8716
84 #define IT8718_ID 0x8718
85 #define IT8720_ID 0x8720
86 #define IT8721_ID 0x8721
87 #define IT8726_ID 0x8726
88 #define IT8728_ID 0x8728
93 #define WDTVALLSB 0x73
94 #define WDTVALMSB 0x74
97 #define WDT_CIRINT 0x80
98 #define WDT_MOUSEINT 0x40
99 #define WDT_KYBINT 0x20
100 #define WDT_GAMEPORT 0x10
101 #define WDT_FORCE 0x02
102 #define WDT_ZERO 0x01
105 #define WDT_TOV1 0x80
106 #define WDT_KRST 0x40
107 #define WDT_TOVE 0x20
108 #define WDT_PWROK 0x10
109 #define WDT_INT_MASK 0x0f
115 #define CIR_BASE 0x0208
118 #define CIR_DR(b) (b)
119 #define CIR_IER(b) (b + 1)
120 #define CIR_RCR(b) (b + 2)
121 #define CIR_TCR1(b) (b + 3)
122 #define CIR_TCR2(b) (b + 4)
123 #define CIR_TSR(b) (b + 5)
124 #define CIR_RSR(b) (b + 6)
125 #define CIR_BDLR(b) (b + 5)
126 #define CIR_BDHR(b) (b + 6)
127 #define CIR_IIR(b) (b + 7)
130 #define GP_BASE_DEFAULT 0x0201
133 #define WDTS_TIMER_RUN 0
134 #define WDTS_DEV_OPEN 1
135 #define WDTS_KEEPALIVE 2
136 #define WDTS_LOCKED 3
137 #define WDTS_USE_GP 4
138 #define WDTS_EXPECTED 5
140 static unsigned int base, gpact, ciract, max_units,
chip_type;
141 static unsigned long wdt_status;
162 MODULE_PARM_DESC(nowayout,
"Watchdog cannot be stopped once started, default="
167 static inline int superio_enter(
void)
182 static inline void superio_exit(
void)
195 static inline int superio_inb(
int reg)
201 static inline void superio_outb(
int val,
int reg)
207 static inline int superio_inw(
int reg)
217 static inline void superio_outw(
int val,
int reg)
226 static void wdt_update_timeout(
void)
242 superio_outb(cfg,
WDTCFG);
248 static int wdt_round_time(
int t)
257 static void wdt_keepalive(
void)
267 static int wdt_start(
void)
269 int ret = superio_enter();
278 wdt_update_timeout();
285 static int wdt_stop(
void)
287 int ret = superio_enter();
312 static int wdt_set_timeout(
int t)
314 if (t < 1 || t > max_units * 60)
323 int ret = superio_enter();
328 wdt_update_timeout();
347 static int wdt_get_status(
int *
status)
351 int ret = superio_enter();
416 static int wdt_release(
struct inode *inode,
struct file *file)
420 int ret = wdt_stop();
433 pr_crit(
"unexpected close, not stopping watchdog!\n");
454 size_t count, loff_t *ppos)
464 for (ofs = 0; ofs !=
count; ofs++) {
477 .firmware_version = 1,
493 static long wdt_ioctl(
struct file *file,
unsigned int cmd,
unsigned long arg)
495 int rc = 0,
status, new_options, new_timeout;
501 uarg.i = (
int __user *)arg;
506 &ident,
sizeof(ident)) ? -
EFAULT : 0;
509 rc = wdt_get_status(&status);
525 switch (new_options) {
552 rc = wdt_set_timeout(new_timeout);
575 .unlocked_ioctl = wdt_ioctl,
577 .release = wdt_release,
587 .notifier_call = wdt_notify_sys,
590 static int __init it87_wdt_init(
void)
593 int try_gameport = !nogameport;
595 int gp_rreq_fail = 0;
599 rc = superio_enter();
604 chip_rev = superio_inb(
CHIPREV) & 0x0f;
612 max_units = (chip_rev < 8) ? 255 : 65535;
626 pr_err(
"Unsupported Chip found, Chip %04x Revision %02x\n",
633 pr_err(
"Unknown Chip found, Chip %04x Revision %04x\n",
638 rc = superio_enter();
654 gpact = superio_inb(
ACTREG);
655 superio_outb(0x01,
ACTREG);
666 pr_err(
"I/O Address 0x%04x and 0x%04x already in use\n",
669 pr_err(
"I/O Address 0x%04x already in use\n",
679 ciract = superio_inb(
ACTREG);
680 superio_outb(0x01,
ACTREG);
683 superio_outb(gpact,
ACTREG);
687 if (timeout < 1 || timeout > max_units * 60) {
689 pr_warn(
"Timeout value out of range, use default %d sec\n",
693 if (timeout > max_units)
694 timeout = wdt_round_time(timeout);
698 pr_err(
"Cannot register reboot notifier (err=%d)\n", rc);
704 pr_err(
"Cannot register miscdev on minor=%d (err=%d)\n",
705 wdt_miscdev.
minor, rc);
720 pr_info(
"Chip IT%04x revision %d initialized. timeout=%d sec (nowayout=%d testmode=%d exclusive=%d nogameport=%d)\n",
722 nowayout, testmode, exclusive, nogameport);
733 superio_outb(ciract,
ACTREG);
738 superio_outb(gpact,
ACTREG);
745 static void __exit it87_wdt_exit(
void)
747 if (superio_enter() == 0) {
750 superio_outb(0x00,
WDTCFG);
756 superio_outb(gpact,
ACTREG);
759 superio_outb(ciract,
ACTREG);