static int watchdog_port;
static int mixcomwd_timer_alive;
static struct timer_list mixcomwd_timer = TIMER_INITIALIZER(NULL, 0, 0);
+static int expect_close = 0;
#ifdef CONFIG_WATCHDOG_NOWAYOUT
static int nowayout = 1;
static int mixcomwd_release(struct inode *inode, struct file *file)
{
-
- if (!nowayout) {
+ if (expect_close) {
if(mixcomwd_timer_alive) {
printk(KERN_ERR "mixcomwd: release called while internal timer alive");
return -EBUSY;
mixcomwd_timer.data=0;
mixcomwd_timer_alive=1;
add_timer(&mixcomwd_timer);
+ } else {
+ printk(KERN_CRIT "mixcomwd: WDT device closed unexpectedly. WDT will not stop!\n");
}
+
clear_bit(0,&mixcomwd_opened);
return 0;
}
if(len)
{
+ if (!nowayout) {
+ size_t i;
+
+ /* In case it was set long ago */
+ expect_close = 0;
+
+ for (i = 0; i != len; i++) {
+ char c;
+ if (get_user(c, data + i))
+ return -EFAULT;
+ if (c == 'V')
+ expect_close = 1;
+ }
+ }
mixcomwd_ping();
return 1;
}
unsigned int cmd, unsigned long arg)
{
int status;
- static struct watchdog_info ident = {
- WDIOF_KEEPALIVEPING, 1, "MixCOM watchdog"
+ static struct watchdog_info ident = {
+ .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
+ .firmware_version = 1,
+ .identity = "MixCOM watchdog"
};
switch(cmd)