summaryrefslogtreecommitdiffstats
path: root/Documentation/watchdog/watchdog-kernel-api.txt
diff options
context:
space:
mode:
Diffstat (limited to 'Documentation/watchdog/watchdog-kernel-api.txt')
-rw-r--r--Documentation/watchdog/watchdog-kernel-api.txt214
1 files changed, 0 insertions, 214 deletions
diff --git a/Documentation/watchdog/watchdog-kernel-api.txt b/Documentation/watchdog/watchdog-kernel-api.txt
deleted file mode 100644
index 086638f..0000000
--- a/Documentation/watchdog/watchdog-kernel-api.txt
+++ /dev/null
@@ -1,214 +0,0 @@
-The Linux WatchDog Timer Driver Core kernel API.
-===============================================
-Last reviewed: 22-May-2012
-
-Wim Van Sebroeck <wim@iguana.be>
-
-Introduction
-------------
-This document does not describe what a WatchDog Timer (WDT) Driver or Device is.
-It also does not describe the API which can be used by user space to communicate
-with a WatchDog Timer. If you want to know this then please read the following
-file: Documentation/watchdog/watchdog-api.txt .
-
-So what does this document describe? It describes the API that can be used by
-WatchDog Timer Drivers that want to use the WatchDog Timer Driver Core
-Framework. This framework provides all interfacing towards user space so that
-the same code does not have to be reproduced each time. This also means that
-a watchdog timer driver then only needs to provide the different routines
-(operations) that control the watchdog timer (WDT).
-
-The API
--------
-Each watchdog timer driver that wants to use the WatchDog Timer Driver Core
-must #include <linux/watchdog.h> (you would have to do this anyway when
-writing a watchdog device driver). This include file contains following
-register/unregister routines:
-
-extern int watchdog_register_device(struct watchdog_device *);
-extern void watchdog_unregister_device(struct watchdog_device *);
-
-The watchdog_register_device routine registers a watchdog timer device.
-The parameter of this routine is a pointer to a watchdog_device structure.
-This routine returns zero on success and a negative errno code for failure.
-
-The watchdog_unregister_device routine deregisters a registered watchdog timer
-device. The parameter of this routine is the pointer to the registered
-watchdog_device structure.
-
-The watchdog device structure looks like this:
-
-struct watchdog_device {
- int id;
- struct cdev cdev;
- struct device *dev;
- struct device *parent;
- const struct watchdog_info *info;
- const struct watchdog_ops *ops;
- unsigned int bootstatus;
- unsigned int timeout;
- unsigned int min_timeout;
- unsigned int max_timeout;
- void *driver_data;
- struct mutex lock;
- unsigned long status;
-};
-
-It contains following fields:
-* id: set by watchdog_register_device, id 0 is special. It has both a
- /dev/watchdog0 cdev (dynamic major, minor 0) as well as the old
- /dev/watchdog miscdev. The id is set automatically when calling
- watchdog_register_device.
-* cdev: cdev for the dynamic /dev/watchdog<id> device nodes. This
- field is also populated by watchdog_register_device.
-* dev: device under the watchdog class (created by watchdog_register_device).
-* parent: set this to the parent device (or NULL) before calling
- watchdog_register_device.
-* info: a pointer to a watchdog_info structure. This structure gives some
- additional information about the watchdog timer itself. (Like it's unique name)
-* ops: a pointer to the list of watchdog operations that the watchdog supports.
-* timeout: the watchdog timer's timeout value (in seconds).
-* min_timeout: the watchdog timer's minimum timeout value (in seconds).
-* max_timeout: the watchdog timer's maximum timeout value (in seconds).
-* bootstatus: status of the device after booting (reported with watchdog
- WDIOF_* status bits).
-* driver_data: a pointer to the drivers private data of a watchdog device.
- This data should only be accessed via the watchdog_set_drvdata and
- watchdog_get_drvdata routines.
-* lock: Mutex for WatchDog Timer Driver Core internal use only.
-* 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 nowayout bit set, is the device opened via
- the /dev/watchdog interface or not, ...).
-
-The list of watchdog operations is defined as:
-
-struct watchdog_ops {
- struct module *owner;
- /* mandatory operations */
- int (*start)(struct watchdog_device *);
- int (*stop)(struct watchdog_device *);
- /* optional operations */
- int (*ping)(struct watchdog_device *);
- unsigned int (*status)(struct watchdog_device *);
- int (*set_timeout)(struct watchdog_device *, unsigned int);
- unsigned int (*get_timeleft)(struct watchdog_device *);
- void (*ref)(struct watchdog_device *);
- void (*unref)(struct watchdog_device *);
- long (*ioctl)(struct watchdog_device *, unsigned int, unsigned long);
-};
-
-It is important that you first define the module owner of the watchdog timer
-driver's operations. This module owner will be used to lock the module when
-the watchdog is active. (This to avoid a system crash when you unload the
-module and /dev/watchdog is still open).
-
-If the watchdog_device struct is dynamically allocated, just locking the module
-is not enough and a driver also needs to define the ref and unref operations to
-ensure the structure holding the watchdog_device does not go away.
-
-The simplest (and usually sufficient) implementation of this is to:
-1) Add a kref struct to the same structure which is holding the watchdog_device
-2) Define a release callback for the kref which frees the struct holding both
-3) Call kref_init on this kref *before* calling watchdog_register_device()
-4) Define a ref operation calling kref_get on this kref
-5) Define a unref operation calling kref_put on this kref
-6) When it is time to cleanup:
- * Do not kfree() the struct holding both, the last kref_put will do this!
- * *After* calling watchdog_unregister_device() call kref_put on the kref
-
-Some operations are mandatory and some are optional. The mandatory operations
-are:
-* start: this is a pointer to the routine that starts the watchdog timer
- device.
- The routine needs a pointer to the watchdog timer device structure as a
- parameter. It returns zero on success or a negative errno code for failure.
-* stop: with this routine the watchdog timer device is being stopped.
- The routine needs a pointer to the watchdog timer device structure as a
- parameter. It returns zero on success or a negative errno code for failure.
- Some watchdog timer hardware can only be started and not be stopped. The
- driver supporting this hardware needs to make sure that a start and stop
- routine is being provided. This can be done by using a timer in the driver
- that regularly sends a keepalive ping to the watchdog timer hardware.
-
-Not all watchdog timer hardware supports the same functionality. That's why
-all other routines/operations are optional. They only need to be provided if
-they are supported. These optional routines/operations are:
-* ping: this is the routine that sends a keepalive ping to the watchdog timer
- hardware.
- The routine needs a pointer to the watchdog timer device structure as a
- parameter. It returns zero on success or a negative errno code for failure.
- Most hardware that does not support this as a separate function uses the
- start function to restart the watchdog timer hardware. And that's also what
- the watchdog timer driver core does: to send a keepalive ping to the watchdog
- timer hardware it will either use the ping operation (when available) or the
- start operation (when the ping operation is not available).
- (Note: the WDIOC_KEEPALIVE ioctl call will only be active when the
- WDIOF_KEEPALIVEPING bit has been set in the option field on the watchdog's
- info structure).
-* status: this routine checks the status of the watchdog timer device. The
- status of the device is reported with watchdog WDIOF_* status flags/bits.
-* set_timeout: this routine checks and changes the timeout of the watchdog
- timer device. It returns 0 on success, -EINVAL for "parameter out of range"
- and -EIO for "could not write value to the watchdog". On success this
- routine should set the timeout value of the watchdog_device to the
- achieved timeout value (which may be different from the requested one
- because the watchdog does not necessarily has a 1 second resolution).
- (Note: the WDIOF_SETTIMEOUT needs to be set in the options field of the
- watchdog's info structure).
-* get_timeleft: this routines returns the time that's left before a reset.
-* ref: the operation that calls kref_get on the kref of a dynamically
- allocated watchdog_device struct.
-* unref: the operation that calls kref_put on the kref of a dynamically
- allocated watchdog_device struct.
-* ioctl: if this routine is present then it will be called first before we do
- our own internal ioctl call handling. This routine should return -ENOIOCTLCMD
- if a command is not supported. The parameters that are passed to the ioctl
- call are: watchdog_device, cmd and arg.
-
-The status bits should (preferably) be set with the set_bit and clear_bit alike
-bit-operations. The status bits that are defined are:
-* WDOG_ACTIVE: this status bit indicates whether or not a watchdog timer device
- 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_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).
-* 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).
-* 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_UNREGISTERED: this bit gets set by the WatchDog Timer Driver Core
- after calling watchdog_unregister_device, and then checked before calling
- any watchdog_ops, so that you can be sure that no operations (other then
- unref) will get called after unregister, even if userspace still holds a
- reference to /dev/watchdog
-
- To set the WDOG_NO_WAY_OUT status bit (before registering your watchdog
- timer device) you can either:
- * set it statically in your watchdog_device struct with
- .status = WATCHDOG_NOWAYOUT_INIT_STATUS,
- (this will set the value the same as CONFIG_WATCHDOG_NOWAYOUT) or
- * use the following helper function:
- static inline void watchdog_set_nowayout(struct watchdog_device *wdd, int nowayout)
-
-Note: The WatchDog Timer Driver Core supports the magic close feature and
-the nowayout feature. To use the magic close feature you must set the
-WDIOF_MAGICCLOSE bit in the options field of the watchdog's info structure.
-The nowayout feature will overrule the magic close feature.
-
-To get or set driver specific data the following two helper functions should be
-used:
-
-static inline void watchdog_set_drvdata(struct watchdog_device *wdd, void *data)
-static inline void *watchdog_get_drvdata(struct watchdog_device *wdd)
-
-The watchdog_set_drvdata function allows you to add driver specific data. The
-arguments of this function are the watchdog device where you want to add the
-driver specific data to and a pointer to the data itself.
-
-The watchdog_get_drvdata function allows you to retrieve driver specific data.
-The argument of this function is the watchdog device where you want to retrieve
-data from. The function returns the pointer to the driver specific data.