2011-04-26 10:29:28

by Jimmy Chen (陳永達)

[permalink] [raw]
Subject: [PATCH 0/2] watchdog: add support to MOXA V2100 watchdog driver

From: Jimmy Chen <[email protected]>

MOXA V2100 platform watchdog driver

Signed-off-by: Jimmy Chen <[email protected]>
---
To unsubscribe from this list: send the line "unsubscribe
linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/


2011-04-26 10:32:33

by Jimmy Chen (陳永達)

[permalink] [raw]
Subject: RE: [PATCH 1/2] watchdog: add option in menu to support MOXA V2100 watchdog driver

From: Jimmy Chen <[email protected]>

Add selection and help in menu to support watchdog driver

Signed-off-by: Jimmy Chen <[email protected]>
---
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 1b0f98b..224dc9d 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -384,6 +384,18 @@ config ADVANTECH_WDT
feature. More information can be found at
<http://www.advantech.com.tw/products/>

+config MOXA_SWTD
+ tristate "MOXA V2100 WATCHDOG driver"
+ depends on X86
+ default n
+ help
+ If you say yes here you get support for the MOXA V2100 watchdog
+ driver.
+
+ This driver can also be built as a module. If so, the module
+ will be called moxa_swtd. More information can be found at
+ <http://www.moxa.com>
+
config ALIM1535_WDT
tristate "ALi M1535 PMU Watchdog Timer"
depends on X86 && PCI
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 3f8608b..df04622 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -65,6 +65,7 @@ obj-$(CONFIG_BFIN_WDT) += bfin_wdt.o
# X86 (i386 + ia64 + x86_64) Architecture
obj-$(CONFIG_ACQUIRE_WDT) += acquirewdt.o
obj-$(CONFIG_ADVANTECH_WDT) += advantechwdt.o
+obj-$(CONFIG_MOXA_SWTD) += moxa_swtd.o
obj-$(CONFIG_ALIM1535_WDT) += alim1535_wdt.o
obj-$(CONFIG_ALIM7101_WDT) += alim7101_wdt.o
obj-$(CONFIG_F71808E_WDT) += f71808e_wdt.o
diff --git a/drivers/watchdog/moxa_swtd.c b/drivers/watchdog/moxa_swtd.c
new file mode 100644
index 0000000..e69de29
diff --git a/drivers/watchdog/moxa_swtd.h b/drivers/watchdog/moxa_swtd.h
new file mode 100644
index 0000000..e69de29

2011-04-26 10:43:40

by Jimmy Chen (陳永達)

[permalink] [raw]
Subject: RE: [PATCH 2/2] watchdog: add real function on MOXA V2100 watchdog driver

From: Jimmy Chen <[email protected]>

Add real function for watchdog driver

