The Linux software watchdog is a timer that continuously counts down from a specified start value. Once it reaches zero a function named “watchdogfire” is called that logs the event and initiates a hard reset. A watchdog daemon is therefore needed to. The watchdog reset is a CPU-configurable device. It is programmed by software to generate a chip-wide reset after HWRTCWATCHDOG milliseconds. The watchdog generates this reset if software does not rewrite this register before this time elapses.
by Wolfram Sang <firstname.lastname@example.org>
Disable Watchdog Linux
Before the watchdog framework came into the kernel, every driver had toimplement the API on its own. Now, as the framework factored out the commoncomponents, those drivers can be lightened making it a user of the framework.This document shall guide you for this task. The necessary steps are describedas well as things to look out for.
Remove the file_operations struct¶
Old drivers define their own file_operations for actions like open(), write(),etc… These are now handled by the framework and just call the driver whenneeded. So, in general, the ‘file_operations’ struct and assorted functions cango. Only very few driver-specific details have to be moved to other functions.Here is a overview of the functions and probably needed actions:
open: Everything dealing with resource management (file-open checks, magicclose preparations) can simply go. Device specific stuff needs to go to thedriver specific start-function. Note that for some drivers, the start-functionalso serves as the ping-function. If that is the case and you need start/stopto be balanced (clocks!), you are better off refactoring a separate start-function.
close: Same hints as for open apply.
write: Can simply go, all defined behaviour is taken care of by the framework,i.e. ping on write and magic char (‘V’) handling.
ioctl: While the driver is allowed to have extensions to the IOCTL interface,the most common ones are handled by the framework, supported by some assistancefrom the driver:
Returns the mandatory watchdog_info struct from the driver
Needs the status-callback defined, otherwise returns 0
Needs the bootstatus member properly set. Make sure it is 0 if youdon’t have further support!
No preparations needed
If wanted, options in watchdog_info need to have WDIOF_KEEPALIVEPINGset
Options in watchdog_info need to have WDIOF_SETTIMEOUT setand a set_timeout-callback has to be defined. The core will alsodo limit-checking, if min_timeout and max_timeout in the watchdogdevice are set. All is optional.
No preparations needed
It needs get_timeleft() callback to be defined. Otherwise itwill return EOPNOTSUPP
Other IOCTLs can be served using the ioctl-callback. Note that this is mainlyintended for porting old drivers; new drivers should not invent private IOCTLs.Private IOCTLs are processed first. When the callback returns with-ENOIOCTLCMD, the IOCTLs of the framework will be tried, too. Any other erroris directly given to the user.
Check the functions for device-specific stuff and keep it for laterrefactoring. The rest can go.
Remove the miscdevice¶
Since the file_operations are gone now, you can also remove the ‘structmiscdevice’. The framework will create it on watchdog_dev_register() called bywatchdog_register_device():
Remove obsolete includes and defines¶
Because of the simplifications, a few defines are probably unused now. Removethem. Includes can be removed, too. For example:
Add the watchdog operations¶
All possible callbacks are defined in ‘struct watchdog_ops’. You can find itexplained in ‘watchdog-kernel-api.txt’ in this directory.
start() andowner must be set, the rest are optional. You will easily find correspondingfunctions in the old driver. Note that you will now get a pointer to thewatchdog_device as a parameter to these functions, so you probably have tochange the function header. Other changes are most likely not needed, becausehere simply happens the direct hardware access. If you have device-specificcode left from the above steps, it should be refactored into these callbacks.
Here is a simple example:
A typical function-header change looks like:
Add the watchdog device¶
Now we need to create a ‘struct watchdog_device’ and populate it with thenecessary information for the framework. The struct is also explained in detailin ‘watchdog-kernel-api.txt’ in this directory. We pass it the mandatorywatchdog_info struct and the newly created watchdog_ops. Often, old drivershave their own record-keeping for things like bootstatus and timeout usingstatic variables. Those have to be converted to use the members inwatchdog_device. Note that the timeout values are unsigned int. Some driversuse signed int, so this has to be converted, too.
Here is a simple example for a watchdog device:
Handle the ‘nowayout’ feature¶
A few drivers use nowayout statically, i.e. there is no module parameter for itand only CONFIG_WATCHDOG_NOWAYOUT determines if the feature is going to beused. This needs to be converted by initializing the status variable of thewatchdog_device like this:
Most drivers, however, also allow runtime configuration of nowayout, usuallyby adding a module parameter. The conversion for this would be something like:
The module parameter itself needs to stay, everything else related to nowayoutcan go, though. This will likely be some code in open(), close() or write().
Register the watchdog device¶
Replace misc_register(&miscdev) with watchdog_register_device(&watchdog_dev).Make sure the return value gets checked and the error message, if present,still fits. Also convert the unregister case:
Watchdog Linux Tutorial
Update the Kconfig-entry¶
The entry for the driver now needs to select WATCHDOG_CORE:
Create a patch and send it to upstream¶
Watchdog Linux Process
Make sure you understood Submitting patches: the essential guide to getting your code into the kernel and send your patch email@example.com. We are looking forward to it :)