From 24ed5317d427bfe278a1329abbf4522dba1025a3 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sun, 12 Sep 2021 21:11:46 +0200 Subject: sysreset: provide SBI based sysreset driver Provide sysreset driver using the SBI system reset extension. Signed-off-by: Heinrich Schuchardt Reviewed-by: Sean Anderson Reviewed-by: Bin Meng Tested-by: Samuel Holland --- drivers/sysreset/Kconfig | 12 ++++++++++ drivers/sysreset/Makefile | 1 + drivers/sysreset/sysreset_sbi.c | 51 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+) create mode 100644 drivers/sysreset/sysreset_sbi.c (limited to 'drivers/sysreset') diff --git a/drivers/sysreset/Kconfig b/drivers/sysreset/Kconfig index ac77ffb..43a948c 100644 --- a/drivers/sysreset/Kconfig +++ b/drivers/sysreset/Kconfig @@ -85,6 +85,18 @@ config SYSRESET_PSCI Enable PSCI SYSTEM_RESET function call. To use this, PSCI firmware must be running on your system. +config SYSRESET_SBI + bool "Enable support for SBI System Reset" + depends on RISCV_SMODE && SBI_V02 + select SYSRESET_CMD_POWEROFF if CMD_POWEROFF + help + Enable system reset and poweroff via the SBI system reset extension. + The extension was introduced in version 0.3 of the SBI specification. + + If the SBI implementation provides the extension, is board specific. + The RISC-V platform specification mandates the extension for rich + operating system platforms. + config SYSRESET_SOCFPGA bool "Enable support for Intel SOCFPGA family" depends on ARCH_SOCFPGA && (TARGET_SOCFPGA_GEN5 || TARGET_SOCFPGA_ARRIA10) diff --git a/drivers/sysreset/Makefile b/drivers/sysreset/Makefile index de81c39..8e00be0 100644 --- a/drivers/sysreset/Makefile +++ b/drivers/sysreset/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_SYSRESET_MPC83XX) += sysreset_mpc83xx.o obj-$(CONFIG_SYSRESET_MICROBLAZE) += sysreset_microblaze.o obj-$(CONFIG_SYSRESET_OCTEON) += sysreset_octeon.o obj-$(CONFIG_SYSRESET_PSCI) += sysreset_psci.o +obj-$(CONFIG_SYSRESET_SBI) += sysreset_sbi.o obj-$(CONFIG_SYSRESET_SOCFPGA) += sysreset_socfpga.o obj-$(CONFIG_SYSRESET_SOCFPGA_SOC64) += sysreset_socfpga_soc64.o obj-$(CONFIG_SYSRESET_TI_SCI) += sysreset-ti-sci.o diff --git a/drivers/sysreset/sysreset_sbi.c b/drivers/sysreset/sysreset_sbi.c new file mode 100644 index 0000000..5e8090d --- /dev/null +++ b/drivers/sysreset/sysreset_sbi.c @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2021, Heinrich Schuchardt + */ + +#include +#include +#include +#include +#include +#include + +static enum sbi_srst_reset_type reset_type_map[SYSRESET_COUNT] = { + [SYSRESET_WARM] = SBI_SRST_RESET_TYPE_WARM_REBOOT, + [SYSRESET_COLD] = SBI_SRST_RESET_TYPE_COLD_REBOOT, + [SYSRESET_POWER] = SBI_SRST_RESET_TYPE_COLD_REBOOT, + [SYSRESET_POWER_OFF] = SBI_SRST_RESET_TYPE_SHUTDOWN, +}; + +static int sbi_sysreset_request(struct udevice *dev, enum sysreset_t type) +{ + enum sbi_srst_reset_type reset_type; + + reset_type = reset_type_map[type]; + sbi_srst_reset(reset_type, SBI_SRST_RESET_REASON_NONE); + + return -EINPROGRESS; +} + +static int sbi_sysreset_probe(struct udevice *dev) +{ + long have_reset; + + have_reset = sbi_probe_extension(SBI_EXT_SRST); + if (have_reset) + return 0; + + log_warning("SBI has no system reset extension\n"); + return -ENOENT; +} + +static struct sysreset_ops sbi_sysreset_ops = { + .request = sbi_sysreset_request, +}; + +U_BOOT_DRIVER(sbi_sysreset) = { + .name = "sbi-sysreset", + .id = UCLASS_SYSRESET, + .ops = &sbi_sysreset_ops, + .probe = sbi_sysreset_probe, +}; -- cgit v1.1