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