diff mbox series

[U-Boot] cmd: add wdt command

Message ID 20190406002402.19039-1-michael@walle.cc
State Accepted
Commit 82a00be35382b537cbe1338ade00252242383a90
Delegated to: Stefan Roese
Headers show
Series [U-Boot] cmd: add wdt command | expand

Commit Message

Michael Walle April 6, 2019, 12:24 a.m. UTC
Add a command to control the watchdog devices. This is useful if the
watchdog is rather long running (eg. seconds) and it should be
controlled by scripts. It is also handy during debugging.

Signed-off-by: Michael Walle <michael@walle.cc>
---
 cmd/Kconfig  |   6 +++
 cmd/Makefile |   1 +
 cmd/wdt.c    | 174 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 181 insertions(+)
 create mode 100644 cmd/wdt.c

Comments

Stefan Roese April 11, 2019, 12:12 p.m. UTC | #1
On 06.04.19 02:24, Michael Walle wrote:
> Add a command to control the watchdog devices. This is useful if the
> watchdog is rather long running (eg. seconds) and it should be
> controlled by scripts. It is also handy during debugging.
> 
> Signed-off-by: Michael Walle <michael@walle.cc>

Applied to u-boot-marvell/master.

Thanks,
Stefan
diff mbox series

Patch

diff --git a/cmd/Kconfig b/cmd/Kconfig
index 0b07b3b9d7..2bdbfcb3d0 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -1101,6 +1101,12 @@  config CMD_VIRTIO
 	help
 	  VirtIO block device support
 
+config CMD_WDT
+	bool "wdt"
+	depends on WDT
+	help
+	  This provides commands to control the watchdog timer devices.
+
 config CMD_AXI
 	bool "axi"
 	depends on AXI
diff --git a/cmd/Makefile b/cmd/Makefile
index acb85f49fb..6b1c6b094e 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -142,6 +142,7 @@  obj-$(CONFIG_CMD_UBIFS) += ubifs.o
 obj-$(CONFIG_CMD_UNIVERSE) += universe.o
 obj-$(CONFIG_CMD_UNZIP) += unzip.o
 obj-$(CONFIG_CMD_VIRTIO) += virtio.o
+obj-$(CONFIG_CMD_WDT) += wdt.o
 obj-$(CONFIG_CMD_LZMADEC) += lzmadec.o
 
 obj-$(CONFIG_CMD_USB) += usb.o disk.o
