21 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
23 #include <linux/module.h>
24 #include <linux/types.h>
26 #include <linux/watchdog.h>
31 #include <linux/reboot.h>
41 #define DEFAULT_TIMEOUT 1
42 #define MAX_TIMEOUT 255
45 #define MODNAME "pc87413 WDT"
46 #define DPFX MODNAME " - DEBUG: "
48 #define WDT_INDEX_IO_PORT (io+0)
49 #define WDT_DATA_IO_PORT (WDT_INDEX_IO_PORT+1)
56 #define IO_DEFAULT 0x2E
59 static int swc_base_addr = -1;
62 static unsigned long timer_enabled;
74 static inline void pc87413_select_wdt_out(
void)
76 unsigned int cr_data = 0;
91 "Select multiple pin,pin55,as WDT output: Bit7 to 1: %d\n",
98 static inline void pc87413_enable_swc(
void)
100 unsigned int cr_data = 0;
120 static void pc87413_get_swc_base_addr(
void)
122 unsigned char addr_l, addr_h = 0;
133 swc_base_addr = (addr_h << 8) + addr_l;
136 "Read SWC I/O Base Address: low %d, high %d, res %d\n",
137 addr_l, addr_h, swc_base_addr);
143 static inline void pc87413_swc_bank3(
void)
146 outb_p(
inb(swc_base_addr + 0x0f) | 0x03, swc_base_addr + 0x0f);
154 static inline void pc87413_programm_wdto(
char pc87413_time)
159 pr_info(
DPFX "Set WDTO to %d minutes\n", pc87413_time);
165 static inline void pc87413_enable_wden(
void)
175 static inline void pc87413_enable_sw_wd_tren(
void)
186 static inline void pc87413_disable_sw_wd_tren(
void)
197 static inline void pc87413_enable_sw_wd_trg(
void)
208 static inline void pc87413_disable_sw_wd_trg(
void)
221 static void pc87413_enable(
void)
226 pc87413_programm_wdto(timeout);
227 pc87413_enable_wden();
228 pc87413_enable_sw_wd_tren();
229 pc87413_enable_sw_wd_trg();
236 static void pc87413_disable(
void)
241 pc87413_disable_sw_wd_tren();
242 pc87413_disable_sw_wd_trg();
243 pc87413_programm_wdto(0);
250 static void pc87413_refresh(
void)
255 pc87413_disable_sw_wd_tren();
256 pc87413_disable_sw_wd_trg();
257 pc87413_programm_wdto(timeout);
258 pc87413_enable_wden();
259 pc87413_enable_sw_wd_tren();
260 pc87413_enable_sw_wd_trg();
287 pr_info(
"Watchdog enabled. Timeout set to %d minute(s).\n", timeout);
304 static int pc87413_release(
struct inode *inode,
struct file *file)
308 if (expect_close == 42) {
310 pr_info(
"Watchdog disabled, sleeping again...\n");
312 pr_crit(
"Unexpected close, not stopping watchdog!\n");
327 static int pc87413_status(
void)
343 static ssize_t pc87413_write(
struct file *file,
const char __user *
data,
344 size_t len, loff_t *ppos)
356 for (i = 0; i != len; i++) {
382 static long pc87413_ioctl(
struct file *file,
unsigned int cmd,
396 .firmware_version = 1,
397 .identity =
"PC87413(HF/F) watchdog",
400 uarg.i = (
int __user *)arg;
405 sizeof(ident)) ? -
EFAULT : 0;
407 return put_user(pc87413_status(), uarg.i);
443 return put_user(new_timeout, uarg.i);
478 .write = pc87413_write,
479 .unlocked_ioctl = pc87413_ioctl,
480 .open = pc87413_open,
481 .release = pc87413_release,
491 .fops = &pc87413_fops,
504 static int __init pc87413_init(
void)
516 pr_err(
"cannot register reboot notifier (err=%d)\n", ret);
521 pr_err(
"cannot register miscdev on minor=%d (err=%d)\n",
525 pr_info(
"initialized. timeout=%d min\n", timeout);
527 pc87413_select_wdt_out();
528 pc87413_enable_swc();
529 pc87413_get_swc_base_addr();
532 pr_err(
"cannot request SWC region at 0x%x\n", swc_base_addr);
560 static void __exit pc87413_exit(
void)
565 pr_info(
"Watchdog disabled\n");
572 pr_info(
"watchdog component driver removed\n");
591 "Watchdog timeout in minutes (default="
596 "Watchdog cannot be stopped once started (default="