48 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
51 #include <linux/module.h>
53 #include <linux/types.h>
55 #include <linux/watchdog.h>
59 #include <linux/reboot.h>
65 static unsigned long eurwdt_is_open;
66 static int eurwdt_timeout;
67 static char eur_expect_close;
74 static int io = 0x3f0;
76 static char *ev =
"int";
78 #define WDT_TIMEOUT 60
83 "Watchdog cannot be stopped once started (default="
90 #define WDT_CTRL_REG 0x30
91 #define WDT_OUTPIN_CFG 0xe2
92 #define WDT_EVENT_INT 0x00
93 #define WDT_EVENT_REBOOT 0x08
94 #define WDT_UNIT_SEL 0xf1
95 #define WDT_UNIT_SECS 0x80
96 #define WDT_TIMEOUT_VAL 0xf2
97 #define WDT_TIMER_CFG 0xf3
118 static inline void eurwdt_lock_chip(
void)
123 static inline void eurwdt_unlock_chip(
void)
126 eurwdt_write_reg(0x07, 0x08);
129 static inline void eurwdt_set_timeout(
int timeout)
134 static inline void eurwdt_disable_timer(
void)
136 eurwdt_set_timeout(0);
139 static void eurwdt_activate_timer(
void)
141 eurwdt_disable_timer();
147 if (irq == 2 || irq > 15 || irq < 0) {
148 pr_err(
"invalid irq number\n");
152 pr_info(
"interrupt disabled\n");
157 eurwdt_set_timeout(0);
167 pr_crit(
"timeout WDT timeout\n");
172 pr_crit(
"Initiating system reboot\n");
185 static void eurwdt_ping(
void)
188 eurwdt_set_timeout(eurwdt_timeout);
203 size_t count, loff_t *ppos)
209 eur_expect_close = 0;
211 for (i = 0; i !=
count; i++) {
216 eur_expect_close = 42;
219 spin_lock(&eurwdt_lock);
221 spin_unlock(&eurwdt_lock);
236 static long eurwdt_ioctl(
struct file *file,
237 unsigned int cmd,
unsigned long arg)
244 .firmware_version = 1,
245 .identity =
"WDT Eurotech CPU-1220/1410",
262 spin_lock(&eurwdt_lock);
264 eurwdt_disable_timer();
268 eurwdt_activate_timer();
272 spin_unlock(&eurwdt_lock);
276 spin_lock(&eurwdt_lock);
278 spin_unlock(&eurwdt_lock);
286 if (time < 0 || time > 255)
289 spin_lock(&eurwdt_lock);
290 eurwdt_timeout =
time;
291 eurwdt_set_timeout(time);
292 spin_unlock(&eurwdt_lock);
312 static int eurwdt_open(
struct inode *
inode,
struct file *file)
318 eurwdt_activate_timer();
334 static int eurwdt_release(
struct inode *inode,
struct file *file)
336 if (eur_expect_close == 42)
337 eurwdt_disable_timer();
339 pr_crit(
"Unexpected close, not stopping watchdog!\n");
343 eur_expect_close = 0;
363 eurwdt_disable_timer();
376 .write = eurwdt_write,
377 .unlocked_ioctl = eurwdt_ioctl,
379 .release = eurwdt_release,
385 .fops = &eurwdt_fops,
407 static void __exit eurwdt_exit(
void)
426 static int __init eurwdt_init(
void)
432 pr_err(
"IRQ %d is not free\n", irq);
444 pr_err(
"can't register reboot notifier (err=%d)\n", ret);
454 eurwdt_unlock_chip();
457 pr_info(
"Eurotech WDT driver 0.01 at %X (Interrupt %d) - timeout event: %s\n",
458 io, irq, (!
strcmp(
"int", ev) ?
"int" :
"reboot"));