diff mbox series

[03/12] watchdog: Add a pretimeout governor to provide read data

Message ID 20190819203711.32599-4-minyard@acm.org (mailing list archive)
State Changes Requested
Headers show
Series [01/12] watchdog: NULL the default governor if it is unregistered | expand

Commit Message

Corey Minyard Aug. 19, 2019, 8:37 p.m. UTC
From: Corey Minyard <cminyard@mvista.com>

When a pretimeout occurs, provide a byte of data on the watchdog
device.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
---
 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 mbox series

Patch

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@mvista.com>");
+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