From: Corey Minyard <cminyard@xxxxxxxxxx> When a pretimeout occurs, provide a byte of data on the watchdog device. Signed-off-by: Corey Minyard <cminyard@xxxxxxxxxx> --- drivers/watchdog/Kconfig | 16 +++++++++ drivers/watchdog/Makefile | 1 + drivers/watchdog/pretimeout_read_data.c | 47 +++++++++++++++++++++++++ drivers/watchdog/watchdog_pretimeout.h | 2 ++ 4 files changed, 66 insertions(+) create mode 100644 drivers/watchdog/pretimeout_read_data.c diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 8188963a405b..3578b7bc863c 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -105,6 +105,14 @@ config WATCHDOG_PRETIMEOUT_GOV_PANIC Panic watchdog pretimeout governor, on watchdog pretimeout event put the kernel into panic. +config WATCHDOG_PRETIMEOUT_GOV_READ_DATA + tristate "Read data watchdog pretimeout governor" + depends on WATCHDOG_CORE + default WATCHDOG_CORE + help + Read data watchdog pretimeout governor, on watchdog pretimeout + event provide a byte of data on the watchdog device. + choice prompt "Default Watchdog Pretimeout Governor" default WATCHDOG_PRETIMEOUT_DEFAULT_GOV_PANIC @@ -129,6 +137,14 @@ config WATCHDOG_PRETIMEOUT_DEFAULT_GOV_PANIC a watchdog pretimeout event happens, consider that a watchdog feeder is dead and reboot is unavoidable. +config WATCHDOG_PRETIMEOUT_DEFAULT_GOV_READ_DATA + bool "read_data" + depends on WATCHDOG_PRETIMEOUT_GOV_READ_DATA + help + Use read data watchdog pretimeout governor by default, if + a watchdog pretimeout event happens, provide a byte of read + data on the watchdog device. + endchoice endif # WATCHDOG_PRETIMEOUT_GOV diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 7caa920e7e60..9cfe4ad32dc4 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -12,6 +12,7 @@ watchdog-$(CONFIG_WATCHDOG_PRETIMEOUT_GOV) += watchdog_pretimeout.o obj-$(CONFIG_WATCHDOG_PRETIMEOUT_GOV_NOOP) += pretimeout_noop.o obj-$(CONFIG_WATCHDOG_PRETIMEOUT_GOV_PANIC) += pretimeout_panic.o +obj-$(CONFIG_WATCHDOG_PRETIMEOUT_GOV_READ_DATA) += pretimeout_read_data.o # Only one watchdog can succeed. We probe the ISA/PCI/USB based # watchdog-cards first, then the architecture specific watchdog diff --git a/drivers/watchdog/pretimeout_read_data.c b/drivers/watchdog/pretimeout_read_data.c new file mode 100644 index 000000000000..197e9d692044 --- /dev/null +++ b/drivers/watchdog/pretimeout_read_data.c @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2019 MontaVista Software, LLC + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/fs.h> +#include <linux/watchdog.h> + +#include "watchdog_pretimeout.h" + +/** + * pretimeout_read_data - Cause a read to return on the watchdog device. + * @wdd - watchdog_device + */ +static void pretimeout_read_data(struct watchdog_device *wdd) +{ + unsigned long flags; + + spin_lock_irqsave(&wdd->readlock, flags); + wdd->data_to_read = 1; + wake_up_interruptible(&wdd->read_q); + kill_fasync(&wdd->fasync_q, SIGIO, POLL_IN); + spin_unlock_irqrestore(&wdd->readlock, flags); +} + +static struct watchdog_governor watchdog_gov_read_data = { + .name = "read_data", + .pretimeout = pretimeout_read_data, +}; + +static int __init watchdog_gov_read_data_register(void) +{ + return watchdog_register_governor(&watchdog_gov_read_data); +} + +static void __exit watchdog_gov_read_data_unregister(void) +{ + watchdog_unregister_governor(&watchdog_gov_read_data); +} +module_init(watchdog_gov_read_data_register); +module_exit(watchdog_gov_read_data_unregister); + +MODULE_AUTHOR("Corey Minyard <cminyard@xxxxxxxxxx>"); +MODULE_DESCRIPTION("Read data watchdog pretimeout governor"); +MODULE_LICENSE("GPL"); diff --git a/drivers/watchdog/watchdog_pretimeout.h b/drivers/watchdog/watchdog_pretimeout.h index a3f1abc68839..819517ed0138 100644 --- a/drivers/watchdog/watchdog_pretimeout.h +++ b/drivers/watchdog/watchdog_pretimeout.h @@ -28,6 +28,8 @@ int watchdog_pretimeout_governor_set(struct watchdog_device *wdd, #define WATCHDOG_PRETIMEOUT_DEFAULT_GOV "noop" #elif IS_ENABLED(CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_PANIC) #define WATCHDOG_PRETIMEOUT_DEFAULT_GOV "panic" +#elif IS_ENABLED(CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_READ_DATA) +#define WATCHDOG_PRETIMEOUT_DEFAULT_GOV "read_data" #endif #else -- 2.17.1