
From: Simon Glass <sjg@chromium.org> In some cases we may wish to return back to the program which started U-Boot. Add the concept of a 'hot' reset, to support this. Signed-off-by: Simon Glass <sjg@chromium.org> --- cmd/boot.c | 1 + doc/usage/cmd/reset.rst | 3 +++ drivers/sysreset/sysreset-uclass.c | 15 +++++++++++++-- drivers/sysreset/sysreset_sandbox.c | 1 + include/sysreset.h | 3 +++ test/dm/sysreset.c | 2 ++ 6 files changed, 23 insertions(+), 2 deletions(-) diff --git a/cmd/boot.c b/cmd/boot.c index 23496cafdf5..832ad08c319 100644 --- a/cmd/boot.c +++ b/cmd/boot.c @@ -60,6 +60,7 @@ U_BOOT_CMD( reset, 2, 0, do_reset, "Perform RESET of the CPU", "- cold boot without level specifier\n" + "reset -h - hotreset if implemented\n" "reset -w - warm reset if implemented" ); diff --git a/doc/usage/cmd/reset.rst b/doc/usage/cmd/reset.rst index 126db21cdb8..3a43db204e5 100644 --- a/doc/usage/cmd/reset.rst +++ b/doc/usage/cmd/reset.rst @@ -22,6 +22,9 @@ DDR and peripherals, on some boards also resets external PMIC. -w Do warm WARM, reset CPU but keep peripheral/DDR/PMIC active. +-h + Do a hot reset, if supported, which returns back to the program which + started U-Boot. Return value ------------ diff --git a/drivers/sysreset/sysreset-uclass.c b/drivers/sysreset/sysreset-uclass.c index 536ac727142..db81c9b5779 100644 --- a/drivers/sysreset/sysreset-uclass.c +++ b/drivers/sysreset/sysreset-uclass.c @@ -125,8 +125,19 @@ 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') { - reset_type = SYSRESET_WARM; + if (argc == 2 && argv[1][0] == '-') { + int type = argv[1][1]; + + switch (type) { + case 'h': + reset_type = SYSRESET_HOT; + break; + case 'w': + reset_type = SYSRESET_WARM; + break; + default: + return CMD_RET_USAGE; + } } printf("resetting ...\n"); diff --git a/drivers/sysreset/sysreset_sandbox.c b/drivers/sysreset/sysreset_sandbox.c index 93179f90bbb..522050eb4bf 100644 --- a/drivers/sysreset/sysreset_sandbox.c +++ b/drivers/sysreset/sysreset_sandbox.c @@ -65,6 +65,7 @@ static int sandbox_sysreset_request(struct udevice *dev, enum sysreset_t type) return -EACCES; sandbox_exit(); case SYSRESET_POWER: + case SYSRESET_HOT: if (!state->sysreset_allowed[type]) return -EACCES; sandbox_exit(); diff --git a/include/sysreset.h b/include/sysreset.h index ff20abdeed3..f231d4e8bc4 100644 --- a/include/sysreset.h +++ b/include/sysreset.h @@ -21,6 +21,9 @@ enum sysreset_t { SYSRESET_POWER, /** @SYSRESET_POWER_OFF: turn off power */ SYSRESET_POWER_OFF, + /** @SYSRESET_HOT: exit out of U-Boot (e.g. from EFI app) */ + SYSRESET_HOT, + /** @SYSRESET_COUNT: number of available reset types */ SYSRESET_COUNT, }; diff --git a/test/dm/sysreset.c b/test/dm/sysreset.c index 8431aaa0a9e..a30d035b9a6 100644 --- a/test/dm/sysreset.c +++ b/test/dm/sysreset.c @@ -76,10 +76,12 @@ static int dm_test_sysreset_walk(struct unit_test_state *uts) state->sysreset_allowed[SYSRESET_COLD] = false; state->sysreset_allowed[SYSRESET_POWER] = false; state->sysreset_allowed[SYSRESET_POWER_OFF] = false; + state->sysreset_allowed[SYSRESET_HOT] = false; ut_asserteq(-EACCES, sysreset_walk(SYSRESET_WARM)); ut_asserteq(-EACCES, sysreset_walk(SYSRESET_COLD)); ut_asserteq(-EACCES, sysreset_walk(SYSRESET_POWER)); ut_asserteq(-EACCES, sysreset_walk(SYSRESET_POWER_OFF)); + ut_asserteq(-EACCES, sysreset_walk(SYSRESET_HOT)); /* * Enable cold system reset - this should make cold system reset work, -- 2.43.0