Teach the "reset" command to trigger the reset modes registered with the reboot-mode framework in addition to the existing cold and warm resets:
reset cold reset (unchanged) reset -w warm reset (unchanged) reset -<mode> reset into a mode declared in the device tree reset -l list the available reset modes For example "reset -edl" enters Qualcomm EDL/download mode when the psci device tree node carries a "reboot-mode" subnode with "mode-edl = <0x80000000 0x00000001>". The command never parses the magic values itself; it strips the leading '-' and hands the mode name to reboot_mode_request(), so the values stay in the device tree and are not hardcoded per SoC. An unknown mode prints the registered modes rather than silently falling through to a cold reset. Signed-off-by: Balaji Selvanathan <[email protected]> --- cmd/boot.c | 6 +++++- drivers/sysreset/sysreset-uclass.c | 27 ++++++++++++++++++++++++++- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/cmd/boot.c b/cmd/boot.c index 23496cafdf5..5f89c3ed889 100644 --- a/cmd/boot.c +++ b/cmd/boot.c @@ -60,7 +60,11 @@ U_BOOT_CMD( reset, 2, 0, do_reset, "Perform RESET of the CPU", "- cold boot without level specifier\n" - "reset -w - warm reset if implemented" + "reset -w - warm reset if implemented\n" +#if IS_ENABLED(CONFIG_DM_REBOOT_MODE) + "reset -<mode> - reset into a mode declared in the device tree\n" + "reset -l - list the available reset modes\n" +#endif ); #ifdef CONFIG_CMD_POWEROFF diff --git a/drivers/sysreset/sysreset-uclass.c b/drivers/sysreset/sysreset-uclass.c index 536ac727142..960d8ddac23 100644 --- a/drivers/sysreset/sysreset-uclass.c +++ b/drivers/sysreset/sysreset-uclass.c @@ -13,6 +13,7 @@ #include <hang.h> #include <log.h> #include <regmap.h> +#include <reboot-mode/reboot-mode.h> #include <spl.h> #include <sysreset.h> #include <dm/device-internal.h> @@ -125,8 +126,32 @@ int do_reset(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) if (argc > 2) return CMD_RET_USAGE; - if (argc == 2 && argv[1][0] == '-' && argv[1][1] == 'w') { + if (argc == 2 && argv[1][0] == '-' && argv[1][1] == 'w' && + !argv[1][2]) { reset_type = SYSRESET_WARM; + } else if (CONFIG_IS_ENABLED(DM_REBOOT_MODE) && argc == 2 && + argv[1][0] == '-') { + /* + * "reset -l" lists the modes registered with the reboot-mode + * framework; "reset -<mode>" triggers a named mode (for + * example "reset -edl"). The mode magic values live in the + * device tree. + */ + const char *name = &argv[1][1]; + + if (!strcmp(name, "l")) + return reboot_mode_list() ? CMD_RET_FAILURE : + CMD_RET_SUCCESS; + + printf("resetting into \"%s\" mode ...\n", name); + mdelay(100); + + /* Does not return on success. */ + reboot_mode_request(name); + + printf("Unknown reset mode \"%s\"\n", name); + reboot_mode_list(); + return CMD_RET_USAGE; } printf("resetting ...\n"); -- 2.34.1
