2 * This is Moxa UC7000 watch dog driver for CV case.
6 * 09-15-2004 Victor Yu. Create it. I name it sWatchDog
7 * 06-10-2005 Jared Wu. Fix the watch dog devic driver bug. kernel_thread() is a system call cannot be invoke in timer timeout interrupt. I move it to the moxa_swtd_init()
8 * 06-18-2009 Wade Liang Change to interrupt mode for flash problem
10 #define __KERNEL_SYSCALLS__
11 #include <linux/config.h>
12 #include <linux/proc_fs.h> /* Necessary because we use the proc fs */
13 #include <linux/version.h>
14 #include <linux/unistd.h>
15 #include <linux/string.h>
16 #include <linux/ctype.h>
17 #include <linux/module.h>
18 #include <linux/kernel.h>
19 #include <linux/miscdevice.h>
20 #include <linux/fcntl.h>
21 #include <linux/init.h>
22 #include <linux/poll.h>
23 #include <linux/spinlock.h>
24 #include <linux/delay.h>
25 #include <linux/timer.h>
26 #include <linux/ioport.h>
27 #include <linux/interrupt.h>
28 #include <linux/sched.h>
29 #include <linux/signal.h>
32 #include <asm/uaccess.h>
33 #include <asm/system.h>
35 #include <asm/bitops.h>
36 #include <linux/reboot.h>
37 #include <asm/types.h>
38 #include <linux/notifier.h>
39 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
40 #include <linux/workqueue.h>
43 #define CONFIG_ARCH_MOXACPU // define for IA-24X/W3X1/W3X5 serials
46 #include "x86_moxa_swtd.h"
47 #elif defined (CONFIG_CPU_IXP43X) || defined (ARCH_IXDP425) || defined (ARCH_IXDP422)
48 #include "ixp43x_moxa_swtd.h"
49 #elif defined(CONFIG_ARCH_MOXACPU)
50 #include "moxaart_moxa_swtd.h"
51 #elif defined(CONFIG_MACH_MOXA_IA261) || defined(CONFIG_MACH_MOXA_W406)
52 #include "ep93xx_moxa_swtd.h"
54 #ifndef WATCHDOG_NOWAYOUT
55 #define WATCHDOG_NOWAYOUT 0
58 static struct proc_dir_entry
*swtd_proc_file
;
59 static int opencounts
=0;
60 static int swtduserenabled
=0;
61 static unsigned long swtdtime
=DEFAULT_WATCHDOG_TIME
;
62 static struct timer_list timer_swtd
;
63 static int bswtd_timeout
= 0;
64 static int nowayout
= WATCHDOG_NOWAYOUT
;
66 static char expect_close
;
67 static spinlock_t swtd_lock
=SPIN_LOCK_UNLOCKED
;
68 static int irq_res
=-1;
69 static unsigned long flags
=0;
70 #if defined(CONFIG_MACH_MOXA_IA261)||defined(CONFIG_MACH_MOXA_W406)
73 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
74 static wait_queue_head_t swtd_queue
;
77 // add by Jared Wu. 03-10-2009 Ack the watchdog instead of disable it.
78 // this means that if the kernel crashed, the hardware watchdog will
80 static void swtd_ack(unsigned long swtd_ack_time
)
83 printk("<1>swtd_ack: swtd_time=%lu\n",swtd_ack_time
);
86 superio_enter_config();
87 superio_set_logic_device(8); //logic device 8
88 superio_set_reg((swtd_ack_time
/1000), 0xF6); //Reg:F6,30 sec
89 #elif defined (CONFIG_CPU_IXP43X) || defined (ARCH_IXDP425)
90 *IXP4XX_OSWK
= IXP4XX_WDT_KEY
;
92 *IXP4XX_OSWT
= WATCHDOG_COUNTER(swtd_ack_time
);
93 *IXP4XX_OSWE
= IXP4XX_WDT_COUNT_ENABLE
| IXP4XX_WDT_RESET_ENABLE
;
95 #elif defined (ARCH_IXDP422)
96 *IXP425_OSWK
= 0x482e;
98 *IXP425_OSWT
= WATCHDOG_COUNTER(swtd_ack_time
);
99 *IXP425_OSWE
= IXP4XX_WDOG_CNT_ENA
| IXP4XX_WDOG_RST_ENA
;
101 #elif defined(CONFIG_ARCH_MOXACPU)
102 *(unsigned int *)(CPE_WATCHDOG_VA_BASE
+4) = WATCHDOG_COUNTER(swtd_ack_time
);
103 *(unsigned int *)(CPE_WATCHDOG_VA_BASE
+8) = 0x5ab9;
104 /* Change to interrupt mode 0x05, reset mode is 0x03*/
105 *(unsigned int *)(CPE_WATCHDOG_VA_BASE
+12) = 0x05;
106 #elif defined(CONFIG_MACH_MOXA_IA261)||defined(CONFIG_MACH_MOXA_W406)
112 static void swtd_enable(void)
115 printk("swtd_enable: swtdtime=%lu\n",swtdtime
+WATCHDOG_DEFER_TIME
);
118 superio_enter_config();
119 superio_set_logic_device(8); //logic device 8
120 superio_set_reg(1, 0x30); //Reg:30 active WDT
121 superio_set_reg(0, 0xF5); //Reg:F5
122 superio_set_reg(0, 0xF7); //Reg:F7
123 superio_set_reg((swtdtime
+WATCHDOG_DEFER_TIME
)/1000, 0xF6); //Reg:F6,30 sec
124 #elif defined (CONFIG_CPU_IXP43X) || defined (ARCH_IXDP425)
125 *IXP4XX_OSWK
= IXP4XX_WDT_KEY
;
127 *IXP4XX_OSWT
= WATCHDOG_COUNTER(swtdtime
+WATCHDOG_DEFER_TIME
);
128 *IXP4XX_OSWE
= IXP4XX_WDT_COUNT_ENABLE
| IXP4XX_WDT_RESET_ENABLE
;
130 #elif defined (ARCH_IXDP422)
131 *IXP425_OSWK
= 0x482e;
133 *IXP425_OSWT
= WATCHDOG_COUNTER(swtdtime
+WATCHDOG_DEFER_TIME
);
134 //*IXP425_OSWE = IXP4XX_WDOG_CNT_ENA | IXP4XX_WDOG_INT_ENA | IXP4XX_WDOG_RST_ENA ;
135 *IXP425_OSWE
= IXP4XX_WDOG_CNT_ENA
| IXP4XX_WDOG_RST_ENA
;
137 #elif defined(CONFIG_ARCH_MOXACPU)
138 *(unsigned int *)(CPE_WATCHDOG_VA_BASE
+4) = WATCHDOG_COUNTER(swtdtime
+WATCHDOG_DEFER_TIME
);
139 *(unsigned int *)(CPE_WATCHDOG_VA_BASE
+8) = 0x5ab9;
140 *(unsigned int *)(CPE_WATCHDOG_VA_BASE
+12) = 0x03;
141 #elif defined(CONFIG_MACH_MOXA_IA261)||defined(CONFIG_MACH_MOXA_W406)
142 __raw_writew(0x5555, EP93XX_WATCHDOG_BASE
); // reset watchdog counter
143 __raw_writew(0xaaaa, EP93XX_WATCHDOG_BASE
); // enable watchdog
148 static void swtd_disable(void)
151 printk("swtd_disable\n");
154 superio_enter_config();
155 superio_set_logic_device(8); //logic device 8
156 superio_set_reg(0, 0xF6); //Reg:F6 counter register
157 #elif defined (CONFIG_CPU_IXP43X) || defined (ARCH_IXDP425)
158 *IXP4XX_OSWK
= IXP4XX_WDT_KEY
;
161 #elif defined (ARCH_IXDP422)
162 *IXP425_OSWK
= 0x482e;
165 #elif defined(CONFIG_ARCH_MOXACPU)
166 *(unsigned int *)(CPE_WATCHDOG_VA_BASE
+12) = 0;
167 #elif defined(CONFIG_MACH_MOXA_IA261)||defined(CONFIG_MACH_MOXA_W406)
168 __raw_writew(0xaa55, EP93XX_WATCHDOG_BASE
);
173 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
174 static void swtd_reboot(void *unused
)
176 char *argv
[2], *envp
[5];
178 if ( in_interrupt() )
180 if ( !current
->fs
->root
)
183 argv[0] = "/bin/reboot";
186 argv
[0] = "/sbin/reboot";
189 envp
[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
191 call_usermodehelper(argv
[0], argv
, envp
, 0);
194 static char *argv_init
[2]={"reboot", NULL
};
195 static char *envp_init
[3]={"HOME=/", "TERM=linux", NULL
};
197 static int swtd_reboot(void *unused
)
199 interruptible_sleep_on(&swtd_queue
);
200 printk("<1>exec reboot.\n");
201 execve("/sbin/reboot", argv_init
, envp_init
);
206 #if defined (DA68X) || defined (ARCH_IXDP425) || defined(CONFIG_ARCH_MOXACPU)
207 DECLARE_WORK(rebootqueue
, swtd_reboot
, NULL
);
208 #elif defined (CONFIG_CPU_IXP43X) || defined(CONFIG_MACH_MOXA_IA261) || defined(CONFIG_MACH_MOXA_W406)
209 DECLARE_WORK(rebootqueue
, swtd_reboot
);
212 static void swtd_poll(unsigned long ignore
)
214 spin_lock(&swtd_lock
);
215 #if defined(CONFIG_MACH_MOXA_IA261)||defined(CONFIG_MACH_MOXA_W406)
216 if ( pollcnt
++ <= (swtdtime
/WATCHDOG_ACK_JIFFIES
) ) {
217 timer_swtd
.expires
= jiffies
+ WATCHDOG_ACK_JIFFIES
;
218 add_timer(&timer_swtd
);
220 spin_unlock(&swtd_lock
);
225 printk("<1>swtd_poll: Now reboot the system.\n");
227 schedule_work(&rebootqueue
);
230 #else // (CONFIG_CPU_IXP43X) || defined(CONFIG_MACH_MOXA_IA261) || defined(CONFIG_MACH_MOXA_W406) || defined(CONFIG_ARCH_MOXACPU)
232 if ( swtduserenabled
) {
233 swtd_ack(WATCHDOG_DEFER_TIME
);
235 printk("<1>swtd_poll: Now reboot the system.\n");
237 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
238 schedule_work(&rebootqueue
);
240 /* Jared said, awake any swtd_reboot kernel thread */
241 wake_up_interruptible(&swtd_queue
);
249 printk("swtd_poll: ack the hardware watchdog timer\n");
250 /* 1-17-2005 Jared said, if disable the watchdog,
251 * it would not reboot while the system is very busy
253 timer_swtd
.expires
= jiffies
+WATCHDOG_ACK_JIFFIES(swtdtime
);
254 add_timer(&timer_swtd
);
255 swtd_ack(swtdtime
+WATCHDOG_DEFER_TIME
);
258 spin_unlock(&swtd_lock
);
261 ssize_t
moxaswtd_proc_read(char *buffer
,char **buffer_location
,off_t offset
, int buffer_length
, int *eof
, void *data
)
263 int len
=0; /* The number of bytes actually used */
269 //Fill the buffer and get its length
270 len
+= sprintf(buffer
+len
,
271 "user enable\t: %d\n"
272 "ack time\t: %d msec\n"
274 "hardware watchdog counter\t: %d sec\n"
276 ,swtduserenabled
, (int)swtdtime
278 ,superio_get_reg(0xF6)
285 static int swtd_open(struct inode
*inode
, struct file
*file
)
287 if ( MINOR(inode
->i_rdev
) != MOXA_WATCHDOG_MINOR
)
290 spin_lock_irq(&swtd_lock
);
291 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
293 __module_get(THIS_MODULE
);
295 bswtd_timeout
= 0; // reset the timeout flag
297 spin_unlock_irq(&swtd_lock
);
302 // Kernel ack the watchdog timer and reset the state machine
303 static void swtd_release_timer(void) {
304 swtdtime
= DEFAULT_WATCHDOG_TIME
;
305 #if defined(CONFIG_MACH_MOXA_IA261)||defined(CONFIG_MACH_MOXA_W406)
307 del_timer(&timer_swtd
);
309 mod_timer(&timer_swtd
, jiffies
+ WATCHDOG_ACK_JIFFIES(swtdtime
));
310 swtd_ack(swtdtime
+WATCHDOG_DEFER_TIME
);
313 bswtd_timeout
= 0; // reset the timeout flag
317 static int swtd_release(struct inode
*inode
, struct file
*file
)
319 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
320 sigset_t
*sigset
= ¤t
->signal
->shared_pending
.signal
;
322 sigset_t
*sigset
= ¤t
->pending
.signal
;
325 spin_lock_irq(&swtd_lock
);
328 printk("<1>swtd_release entry\n");
331 if ( opencounts
<= 0 ) {
333 * Shut off the timer.
335 if (expect_close
== 42) {
336 printk("<1>swtd_release: expect close\n");
337 if ( !bswtd_timeout
) {
338 swtd_release_timer();
341 else if ( signal_pending(current
) ) {
343 printk("<1>swtd_release[%d] has signal pending\n",__LINE__
);
344 if ( sigismember (sigset
, SIGKILL
) || \
345 sigismember (sigset
, SIGINT
) || \
346 sigismember (sigset
, SIGTERM
) ) {
348 printk("<1>swtd_release[%d] get SIGKILL/SIGINT/SIGTERM signal\n",__LINE__
);
349 #if 1 // For Taitung, 03-30-2009 should comment out this line
350 if ( !bswtd_timeout
) {
351 swtd_release_timer();
355 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
356 } else if ( current
->signal
->group_exit_code
== SIGQUIT
|| \
357 current
->signal
->group_exit_code
== SIGILL
|| \
358 current
->signal
->group_exit_code
== SIGABRT
|| \
359 current
->signal
->group_exit_code
== SIGFPE
|| \
360 current
->signal
->group_exit_code
== SIGSEGV
) {
362 printk("<1>swtd_release[%d] got coredump\n",__LINE__
);
365 } else if ( sigismember (sigset
, SIGILL
) || \
366 sigismember (sigset
, SIGABRT
) || \
367 sigismember (sigset
, SIGFPE
) || \
368 sigismember (sigset
, SIGSEGV
) ) {
370 printk("<1>swtd_release[%d] got coredump\n",__LINE__
);
373 else { // normal close the file handle
375 printk("<1>swtd_release_l1[%d] kernel ack the watchdog timer\n",__LINE__
);
376 if ( !bswtd_timeout
) {
377 #if 1 // For Taitung, 03-30-2009 should comment out this line
378 swtd_release_timer();
384 spin_unlock_irq(&swtd_lock
);
389 static int swtd_ioctl (struct inode
*inode
, struct file
*file
, unsigned int ioc_cmd
, unsigned long arg
)
392 struct swtd_set_struct nowset
;
395 case IOCTL_WATCHDOG_ENABLE
:
396 if ( copy_from_user(&time
, (unsigned long *)arg
, sizeof(unsigned long)) )
398 if ( time
< WATCHDOG_MIN_TIME
|| time
> WATCHDOG_MAX_TIME
)
400 spin_lock_irq(&swtd_lock
);
401 if ( !bswtd_timeout
) {
402 // Switch to user mode watchdog.
403 // When the kernel timer timeout, the system will reboot
406 #if defined(CONFIG_MACH_MOXA_IA261)||defined(CONFIG_MACH_MOXA_W406)
409 if(timer_pending(&timer_swtd
))
410 mod_timer(&timer_swtd
, jiffies
+ WATCHDOG_ACK_JIFFIES
);
412 add_timer(&timer_swtd
);
414 mod_timer(&timer_swtd
, jiffies
+ WATCHDOG_ACK_JIFFIES(swtdtime
));
415 swtd_ack(swtdtime
+WATCHDOG_DEFER_TIME
);
418 spin_unlock_irq(&swtd_lock
);
420 case IOCTL_WATCHDOG_DISABLE
:
421 spin_lock_irq(&swtd_lock
);
422 if ( swtduserenabled
&& !bswtd_timeout
) {
423 #if defined(CONFIG_MACH_MOXA_IA261)||defined(CONFIG_MACH_MOXA_W406)
426 del_timer(&timer_swtd
);
428 // Switch to kernel mode watchdog.
429 // The kernel timer will acknowledge the HW watchdog
431 mod_timer(&timer_swtd
, jiffies
+ WATCHDOG_ACK_JIFFIES(swtdtime
));
433 swtdtime
= DEFAULT_WATCHDOG_TIME
;
434 bswtd_timeout
= 0; // reset the timeout flag
437 spin_unlock_irq(&swtd_lock
);
439 case IOCTL_WATCHDOG_GET_SETTING
:
440 nowset
.mode
= swtduserenabled
;
441 nowset
.time
= swtdtime
;
442 if ( copy_to_user((void *)arg
, &nowset
, sizeof(nowset
)) )
445 case IOCTL_WATCHDOG_ACK
:
446 spin_lock_irq(&swtd_lock
);
447 if ( swtduserenabled
&& !bswtd_timeout
) {
448 #if defined(CONFIG_MACH_MOXA_IA261)||defined(CONFIG_MACH_MOXA_W406)
451 mod_timer(&timer_swtd
, jiffies
+ WATCHDOG_ACK_JIFFIES
);
453 // Switch to user mode watchdog.
454 // When the kernel timer timeout, the system will reboot
455 mod_timer(&timer_swtd
, jiffies
+ WATCHDOG_ACK_JIFFIES(swtdtime
));
456 swtd_ack(swtdtime
+WATCHDOG_DEFER_TIME
);
459 spin_unlock_irq(&swtd_lock
);
470 * @file: file handle to the watchdog
471 * @buf: buffer to write (unused as data does not matter here
472 * @count: count of bytes
473 * @ppos: pointer to the position to write. No seeks allowed
475 * A write to a watchdog device is defined as a keepalive signal. Any
476 * write of data will do, as we we don't define content meaning.
479 static ssize_t
swtd_write(struct file
*file
, const char *buf
, \
480 size_t count
, loff_t
*ppos
)
488 /* In case it was set long ago */
489 #if 0 // Comment out by Jared 2009-05-11, don't reset the expect_close flag
492 for (i
= 0; i
!= count
; i
++)
495 if (get_user(c
, buf
+ i
))
502 /* someone wrote to us, we should restart timer */
503 spin_lock_irq(&swtd_lock
);
504 if ( !bswtd_timeout
) {
505 // Switch to user mode watchdog.
506 // When the kernel timer timeout, the system will reboot
508 #if defined(CONFIG_MACH_MOXA_IA261)||defined(CONFIG_MACH_MOXA_W406)
510 mod_timer(&timer_swtd
, jiffies
+ WATCHDOG_ACK_JIFFIES
);
513 mod_timer(&timer_swtd
, jiffies
+ WATCHDOG_ACK_JIFFIES(swtdtime
));
514 swtd_ack(swtdtime
+WATCHDOG_DEFER_TIME
);
517 spin_unlock_irq(&swtd_lock
);
523 /* IRQ handler: for hw watchdog and system reboot will call */
524 static irqreturn_t
swtd_interrupt_handler(int irq
, void *dev_id
, struct pt_regs
*regs
)
527 local_irq_save(flags
);
529 printk("swtd_interrupt_handler: enter\n");
531 /* Reset flash state */
532 *( volatile u16
*)(CPE_FLASH_VA_BASE
+0x55*2) = 0xb0;//Suspend block erase
533 *( volatile u16
*)(CPE_FLASH_VA_BASE
+0x55*2) = 0xff;//Change to read array mode
535 /* Call hardware reboot */
536 *(unsigned int *)(CPE_WATCHDOG_VA_BASE
+4) = 1;
537 *(unsigned int *)(CPE_WATCHDOG_VA_BASE
+8) = 0x5ab9;
538 *(unsigned int *)(CPE_WATCHDOG_VA_BASE
+12) = 0x03;
542 local_irq_restore(flags
);
548 static int swtd_panic_handler(struct notifier_block
*this,
552 /* Avoid the software interrupt of swtd_ack */
553 spin_lock_bh(&swtd_lock
);
555 if (debug
) printk("swtd_panic_handler: enter\n");
557 /* Reset flash state */
558 if (debug
) printk("swtd_panic_handler: reset flash state\n");
559 *( volatile u16
*)(CPE_FLASH_VA_BASE
+0x55*2) = 0xb0;//Suspend block erase
560 *( volatile u16
*)(CPE_FLASH_VA_BASE
+0x55*2) = 0xff;//Change to read array mode
562 /* Call hardware reboot */
563 if (debug
) printk("swtd_panic_handler: call hardware rebooot\n");
564 *(unsigned int *)(CPE_WATCHDOG_VA_BASE
+4) = 1;
565 *(unsigned int *)(CPE_WATCHDOG_VA_BASE
+8) = 0x5ab9;
566 *(unsigned int *)(CPE_WATCHDOG_VA_BASE
+12) = 0x03;
571 spin_unlock_bh(&swtd_lock
);
574 /* Structure for notification */
575 static struct notifier_block swtd_panic_notifier
= {
578 150 /* priority: INT_MAX >= x >= 0 */
581 static struct file_operations moxa_swtd_fops
= {
586 .release
=swtd_release
,
589 static struct miscdevice wdt_miscdev
= {
590 .minor
= MOXA_WATCHDOG_MINOR
,
592 .fops
= &moxa_swtd_fops
,
595 static int __init
moxaswtd_init(void) {
598 if ( misc_register(&wdt_miscdev
)!=0 ) {
599 printk("Moxa DA-681/662-LX WatchDog: Register misc fail !\n");
600 goto moxa_swtd_init_err1
;
603 /* Register IRQ handler */
604 irq_res
= request_irq(IRQ_WATCHDOG
, swtd_interrupt_handler
,
605 SA_INTERRUPT
,"swtd_irq",
608 printk( KERN_EMERG
"swtd: can't get assigned irq %i\n", IRQ_WATCHDOG
);
612 /* Resister panic handler */
613 notifier_chain_register(&panic_notifier_list
, &swtd_panic_notifier
);
616 init_timer(&timer_swtd
);
617 timer_swtd
.function
=swtd_poll
;
618 #if defined(CONFIG_MACH_MOXA_IA261)||defined(CONFIG_MACH_MOXA_W406)
619 timer_swtd
.expires
= jiffies
+ WATCHDOG_ACK_JIFFIES
;
621 timer_swtd
.expires
= jiffies
+ WATCHDOG_ACK_JIFFIES(swtdtime
);
622 add_timer(&timer_swtd
);
626 /* Create proc file */
627 swtd_proc_file
= create_proc_read_entry("driver/swtd", 0644, NULL
, moxaswtd_proc_read
, NULL
);
628 if ( !swtd_proc_file
) {
629 printk("<1>moxaswtd_init:create_proc_read_entry() fail\n");
630 goto moxa_swtd_init_err2
;
634 struct resource
*base_res
;
636 base_res
= request_region(SUPERIO_CONFIG_PORT
, 2, "swtd");
638 printk("<1>moxaswtd_init: can't get I/O address 0x%x\n", SUPERIO_CONFIG_PORT
);
639 goto moxa_swtd_init_err3
;
643 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
644 init_waitqueue_head (&swtd_queue
);
645 kernel_thread(swtd_reboot
, NULL
, CLONE_FS
| CLONE_FILES
| CLONE_SIGNAL
);
648 printk (KERN_INFO
"initialized. (nowayout=%d)\n", nowayout
);
649 printk (KERN_INFO
"initialized. (debug=%d)\n", debug
);
655 remove_proc_entry("driver/swtd", NULL
);
658 if(timer_pending(&timer_swtd
))
659 del_timer(&timer_swtd
);
660 misc_deregister(&wdt_miscdev
);
665 static void __exit
moxaswtd_exit(void) {
668 release_region(SUPERIO_CONFIG_PORT
, 2);
669 superio_exit_config();
671 remove_proc_entry("driver/swtd", NULL
);
673 if(timer_pending(&timer_swtd
))
674 del_timer(&timer_swtd
);
675 if ( swtduserenabled
) {
679 misc_deregister(&wdt_miscdev
);
682 free_irq(IRQ_WATCHDOG
, NULL
);
684 /* Free panic hander */
685 notifier_chain_unregister(&panic_notifier_list
, &swtd_panic_notifier
);
689 module_init(moxaswtd_init
);
690 module_exit(moxaswtd_exit
);
692 MODULE_AUTHOR("Jared_Wu@moxa.com.tw");
693 MODULE_LICENSE("GPL");
694 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
695 module_param(nowayout
, int, 0);
697 MODULE_PARM(nowayout
, "i");
699 MODULE_PARM_DESC(nowayout
, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
700 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
701 module_param(debug
, int, 0);
703 MODULE_PARM(debug
, "i");
705 MODULE_PARM_DESC(debug
, "print the debug message in this driver");