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 13static struct udevice *currdev; 14 15static 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 32static 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 54static 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 63static 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 93static 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 114static 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 135static 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 160U_BOOT_LONGHELP(wdt, 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 168U_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