sysreset: provide SBI based sysreset driver

Provide sysreset driver using the SBI system reset extension.

Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Reviewed-by: Sean Anderson <seanga2@gmail.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Tested-by: Samuel Holland <samuel@sholland.org>
diff --git a/arch/riscv/cpu/cpu.c b/arch/riscv/cpu/cpu.c
index c894ac1..8e49b6d 100644
--- a/arch/riscv/cpu/cpu.c
+++ b/arch/riscv/cpu/cpu.c
@@ -6,6 +6,7 @@
 #include <common.h>
 #include <cpu.h>
 #include <dm.h>
+#include <dm/lists.h>
 #include <init.h>
 #include <log.h>
 #include <asm/encoding.h>
@@ -138,7 +139,17 @@
 
 int arch_early_init_r(void)
 {
-	return riscv_cpu_probe();
+	int ret;
+
+	ret = riscv_cpu_probe();
+	if (ret)
+		return ret;
+
+	if (IS_ENABLED(CONFIG_SYSRESET_SBI))
+		device_bind_driver(gd->dm_root, "sbi-sysreset",
+				   "sbi-sysreset", NULL);
+
+	return 0;
 }
 
 /**
diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h
index 34a115a..5030892 100644
--- a/arch/riscv/include/asm/sbi.h
+++ b/arch/riscv/include/asm/sbi.h
@@ -153,5 +153,6 @@
 long sbi_get_spec_version(void);
 int sbi_get_impl_id(void);
 int sbi_probe_extension(int ext);
+void sbi_srst_reset(unsigned long type, unsigned long reason);
 
 #endif
diff --git a/arch/riscv/lib/sbi.c b/arch/riscv/lib/sbi.c
index 77845a7..2b53896 100644
--- a/arch/riscv/lib/sbi.c
+++ b/arch/riscv/lib/sbi.c
@@ -108,6 +108,18 @@
 	return -ENOTSUPP;
 }
 
+/**
+ * sbi_srst_reset() - invoke system reset extension
+ *
+ * @type:	type of reset
+ * @reason:	reason for reset
+ */
+void sbi_srst_reset(unsigned long type, unsigned long reason)
+{
+	sbi_ecall(SBI_EXT_SRST, SBI_EXT_SRST_RESET, type, reason,
+		  0, 0, 0, 0);
+}
+
 #ifdef CONFIG_SBI_V01
 
 /**