提交 017cf080 编写于 作者: W Wim Van Sebroeck

watchdog: WatchDog Timer Driver Core - Add Magic Close feature

Add support for the Magic Close feature to the
WatchDog Timer Driver Core framework.
Signed-off-by: NAlan Cox <alan@lxorguk.ukuu.org.uk>
Signed-off-by: NWim Van Sebroeck <wim@iguana.be>
Acked-by: NArnd Bergmann <arnd@arndb.de>
Acked-by: NWolfram Sang <w.sang@pengutronix.de>
上级 014d694e
...@@ -127,6 +127,13 @@ bit-operations. The status bits that are defined are: ...@@ -127,6 +127,13 @@ bit-operations. The status bits that are defined are:
* WDOG_DEV_OPEN: this status bit shows whether or not the watchdog device * WDOG_DEV_OPEN: this status bit shows whether or not the watchdog device
was opened via /dev/watchdog. was opened via /dev/watchdog.
(This bit should only be used by the WatchDog Timer Driver Core). (This bit should only be used by the WatchDog Timer Driver Core).
* WDOG_ALLOW_RELEASE: this bit stores whether or not the magic close character
has been sent (so that we can support the magic close feature).
(This bit should only be used by the WatchDog Timer Driver Core).
Note: The WatchDog Timer Driver Core supports the magic close feature. To use
the magic close feature you must set the WDIOF_MAGICCLOSE bit in the options
field of the watchdog's info structure.
To get or set driver specific data the following two helper functions should be To get or set driver specific data the following two helper functions should be
used: used:
......
...@@ -122,6 +122,8 @@ static int watchdog_stop(struct watchdog_device *wddev) ...@@ -122,6 +122,8 @@ static int watchdog_stop(struct watchdog_device *wddev)
* @ppos: pointer to the file offset * @ppos: pointer to the file offset
* *
* A write to a watchdog device is defined as a keepalive ping. * A write to a watchdog device is defined as a keepalive ping.
* Writing the magic 'V' sequence allows the next close to turn
* off the watchdog.
*/ */
static ssize_t watchdog_write(struct file *file, const char __user *data, static ssize_t watchdog_write(struct file *file, const char __user *data,
...@@ -133,9 +135,18 @@ static ssize_t watchdog_write(struct file *file, const char __user *data, ...@@ -133,9 +135,18 @@ static ssize_t watchdog_write(struct file *file, const char __user *data,
if (len == 0) if (len == 0)
return 0; return 0;
/*
* Note: just in case someone wrote the magic character
* five months ago...
*/
clear_bit(WDOG_ALLOW_RELEASE, &wdd->status);
/* scan to see whether or not we got the magic character */
for (i = 0; i != len; i++) { for (i = 0; i != len; i++) {
if (get_user(c, data + i)) if (get_user(c, data + i))
return -EFAULT; return -EFAULT;
if (c == 'V')
set_bit(WDOG_ALLOW_RELEASE, &wdd->status);
} }
/* someone wrote to us, so we send the watchdog a keepalive ping */ /* someone wrote to us, so we send the watchdog a keepalive ping */
...@@ -259,14 +270,24 @@ static int watchdog_open(struct inode *inode, struct file *file) ...@@ -259,14 +270,24 @@ static int watchdog_open(struct inode *inode, struct file *file)
* @inode: inode of device * @inode: inode of device
* @file: file handle to device * @file: file handle to device
* *
* This is the code for when /dev/watchdog gets closed. * This is the code for when /dev/watchdog gets closed. We will only
* stop the watchdog when we have received the magic char, else the
* watchdog will keep running.
*/ */
static int watchdog_release(struct inode *inode, struct file *file) static int watchdog_release(struct inode *inode, struct file *file)
{ {
int err; int err = -EBUSY;
/*
* We only stop the watchdog if we received the magic character
* or if WDIOF_MAGICCLOSE is not set
*/
if (test_and_clear_bit(WDOG_ALLOW_RELEASE, &wdd->status) ||
!(wdd->info->options & WDIOF_MAGICCLOSE))
err = watchdog_stop(wdd);
err = watchdog_stop(wdd); /* If the watchdog was not stopped, send a keepalive ping */
if (err < 0) { if (err < 0) {
pr_crit("%s: watchdog did not stop!\n", wdd->info->identity); pr_crit("%s: watchdog did not stop!\n", wdd->info->identity);
watchdog_ping(wdd); watchdog_ping(wdd);
......
...@@ -112,6 +112,7 @@ struct watchdog_device { ...@@ -112,6 +112,7 @@ struct watchdog_device {
/* Bit numbers for status flags */ /* Bit numbers for status flags */
#define WDOG_ACTIVE 0 /* Is the watchdog running/active */ #define WDOG_ACTIVE 0 /* Is the watchdog running/active */
#define WDOG_DEV_OPEN 1 /* Opened via /dev/watchdog ? */ #define WDOG_DEV_OPEN 1 /* Opened via /dev/watchdog ? */
#define WDOG_ALLOW_RELEASE 2 /* Did we receive the magic char ? */
}; };
/* Use the following functions to manipulate watchdog driver specific data */ /* Use the following functions to manipulate watchdog driver specific data */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册