Signed-off-by: Jimmy Chen <[email protected]>
---
diff --git a/drivers/watchdog/moxa_swtd.c b/drivers/watchdog/moxa_swtd.c
index e69de29..4905338 100644
--- a/drivers/watchdog/moxa_swtd.c
+++ b/drivers/watchdog/moxa_swtd.c
@@ -0,0 +1,471 @@
+/*
+ * serial driver for the MOXA V2100 platform.
+ *
+ * Copyright (c) MOXA Inc. All rights reserved.
+ * Jimmy Chen <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#define __KERNEL_SYSCALLS__
+#include <linux/proc_fs.h> /* Necessary because we use the proc fs */
+#include <linux/version.h>
+#include <linux/fs_struct.h>
+#include <linux/unistd.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/miscdevice.h>
+#include <linux/fcntl.h>
+#include <linux/init.h>
+#include <linux/poll.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/mm.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
+#include <asm/system.h>
+#include <linux/irq.h>
+#include <linux/bitops.h>
+#include <linux/reboot.h>
+#include <linux/types.h>
+#include <linux/notifier.h>
+#include <linux/workqueue.h>
+
+#include "moxa_swtd.h"
+#ifndef WATCHDOG_NOWAYOUT
+#define WATCHDOG_NOWAYOUT 0
+#endif
+
+#define MOXA_SWTD_VERSION "v0.1.0"
+
+static struct proc_dir_entry *swtd_proc_file;
+static int opencounts ;
+static int swtduserenabled ;
+static unsigned long swtdtime = DEFAULT_WATCHDOG_TIME;
+static struct timer_list timer_swtd;
+static int bswtd_timeout ;
+static int nowayout = WATCHDOG_NOWAYOUT;
+static int debug ;
+static char expect_close;
+static spinlock_t swtd_lock = SPIN_LOCK_UNLOCKED;
+
+static void swtd_ack(unsigned long swtd_ack_time)
+{
+ if (debug)
+ printk(KERN_DEBUG "swtd_ack: swtd_time=%lu\n", swtd_ack_time);
+ superio_enter_config();
+ superio_set_logic_device(7); /* logic device 7 */
+ superio_set_reg((swtd_ack_time/1000), 0x73); /* Reg:F6,30 sec */
+}
+
+static void swtd_enable(void)
+{
+ unsigned char reg_tmp;
+ if (debug)
+ printk(KERN_DEBUG "swtd_enable: swtdtime=%lu\n", swtdtime);
+ superio_enter_config();
+ superio_set_logic_device(7);
+ reg_tmp = superio_get_reg(0x72) | 0x10;
+ superio_set_reg(reg_tmp, 0x72);
+ superio_set_reg((swtdtime+WATCHDOG_DEFER_TIME)/1000, 0x73);
+}
+
+static void swtd_disable(void)
+{
+ if (debug)
+ printk(KERN_DEBUG "swtd_disable\n");
+ superio_enter_config();
+ superio_set_logic_device(7); /* logic device 8 */
+ superio_set_reg(0, 0x73); /* Reg:F6 counter register */
+}
+
+static void swtd_reboot(void *unused)
+{
+ char *argv[2], *envp[5];
+
+ if (in_interrupt())
+ return;
+ if (!current->fs->root.dentry)
+ return;
+ argv[0] = "/sbin/reboot";
+ argv[1] = 0;
+ envp[0] = "HOME=/";
+ envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
+ envp[2] = 0;
+ /* important: prefer sw approach before hw reset,
+ * make sure file system keep in safety
+ * circumstances.
+ */
+ call_usermodehelper(argv[0], argv, envp, 0);
+}
+
+DECLARE_WORK(rebootqueue, swtd_reboot);
+
+static void swtd_poll(unsigned long ignore)
+{
+ spin_lock(&swtd_lock);
+
+ if (swtduserenabled) {
+ swtd_ack(WATCHDOG_DEFER_TIME);
+ if (debug)
+ printk(KERN_DEBUG "swtd_poll: Now reboot the system.\n");
+ schedule_work(&rebootqueue);
+ bswtd_timeout = 1;
+ } else {
+ if (debug)
+ printk(KERN_DEBUG "swtd_poll: ack the hardware watchdog timer\n");
+
+ timer_swtd.expires = jiffies + WATCHDOG_ACK_JIFFIES(swtdtime);
+ add_timer(&timer_swtd);
+ swtd_ack(swtdtime + WATCHDOG_DEFER_TIME);
+ }
+ spin_unlock(&swtd_lock);
+}
+
+ssize_t moxaswtd_proc_read(char *buffer, char **buffer_location,
+ off_t offset, int buffer_length, int *eof, void *data)
+{
+ /* The number of bytes actually used */
+ int len = 0;
+
+ if (offset > 0) {
+ len = 0;
+ } else {
+ /* Fill the buffer and get its length */
+ len += sprintf(buffer+len,
+ "user enable\t: %d\n"
+ "ack time\t: %d msec\n"
+ "hardware watchdog counter\t: %d sec\n"
+ , swtduserenabled, (int)swtdtime,
+ superio_get_reg(0x73));
+ }
+ return len;
+}
+
+static int swtd_open(struct inode *inode, struct file *file)
+{
+
+ spin_lock_irq(&swtd_lock);
+ if (nowayout)
+ __module_get(THIS_MODULE);
+ bswtd_timeout = 0; /* reset the timeout flag */
+ opencounts++;
+ spin_unlock_irq(&swtd_lock);
+
+ return 0;
+}
+
+/* Kernel ack the watchdog timer and reset the state machine */
+static void swtd_release_timer(void)
+{
+ swtdtime = DEFAULT_WATCHDOG_TIME;
+ mod_timer(&timer_swtd, jiffies + WATCHDOG_ACK_JIFFIES(swtdtime));
+ swtd_ack(swtdtime+WATCHDOG_DEFER_TIME);
+ swtduserenabled = 0;
+ bswtd_timeout = 0; /* reset the timeout flag */
+
+}
+
+static int swtd_release(struct inode *inode, struct file *file)
+{
+ sigset_t *sigset = &current->signal->shared_pending.signal;
+
+ spin_lock_irq(&swtd_lock);
+
+ if (debug)
+ printk(KERN_DEBUG "swtd_release entry\n");
+ opencounts--;
+
+ if (opencounts <= 0) {
+ /*
+ * Shut off the timer.
+ */
+ if (expect_close == 42) {
+ printk(KERN_DEBUG "swtd_release: expect close\n");
+ if (!bswtd_timeout)
+ swtd_release_timer();
+ } else if (signal_pending(current)) {
+ if (debug)
+ printk(KERN_DEBUG "swtd_release[%d] has\
+ signal pending\n", __LINE__);
+ if (sigismember(sigset, SIGKILL) ||
+ sigismember(sigset, SIGINT) ||
+ sigismember(sigset, SIGTERM)) {
+ if (debug)
+ printk(KERN_DEBUG "swtd_release[%d]\
+ get SIGKILL/\
+ SIGINT/SIGTERM\
+ signal\n", __LINE__);
+ if (!bswtd_timeout)
+ swtd_release_timer();
+ }
+ } else if (current->signal->group_exit_code == SIGQUIT ||
+ current->signal->group_exit_code == SIGILL ||
+ current->signal->group_exit_code == SIGABRT ||
+ current->signal->group_exit_code == SIGFPE ||
+ current->signal->group_exit_code == SIGSEGV) {
+ if (debug)
+ printk(KERN_DEBUG "swtd_release[%d]\
+ got coredump\n", __LINE__);
+ } else { /* normal close the file handle */
+ if (debug)
+ printk(KERN_DEBUG "swtd_release_l1[%d]\
+ kernel ack the\
+ watchdog timer\n", __LINE__);
+ if (!bswtd_timeout)
+ swtd_release_timer();
+ }
+ expect_close = 0;
+ }
+ spin_unlock_irq(&swtd_lock);
+
+ return 0;
+}
+
+static int swtd_ioctl(struct inode *inode, struct file *file,
+ unsigned int ioc_cmd, unsigned long arg)
+{
+ unsigned long time;
+ struct swtd_set_struct nowset;
+
+ switch (ioc_cmd) {
+ case IOCTL_WATCHDOG_ENABLE:
+ if (copy_from_user(&time, (unsigned long *)arg,
+ sizeof(unsigned long)))
+ return -EFAULT;
+ if (time < WATCHDOG_MIN_TIME || time > WATCHDOG_MAX_TIME)
+ return -EINVAL;
+ spin_lock_irq(&swtd_lock);
+ if (!bswtd_timeout) {
+ /* Switch to user mode watchdog.
+ * When the kernel timer timeout, the system will reboot
+ */
+ swtduserenabled = 1;
+ swtdtime = time;
+ mod_timer(&timer_swtd, jiffies +
+ WATCHDOG_ACK_JIFFIES(swtdtime));
+ swtd_ack(swtdtime + WATCHDOG_DEFER_TIME);
+ }
+ spin_unlock_irq(&swtd_lock);
+ break;
+ case IOCTL_WATCHDOG_DISABLE:
+ spin_lock_irq(&swtd_lock);
+ if (swtduserenabled && !bswtd_timeout) {
+ /* Switch to kernel mode watchdog.
+ * The kernel timer will acknowledge the HW watchdog
+ */
+ swtd_enable();
+ mod_timer(&timer_swtd, jiffies +
+ WATCHDOG_ACK_JIFFIES(swtdtime));
+ swtdtime = DEFAULT_WATCHDOG_TIME;
+ bswtd_timeout = 0; /* reset the timeout flag */
+ swtduserenabled = 0;
+ }
+ spin_unlock_irq(&swtd_lock);
+ break;
+ case IOCTL_WATCHDOG_GET_SETTING:
+ nowset.mode = swtduserenabled;
+ nowset.time = swtdtime;
+ if (copy_to_user((void *)arg, &nowset, sizeof(nowset)))
+ return -EFAULT;
+ break;
+ case IOCTL_WATCHDOG_ACK:
+ spin_lock_irq(&swtd_lock);
+ if (swtduserenabled && !bswtd_timeout) {
+ /* Switch to user mode watchdog.
+ * When the kernel timer timeout, the system will reboot
+ */
+ mod_timer(&timer_swtd, jiffies +
+ WATCHDOG_ACK_JIFFIES(swtdtime));
+ swtd_ack(swtdtime + WATCHDOG_DEFER_TIME);
+ }
+ spin_unlock_irq(&swtd_lock);
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+/*
+ * swtd_write:
+ * @file: file handle to the watchdog
+ * @buf: buffer to write (unused as data does not matter here
+ * @count: count of bytes
+ * @ppos: pointer to the position to write. No seeks allowed
+ *
+ * A write to a watchdog device is defined as a keepalive signal. Any
+ * write of data will do, as we we don't define content meaning.
+ */
+
+static ssize_t swtd_write(struct file *file, const char *buf, \
+ size_t count, loff_t *ppos)
+{
+ if (count) {
+ if (!nowayout) {
+ size_t i;
+
+ /* In case it was set long ago */
+ for (i = 0; i != count; i++) {
+ char c;
+ if (get_user(c, buf + i))
+ return -EFAULT;
+ if (c == 'V')
+ expect_close = 42;
+ }
+ }
+
+ /* someone wrote to us, we should restart timer */
+ spin_lock_irq(&swtd_lock);
+ if (!bswtd_timeout) {
+ swtduserenabled = 1;
+ mod_timer(&timer_swtd, jiffies +
+ WATCHDOG_ACK_JIFFIES(swtdtime));
+ swtd_ack(swtdtime + WATCHDOG_DEFER_TIME);
+ }
+ spin_unlock_irq(&swtd_lock);
+ }
+ return count;
+}
+
+/* Panic hander */
+static int swtd_panic_handler(struct notifier_block *this,
+ unsigned long event, void *unused)
+{
+ unsigned char reg_tmp;
+ /* Avoid the software interrupt of swtd_ack */
+ spin_lock_bh(&swtd_lock);
+
+ if (debug) {
+ printk(KERN_DEBUG "swtd_panic_handler: enter\n");
+
+ /* Reset flash state */
+ printk(KERN_DEBUG "swtd_panic_handler: reset flash state\n");
+ /* Call hardware reboot */
+ printk(KERN_DEBUG "swtd_panic_handler: call hardware rebooot\n");
+ }
+ superio_enter_config();
+ superio_set_logic_device(7);
+ reg_tmp = superio_get_reg(0x72) | 0x10;
+ superio_set_reg(reg_tmp, 0x72);
+ superio_set_reg(1000/1000, 0x73);
+
+ return NOTIFY_OK;
+
+ spin_unlock_bh(&swtd_lock);
+}
+
+/* Structure for notification */
+static struct notifier_block swtd_panic_notifier = {
+ swtd_panic_handler,
+ NULL,
+ 150 /* priority: INT_MAX >= x >= 0 */
+};
+
+static const struct file_operations moxa_swtd_fops = {
+ .owner = THIS_MODULE,
+ .open = swtd_open,
+ .write = swtd_write,
+ .ioctl = swtd_ioctl,
+ .release = swtd_release,
+};
+
+static struct miscdevice wdt_miscdev = {
+ .minor = MOXA_WATCHDOG_MINOR,
+ .name = "swtd",
+ .fops = &moxa_swtd_fops,
+};
+
+static int __init moxaswtd_init(void)
+{
+ struct resource *base_res;
+
+ /* register misc */
+ if (misc_register(&wdt_miscdev) != 0) {
+ printk(KERN_ERR "Moxa V2100-LX WatchDog: Register misc fail !\n");
+ goto moxa_swtd_init_err1;
+ }
+
+ /* register panic hander */
+ atomic_notifier_chain_register(&panic_notifier_list,
+ &swtd_panic_notifier);
+
+ init_timer(&timer_swtd);
+ timer_swtd.function = swtd_poll;
+ timer_swtd.expires = jiffies + WATCHDOG_ACK_JIFFIES(swtdtime);
+ add_timer(&timer_swtd);
+ swtd_enable();
+
+ swtd_proc_file = create_proc_read_entry("driver/swtd", 0644,
+ NULL, moxaswtd_proc_read, NULL);
+ if (!swtd_proc_file) {
+ printk(KERN_ERR "moxaswtd_init:create_proc_read_entry() fail\n");
+ goto moxa_swtd_init_err2;
+ }
+
+ base_res = request_region(SUPERIO_CONFIG_PORT, 2, "swtd");
+ if (!base_res) {
+ printk(KERN_ERR "moxaswtd_init: can't get I/O\
+ address 0x%x\n", SUPERIO_CONFIG_PORT);
+ goto moxa_swtd_init_err3;
+ }
+
+ opencounts = 0;
+ swtduserenabled = 0;
+ bswtd_timeout = 0;
+
+ printk(KERN_INFO "Moxa V2100 Watchdog Driver, version "
+ MOXA_SWTD_VERSION", init OK\n");
+ printk(KERN_INFO "initialized. (nowayout=%d)\n", nowayout);
+ printk(KERN_INFO "initialized. (debug=%d)\n", debug);
+
+ return 0;
+
+moxa_swtd_init_err3:
+ remove_proc_entry("driver/swtd", NULL);
+moxa_swtd_init_err2:
+ if (timer_pending(&timer_swtd))
+ del_timer(&timer_swtd);
+ misc_deregister(&wdt_miscdev);
+moxa_swtd_init_err1:
+ return -ENOMEM;
+}
+
+static void __exit moxaswtd_exit(void)
+{
+ release_region(SUPERIO_CONFIG_PORT, 2);
+ superio_exit_config();
+ remove_proc_entry("driver/swtd", NULL);
+ swtd_disable();
+ if (timer_pending(&timer_swtd))
+ del_timer(&timer_swtd);
+ if (swtduserenabled) {
+ swtduserenabled = 0;
+ opencounts = 0;
+ }
+ misc_deregister(&wdt_miscdev);
+
+ atomic_notifier_chain_unregister(&panic_notifier_list,
+ &swtd_panic_notifier);
+
+}
+
+module_init(moxaswtd_init);
+module_exit(moxaswtd_exit);
+
+MODULE_AUTHOR("[email protected]");
+MODULE_LICENSE("GPL v2");
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be\
+ stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+module_param(debug, int, 0);
+MODULE_PARM_DESC(debug, "print the debug message in this driver");
diff --git a/drivers/watchdog/moxa_swtd.h b/drivers/watchdog/moxa_swtd.h
index e69de29..f026858 100644
--- a/drivers/watchdog/moxa_swtd.h
+++ b/drivers/watchdog/moxa_swtd.h
@@ -0,0 +1,73 @@
+/*
+ * serial driver for the MOXA V2100 platform.
+ *
+ * Copyright (c) MOXA Inc. All rights reserved.
+ * Jimmy Chen <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __X86__MOXAWDT__
+#define __X86__MOXAWDT__
+
+#define SUPERIO_CONFIG_PORT 0x2e
+
+#define DEFAULT_WATCHDOG_TIME (30UL*1000UL) /* 30 seconds */
+#define WATCHDOG_MIN_TIME (1UL*1000UL) /* 2 seconds */
+#define WATCHDOG_MAX_TIME (255UL*1000UL) /* 255 seconds */
+/* 50 msec, for watchdog timer polling */
+#define WATCHDOG_TOL_TIME (50UL)
+/* 5 sec, for hw watchdog timer rebooting */
+#define WATCHDOG_DEFER_TIME (15000UL)
+#define WATCHDOG_ACK_JIFFIES(x) (((x-WATCHDOG_TOL_TIME)*HZ/1000UL))
+
+#define MOXA_WATCHDOG_MINOR 255
+/* enable watch dog and set time (unint msec) */
+#define IOCTL_WATCHDOG_ENABLE 1
+/* disable watch dog, kernel do it */
+#define IOCTL_WATCHDOG_DISABLE 2
+/* get now setting about mode and time */
+#define IOCTL_WATCHDOG_GET_SETTING 3
+/* to ack watch dog */
+#define IOCTL_WATCHDOG_ACK 4
+
+struct swtd_set_struct {
+ int mode;
+ unsigned long time;
+};
+
+unsigned char superio_get_reg(u8 val)
+{
+ outb_p(val, SUPERIO_CONFIG_PORT);
+ val = inb(SUPERIO_CONFIG_PORT+1);
+ return val;
+}
+
+void superio_set_reg(u8 val, u8 index)
+{
+ outb_p(index, SUPERIO_CONFIG_PORT);
+ outb_p(val, (SUPERIO_CONFIG_PORT+1));
+}
+
+void superio_set_logic_device(u8 val)
+{
+ superio_set_reg(val, 0x07);
+}
+
+void superio_enter_config(void)
+{
+ outb_p(0x87, SUPERIO_CONFIG_PORT);
+ outb_p(0x01, SUPERIO_CONFIG_PORT);
+ outb_p(0x55, SUPERIO_CONFIG_PORT);
+ outb_p(0x55, SUPERIO_CONFIG_PORT);
+}
+
+void superio_exit_config(void)
+{
+ outb_p(0x02, SUPERIO_CONFIG_PORT);
+ outb_p(0x02, SUPERIO_CONFIG_PORT+1);
+}
+
+#endif /* __X86__MOXAWDT__ */

2011-04-26 10:51:24

by Alan

[permalink] [raw]
Subject: Re: [PATCH 2/2] watchdog: add real function on MOXA V2100 watchdog driver

> + superio_set_logic_device(7); /* logic device 7 */
> + superio_set_reg((swtd_ack_time/1000), 0x73); /* Reg:F6,30 sec */
> +}

If the time is configurable then you want to support that ideally.

> +static void swtd_reboot(void *unused)

No - the watchdog driver needs to deal with hardware reboot, randomly
trying to exec things which may not even be where you expect isn't safe.
User space watchdog daemons can manage their own shutdown just fine. The
watchdog is there to catch the actual hang case.


> + superio_set_reg(1000/1000, 0x73);
> +
> + return NOTIFY_OK;
> +
> + spin_unlock_bh(&swtd_lock);

Wrong order - your lock is left locked !


> +static struct miscdevice wdt_miscdev = {
> + .minor = MOXA_WATCHDOG_MINOR,
> + .name = "swtd",
> + .fops = &moxa_swtd_fops,
> +};

This should use the standard watchdog device


> +moxa_swtd_init_err3:
> + remove_proc_entry("driver/swtd", NULL);
> +moxa_swtd_init_err2:
> + if (timer_pending(&timer_swtd))
> + del_timer(&timer_swtd);

del_timer_sync to ensure it has run

You also need to sort out locking.

There is also no test to ensure the hardware is present so the driver
isn't safe to load on any PC hardware

Is there a magic signature to detect the hardware ?

Alan

2011-04-26 12:44:48

by Wim Van Sebroeck

[permalink] [raw]
Subject: Re: [PATCH 2/2] watchdog: add real function on MOXA V2100 watchdog driver

Hi Jimmy,

> From: Jimmy Chen <[email protected]>
>
> Add real function for watchdog driver
>
> Signed-off-by: Jimmy Chen <[email protected]>

My first remarks:
* This driver doesn't use /dev/watchdog.
* It doesn't follow the IOCTL API for watchdog devices
* It uses .ioctl and not an .unlocked_ioctl

Kind regards,
Wim.

2011-05-03 05:34:34

by Jimmy Chen (陳永達)

[permalink] [raw]
Subject: RE: [PATCH 0/2] watchdog: add support for MOXA V2100 watchdog driver

From: Jimmy Chen <[email protected]>

MOXA V2100 platform watchdog driver

Signed-off-by: Jimmy Chen <[email protected]>
---
To unsubscribe from this list: send the line "unsubscribe
linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/