2 * This is Moxa UC7000 watch dog driver for CV case.
\r
5 * Date Aurhor Comment
\r
6 * 09-15-2004 Victor Yu. Create it. I name it sWatchDog
\r
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()
\r
9 #define __KERNEL_SYSCALLS__
\r
10 #include <linux/config.h>
\r
11 #include <linux/proc_fs.h> /* Necessary because we use the proc fs */
\r
12 #include <linux/version.h>
\r
13 #include <linux/unistd.h>
\r
14 #include <linux/string.h>
\r
15 #include <linux/ctype.h>
\r
16 #include <linux/module.h>
\r
17 #include <linux/kernel.h>
\r
18 #include <linux/miscdevice.h>
\r
19 #include <linux/fcntl.h>
\r
20 #include <linux/init.h>
\r
21 #include <linux/poll.h>
\r
22 #include <linux/spinlock.h>
\r
23 #include <linux/delay.h>
\r
24 #include <linux/timer.h>
\r
25 #include <linux/ioport.h>
\r
26 #include <linux/interrupt.h>
\r
27 #include <linux/sched.h>
\r
28 #include <linux/signal.h>
\r
29 #include <linux/mm.h>
\r
31 #include <asm/uaccess.h>
\r
32 #include <asm/system.h>
\r
33 #include <asm/irq.h>
\r
34 #include <asm/bitops.h>
\r
35 #include <linux/reboot.h>
\r
36 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
\r
37 #include <linux/workqueue.h>
\r
40 #define CONFIG_ARCH_MOXACPU // define for IA-24X/W3X1/W3X5 serials
\r
43 #include "x86_moxa_swtd.h"
\r
44 #elif defined (CONFIG_CPU_IXP43X) || defined (ARCH_IXDP425) || defined (ARCH_IXDP422)
\r
45 #include "ixp43x_moxa_swtd.h"
\r
46 #elif defined(CONFIG_ARCH_MOXACPU)
\r
47 #include "moxaart_moxa_swtd.h"
\r
48 #elif defined(CONFIG_MACH_MOXA_IA261) || defined(CONFIG_MACH_MOXA_W406)
\r
49 #include "ep93xx_moxa_swtd.h"
\r
51 #ifndef WATCHDOG_NOWAYOUT
\r
52 #define WATCHDOG_NOWAYOUT 0
\r
55 static struct proc_dir_entry *swtd_proc_file;
\r
56 static int opencounts=0;
\r
57 static int swtduserenabled=0;
\r
58 static unsigned long swtdtime=DEFAULT_WATCHDOG_TIME;
\r
59 static struct timer_list timer_swtd;
\r
60 static int bswtd_timeout = 0;
\r
61 static int nowayout = WATCHDOG_NOWAYOUT;
\r
62 static int debug = 0;
\r
63 static char expect_close;
\r
64 static spinlock_t swtd_lock=SPIN_LOCK_UNLOCKED;
\r
65 #if defined(CONFIG_MACH_MOXA_IA261)||defined(CONFIG_MACH_MOXA_W406)
\r
66 static int pollcnt=0;
\r
68 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
\r
69 static wait_queue_head_t swtd_queue;
\r
72 // add by Jared Wu. 03-10-2009 Ack the watchdog instead of disable it.
\r
73 // this means that if the kernel crashed, the hardware watchdog will
\r
75 static void swtd_ack(unsigned long swtd_ack_time)
\r
78 printk("<1>swtd_ack: swtd_time=%lu\n",swtd_ack_time);
\r
79 #ifndef __WDT_TEST__
\r
81 superio_enter_config();
\r
82 superio_set_logic_device(8); //logic device 8
\r
83 superio_set_reg((swtd_ack_time/1000), 0xF6); //Reg:F6,30 sec
\r
84 #elif defined (CONFIG_CPU_IXP43X) || defined (ARCH_IXDP425)
\r
85 *IXP4XX_OSWK = IXP4XX_WDT_KEY;
\r
87 *IXP4XX_OSWT = WATCHDOG_COUNTER(swtd_ack_time);
\r
88 *IXP4XX_OSWE = IXP4XX_WDT_COUNT_ENABLE | IXP4XX_WDT_RESET_ENABLE;
\r
90 #elif defined (ARCH_IXDP422)
\r
91 *IXP425_OSWK = 0x482e;
\r
93 *IXP425_OSWT = WATCHDOG_COUNTER(swtd_ack_time);
\r
94 *IXP425_OSWE = IXP4XX_WDOG_CNT_ENA | IXP4XX_WDOG_RST_ENA;
\r
96 #elif defined(CONFIG_ARCH_MOXACPU)
\r
97 *(unsigned int *)(CPE_WATCHDOG_VA_BASE+4) = WATCHDOG_COUNTER(swtd_ack_time);
\r
98 *(unsigned int *)(CPE_WATCHDOG_VA_BASE+8) = 0x5ab9;
\r
99 *(unsigned int *)(CPE_WATCHDOG_VA_BASE+12) = 0x03;
\r
100 #elif defined(CONFIG_MACH_MOXA_IA261)||defined(CONFIG_MACH_MOXA_W406)
\r
106 static void swtd_enable(void)
\r
109 printk("swtd_enable: swtdtime=%lu\n",swtdtime);
\r
110 #ifndef __WDT_TEST__
\r
111 #if defined (DA68X)
\r
112 superio_enter_config();
\r
113 superio_set_logic_device(8); //logic device 8
\r
114 superio_set_reg(1, 0x30); //Reg:30 active WDT
\r
115 superio_set_reg(0, 0xF5); //Reg:F5
\r
116 superio_set_reg(0, 0xF7); //Reg:F7
\r
117 superio_set_reg((swtdtime+WATCHDOG_DEFER_TIME)/1000, 0xF6); //Reg:F6,30 sec
\r
118 #elif defined (CONFIG_CPU_IXP43X) || defined (ARCH_IXDP425)
\r
119 *IXP4XX_OSWK = IXP4XX_WDT_KEY;
\r
120 *IXP4XX_OSWE = 0x0;
\r
121 *IXP4XX_OSWT = WATCHDOG_COUNTER(swtdtime+WATCHDOG_DEFER_TIME);
\r
122 *IXP4XX_OSWE = IXP4XX_WDT_COUNT_ENABLE | IXP4XX_WDT_RESET_ENABLE;
\r
124 #elif defined (ARCH_IXDP422)
\r
125 *IXP425_OSWK = 0x482e;
\r
126 *IXP425_OSWE = 0x0;
\r
127 *IXP425_OSWT = WATCHDOG_COUNTER(swtdtime+WATCHDOG_DEFER_TIME);
\r
128 //*IXP425_OSWE = IXP4XX_WDOG_CNT_ENA | IXP4XX_WDOG_INT_ENA | IXP4XX_WDOG_RST_ENA ;
\r
129 *IXP425_OSWE = IXP4XX_WDOG_CNT_ENA | IXP4XX_WDOG_RST_ENA ;
\r
131 #elif defined(CONFIG_ARCH_MOXACPU)
\r
132 *(unsigned int *)(CPE_WATCHDOG_VA_BASE+4) = WATCHDOG_COUNTER(swtdtime+WATCHDOG_DEFER_TIME);
\r
133 *(unsigned int *)(CPE_WATCHDOG_VA_BASE+8) = 0x5ab9;
\r
134 *(unsigned int *)(CPE_WATCHDOG_VA_BASE+12) = 0x03;
\r
135 #elif defined(CONFIG_MACH_MOXA_IA261)||defined(CONFIG_MACH_MOXA_W406)
\r
136 __raw_writew(0x5555, EP93XX_WATCHDOG_BASE); // reset watchdog counter
\r
137 __raw_writew(0xaaaa, EP93XX_WATCHDOG_BASE); // enable watchdog
\r
142 static void swtd_disable(void)
\r
145 printk("swtd_disable\n");
\r
146 #ifndef __WDT_TEST__
\r
147 #if defined (DA68X)
\r
148 superio_enter_config();
\r
149 superio_set_logic_device(8); //logic device 8
\r
150 superio_set_reg(0, 0xF6); //Reg:F6 counter register
\r
151 #elif defined (CONFIG_CPU_IXP43X) || defined (ARCH_IXDP425)
\r
152 *IXP4XX_OSWK = IXP4XX_WDT_KEY;
\r
155 #elif defined (ARCH_IXDP422)
\r
156 *IXP425_OSWK = 0x482e;
\r
159 #elif defined(CONFIG_ARCH_MOXACPU)
\r
160 *(unsigned int *)(CPE_WATCHDOG_VA_BASE+12) = 0;
\r
161 #elif defined(CONFIG_MACH_MOXA_IA261)||defined(CONFIG_MACH_MOXA_W406)
\r
162 __raw_writew(0xaa55, EP93XX_WATCHDOG_BASE);
\r
167 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
\r
168 static void swtd_reboot(void *unused)
\r
170 char *argv[2], *envp[5];
\r
172 if ( in_interrupt() )
\r
174 if ( !current->fs->root )
\r
177 argv[0] = "/bin/reboot";
\r
180 argv[0] = "/sbin/reboot";
\r
182 envp[0] = "HOME=/";
\r
183 envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
\r
185 call_usermodehelper(argv[0], argv, envp, 0);
\r
188 static char *argv_init[2]={"reboot", NULL};
\r
189 static char *envp_init[3]={"HOME=/", "TERM=linux", NULL};
\r
191 static int swtd_reboot(void *unused)
\r
193 interruptible_sleep_on(&swtd_queue);
\r
194 printk("<1>exec reboot.\n");
\r
195 execve("/sbin/reboot", argv_init, envp_init);
\r
200 #if defined (DA68X) || defined (ARCH_IXDP425) || defined(CONFIG_ARCH_MOXACPU)
\r
201 DECLARE_WORK(rebootqueue, swtd_reboot, NULL);
\r
202 #elif defined (CONFIG_CPU_IXP43X) || defined(CONFIG_MACH_MOXA_IA261) || defined(CONFIG_MACH_MOXA_W406)
\r
203 DECLARE_WORK(rebootqueue, swtd_reboot);
\r
206 static void swtd_poll(unsigned long ignore)
\r
208 spin_lock(&swtd_lock);
\r
209 #if defined(CONFIG_MACH_MOXA_IA261)||defined(CONFIG_MACH_MOXA_W406)
\r
210 if ( pollcnt++ <= (swtdtime/WATCHDOG_ACK_JIFFIES) ) {
\r
211 timer_swtd.expires = jiffies + WATCHDOG_ACK_JIFFIES;
\r
212 add_timer(&timer_swtd);
\r
214 spin_unlock(&swtd_lock);
\r
219 printk("<1>swtd_poll: Now reboot the system.\n");
\r
220 #ifndef __WDT_TEST__
\r
221 schedule_work(&rebootqueue);
\r
224 #else // (CONFIG_CPU_IXP43X) || defined(CONFIG_MACH_MOXA_IA261) || defined(CONFIG_MACH_MOXA_W406) || defined(CONFIG_ARCH_MOXACPU)
\r
226 if ( swtduserenabled ) {
\r
227 swtd_ack(WATCHDOG_DEFER_TIME);
\r
229 printk("<1>swtd_poll: Now reboot the system.\n");
\r
230 #ifndef __WDT_TEST__
\r
231 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
\r
232 schedule_work(&rebootqueue);
\r
234 /* Jared said, awake any swtd_reboot kernel thread */
\r
235 wake_up_interruptible(&swtd_queue);
\r
243 printk("swtd_poll: ack the hardware watchdog timer\n");
\r
244 /* 1-17-2005 Jared said, if disable the watchdog,
\r
245 * it would not reboot while the system is very busy
\r
247 timer_swtd.expires = jiffies +WATCHDOG_ACK_JIFFIES(swtdtime);
\r
248 add_timer(&timer_swtd);
\r
249 swtd_ack(swtdtime+WATCHDOG_DEFER_TIME);
\r
252 spin_unlock(&swtd_lock);
\r
255 ssize_t moxaswtd_proc_read(char *buffer,char **buffer_location,off_t offset, int buffer_length, int *eof, void *data)
\r
257 int len=0; /* The number of bytes actually used */
\r
263 //Fill the buffer and get its length
\r
264 len += sprintf(buffer+len,
\r
265 "user enable\t: %d\n"
\r
266 "ack time\t: %d msec\n"
\r
267 #if defined (DA68X)
\r
268 "hardware watchdog counter\t: %d sec\n"
\r
270 ,swtduserenabled, (int)swtdtime
\r
271 #if defined (DA68X)
\r
272 ,superio_get_reg(0xF6)
\r
279 static int swtd_open(struct inode *inode, struct file *file)
\r
281 if ( MINOR(inode->i_rdev) != MOXA_WATCHDOG_MINOR )
\r
284 spin_lock_irq(&swtd_lock);
\r
285 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
\r
287 __module_get(THIS_MODULE);
\r
289 bswtd_timeout = 0; // reset the timeout flag
\r
291 spin_unlock_irq(&swtd_lock);
\r
296 // Kernel ack the watchdog timer and reset the state machine
\r
297 static void swtd_release_timer() {
\r
298 swtdtime = DEFAULT_WATCHDOG_TIME;
\r
299 #if defined(CONFIG_MACH_MOXA_IA261)||defined(CONFIG_MACH_MOXA_W406)
\r
301 del_timer(&timer_swtd);
\r
303 mod_timer(&timer_swtd, jiffies + WATCHDOG_ACK_JIFFIES(swtdtime));
\r
304 swtd_ack(swtdtime+WATCHDOG_DEFER_TIME);
\r
306 swtduserenabled = 0;
\r
307 bswtd_timeout = 0; // reset the timeout flag
\r
311 static int swtd_release(struct inode *inode, struct file *file)
\r
313 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
\r
314 sigset_t *sigset = ¤t->signal->shared_pending.signal;
\r
316 sigset_t *sigset = ¤t->pending.signal;
\r
319 spin_lock_irq(&swtd_lock);
\r
322 printk("<1>swtd_release entry\n");
\r
325 if ( opencounts <= 0 ) {
\r
327 * Shut off the timer.
\r
329 if (expect_close == 42) {
\r
330 printk("<1>swtd_release: expect close\n");
\r
331 if ( !bswtd_timeout ) {
\r
332 swtd_release_timer();
\r
335 else if ( signal_pending(current) ) {
\r
337 printk("<1>swtd_release[%d] has signal pending\n",__LINE__);
\r
338 if ( sigismember (sigset, SIGKILL) || \
\r
339 sigismember (sigset, SIGINT) || \
\r
340 sigismember (sigset, SIGTERM) ) {
\r
342 printk("<1>swtd_release[%d] get SIGKILL/SIGINT/SIGTERM signal\n",__LINE__);
\r
343 #if 1 // For Taitung, 03-30-2009 should comment out this line
\r
344 if ( !bswtd_timeout ) {
\r
345 swtd_release_timer();
\r
349 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
\r
350 } else if ( current->signal->group_exit_code == SIGQUIT || \
\r
351 current->signal->group_exit_code == SIGILL || \
\r
352 current->signal->group_exit_code == SIGABRT || \
\r
353 current->signal->group_exit_code == SIGFPE || \
\r
354 current->signal->group_exit_code == SIGSEGV ) {
\r
356 printk("<1>swtd_release[%d] got coredump\n",__LINE__);
\r
359 } else if ( sigismember (sigset, SIGILL) || \
\r
360 sigismember (sigset, SIGABRT) || \
\r
361 sigismember (sigset, SIGFPE) || \
\r
362 sigismember (sigset, SIGSEGV) ) {
\r
364 printk("<1>swtd_release[%d] got coredump\n",__LINE__);
\r
367 else { // normal close the file handle
\r
369 printk("<1>swtd_release_l1[%d] kernel ack the watchdog timer\n",__LINE__);
\r
370 if ( !bswtd_timeout ) {
\r
371 #if 1 // For Taitung, 03-30-2009 should comment out this line
\r
372 swtd_release_timer();
\r
378 spin_unlock_irq(&swtd_lock);
\r
383 static int swtd_ioctl (struct inode *inode, struct file *file, unsigned int ioc_cmd, unsigned long arg)
\r
385 unsigned long time;
\r
386 struct swtd_set_struct nowset;
\r
388 switch ( ioc_cmd ) {
\r
389 case IOCTL_WATCHDOG_ENABLE :
\r
390 if ( copy_from_user(&time, (unsigned long *)arg, sizeof(unsigned long)) )
\r
392 if ( time < WATCHDOG_MIN_TIME || time > WATCHDOG_MAX_TIME )
\r
394 spin_lock_irq(&swtd_lock);
\r
395 if ( !bswtd_timeout ) {
\r
396 // Switch to user mode watchdog.
\r
397 // When the kernel timer timeout, the system will reboot
\r
398 swtduserenabled = 1;
\r
400 #if defined(CONFIG_MACH_MOXA_IA261)||defined(CONFIG_MACH_MOXA_W406)
\r
403 if(timer_pending(&timer_swtd))
\r
404 mod_timer(&timer_swtd, jiffies + WATCHDOG_ACK_JIFFIES);
\r
406 add_timer(&timer_swtd);
\r
408 mod_timer(&timer_swtd, jiffies + WATCHDOG_ACK_JIFFIES(swtdtime));
\r
409 swtd_ack(swtdtime+WATCHDOG_DEFER_TIME);
\r
412 spin_unlock_irq(&swtd_lock);
\r
414 case IOCTL_WATCHDOG_DISABLE :
\r
415 spin_lock_irq(&swtd_lock);
\r
416 if ( swtduserenabled && !bswtd_timeout ) {
\r
417 #if defined(CONFIG_MACH_MOXA_IA261)||defined(CONFIG_MACH_MOXA_W406)
\r
420 del_timer(&timer_swtd);
\r
422 // Switch to kernel mode watchdog.
\r
423 // The kernel timer will acknowledge the HW watchdog
\r
425 mod_timer(&timer_swtd, jiffies + WATCHDOG_ACK_JIFFIES(swtdtime));
\r
427 swtdtime = DEFAULT_WATCHDOG_TIME;
\r
428 bswtd_timeout = 0; // reset the timeout flag
\r
429 swtduserenabled = 0;
\r
431 spin_unlock_irq(&swtd_lock);
\r
433 case IOCTL_WATCHDOG_GET_SETTING :
\r
434 nowset.mode = swtduserenabled;
\r
435 nowset.time = swtdtime;
\r
436 if ( copy_to_user((void *)arg, &nowset, sizeof(nowset)) )
\r
439 case IOCTL_WATCHDOG_ACK :
\r
440 spin_lock_irq(&swtd_lock);
\r
441 if ( swtduserenabled && !bswtd_timeout ) {
\r
442 #if defined(CONFIG_MACH_MOXA_IA261)||defined(CONFIG_MACH_MOXA_W406)
\r
445 mod_timer(&timer_swtd, jiffies + WATCHDOG_ACK_JIFFIES);
\r
447 // Switch to user mode watchdog.
\r
448 // When the kernel timer timeout, the system will reboot
\r
449 mod_timer(&timer_swtd, jiffies + WATCHDOG_ACK_JIFFIES(swtdtime));
\r
450 swtd_ack(swtdtime+WATCHDOG_DEFER_TIME);
\r
453 spin_unlock_irq(&swtd_lock);
\r
464 * @file: file handle to the watchdog
\r
465 * @buf: buffer to write (unused as data does not matter here
\r
466 * @count: count of bytes
\r
467 * @ppos: pointer to the position to write. No seeks allowed
\r
469 * A write to a watchdog device is defined as a keepalive signal. Any
\r
470 * write of data will do, as we we don't define content meaning.
\r
473 static ssize_t swtd_write(struct file *file, const char *buf, \
\r
474 size_t count, loff_t *ppos)
\r
482 /* In case it was set long ago */
\r
483 #if 0 // Comment out by Jared 2009-05-11, don't reset the expect_close flag
\r
486 for (i = 0; i != count; i++)
\r
489 if (get_user(c, buf + i))
\r
496 /* someone wrote to us, we should restart timer */
\r
497 spin_lock_irq(&swtd_lock);
\r
498 if ( !bswtd_timeout ) {
\r
499 // Switch to user mode watchdog.
\r
500 // When the kernel timer timeout, the system will reboot
\r
501 swtduserenabled = 1;
\r
502 #if defined(CONFIG_MACH_MOXA_IA261)||defined(CONFIG_MACH_MOXA_W406)
\r
504 mod_timer(&timer_swtd, jiffies + WATCHDOG_ACK_JIFFIES);
\r
507 mod_timer(&timer_swtd, jiffies + WATCHDOG_ACK_JIFFIES(swtdtime));
\r
508 swtd_ack(swtdtime+WATCHDOG_DEFER_TIME);
\r
511 spin_unlock_irq(&swtd_lock);
\r
517 static struct file_operations moxa_swtd_fops = {
\r
518 .owner=THIS_MODULE,
\r
522 .release=swtd_release,
\r
525 static struct miscdevice wdt_miscdev = {
\r
526 .minor = MOXA_WATCHDOG_MINOR,
\r
528 .fops = &moxa_swtd_fops,
\r
531 static int __init moxaswtd_init(void) {
\r
533 if ( misc_register(&wdt_miscdev)!=0 ) {
\r
534 printk("Moxa DA-681/662-LX WatchDog: Register misc fail !\n");
\r
535 goto moxa_swtd_init_err1;
\r
538 init_timer(&timer_swtd);
\r
539 timer_swtd.function=swtd_poll;
\r
540 #if defined(CONFIG_MACH_MOXA_IA261)||defined(CONFIG_MACH_MOXA_W406)
\r
541 timer_swtd.expires = jiffies + WATCHDOG_ACK_JIFFIES;
\r
543 timer_swtd.expires = jiffies + WATCHDOG_ACK_JIFFIES(swtdtime);
\r
544 add_timer(&timer_swtd);
\r
548 swtd_proc_file = create_proc_read_entry("driver/swtd", 0644, NULL, moxaswtd_proc_read, NULL);
\r
549 if ( !swtd_proc_file ) {
\r
550 printk("<1>moxaswtd_init:create_proc_read_entry() fail\n");
\r
551 goto moxa_swtd_init_err2;
\r
554 #if defined (DA68X)
\r
555 struct resource *base_res;
\r
557 base_res = request_region(SUPERIO_CONFIG_PORT, 2, "swtd");
\r
559 printk("<1>moxaswtd_init: can't get I/O address 0x%x\n", SUPERIO_CONFIG_PORT);
\r
560 goto moxa_swtd_init_err3;
\r
564 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
\r
565 init_waitqueue_head (&swtd_queue);
\r
566 kernel_thread(swtd_reboot, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGNAL);
\r
569 printk (KERN_INFO "initialized. (nowayout=%d)\n", nowayout);
\r
570 printk (KERN_INFO "initialized. (debug=%d)\n", debug);
\r
574 #if defined (DA68X)
\r
575 moxa_swtd_init_err3:
\r
576 remove_proc_entry("driver/swtd", NULL);
\r
578 moxa_swtd_init_err2:
\r
579 if(timer_pending(&timer_swtd))
\r
580 del_timer(&timer_swtd);
\r
581 misc_deregister(&wdt_miscdev);
\r
582 moxa_swtd_init_err1:
\r
586 static void __exit moxaswtd_exit(void) {
\r
588 #if defined (DA68X)
\r
589 release_region(SUPERIO_CONFIG_PORT, 2);
\r
590 superio_exit_config();
\r
592 remove_proc_entry("driver/swtd", NULL);
\r
594 if(timer_pending(&timer_swtd))
\r
595 del_timer(&timer_swtd);
\r
596 if ( swtduserenabled ) {
\r
597 swtduserenabled = 0;
\r
600 misc_deregister(&wdt_miscdev);
\r
603 module_init(moxaswtd_init);
\r
604 module_exit(moxaswtd_exit);
\r
606 MODULE_AUTHOR("Jared_Wu@moxa.com.tw");
\r
607 MODULE_LICENSE("GPL");
\r
608 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
\r
609 module_param(nowayout, int, 0);
\r
611 MODULE_PARM(nowayout, "i");
\r
613 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
\r
614 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
\r
615 module_param(debug, int, 0);
\r
617 MODULE_PARM(debug, "i");
\r
619 MODULE_PARM_DESC(debug, "print the debug message in this driver");
\r