aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/watchdog.h
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2012-05-22 05:40:26 -0400
committerWim Van Sebroeck <wim@iguana.be>2012-05-30 01:55:31 -0400
commite907df32725204d6d2cb79b872529911c8eadcdf (patch)
tree3e90c58ea0ee9c2d77c1c4b0854dc046f6efb6a0 /include/linux/watchdog.h
parentf4e9c82f64b524314a390b13d3ba7d483f09258f (diff)
watchdog: Add support for dynamically allocated watchdog_device structs
If a driver's watchdog_device struct is part of a dynamically allocated struct (which it often will be), merely locking the module is not enough, even with a drivers module locked, the driver can be unbound from the device, examples: 1) The root user can unbind it through sysfd 2) The i2c bus master driver being unloaded for an i2c watchdog I will gladly admit that these are corner cases, but we still need to handle them correctly. The fix for this consists of 2 parts: 1) Add ref / unref operations, so that the driver can refcount the struct holding the watchdog_device struct and delay freeing it until any open filehandles referring to it are closed 2) Most driver operations will do IO on the device and the driver should not do any IO on the device after it has been unbound. Rather then letting each driver deal with this internally, it is better to ensure at the watchdog core level that no operations (other then unref) will get called after the driver has called watchdog_unregister_device(). This actually is the bulk of this patch. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
Diffstat (limited to 'include/linux/watchdog.h')
-rw-r--r--include/linux/watchdog.h5
1 files changed, 5 insertions, 0 deletions
diff --git a/include/linux/watchdog.h b/include/linux/watchdog.h
index da1dc1b52744..da70f0facd2b 100644
--- a/include/linux/watchdog.h
+++ b/include/linux/watchdog.h
@@ -71,6 +71,8 @@ struct watchdog_device;
71 * @status: The routine that shows the status of the watchdog device. 71 * @status: The routine that shows the status of the watchdog device.
72 * @set_timeout:The routine for setting the watchdog devices timeout value. 72 * @set_timeout:The routine for setting the watchdog devices timeout value.
73 * @get_timeleft:The routine that get's the time that's left before a reset. 73 * @get_timeleft:The routine that get's the time that's left before a reset.
74 * @ref: The ref operation for dyn. allocated watchdog_device structs
75 * @unref: The unref operation for dyn. allocated watchdog_device structs
74 * @ioctl: The routines that handles extra ioctl calls. 76 * @ioctl: The routines that handles extra ioctl calls.
75 * 77 *
76 * The watchdog_ops structure contains a list of low-level operations 78 * The watchdog_ops structure contains a list of low-level operations
@@ -88,6 +90,8 @@ struct watchdog_ops {
88 unsigned int (*status)(struct watchdog_device *); 90 unsigned int (*status)(struct watchdog_device *);
89 int (*set_timeout)(struct watchdog_device *, unsigned int); 91 int (*set_timeout)(struct watchdog_device *, unsigned int);
90 unsigned int (*get_timeleft)(struct watchdog_device *); 92 unsigned int (*get_timeleft)(struct watchdog_device *);
93 void (*ref)(struct watchdog_device *);
94 void (*unref)(struct watchdog_device *);
91 long (*ioctl)(struct watchdog_device *, unsigned int, unsigned long); 95 long (*ioctl)(struct watchdog_device *, unsigned int, unsigned long);
92}; 96};
93 97
@@ -135,6 +139,7 @@ struct watchdog_device {
135#define WDOG_DEV_OPEN 1 /* Opened via /dev/watchdog ? */ 139#define WDOG_DEV_OPEN 1 /* Opened via /dev/watchdog ? */
136#define WDOG_ALLOW_RELEASE 2 /* Did we receive the magic char ? */ 140#define WDOG_ALLOW_RELEASE 2 /* Did we receive the magic char ? */
137#define WDOG_NO_WAY_OUT 3 /* Is 'nowayout' feature set ? */ 141#define WDOG_NO_WAY_OUT 3 /* Is 'nowayout' feature set ? */
142#define WDOG_UNREGISTERED 4 /* Has the device been unregistered */
138}; 143};
139 144
140#ifdef CONFIG_WATCHDOG_NOWAYOUT 145#ifdef CONFIG_WATCHDOG_NOWAYOUT