dm: sysreset: support mode args for reboot/reset command

Support command like: reboot loader/bootloader/recovery, etc.
It depends on the node whose compatible is "syscon-reboot-mode".

Change-Id: I3ef497c6a4355a0d8be9a277bd77bbee43df57fb
Signed-off-by: Joseph Chen <chenjh@rock-chips.com>
This commit is contained in:
Joseph Chen 2019-10-29 21:19:25 +08:00 committed by Jianhong Chen
parent 467d16db4b
commit bcb84b5d64
4 changed files with 127 additions and 1 deletions

View File

@ -5,9 +5,15 @@
#
obj-$(CONFIG_$(SPL_TPL_)SYSRESET) += sysreset-uclass.o
ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_SYSRESET) += sysreset-syscon-reboot.o
endif
ifndef CONFIG_TPL_BUILD
obj-$(CONFIG_SYSRESET_PSCI) += sysreset_psci.o
endif
obj-$(CONFIG_SYSRESET_SYSCON) += sysreset_syscon.o
obj-$(CONFIG_SYSRESET_WATCHDOG) += sysreset_watchdog.o
@ -16,6 +22,7 @@ obj-$(CONFIG_ARCH_SNAPDRAGON) += sysreset_snapdragon.o
obj-$(CONFIG_ARCH_STI) += sysreset_sti.o
obj-$(CONFIG_TARGET_XTFPGA) += sysreset_xtfpga.o
obj-$(CONFIG_ARCH_ASPEED) += sysreset_ast.o
ifndef CONFIG_TPL_BUILD
obj-$(CONFIG_ARCH_ROCKCHIP) += sysreset_rockchip.o
endif

View File

@ -0,0 +1,73 @@
/*
* (C) Copyright 2019 Rockchip Electronics Co., Ltd
*
* SPDX-License-Identifier: GPL-2.0
*/
#include <common.h>
#include <dm.h>
#include <sysreset.h>
#include <linux/io.h>
#include <asm/arch/boot_mode.h>
#define CMD_PREFIX "mode-"
struct command {
const char *name;
u32 magic;
};
static const struct command static_defined_command[] = {
{ .name = "bootrom", .magic = BOOT_BROM_DOWNLOAD, }
};
static int syscon_reboot_request_by_mode(struct udevice *dev, const char *mode)
{
const char *prefix = CMD_PREFIX;
char *command;
u32 magic;
int i;
if (!mode)
return 0;
command = calloc(1, strlen(mode) + sizeof(prefix));
if (!command)
return -ENOMEM;
strcat(command, prefix);
strcat(command, mode);
magic = dev_read_u32_default(dev, command, BOOT_NORMAL);
if (magic == BOOT_NORMAL) {
for (i = 0; i < ARRAY_SIZE(static_defined_command); i++) {
if (!strcmp(static_defined_command[i].name, mode)) {
magic = static_defined_command[i].magic;
break;
}
}
}
printf("## Reboot mode: %s(%x)\n\n", mode, magic);
writel(magic, CONFIG_ROCKCHIP_BOOT_MODE_REG);
free(command);
return 0;
}
static const struct sysreset_ops syscon_reboot_ops = {
.request_by_mode = syscon_reboot_request_by_mode,
};
static const struct udevice_id syscon_reboot_match[] = {
{ .compatible = "syscon-reboot-mode", },
{},
};
U_BOOT_DRIVER(sysreset_syscon_reboot) = {
.name = "sysreset_syscon_reboot",
.id = UCLASS_SYSRESET,
.of_match = syscon_reboot_match,
.ops = &syscon_reboot_ops,
};

View File

@ -81,10 +81,36 @@ void reset_cpu(ulong addr)
sysreset_walk_halt(SYSRESET_WARM);
}
void reboot(const char *mode)
{
#ifndef CONFIG_SPL_BUILD
struct sysreset_ops *ops;
struct udevice *dev;
int ret;
if (!mode)
goto finish;
ret = uclass_get_device_by_driver(UCLASS_SYSRESET,
DM_GET_DRIVER(sysreset_syscon_reboot),
&dev);
if (!ret) {
ops = sysreset_get_ops(dev);
if (ops && ops->request_by_mode)
ops->request_by_mode(dev, mode);
}
finish:
#endif
flushc();
sysreset_walk_halt(SYSRESET_COLD);
}
int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
sysreset_walk_halt(SYSRESET_COLD);
if (argc > 1)
reboot(argv[1]);
else
reboot(NULL);
return 0;
}

View File

@ -29,6 +29,19 @@ struct sysreset_ops {
* (in which case this method will not actually return)
*/
int (*request)(struct udevice *dev, enum sysreset_t type);
/**
* request_by_mode() - request a sysreset of the given mode
*
* Note that this function may return before the reset takes effect.
*
* @mode: mode to request
* @return -EINPROGRESS if the reset has been started and
* will complete soon, -EPROTONOSUPPORT if not supported
* by this device, 0 if the reset has already happened
* (in which case this method will not actually return)
*/
int (*request_by_mode)(struct udevice *dev, const char *mode);
};
#define sysreset_get_ops(dev) ((struct sysreset_ops *)(dev)->driver->ops)
@ -68,4 +81,11 @@ void sysreset_walk_halt(enum sysreset_t type);
*/
void reset_cpu(ulong addr);
/**
* reboot() - calls sysreset_walk(SYSRESET_WARM)
*
* Support the command like: reboot loader/bootloader/recovery, etc.
*/
void reboot(const char *mode);
#endif