Skip to content

Commit

Permalink
watchdog: Make stop function optional
Browse files Browse the repository at this point in the history
Not all hardware watchdogs can be stopped. The driver for
such watchdogs would typically only set the WATCHDOG_HW_RUNNING
flag in its stop function. Make the stop function optional and set
WATCHDOG_HW_RUNNING in the watchdog core if it is not provided.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
  • Loading branch information
groeck authored and Wim Van Sebroeck committed Mar 16, 2016
1 parent ee14288 commit d0684c8
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 10 deletions.
20 changes: 12 additions & 8 deletions Documentation/watchdog/watchdog-kernel-api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ It contains following fields:
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.
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.
Expand Down Expand Up @@ -134,17 +135,20 @@ are:
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.
If a watchdog can not be stopped, the watchdog driver must set the
WDOG_HW_RUNNING flag in its stop function to inform the watchdog core that
the watchdog is still running.

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
Expand Down
2 changes: 1 addition & 1 deletion drivers/watchdog/watchdog_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ static int __watchdog_register_device(struct watchdog_device *wdd)
return -EINVAL;

/* Mandatory operations need to be supported */
if (wdd->ops->start == NULL || wdd->ops->stop == NULL)
if (!wdd->ops->start || (!wdd->ops->stop && !wdd->max_hw_heartbeat_ms))
return -EINVAL;

watchdog_check_min_max_timeout(wdd);
Expand Down
6 changes: 5 additions & 1 deletion drivers/watchdog/watchdog_dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,11 @@ static int watchdog_stop(struct watchdog_device *wdd)
return -EBUSY;
}

err = wdd->ops->stop(wdd);
if (wdd->ops->stop)
err = wdd->ops->stop(wdd);
else
set_bit(WDOG_HW_RUNNING, &wdd->status);

if (err == 0) {
clear_bit(WDOG_ACTIVE, &wdd->status);
watchdog_update_worker(wdd);
Expand Down

0 comments on commit d0684c8

Please sign in to comment.