diff options
-rw-r--r-- | Documentation/watchdog/watchdog-kernel-api.txt | 13 | ||||
-rw-r--r-- | drivers/watchdog/watchdog_dev.c | 18 | ||||
-rw-r--r-- | include/linux/watchdog.h | 1 |
3 files changed, 22 insertions, 10 deletions
diff --git a/Documentation/watchdog/watchdog-kernel-api.txt b/Documentation/watchdog/watchdog-kernel-api.txt index 41d552698ada..785fa0c996a4 100644 --- a/Documentation/watchdog/watchdog-kernel-api.txt +++ b/Documentation/watchdog/watchdog-kernel-api.txt | |||
@@ -59,8 +59,8 @@ It contains following fields: | |||
59 | watchdog_get_drvdata routines. | 59 | watchdog_get_drvdata routines. |
60 | * status: this field contains a number of status bits that give extra | 60 | * status: this field contains a number of status bits that give extra |
61 | information about the status of the device (Like: is the watchdog timer | 61 | information about the status of the device (Like: is the watchdog timer |
62 | running/active, is the device opened via the /dev/watchdog interface or not, | 62 | running/active, is the nowayout bit set, is the device opened via |
63 | ...). | 63 | the /dev/watchdog interface or not, ...). |
64 | 64 | ||
65 | The list of watchdog operations is defined as: | 65 | The list of watchdog operations is defined as: |
66 | 66 | ||
@@ -130,10 +130,13 @@ bit-operations. The status bits that are defined are: | |||
130 | * WDOG_ALLOW_RELEASE: this bit stores whether or not the magic close character | 130 | * WDOG_ALLOW_RELEASE: this bit stores whether or not the magic close character |
131 | has been sent (so that we can support the magic close feature). | 131 | has been sent (so that we can support the magic close feature). |
132 | (This bit should only be used by the WatchDog Timer Driver Core). | 132 | (This bit should only be used by the WatchDog Timer Driver Core). |
133 | * WDOG_NO_WAY_OUT: this bit stores the nowayout setting for the watchdog. | ||
134 | If this bit is set then the watchdog timer will not be able to stop. | ||
133 | 135 | ||
134 | Note: The WatchDog Timer Driver Core supports the magic close feature. To use | 136 | Note: The WatchDog Timer Driver Core supports the magic close feature and |
135 | the magic close feature you must set the WDIOF_MAGICCLOSE bit in the options | 137 | the nowayout feature. To use the magic close feature you must set the |
136 | field of the watchdog's info structure. | 138 | WDIOF_MAGICCLOSE bit in the options field of the watchdog's info structure. |
139 | The nowayout feature will overrule the magic close feature. | ||
137 | 140 | ||
138 | To get or set driver specific data the following two helper functions should be | 141 | To get or set driver specific data the following two helper functions should be |
139 | used: | 142 | used: |
diff --git a/drivers/watchdog/watchdog_dev.c b/drivers/watchdog/watchdog_dev.c index db40c6c79ef8..ac20f92347b1 100644 --- a/drivers/watchdog/watchdog_dev.c +++ b/drivers/watchdog/watchdog_dev.c | |||
@@ -98,11 +98,18 @@ static int watchdog_start(struct watchdog_device *wddev) | |||
98 | * Stop the watchdog if it is still active and unmark it active. | 98 | * Stop the watchdog if it is still active and unmark it active. |
99 | * This function returns zero on success or a negative errno code for | 99 | * This function returns zero on success or a negative errno code for |
100 | * failure. | 100 | * failure. |
101 | * If the 'nowayout' feature was set, the watchdog cannot be stopped. | ||
101 | */ | 102 | */ |
102 | 103 | ||
103 | static int watchdog_stop(struct watchdog_device *wddev) | 104 | static int watchdog_stop(struct watchdog_device *wddev) |
104 | { | 105 | { |
105 | int err; | 106 | int err = -EBUSY; |
107 | |||
108 | if (test_bit(WDOG_NO_WAY_OUT, &wdd->status)) { | ||
109 | pr_info("%s: nowayout prevents watchdog to be stopped!\n", | ||
110 | wdd->info->identity); | ||
111 | return err; | ||
112 | } | ||
106 | 113 | ||
107 | if (test_bit(WDOG_ACTIVE, &wdd->status)) { | 114 | if (test_bit(WDOG_ACTIVE, &wdd->status)) { |
108 | err = wddev->ops->stop(wddev); | 115 | err = wddev->ops->stop(wddev); |
@@ -123,7 +130,7 @@ static int watchdog_stop(struct watchdog_device *wddev) | |||
123 | * | 130 | * |
124 | * A write to a watchdog device is defined as a keepalive ping. | 131 | * A write to a watchdog device is defined as a keepalive ping. |
125 | * Writing the magic 'V' sequence allows the next close to turn | 132 | * Writing the magic 'V' sequence allows the next close to turn |
126 | * off the watchdog. | 133 | * off the watchdog (if 'nowayout' is not set). |
127 | */ | 134 | */ |
128 | 135 | ||
129 | static ssize_t watchdog_write(struct file *file, const char __user *data, | 136 | static ssize_t watchdog_write(struct file *file, const char __user *data, |
@@ -271,8 +278,8 @@ out: | |||
271 | * @file: file handle to device | 278 | * @file: file handle to device |
272 | * | 279 | * |
273 | * This is the code for when /dev/watchdog gets closed. We will only | 280 | * This is the code for when /dev/watchdog gets closed. We will only |
274 | * stop the watchdog when we have received the magic char, else the | 281 | * stop the watchdog when we have received the magic char (and nowayout |
275 | * watchdog will keep running. | 282 | * was not set), else the watchdog will keep running. |
276 | */ | 283 | */ |
277 | 284 | ||
278 | static int watchdog_release(struct inode *inode, struct file *file) | 285 | static int watchdog_release(struct inode *inode, struct file *file) |
@@ -281,7 +288,8 @@ static int watchdog_release(struct inode *inode, struct file *file) | |||
281 | 288 | ||
282 | /* | 289 | /* |
283 | * We only stop the watchdog if we received the magic character | 290 | * We only stop the watchdog if we received the magic character |
284 | * or if WDIOF_MAGICCLOSE is not set | 291 | * or if WDIOF_MAGICCLOSE is not set. If nowayout was set then |
292 | * watchdog_stop will fail. | ||
285 | */ | 293 | */ |
286 | if (test_and_clear_bit(WDOG_ALLOW_RELEASE, &wdd->status) || | 294 | if (test_and_clear_bit(WDOG_ALLOW_RELEASE, &wdd->status) || |
287 | !(wdd->info->options & WDIOF_MAGICCLOSE)) | 295 | !(wdd->info->options & WDIOF_MAGICCLOSE)) |
diff --git a/include/linux/watchdog.h b/include/linux/watchdog.h index e9881ca2452b..f719883c5141 100644 --- a/include/linux/watchdog.h +++ b/include/linux/watchdog.h | |||
@@ -113,6 +113,7 @@ struct watchdog_device { | |||
113 | #define WDOG_ACTIVE 0 /* Is the watchdog running/active */ | 113 | #define WDOG_ACTIVE 0 /* Is the watchdog running/active */ |
114 | #define WDOG_DEV_OPEN 1 /* Opened via /dev/watchdog ? */ | 114 | #define WDOG_DEV_OPEN 1 /* Opened via /dev/watchdog ? */ |
115 | #define WDOG_ALLOW_RELEASE 2 /* Did we receive the magic char ? */ | 115 | #define WDOG_ALLOW_RELEASE 2 /* Did we receive the magic char ? */ |
116 | #define WDOG_NO_WAY_OUT 3 /* Is 'nowayout' feature set ? */ | ||
116 | }; | 117 | }; |
117 | 118 | ||
118 | /* Use the following functions to manipulate watchdog driver specific data */ | 119 | /* Use the following functions to manipulate watchdog driver specific data */ |