1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Watchdog commands
4  *
5  * Copyright (c) 2019 Michael Walle <michael@walle.cc>
6  */
7 
8 #include <common.h>
9 #include <command.h>
10 #include <dm.h>
11 #include <wdt.h>
12 
13 static struct udevice *currdev;
14 
do_wdt_list(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])15 static int do_wdt_list(struct cmd_tbl *cmdtp, int flag, int argc,
16 		       char *const argv[])
17 {
18 	struct udevice *dev;
19 	struct uclass *uc;
20 	int ret;
21 
22 	ret = uclass_get(UCLASS_WDT, &uc);
23 	if (ret)
24 		return CMD_RET_FAILURE;
25 
26 	uclass_foreach_dev(dev, uc)
27 		printf("%s (%s)\n", dev->name, dev->driver->name);
28 
29 	return CMD_RET_SUCCESS;
30 }
31 
do_wdt_dev(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])32 static int do_wdt_dev(struct cmd_tbl *cmdtp, int flag, int argc,
33 		      char *const argv[])
34 {
35 	int ret;
36 
37 	if (argc > 1) {
38 		ret = uclass_get_device_by_name(UCLASS_WDT, argv[1], &currdev);
39 		if (ret) {
40 			printf("Can't get the watchdog timer: %s\n", argv[1]);
41 			return CMD_RET_FAILURE;
42 		}
43 	} else {
44 		if (!currdev) {
45 			printf("No watchdog timer device set!\n");
46 			return CMD_RET_FAILURE;
47 		}
48 		printf("dev: %s\n", currdev->name);
49 	}
50 
51 	return CMD_RET_SUCCESS;
52 }
53 
check_currdev(void)54 static int check_currdev(void)
55 {
56 	if (!currdev) {
57 		printf("No device set, use 'wdt dev' first\n");
58 		return CMD_RET_FAILURE;
59 	}
60 	return 0;
61 }
62 
do_wdt_start(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])63 static int do_wdt_start(struct cmd_tbl *cmdtp, int flag, int argc,
64 			char *const argv[])
65 {
66 	int ret;
67 	u64 timeout;
68 	ulong flags = 0;
69 
70 	if (argc < 2)
71 		return CMD_RET_USAGE;
72 
73 	ret = check_currdev();
74 	if (ret)
75 		return ret;
76 
77 	timeout = simple_strtoull(argv[1], NULL, 0);
78 	if (argc > 2)
79 		flags = simple_strtoul(argv[2], NULL, 0);
80 
81 	ret = wdt_start(currdev, timeout, flags);
82 	if (ret == -ENOSYS) {
83 		printf("Starting watchdog timer not supported.\n");
84 		return CMD_RET_FAILURE;
85 	} else if (ret) {
86 		printf("Starting watchdog timer failed (%d)\n", ret);
87 		return CMD_RET_FAILURE;
88 	}
89 
90 	return CMD_RET_SUCCESS;
91 }
92 
do_wdt_stop(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])93 static int do_wdt_stop(struct cmd_tbl *cmdtp, int flag, int argc,
94 		       char *const argv[])
95 {
96 	int ret;
97 
98 	ret = check_currdev();
99 	if (ret)
100 		return ret;
101 
102 	ret = wdt_stop(currdev);
103 	if (ret == -ENOSYS) {
104 		printf("Stopping watchdog timer not supported.\n");
105 		return CMD_RET_FAILURE;
106 	} else if (ret) {
107 		printf("Stopping watchdog timer failed (%d)\n", ret);
108 		return CMD_RET_FAILURE;
109 	}
110 
111 	return CMD_RET_SUCCESS;
112 }
113 
do_wdt_reset(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])114 static int do_wdt_reset(struct cmd_tbl *cmdtp, int flag, int argc,
115 			char *const argv[])
116 {
117 	int ret;
118 
119 	ret = check_currdev();
120 	if (ret)
121 		return ret;
122 
123 	ret = wdt_reset(currdev);
124 	if (ret == -ENOSYS) {
125 		printf("Resetting watchdog timer not supported.\n");
126 		return CMD_RET_FAILURE;
127 	} else if (ret) {
128 		printf("Resetting watchdog timer failed (%d)\n", ret);
129 		return CMD_RET_FAILURE;
130 	}
131 
132 	return CMD_RET_SUCCESS;
133 }
134 
do_wdt_expire(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])135 static int do_wdt_expire(struct cmd_tbl *cmdtp, int flag, int argc,
136 			 char *const argv[])
137 {
138 	int ret;
139 	ulong flags = 0;
140 
141 	ret = check_currdev();
142 	if (ret)
143 		return ret;
144 
145 	if (argc > 1)
146 		flags = simple_strtoul(argv[1], NULL, 0);
147 
148 	ret = wdt_expire_now(currdev, flags);
149 	if (ret == -ENOSYS) {
150 		printf("Expiring watchdog timer not supported.\n");
151 		return CMD_RET_FAILURE;
152 	} else if (ret) {
153 		printf("Expiring watchdog timer failed (%d)\n", ret);
154 		return CMD_RET_FAILURE;
155 	}
156 
157 	return CMD_RET_SUCCESS;
158 }
159 
160 static char wdt_help_text[] =
161 	"list - list watchdog devices\n"
162 	"wdt dev [<name>] - get/set current watchdog device\n"
163 	"wdt start <timeout ms> [flags] - start watchdog timer\n"
164 	"wdt stop - stop watchdog timer\n"
165 	"wdt reset - reset watchdog timer\n"
166 	"wdt expire [flags] - expire watchdog timer immediately\n";
167 
168 U_BOOT_CMD_WITH_SUBCMDS(wdt, "Watchdog sub-system", wdt_help_text,
169 	U_BOOT_SUBCMD_MKENT(list, 1, 1, do_wdt_list),
170 	U_BOOT_SUBCMD_MKENT(dev, 2, 1, do_wdt_dev),
171 	U_BOOT_SUBCMD_MKENT(start, 3, 1, do_wdt_start),
172 	U_BOOT_SUBCMD_MKENT(stop, 1, 1, do_wdt_stop),
173 	U_BOOT_SUBCMD_MKENT(reset, 1, 1, do_wdt_reset),
174 	U_BOOT_SUBCMD_MKENT(expire, 2, 1, do_wdt_expire));
175