diff --git a/cmd/wdt.c b/cmd/wdt.c
new file mode 100644
index 0000000000..647d9899b4
--- /dev/null
+++ b/cmd/wdt.c
@@ -0,0 +1,174 @@ 
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Watchdog commands
+ *
+ * Copyright (c) 2019 Michael Walle <michael@walle.cc>
+ */
+
+#include <common.h>
+#include <command.h>
+#include <dm.h>
+#include <wdt.h>
+
+static struct udevice *currdev;
+
+static int do_wdt_list(cmd_tbl_t *cmdtp, int flag, int argc,
+		       char *const argv[])
+{
+	struct udevice *dev;
+	struct uclass *uc;
+	int ret;
+
+	ret = uclass_get(UCLASS_WDT, &uc);
+	if (ret)
+		return CMD_RET_FAILURE;
+
+	uclass_foreach_dev(dev, uc)
+		printf("%s (%s)\n", dev->name, dev->driver->name);
+
+	return CMD_RET_SUCCESS;
+}
+
+static int do_wdt_dev(cmd_tbl_t *cmdtp, int flag, int argc,
+		      char *const argv[])
+{
+	int ret;
+
+	if (argc > 1) {
+		ret = uclass_get_device_by_name(UCLASS_WDT, argv[1], &currdev);
+		if (ret) {
+			printf("Can't get the watchdog timer: %s\n", argv[1]);
+			return CMD_RET_FAILURE;
+		}
+	} else {
+		if (!currdev) {
+			printf("No watchdog timer device set!\n");
+			return CMD_RET_FAILURE;
+		}
+		printf("dev: %s\n", currdev->name);
+	}
+
+	return CMD_RET_SUCCESS;
+}
+
+static int check_currdev(void)
+{
+	if (!currdev) {
+		printf("No device set, use 'wdt dev' first\n");
+		return CMD_RET_FAILURE;
+	}
+	return 0;
+}
+
+static int do_wdt_start(cmd_tbl_t *cmdtp, int flag, int argc,
+			char *const argv[])
+{
+	int ret;
+	u64 timeout;
+	ulong flags = 0;
+
+	if (argc < 2)
+		return CMD_RET_USAGE;
+
+	ret = check_currdev();
+	if (ret)
+		return ret;
+
+	timeout = simple_strtoull(argv[1], NULL, 0);
+	if (argc > 2)
+		flags = simple_strtoul(argv[2], NULL, 0);
+
+	ret = wdt_start(currdev, timeout, flags);
+	if (ret == -ENOSYS) {
+		printf("Starting watchdog timer not supported.\n");
+		return CMD_RET_FAILURE;
+	} else if (ret) {
+		printf("Starting watchdog timer failed (%d)\n", ret);
+		return CMD_RET_FAILURE;
+	}
+
+	return CMD_RET_SUCCESS;
+}
+
+static int do_wdt_stop(cmd_tbl_t *cmdtp, int flag, int argc,
+		       char *const argv[])
+{
+	int ret;
+
+	ret = check_currdev();
+	if (ret)
+		return ret;
+
+	ret = wdt_stop(currdev);
+	if (ret == -ENOSYS) {
+		printf("Stopping watchdog timer not supported.\n");
+		return CMD_RET_FAILURE;
+	} else if (ret) {
+		printf("Stopping watchdog timer failed (%d)\n", ret);
+		return CMD_RET_FAILURE;
+	}
+
+	return CMD_RET_SUCCESS;
+}
+
+static int do_wdt_reset(cmd_tbl_t *cmdtp, int flag, int argc,
+			char *const argv[])
+{
+	int ret;
+
+	ret = check_currdev();
+	if (ret)
+		return ret;
+
+	ret = wdt_reset(currdev);
+	if (ret == -ENOSYS) {
+		printf("Resetting watchdog timer not supported.\n");
+		return CMD_RET_FAILURE;
+	} else if (ret) {
+		printf("Resetting watchdog timer failed (%d)\n", ret);
+		return CMD_RET_FAILURE;
+	}
+
+	return CMD_RET_SUCCESS;
+}
+
+static int do_wdt_expire(cmd_tbl_t *cmdtp, int flag, int argc,
+			 char *const argv[])
+{
+	int ret;
+	ulong flags = 0;
+
+	ret = check_currdev();
+	if (ret)
+		return ret;
+
+	if (argc > 1)
+		flags = simple_strtoul(argv[1], NULL, 0);
+
+	ret = wdt_expire_now(currdev, flags);
+	if (ret == -ENOSYS) {
+		printf("Expiring watchdog timer not supported.\n");
+		return CMD_RET_FAILURE;
+	} else if (ret) {
+		printf("Expiring watchdog timer failed (%d)\n", ret);
+		return CMD_RET_FAILURE;
+	}
+
+	return CMD_RET_SUCCESS;
+}
+
+static char wdt_help_text[] =
+	"list - list watchdog devices\n"
+	"wdt dev [<name>] - get/set current watchdog device\n"
+	"wdt start <timeout ms> [flags] - start watchdog timer\n"
+	"wdt stop - stop watchdog timer\n"
+	"wdt reset - reset watchdog timer\n"
+	"wdt expire [flags] - expire watchdog timer immediately\n";
+
+U_BOOT_CMD_WITH_SUBCMDS(wdt, "Watchdog sub-system", wdt_help_text,
+	U_BOOT_SUBCMD_MKENT(list, 1, 1, do_wdt_list),
+	U_BOOT_SUBCMD_MKENT(dev, 2, 1, do_wdt_dev),
+	U_BOOT_SUBCMD_MKENT(start, 3, 1, do_wdt_start),
+	U_BOOT_SUBCMD_MKENT(stop, 1, 1, do_wdt_stop),
+	U_BOOT_SUBCMD_MKENT(reset, 1, 1, do_wdt_reset),
+	U_BOOT_SUBCMD_MKENT(expire, 2, 1, do_wdt_expire));