1 From b4ffb1909843b28f3b1b60197d517b123b7a9b66 Mon Sep 17 00:00:00 2001
2 From: Guenter Roeck <linux@roeck-us.net>
3 Date: Fri, 25 Dec 2015 16:01:42 -0800
4 Subject: watchdog: Separate and maintain variables based on variable lifetime
6 All variables required by the watchdog core to manage a watchdog are
7 currently stored in struct watchdog_device. The lifetime of those
8 variables is determined by the watchdog driver. However, the lifetime
9 of variables used by the watchdog core differs from the lifetime of
10 struct watchdog_device. To remedy this situation, watchdog drivers
11 can implement ref and unref callbacks, to be used by the watchdog
12 core to lock struct watchdog_device in memory.
14 While this solves the immediate problem, it depends on watchdog drivers
15 to actually implement the ref/unref callbacks. This is error prone,
16 often not implemented in the first place, or not implemented correctly.
18 To solve the problem without requiring driver support, split the variables
19 in struct watchdog_device into two data structures - one for variables
20 associated with the watchdog driver, one for variables associated with
21 the watchdog core. With this approach, the watchdog core can keep track
22 of its variable lifetime and no longer depends on ref/unref callbacks
23 in the driver. As a side effect, some of the variables originally in
24 struct watchdog_driver are now private to the watchdog core and no longer
25 visible in watchdog drivers.
27 As a side effect of the changes made, an ioctl will now always fail
28 with -ENODEV after a watchdog device was unregistered with the character
29 device still open. Previously, it would only fail with -ENODEV in some
30 situations. Also, ioctl operations are now atomic from driver perspective.
31 With this change, it is now guaranteed that the driver will not unregister
32 a watchdog between a timeout change and the subsequent ping.
34 The 'ref' and 'unref' callbacks in struct watchdog_driver are no longer
35 used and marked as deprecated.
37 Signed-off-by: Guenter Roeck <linux@roeck-us.net>
38 Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
40 Documentation/watchdog/watchdog-kernel-api.txt | 45 +--
41 drivers/watchdog/watchdog_core.c | 2 -
42 drivers/watchdog/watchdog_dev.c | 383 +++++++++++++------------
43 include/linux/watchdog.h | 22 +-
44 4 files changed, 218 insertions(+), 234 deletions(-)
46 --- a/Documentation/watchdog/watchdog-kernel-api.txt
47 +++ b/Documentation/watchdog/watchdog-kernel-api.txt
48 @@ -44,7 +44,6 @@ The watchdog device structure looks like
50 struct watchdog_device {
54 struct device *parent;
55 const struct watchdog_info *info;
56 @@ -56,7 +55,7 @@ struct watchdog_device {
57 struct notifier_block reboot_nb;
58 struct notifier_block restart_nb;
61 + struct watchdog_core_data *wd_data;
63 struct list_head deferred;
65 @@ -66,8 +65,6 @@ It contains following fields:
66 /dev/watchdog0 cdev (dynamic major, minor 0) as well as the old
67 /dev/watchdog miscdev. The id is set automatically when calling
68 watchdog_register_device.
69 -* cdev: cdev for the dynamic /dev/watchdog<id> device nodes. This
70 - field is also populated by watchdog_register_device.
71 * dev: device under the watchdog class (created by watchdog_register_device).
72 * parent: set this to the parent device (or NULL) before calling
73 watchdog_register_device.
74 @@ -89,11 +86,10 @@ It contains following fields:
75 * driver_data: a pointer to the drivers private data of a watchdog device.
76 This data should only be accessed via the watchdog_set_drvdata and
77 watchdog_get_drvdata routines.
78 -* lock: Mutex for WatchDog Timer Driver Core internal use only.
79 +* wd_data: a pointer to watchdog core internal data.
80 * status: this field contains a number of status bits that give extra
81 information about the status of the device (Like: is the watchdog timer
82 - running/active, is the nowayout bit set, is the device opened via
83 - the /dev/watchdog interface or not, ...).
84 + running/active, or is the nowayout bit set).
85 * deferred: entry in wtd_deferred_reg_list which is used to
86 register early initialized watchdogs.
88 @@ -110,8 +106,8 @@ struct watchdog_ops {
89 int (*set_timeout)(struct watchdog_device *, unsigned int);
90 unsigned int (*get_timeleft)(struct watchdog_device *);
91 int (*restart)(struct watchdog_device *);
92 - void (*ref)(struct watchdog_device *);
93 - void (*unref)(struct watchdog_device *);
94 + void (*ref)(struct watchdog_device *) __deprecated;
95 + void (*unref)(struct watchdog_device *) __deprecated;
96 long (*ioctl)(struct watchdog_device *, unsigned int, unsigned long);
99 @@ -120,20 +116,6 @@ driver's operations. This module owner w
100 the watchdog is active. (This to avoid a system crash when you unload the
101 module and /dev/watchdog is still open).
103 -If the watchdog_device struct is dynamically allocated, just locking the module
104 -is not enough and a driver also needs to define the ref and unref operations to
105 -ensure the structure holding the watchdog_device does not go away.
107 -The simplest (and usually sufficient) implementation of this is to:
108 -1) Add a kref struct to the same structure which is holding the watchdog_device
109 -2) Define a release callback for the kref which frees the struct holding both
110 -3) Call kref_init on this kref *before* calling watchdog_register_device()
111 -4) Define a ref operation calling kref_get on this kref
112 -5) Define a unref operation calling kref_put on this kref
113 -6) When it is time to cleanup:
114 - * Do not kfree() the struct holding both, the last kref_put will do this!
115 - * *After* calling watchdog_unregister_device() call kref_put on the kref
117 Some operations are mandatory and some are optional. The mandatory operations
119 * start: this is a pointer to the routine that starts the watchdog timer
120 @@ -176,34 +158,21 @@ they are supported. These optional routi
121 * get_timeleft: this routines returns the time that's left before a reset.
122 * restart: this routine restarts the machine. It returns 0 on success or a
123 negative errno code for failure.
124 -* ref: the operation that calls kref_get on the kref of a dynamically
125 - allocated watchdog_device struct.
126 -* unref: the operation that calls kref_put on the kref of a dynamically
127 - allocated watchdog_device struct.
128 * ioctl: if this routine is present then it will be called first before we do
129 our own internal ioctl call handling. This routine should return -ENOIOCTLCMD
130 if a command is not supported. The parameters that are passed to the ioctl
131 call are: watchdog_device, cmd and arg.
133 +The 'ref' and 'unref' operations are no longer used and deprecated.
135 The status bits should (preferably) be set with the set_bit and clear_bit alike
136 bit-operations. The status bits that are defined are:
137 * WDOG_ACTIVE: this status bit indicates whether or not a watchdog timer device
138 is active or not. When the watchdog is active after booting, then you should
139 set this status bit (Note: when you register the watchdog timer device with
140 this bit set, then opening /dev/watchdog will skip the start operation)
141 -* WDOG_DEV_OPEN: this status bit shows whether or not the watchdog device
142 - was opened via /dev/watchdog.
143 - (This bit should only be used by the WatchDog Timer Driver Core).
144 -* WDOG_ALLOW_RELEASE: this bit stores whether or not the magic close character
145 - has been sent (so that we can support the magic close feature).
146 - (This bit should only be used by the WatchDog Timer Driver Core).
147 * WDOG_NO_WAY_OUT: this bit stores the nowayout setting for the watchdog.
148 If this bit is set then the watchdog timer will not be able to stop.
149 -* WDOG_UNREGISTERED: this bit gets set by the WatchDog Timer Driver Core
150 - after calling watchdog_unregister_device, and then checked before calling
151 - any watchdog_ops, so that you can be sure that no operations (other then
152 - unref) will get called after unregister, even if userspace still holds a
153 - reference to /dev/watchdog
155 To set the WDOG_NO_WAY_OUT status bit (before registering your watchdog
156 timer device) you can either:
157 --- a/drivers/watchdog/watchdog_core.c
158 +++ b/drivers/watchdog/watchdog_core.c
159 @@ -210,8 +210,6 @@ static int __watchdog_register_device(st
160 * corrupted in a later stage then we expect a kernel panic!
163 - mutex_init(&wdd->lock);
165 /* Use alias for watchdog id if possible */
167 ret = of_alias_get_id(wdd->parent->of_node, "watchdog");
168 --- a/drivers/watchdog/watchdog_dev.c
169 +++ b/drivers/watchdog/watchdog_dev.c
172 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
174 -#include <linux/module.h> /* For module stuff/... */
175 -#include <linux/types.h> /* For standard types (like size_t) */
176 +#include <linux/cdev.h> /* For character device */
177 #include <linux/errno.h> /* For the -ENODEV/... values */
178 -#include <linux/kernel.h> /* For printk/panic/... */
179 #include <linux/fs.h> /* For file operations */
180 -#include <linux/watchdog.h> /* For watchdog specific items */
181 -#include <linux/miscdevice.h> /* For handling misc devices */
182 #include <linux/init.h> /* For __init/__exit/... */
183 +#include <linux/kernel.h> /* For printk/panic/... */
184 +#include <linux/kref.h> /* For data references */
185 +#include <linux/miscdevice.h> /* For handling misc devices */
186 +#include <linux/module.h> /* For module stuff/... */
187 +#include <linux/mutex.h> /* For mutexes */
188 +#include <linux/slab.h> /* For memory functions */
189 +#include <linux/types.h> /* For standard types (like size_t) */
190 +#include <linux/watchdog.h> /* For watchdog specific items */
191 #include <linux/uaccess.h> /* For copy_to_user/put_user/... */
193 #include "watchdog_core.h"
196 + * struct watchdog_core_data - watchdog core internal data
197 + * @kref: Reference count.
198 + * @cdev: The watchdog's Character device.
199 + * @wdd: Pointer to watchdog device.
200 + * @lock: Lock for watchdog core.
201 + * @status: Watchdog core internal status bits.
203 +struct watchdog_core_data {
206 + struct watchdog_device *wdd;
208 + unsigned long status; /* Internal status bits */
209 +#define _WDOG_DEV_OPEN 0 /* Opened ? */
210 +#define _WDOG_ALLOW_RELEASE 1 /* Did we receive the magic char ? */
213 /* the dev_t structure to store the dynamically allocated watchdog devices */
214 static dev_t watchdog_devt;
215 -/* the watchdog device behind /dev/watchdog */
216 -static struct watchdog_device *old_wdd;
217 +/* Reference to watchdog device behind /dev/watchdog */
218 +static struct watchdog_core_data *old_wd_data;
221 * watchdog_ping: ping the watchdog.
222 * @wdd: the watchdog device to ping
224 + * The caller must hold wd_data->lock.
226 * If the watchdog has no own ping operation then it needs to be
227 * restarted via the start operation. This wrapper function does
229 @@ -61,25 +85,16 @@ static struct watchdog_device *old_wdd;
231 static int watchdog_ping(struct watchdog_device *wdd)
235 - mutex_lock(&wdd->lock);
237 - if (test_bit(WDOG_UNREGISTERED, &wdd->status)) {
243 if (!watchdog_active(wdd))
248 err = wdd->ops->ping(wdd); /* ping the watchdog */
250 err = wdd->ops->start(wdd); /* restart watchdog */
253 - mutex_unlock(&wdd->lock);
257 @@ -87,6 +102,8 @@ out_ping:
258 * watchdog_start: wrapper to start the watchdog.
259 * @wdd: the watchdog device to start
261 + * The caller must hold wd_data->lock.
263 * Start the watchdog if it is not active and mark it active.
264 * This function returns zero on success or a negative errno code for
266 @@ -94,24 +111,15 @@ out_ping:
268 static int watchdog_start(struct watchdog_device *wdd)
272 - mutex_lock(&wdd->lock);
274 - if (test_bit(WDOG_UNREGISTERED, &wdd->status)) {
280 if (watchdog_active(wdd))
284 err = wdd->ops->start(wdd);
286 set_bit(WDOG_ACTIVE, &wdd->status);
289 - mutex_unlock(&wdd->lock);
293 @@ -119,6 +127,8 @@ out_start:
294 * watchdog_stop: wrapper to stop the watchdog.
295 * @wdd: the watchdog device to stop
297 + * The caller must hold wd_data->lock.
299 * Stop the watchdog if it is still active and unmark it active.
300 * This function returns zero on success or a negative errno code for
302 @@ -127,93 +137,58 @@ out_start:
304 static int watchdog_stop(struct watchdog_device *wdd)
308 - mutex_lock(&wdd->lock);
310 - if (test_bit(WDOG_UNREGISTERED, &wdd->status)) {
316 if (!watchdog_active(wdd))
320 if (test_bit(WDOG_NO_WAY_OUT, &wdd->status)) {
321 dev_info(wdd->dev, "nowayout prevents watchdog being stopped!\n");
327 err = wdd->ops->stop(wdd);
329 clear_bit(WDOG_ACTIVE, &wdd->status);
332 - mutex_unlock(&wdd->lock);
337 * watchdog_get_status: wrapper to get the watchdog status
338 * @wdd: the watchdog device to get the status from
339 - * @status: the status of the watchdog device
341 + * The caller must hold wd_data->lock.
343 * Get the watchdog's status flags.
346 -static int watchdog_get_status(struct watchdog_device *wdd,
347 - unsigned int *status)
348 +static unsigned int watchdog_get_status(struct watchdog_device *wdd)
353 if (!wdd->ops->status)
354 - return -EOPNOTSUPP;
356 - mutex_lock(&wdd->lock);
358 - if (test_bit(WDOG_UNREGISTERED, &wdd->status)) {
363 - *status = wdd->ops->status(wdd);
367 - mutex_unlock(&wdd->lock);
369 + return wdd->ops->status(wdd);
373 * watchdog_set_timeout: set the watchdog timer timeout
374 * @wdd: the watchdog device to set the timeout for
375 * @timeout: timeout to set in seconds
377 + * The caller must hold wd_data->lock.
380 static int watchdog_set_timeout(struct watchdog_device *wdd,
381 unsigned int timeout)
385 if (!wdd->ops->set_timeout || !(wdd->info->options & WDIOF_SETTIMEOUT))
388 if (watchdog_timeout_invalid(wdd, timeout))
391 - mutex_lock(&wdd->lock);
393 - if (test_bit(WDOG_UNREGISTERED, &wdd->status)) {
398 - err = wdd->ops->set_timeout(wdd, timeout);
401 - mutex_unlock(&wdd->lock);
403 + return wdd->ops->set_timeout(wdd, timeout);
407 @@ -221,30 +196,22 @@ out_timeout:
408 * @wdd: the watchdog device to get the remaining time from
409 * @timeleft: the time that's left
411 + * The caller must hold wd_data->lock.
413 * Get the time before a watchdog will reboot (if not pinged).
416 static int watchdog_get_timeleft(struct watchdog_device *wdd,
417 unsigned int *timeleft)
423 if (!wdd->ops->get_timeleft)
426 - mutex_lock(&wdd->lock);
428 - if (test_bit(WDOG_UNREGISTERED, &wdd->status)) {
433 *timeleft = wdd->ops->get_timeleft(wdd);
436 - mutex_unlock(&wdd->lock);
441 #ifdef CONFIG_WATCHDOG_SYSFS
442 @@ -261,14 +228,14 @@ static ssize_t status_show(struct device
445 struct watchdog_device *wdd = dev_get_drvdata(dev);
448 + struct watchdog_core_data *wd_data = wdd->wd_data;
449 + unsigned int status;
451 - status = watchdog_get_status(wdd, &val);
453 - status = sprintf(buf, "%u\n", val);
454 + mutex_lock(&wd_data->lock);
455 + status = watchdog_get_status(wdd);
456 + mutex_unlock(&wd_data->lock);
459 + return sprintf(buf, "%u\n", status);
461 static DEVICE_ATTR_RO(status);
463 @@ -285,10 +252,13 @@ static ssize_t timeleft_show(struct devi
466 struct watchdog_device *wdd = dev_get_drvdata(dev);
467 + struct watchdog_core_data *wd_data = wdd->wd_data;
471 + mutex_lock(&wd_data->lock);
472 status = watchdog_get_timeleft(wdd, &val);
473 + mutex_unlock(&wd_data->lock);
475 status = sprintf(buf, "%u\n", val);
477 @@ -365,28 +335,17 @@ __ATTRIBUTE_GROUPS(wdt);
478 * @wdd: the watchdog device to do the ioctl on
479 * @cmd: watchdog command
480 * @arg: argument pointer
482 + * The caller must hold wd_data->lock.
485 static int watchdog_ioctl_op(struct watchdog_device *wdd, unsigned int cmd,
490 if (!wdd->ops->ioctl)
493 - mutex_lock(&wdd->lock);
495 - if (test_bit(WDOG_UNREGISTERED, &wdd->status)) {
500 - err = wdd->ops->ioctl(wdd, cmd, arg);
503 - mutex_unlock(&wdd->lock);
505 + return wdd->ops->ioctl(wdd, cmd, arg);
509 @@ -404,10 +363,11 @@ out_ioctl:
510 static ssize_t watchdog_write(struct file *file, const char __user *data,
511 size_t len, loff_t *ppos)
513 - struct watchdog_device *wdd = file->private_data;
514 + struct watchdog_core_data *wd_data = file->private_data;
515 + struct watchdog_device *wdd;
523 @@ -416,18 +376,25 @@ static ssize_t watchdog_write(struct fil
524 * Note: just in case someone wrote the magic character
527 - clear_bit(WDOG_ALLOW_RELEASE, &wdd->status);
528 + clear_bit(_WDOG_ALLOW_RELEASE, &wd_data->status);
530 /* scan to see whether or not we got the magic character */
531 for (i = 0; i != len; i++) {
532 if (get_user(c, data + i))
535 - set_bit(WDOG_ALLOW_RELEASE, &wdd->status);
536 + set_bit(_WDOG_ALLOW_RELEASE, &wd_data->status);
539 /* someone wrote to us, so we send the watchdog a keepalive ping */
540 - err = watchdog_ping(wdd);
543 + mutex_lock(&wd_data->lock);
544 + wdd = wd_data->wdd;
546 + err = watchdog_ping(wdd);
547 + mutex_unlock(&wd_data->lock);
552 @@ -447,71 +414,94 @@ static ssize_t watchdog_write(struct fil
553 static long watchdog_ioctl(struct file *file, unsigned int cmd,
556 - struct watchdog_device *wdd = file->private_data;
557 + struct watchdog_core_data *wd_data = file->private_data;
558 void __user *argp = (void __user *)arg;
559 + struct watchdog_device *wdd;
560 int __user *p = argp;
564 + mutex_lock(&wd_data->lock);
566 + wdd = wd_data->wdd;
572 err = watchdog_ioctl_op(wdd, cmd, arg);
573 if (err != -ENOIOCTLCMD)
578 case WDIOC_GETSUPPORT:
579 - return copy_to_user(argp, wdd->info,
580 + err = copy_to_user(argp, wdd->info,
581 sizeof(struct watchdog_info)) ? -EFAULT : 0;
583 case WDIOC_GETSTATUS:
584 - err = watchdog_get_status(wdd, &val);
585 - if (err == -ENODEV)
587 - return put_user(val, p);
588 + val = watchdog_get_status(wdd);
589 + err = put_user(val, p);
591 case WDIOC_GETBOOTSTATUS:
592 - return put_user(wdd->bootstatus, p);
593 + err = put_user(wdd->bootstatus, p);
595 case WDIOC_SETOPTIONS:
596 - if (get_user(val, p))
598 + if (get_user(val, p)) {
602 if (val & WDIOS_DISABLECARD) {
603 err = watchdog_stop(wdd);
608 - if (val & WDIOS_ENABLECARD) {
609 + if (val & WDIOS_ENABLECARD)
610 err = watchdog_start(wdd);
616 case WDIOC_KEEPALIVE:
617 - if (!(wdd->info->options & WDIOF_KEEPALIVEPING))
618 - return -EOPNOTSUPP;
619 - return watchdog_ping(wdd);
620 + if (!(wdd->info->options & WDIOF_KEEPALIVEPING)) {
624 + err = watchdog_ping(wdd);
626 case WDIOC_SETTIMEOUT:
627 - if (get_user(val, p))
629 + if (get_user(val, p)) {
633 err = watchdog_set_timeout(wdd, val);
637 /* If the watchdog is active then we send a keepalive ping
638 * to make sure that the watchdog keep's running (and if
639 * possible that it takes the new timeout) */
640 err = watchdog_ping(wdd);
645 case WDIOC_GETTIMEOUT:
646 /* timeout == 0 means that we don't know the timeout */
647 - if (wdd->timeout == 0)
648 - return -EOPNOTSUPP;
649 - return put_user(wdd->timeout, p);
650 + if (wdd->timeout == 0) {
654 + err = put_user(wdd->timeout, p);
656 case WDIOC_GETTIMELEFT:
657 err = watchdog_get_timeleft(wdd, &val);
660 - return put_user(val, p);
663 + err = put_user(val, p);
672 + mutex_unlock(&wd_data->lock);
677 @@ -526,45 +516,59 @@ static long watchdog_ioctl(struct file *
679 static int watchdog_open(struct inode *inode, struct file *file)
682 + struct watchdog_core_data *wd_data;
683 struct watchdog_device *wdd;
686 /* Get the corresponding watchdog device */
687 if (imajor(inode) == MISC_MAJOR)
689 + wd_data = old_wd_data;
691 - wdd = container_of(inode->i_cdev, struct watchdog_device, cdev);
692 + wd_data = container_of(inode->i_cdev, struct watchdog_core_data,
695 /* the watchdog is single open! */
696 - if (test_and_set_bit(WDOG_DEV_OPEN, &wdd->status))
697 + if (test_and_set_bit(_WDOG_DEV_OPEN, &wd_data->status))
700 + wdd = wd_data->wdd;
703 * If the /dev/watchdog device is open, we don't want the module
706 - if (!try_module_get(wdd->ops->owner))
708 + if (!try_module_get(wdd->ops->owner)) {
713 err = watchdog_start(wdd);
717 - file->private_data = wdd;
718 + file->private_data = wd_data;
721 - wdd->ops->ref(wdd);
722 + kref_get(&wd_data->kref);
724 /* dev/watchdog is a virtual (and thus non-seekable) filesystem */
725 return nonseekable_open(inode, file);
728 - module_put(wdd->ops->owner);
730 - clear_bit(WDOG_DEV_OPEN, &wdd->status);
731 + module_put(wd_data->wdd->ops->owner);
733 + clear_bit(_WDOG_DEV_OPEN, &wd_data->status);
737 +static void watchdog_core_data_release(struct kref *kref)
739 + struct watchdog_core_data *wd_data;
741 + wd_data = container_of(kref, struct watchdog_core_data, kref);
747 * watchdog_release: release the watchdog device.
748 * @inode: inode of device
749 @@ -577,9 +581,16 @@ out:
751 static int watchdog_release(struct inode *inode, struct file *file)
753 - struct watchdog_device *wdd = file->private_data;
754 + struct watchdog_core_data *wd_data = file->private_data;
755 + struct watchdog_device *wdd;
758 + mutex_lock(&wd_data->lock);
760 + wdd = wd_data->wdd;
765 * We only stop the watchdog if we received the magic character
766 * or if WDIOF_MAGICCLOSE is not set. If nowayout was set then
767 @@ -587,29 +598,24 @@ static int watchdog_release(struct inode
769 if (!test_bit(WDOG_ACTIVE, &wdd->status))
771 - else if (test_and_clear_bit(WDOG_ALLOW_RELEASE, &wdd->status) ||
772 + else if (test_and_clear_bit(_WDOG_ALLOW_RELEASE, &wd_data->status) ||
773 !(wdd->info->options & WDIOF_MAGICCLOSE))
774 err = watchdog_stop(wdd);
776 /* If the watchdog was not stopped, send a keepalive ping */
778 - mutex_lock(&wdd->lock);
779 - if (!test_bit(WDOG_UNREGISTERED, &wdd->status))
780 - dev_crit(wdd->dev, "watchdog did not stop!\n");
781 - mutex_unlock(&wdd->lock);
782 + dev_crit(wdd->dev, "watchdog did not stop!\n");
786 - /* Allow the owner module to be unloaded again */
787 - module_put(wdd->ops->owner);
789 /* make sure that /dev/watchdog can be re-opened */
790 - clear_bit(WDOG_DEV_OPEN, &wdd->status);
792 - /* Note wdd may be gone after this, do not use after this! */
793 - if (wdd->ops->unref)
794 - wdd->ops->unref(wdd);
795 + clear_bit(_WDOG_DEV_OPEN, &wd_data->status);
798 + mutex_unlock(&wd_data->lock);
799 + /* Allow the owner module to be unloaded again */
800 + module_put(wd_data->cdev.owner);
801 + kref_put(&wd_data->kref, watchdog_core_data_release);
805 @@ -639,10 +645,20 @@ static struct miscdevice watchdog_miscde
807 static int watchdog_cdev_register(struct watchdog_device *wdd, dev_t devno)
809 + struct watchdog_core_data *wd_data;
812 + wd_data = kzalloc(sizeof(struct watchdog_core_data), GFP_KERNEL);
815 + kref_init(&wd_data->kref);
816 + mutex_init(&wd_data->lock);
818 + wd_data->wdd = wdd;
819 + wdd->wd_data = wd_data;
823 + old_wd_data = wd_data;
824 watchdog_miscdev.parent = wdd->parent;
825 err = misc_register(&watchdog_miscdev);
827 @@ -651,23 +667,25 @@ static int watchdog_cdev_register(struct
829 pr_err("%s: a legacy watchdog module is probably present.\n",
830 wdd->info->identity);
832 + old_wd_data = NULL;
838 /* Fill in the data structures */
839 - cdev_init(&wdd->cdev, &watchdog_fops);
840 - wdd->cdev.owner = wdd->ops->owner;
841 + cdev_init(&wd_data->cdev, &watchdog_fops);
842 + wd_data->cdev.owner = wdd->ops->owner;
845 - err = cdev_add(&wdd->cdev, devno, 1);
846 + err = cdev_add(&wd_data->cdev, devno, 1);
848 pr_err("watchdog%d unable to add device %d:%d\n",
849 wdd->id, MAJOR(watchdog_devt), wdd->id);
851 misc_deregister(&watchdog_miscdev);
853 + old_wd_data = NULL;
854 + kref_put(&wd_data->kref, watchdog_core_data_release);
858 @@ -683,15 +701,20 @@ static int watchdog_cdev_register(struct
860 static void watchdog_cdev_unregister(struct watchdog_device *wdd)
862 - mutex_lock(&wdd->lock);
863 - set_bit(WDOG_UNREGISTERED, &wdd->status);
864 - mutex_unlock(&wdd->lock);
865 + struct watchdog_core_data *wd_data = wdd->wd_data;
867 - cdev_del(&wdd->cdev);
868 + cdev_del(&wd_data->cdev);
870 misc_deregister(&watchdog_miscdev);
872 + old_wd_data = NULL;
875 + mutex_lock(&wd_data->lock);
876 + wd_data->wdd = NULL;
877 + wdd->wd_data = NULL;
878 + mutex_unlock(&wd_data->lock);
880 + kref_put(&wd_data->kref, watchdog_core_data_release);
883 static struct class watchdog_class = {
884 @@ -742,9 +765,9 @@ int watchdog_dev_register(struct watchdo
886 void watchdog_dev_unregister(struct watchdog_device *wdd)
888 - watchdog_cdev_unregister(wdd);
889 device_destroy(&watchdog_class, wdd->dev->devt);
891 + watchdog_cdev_unregister(wdd);
895 --- a/include/linux/watchdog.h
896 +++ b/include/linux/watchdog.h
900 struct watchdog_device;
901 +struct watchdog_core_data;
903 /** struct watchdog_ops - The watchdog-devices operations
905 @@ -28,8 +29,6 @@ struct watchdog_device;
906 * @set_timeout:The routine for setting the watchdog devices timeout value (in seconds).
907 * @get_timeleft:The routine that gets the time left before a reset (in seconds).
908 * @restart: The routine for restarting the machine.
909 - * @ref: The ref operation for dyn. allocated watchdog_device structs
910 - * @unref: The unref operation for dyn. allocated watchdog_device structs
911 * @ioctl: The routines that handles extra ioctl calls.
913 * The watchdog_ops structure contains a list of low-level operations
914 @@ -48,15 +47,14 @@ struct watchdog_ops {
915 int (*set_timeout)(struct watchdog_device *, unsigned int);
916 unsigned int (*get_timeleft)(struct watchdog_device *);
917 int (*restart)(struct watchdog_device *);
918 - void (*ref)(struct watchdog_device *);
919 - void (*unref)(struct watchdog_device *);
920 + void (*ref)(struct watchdog_device *) __deprecated;
921 + void (*unref)(struct watchdog_device *) __deprecated;
922 long (*ioctl)(struct watchdog_device *, unsigned int, unsigned long);
925 /** struct watchdog_device - The structure that defines a watchdog device
927 * @id: The watchdog's ID. (Allocated by watchdog_register_device)
928 - * @cdev: The watchdog's Character device.
929 * @dev: The device for our watchdog
930 * @parent: The parent bus device
931 * @info: Pointer to a watchdog_info structure.
932 @@ -67,8 +65,8 @@ struct watchdog_ops {
933 * @max_timeout:The watchdog devices maximum timeout value (in seconds).
934 * @reboot_nb: The notifier block to stop watchdog on reboot.
935 * @restart_nb: The notifier block to register a restart function.
936 - * @driver-data:Pointer to the drivers private data.
937 - * @lock: Lock for watchdog core internal use only.
938 + * @driver_data:Pointer to the drivers private data.
939 + * @wd_data: Pointer to watchdog core internal data.
940 * @status: Field that contains the devices internal status bits.
941 * @deferred: entry in wtd_deferred_reg_list which is used to
942 * register early initialized watchdogs.
943 @@ -84,7 +82,6 @@ struct watchdog_ops {
945 struct watchdog_device {
949 struct device *parent;
950 const struct watchdog_info *info;
951 @@ -96,15 +93,12 @@ struct watchdog_device {
952 struct notifier_block reboot_nb;
953 struct notifier_block restart_nb;
956 + struct watchdog_core_data *wd_data;
957 unsigned long status;
958 /* Bit numbers for status flags */
959 #define WDOG_ACTIVE 0 /* Is the watchdog running/active */
960 -#define WDOG_DEV_OPEN 1 /* Opened via /dev/watchdog ? */
961 -#define WDOG_ALLOW_RELEASE 2 /* Did we receive the magic char ? */
962 -#define WDOG_NO_WAY_OUT 3 /* Is 'nowayout' feature set ? */
963 -#define WDOG_UNREGISTERED 4 /* Has the device been unregistered */
964 -#define WDOG_STOP_ON_REBOOT 5 /* Should be stopped on reboot */
965 +#define WDOG_NO_WAY_OUT 1 /* Is 'nowayout' feature set ? */
966 +#define WDOG_STOP_ON_REBOOT 2 /* Should be stopped on reboot */
967 struct list_head deferred;