diff options
Diffstat (limited to 'Documentation/watchdog/watchdog-kernel-api.txt')
-rw-r--r-- | Documentation/watchdog/watchdog-kernel-api.txt | 305 |
1 files changed, 0 insertions, 305 deletions
diff --git a/Documentation/watchdog/watchdog-kernel-api.txt b/Documentation/watchdog/watchdog-kernel-api.txt deleted file mode 100644 index 3a91ef5af044..000000000000 --- a/Documentation/watchdog/watchdog-kernel-api.txt +++ /dev/null @@ -1,305 +0,0 @@ -The Linux WatchDog Timer Driver Core kernel API. -=============================================== -Last reviewed: 12-Feb-2013 - -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 subsystem includes an registration deferral mechanism, -which allows you to register an watchdog as early as you wish during -the boot process. - -The watchdog device structure looks like this: - -struct watchdog_device { - int id; - struct device *parent; - const struct attribute_group **groups; - const struct watchdog_info *info; - const struct watchdog_ops *ops; - const struct watchdog_governor *gov; - unsigned int bootstatus; - unsigned int timeout; - unsigned int pretimeout; - unsigned int min_timeout; - unsigned int max_timeout; - unsigned int min_hw_heartbeat_ms; - unsigned int max_hw_heartbeat_ms; - struct notifier_block reboot_nb; - struct notifier_block restart_nb; - void *driver_data; - struct watchdog_core_data *wd_data; - unsigned long status; - struct list_head deferred; -}; - -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. -* parent: set this to the parent device (or NULL) before calling - watchdog_register_device. -* groups: List of sysfs attribute groups to create when creating the watchdog - 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. -* gov: a pointer to the assigned watchdog device pretimeout governor or NULL. -* timeout: the watchdog timer's timeout value (in seconds). - This is the time after which the system will reboot if user space does - not send a heartbeat request if WDOG_ACTIVE is set. -* pretimeout: the watchdog timer's pretimeout value (in seconds). -* min_timeout: the watchdog timer's minimum timeout value (in seconds). - If set, the minimum configurable value for 'timeout'. -* max_timeout: the watchdog timer's maximum timeout value (in seconds), - as seen from userspace. If set, the maximum configurable value for - 'timeout'. Not used if max_hw_heartbeat_ms is non-zero. -* min_hw_heartbeat_ms: Hardware limit for minimum time between heartbeats, - in milli-seconds. This value is normally 0; it should only be provided - if the hardware can not tolerate lower intervals between heartbeats. -* max_hw_heartbeat_ms: Maximum hardware heartbeat, in milli-seconds. - If set, the infrastructure will send heartbeats to the watchdog driver - if 'timeout' is larger than max_hw_heartbeat_ms, unless WDOG_ACTIVE - is set and userspace failed to send a heartbeat for at least 'timeout' - seconds. max_hw_heartbeat_ms must be set if a driver does not implement - the stop function. -* reboot_nb: notifier block that is registered for reboot notifications, for - internal use only. If the driver calls watchdog_stop_on_reboot, watchdog core - will stop the watchdog on such notifications. -* restart_nb: notifier block that is registered for machine restart, for - internal use only. If a watchdog is capable of restarting the machine, it - should define ops->restart. Priority can be changed through - watchdog_set_restart_priority. -* 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. -* wd_data: a pointer to watchdog core internal data. -* 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, or is the nowayout bit set). -* deferred: entry in wtd_deferred_reg_list which is used to - register early initialized watchdogs. - -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); - int (*set_pretimeout)(struct watchdog_device *, unsigned int); - unsigned int (*get_timeleft)(struct watchdog_device *); - int (*restart)(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). - -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. - -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: -* 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. A - driver supporting such hardware does not have to implement the stop routine. - If a driver has no stop function, the watchdog core will set WDOG_HW_RUNNING - and start calling the driver's keepalive pings function after the watchdog - device is closed. - If a watchdog driver does not implement the stop function, it must set - max_hw_heartbeat_ms. -* 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. - WDIOF_MAGICCLOSE and WDIOF_KEEPALIVEPING are reported by the watchdog core; - it is not necessary to report those bits from the driver. Also, if no status - function is provided by the driver, the watchdog core reports the status bits - provided in the bootstatus variable of struct watchdog_device. -* 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 have a 1 second resolution). - Drivers implementing max_hw_heartbeat_ms set the hardware watchdog heartbeat - to the minimum of timeout and max_hw_heartbeat_ms. Those drivers set the - timeout value of the watchdog_device either to the requested timeout value - (if it is larger than max_hw_heartbeat_ms), or to the achieved timeout value. - (Note: the WDIOF_SETTIMEOUT needs to be set in the options field of the - watchdog's info structure). - If the watchdog driver does not have to perform any action but setting the - watchdog_device.timeout, this callback can be omitted. - If set_timeout is not provided but, WDIOF_SETTIMEOUT is set, the watchdog - infrastructure updates the timeout value of the watchdog_device internally - to the requested value. - If the pretimeout feature is used (WDIOF_PRETIMEOUT), then set_timeout must - also take care of checking if pretimeout is still valid and set up the timer - accordingly. This can't be done in the core without races, so it is the - duty of the driver. -* set_pretimeout: this routine checks and changes the pretimeout value of - the watchdog. It is optional because not all watchdogs support pretimeout - notification. The timeout value is not an absolute time, but the number of - seconds before the actual timeout would happen. It returns 0 on success, - -EINVAL for "parameter out of range" and -EIO for "could not write value to - the watchdog". A value of 0 disables pretimeout notification. - (Note: the WDIOF_PRETIMEOUT needs to be set in the options field of the - watchdog's info structure). - If the watchdog driver does not have to perform any action but setting the - watchdog_device.pretimeout, this callback can be omitted. That means if - set_pretimeout is not provided but WDIOF_PRETIMEOUT is set, the watchdog - infrastructure updates the pretimeout value of the watchdog_device internally - to the requested value. -* get_timeleft: this routines returns the time that's left before a reset. -* restart: this routine restarts the machine. It returns 0 on success or a - negative errno code for failure. -* 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 from user perspective. User space is expected to send - heartbeat requests to the driver while this flag is set. -* 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_HW_RUNNING: Set by the watchdog driver if the hardware watchdog is - running. The bit must be set if the watchdog timer hardware can not be - stopped. The bit may also be set if the watchdog timer is running after - booting, before the watchdog device is opened. If set, the watchdog - infrastructure will send keepalives to the watchdog hardware while - WDOG_ACTIVE is not set. - Note: when you register the watchdog timer device with this bit set, - then opening /dev/watchdog will skip the start operation but send a keepalive - request instead. - - 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. - -To initialize the timeout field, the following function can be used: - -extern int watchdog_init_timeout(struct watchdog_device *wdd, - unsigned int timeout_parm, struct device *dev); - -The watchdog_init_timeout function allows you to initialize the timeout field -using the module timeout parameter or by retrieving the timeout-sec property from -the device tree (if the module timeout parameter is invalid). Best practice is -to set the default timeout value as timeout value in the watchdog_device and -then use this function to set the user "preferred" timeout value. -This routine returns zero on success and a negative errno code for failure. - -To disable the watchdog on reboot, the user must call the following helper: - -static inline void watchdog_stop_on_reboot(struct watchdog_device *wdd); - -To disable the watchdog when unregistering the watchdog, the user must call -the following helper. Note that this will only stop the watchdog if the -nowayout flag is not set. - -static inline void watchdog_stop_on_unregister(struct watchdog_device *wdd); - -To change the priority of the restart handler the following helper should be -used: - -void watchdog_set_restart_priority(struct watchdog_device *wdd, int priority); - -User should follow the following guidelines for setting the priority: -* 0: should be called in last resort, has limited restart capabilities -* 128: default restart handler, use if no other handler is expected to be - available, and/or if restart is sufficient to restart the entire system -* 255: highest priority, will preempt all other restart handlers - -To raise a pretimeout notification, the following function should be used: - -void watchdog_notify_pretimeout(struct watchdog_device *wdd) - -The function can be called in the interrupt context. If watchdog pretimeout -governor framework (kbuild CONFIG_WATCHDOG_PRETIMEOUT_GOV symbol) is enabled, -an action is taken by a preconfigured pretimeout governor preassigned to -the watchdog device. If watchdog pretimeout governor framework is not -enabled, watchdog_notify_pretimeout() prints a notification message to -the kernel log buffer. |