[RFC] [PATCH 8/10] Generic Watchdog Timer Driver

From: Wim Van Sebroeck
Date: Wed Feb 23 2011 - 15:44:45 EST


commit 5752d34c58c9b654c2fa753b94acc67602836420
Author: Wim Van Sebroeck <wim@xxxxxxxxx>
Date: Sun Jul 18 10:51:52 2010 +0000

watchdog: WatchDog Timer Driver Core - Part 8

Add support for the nowayout feature to the
WatchDog Timer Driver Core framework.
This feature prevents the watchdog timer from being
stopped.

Signed-off-by: Alan Cox <alan@xxxxxxxxxxxxxxxxxxx>
Signed-off-by: Wim Van Sebroeck <wim@xxxxxxxxx>

diff --git a/Documentation/watchdog/src/watchdog-with-timer-example.c b/Documentation/watchdog/src/watchdog-with-timer-example.c
index 158c61d..8ba5d5f 100644
--- a/Documentation/watchdog/src/watchdog-with-timer-example.c
+++ b/Documentation/watchdog/src/watchdog-with-timer-example.c
@@ -45,6 +45,11 @@ module_param(timeout, int, 0);
MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. "
"(default = " __MODULE_STRING(WDT_TIMEOUT) ")");

+static int nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started. "
+ "(default = " __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+
static struct watchdog_device wdt_dev;
static void wdt_timer_tick(unsigned long data);
static DEFINE_TIMER(timer, wdt_timer_tick, 0, 0);
@@ -152,6 +157,8 @@ static int __devinit wdt_probe(struct platform_device *pdev)

/* Set watchdog_device parameters */
wdt_dev.timeout = timeout;
+ if (nowayout)
+ set_bit(WDOG_NO_WAY_OUT, &wdt_dev.status);

/* Register the watchdog timer device */
res = register_watchdogdevice(&wdt_dev);
diff --git a/Documentation/watchdog/watchdog-kernel-api.txt b/Documentation/watchdog/watchdog-kernel-api.txt
index 036c30f..91c4299 100644
--- a/Documentation/watchdog/watchdog-kernel-api.txt
+++ b/Documentation/watchdog/watchdog-kernel-api.txt
@@ -57,8 +57,8 @@ It contains following fields:
WDIOF_* status bits).
* status: this field contains a number of status bits that give extra
information about the status of the device (Like: is the watchdog timer
- running/active, is the device opened via the /dev/watchdog interface or not,
- ...)
+ running/active, is the nowayout bit set, is the device opened via
+ the /dev/watchdog interface or not, ...)

The list of watchdog operations is defined as:

@@ -123,6 +123,8 @@ bit-operations. The status bit's that are defined are:
is active or not. When the watchdog is active after booting, then you should
set this status bit (Note: when you register the watchdog timer device with
this bit set, then opening /dev/watchdog will skip the start operation)
+* WDOG_NO_WAY_OUT: this bit stores the nowayout setting for the watchdog.
+ If this bit is set then the watchdog timer will not be able to stop.
* WDOG_DEV_OPEN: this status bit shows whether or not the watchdog device
was opened via /dev/watchdog.
(This bit should only be used by the WatchDog Timer Driver Core).
@@ -135,6 +137,6 @@ bit-operations. The status bit's that are defined are:
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 feauture. To use
-the magic close feauture you must set the WDIOF_MAGICCLOSE bit in the options
-field of the watchdog's info structure.
+Note: The WatchDog Timer Driver Core supports the nowayout feature and the
+magic close feauture. To use the magic close feauture you must set the
+WDIOF_MAGICCLOSE bit in the options field of the watchdog's info structure.
diff --git a/drivers/watchdog/core/watchdog_dev.c b/drivers/watchdog/core/watchdog_dev.c
index 4a99aeb..76be752 100644
--- a/drivers/watchdog/core/watchdog_dev.c
+++ b/drivers/watchdog/core/watchdog_dev.c
@@ -124,11 +124,15 @@ static int watchdog_start(struct watchdog_device *wddev)
* Stop the watchdog if it is still active and unmark it active.
* This function returns zero on success or a negative errno code for
* failure.
+ * If the 'nowayout' feature was set, the watchdog cannot be stopped.
*/

static int watchdog_stop(struct watchdog_device *wddev)
{
- int err;
+ int err = -1;
+
+ if (test_bit(WDOG_NO_WAY_OUT, &wdd->status))
+ return err;

if (test_bit(WDOG_ACTIVE, &wdd->status)) {
err = wddev->ops->stop(wddev);
@@ -149,7 +153,7 @@ static int watchdog_stop(struct watchdog_device *wddev)
*
* 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.
+ * off the watchdog (if 'nowayout' is not set).
*/

static ssize_t watchdog_write(struct file *file, const char __user *data,
diff --git a/include/linux/watchdog.h b/include/linux/watchdog.h
index 7dbb135..40ed78c 100644
--- a/include/linux/watchdog.h
+++ b/include/linux/watchdog.h
@@ -88,6 +88,7 @@ struct watchdog_device {
#define WDOG_ORPHAN 2 /* is the device module still loaded
* after closing /dev/watchdog */
#define WDOG_EXPECT_RELEASE 3 /* did we receive the magic char ? */
+#define WDOG_NO_WAY_OUT 4 /* is 'nowayout' feature set ? */
};

/* drivers/watchdog/core/watchdog_core.c */
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/