[RFC PATCH 4/4] lib: utils: add sifive reset device

Green Wan green.wan at sifive.com
Thu Jul 1 00:39:58 PDT 2021


Add sifive reset device based on DT binding as below.

	gpio-poweroff {
		compatible = "gpio-poweroff";
		gpios = <&gpio 2 GPIO_ACTIVE_LOW>;
	};

Signed-off-by: Green Wan <green.wan at sifive.com>
---
 include/sbi_utils/sys/sifive_reset.h | 18 ++++++++
 lib/utils/reset/fdt_reset.c          |  2 +
 lib/utils/reset/fdt_reset_sifive.c   | 47 ++++++++++++++++++++
 lib/utils/reset/objects.mk           |  1 +
 lib/utils/sys/objects.mk             |  1 +
 lib/utils/sys/sifive_reset.c         | 66 ++++++++++++++++++++++++++++
 6 files changed, 135 insertions(+)
 create mode 100644 include/sbi_utils/sys/sifive_reset.h
 create mode 100644 lib/utils/reset/fdt_reset_sifive.c
 create mode 100644 lib/utils/sys/sifive_reset.c

diff --git a/include/sbi_utils/sys/sifive_reset.h b/include/sbi_utils/sys/sifive_reset.h
new file mode 100644
index 0000000..357fa8c
--- /dev/null
+++ b/include/sbi_utils/sys/sifive_reset.h
@@ -0,0 +1,18 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2021 SiFive
+ *
+ * Authors:
+ *   Green Wan <green.wan at sifive.com>
+ */
+
+#ifndef __SYS_SIFIVE_RESET_H__
+#define __SYS_SIFIVE_RESET_H__
+
+#include <sbi/sbi_types.h>
+#include <sbi_utils/fdt/fdt_helper.h>
+
+int sifive_reset_init_gpio(struct poweroff_gpio *ppwroff);
+
+#endif
diff --git a/lib/utils/reset/fdt_reset.c b/lib/utils/reset/fdt_reset.c
index 48a49fb..f3978b3 100644
--- a/lib/utils/reset/fdt_reset.c
+++ b/lib/utils/reset/fdt_reset.c
@@ -13,11 +13,13 @@
 #include <sbi_utils/reset/fdt_reset.h>
 
 extern struct fdt_reset fdt_reset_sifive_test;
+extern struct fdt_reset fdt_reset_sifive;
 extern struct fdt_reset fdt_reset_htif;
 extern struct fdt_reset fdt_reset_thead;
 
 static struct fdt_reset *reset_drivers[] = {
 	&fdt_reset_sifive_test,
+	&fdt_reset_sifive,
 	&fdt_reset_htif,
 	&fdt_reset_thead,
 };
diff --git a/lib/utils/reset/fdt_reset_sifive.c b/lib/utils/reset/fdt_reset_sifive.c
new file mode 100644
index 0000000..b5f3b1b
--- /dev/null
+++ b/lib/utils/reset/fdt_reset_sifive.c
@@ -0,0 +1,47 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2021 SiFive
+ *
+ * Authors:
+ *   Green Wan <green.wan at sifive.com>
+ */
+
+#include <sbi/sbi_console.h>
+#include <sbi/sbi_platform.h>
+#include <sbi/sbi_scratch.h>
+#include <sbi_utils/fdt/fdt_helper.h>
+#include <sbi_utils/gpio/fdt_gpio.h>
+#include <sbi_utils/reset/fdt_reset.h>
+#include <sbi_utils/sys/sifive_reset.h>
+
+static struct poweroff_gpio pwroff = {
+	.act_delay = 100,
+	.gpio = -1,
+	.output_type = GPIO_ACTIVE_LOW,
+};
+
+static int sifive_reset_init(void *fdt, int nodeoff,
+			     const struct fdt_match *match)
+{
+	int rc;
+
+	rc = fdt_parse_gpio_pwroff(fdt, &pwroff, "/gpio-poweroff");
+	if (rc) {
+		sbi_printf("Warning: no gpio-poweroff definition in DT\n");
+
+		return rc;
+	}
+
+	return sifive_reset_init_gpio(&pwroff);
+}
+
+static const struct fdt_match sifive_reset_match[] = {
+	{ .compatible = "gpio-poweroff" },
+	{ },
+};
+
+struct fdt_reset fdt_reset_sifive = {
+	.match_table = sifive_reset_match,
+	.init = sifive_reset_init,
+};
diff --git a/lib/utils/reset/objects.mk b/lib/utils/reset/objects.mk
index bf005e8..1196e30 100644
--- a/lib/utils/reset/objects.mk
+++ b/lib/utils/reset/objects.mk
@@ -10,5 +10,6 @@
 libsbiutils-objs-y += reset/fdt_reset.o
 libsbiutils-objs-y += reset/fdt_reset_htif.o
 libsbiutils-objs-y += reset/fdt_reset_sifive_test.o
+libsbiutils-objs-y += reset/fdt_reset_sifive.o
 libsbiutils-objs-y += reset/fdt_reset_thead.o
 libsbiutils-objs-y += reset/fdt_reset_thead_asm.o
diff --git a/lib/utils/sys/objects.mk b/lib/utils/sys/objects.mk
index 06be322..ad75f62 100644
--- a/lib/utils/sys/objects.mk
+++ b/lib/utils/sys/objects.mk
@@ -9,3 +9,4 @@
 
 libsbiutils-objs-y += sys/htif.o
 libsbiutils-objs-y += sys/sifive_test.o
+libsbiutils-objs-y += sys/sifive_reset.o
diff --git a/lib/utils/sys/sifive_reset.c b/lib/utils/sys/sifive_reset.c
new file mode 100644
index 0000000..d086363
--- /dev/null
+++ b/lib/utils/sys/sifive_reset.c
@@ -0,0 +1,66 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2021 SiFive
+ *
+ * Authors:
+ *   Green Wan <green.wan at sifive.com>
+ */
+
+#include <sbi/riscv_io.h>
+#include <sbi/sbi_console.h>
+#include <sbi/sbi_ecall_interface.h>
+#include <sbi/sbi_platform.h>
+#include <sbi/sbi_system.h>
+#include <sbi_utils/gpio/fdt_gpio.h>
+#include <sbi_utils/sys/sifive_reset.h>
+
+static struct poweroff_gpio *ppwroff;
+
+static int sifive_system_reset_check(u32 type, u32 reason)
+{
+	switch (type) {
+	case SBI_SRST_RESET_TYPE_SHUTDOWN:
+	case SBI_SRST_RESET_TYPE_COLD_REBOOT:
+	case SBI_SRST_RESET_TYPE_WARM_REBOOT:
+		return 1;
+	}
+
+	return 0;
+}
+
+static void sifive_system_reset(u32 type, u32 reason)
+{
+	switch (type) {
+	case SBI_SRST_RESET_TYPE_SHUTDOWN:
+		if (!ppwroff || ppwroff->gpio < 0)
+			return;
+
+		if (ppwroff->output_type == GPIO_ACTIVE_LOW)
+			gpio_direction_output(ppwroff->gpio, 0);
+		else
+			gpio_direction_output(ppwroff->gpio, 1);
+
+		/* if success, power is off now. */
+		while (1)
+			wfi();
+
+		break;
+	case SBI_SRST_RESET_TYPE_COLD_REBOOT:
+	case SBI_SRST_RESET_TYPE_WARM_REBOOT:
+		break;
+	}
+}
+
+static struct sbi_system_reset_device sifive_reset = {
+	.name = "sifive_reset",
+	.system_reset_check = sifive_system_reset_check,
+	.system_reset = sifive_system_reset
+};
+
+int sifive_reset_init_gpio(struct poweroff_gpio *gpio)
+{
+	ppwroff = gpio;
+	sbi_system_reset_set_device(&sifive_reset);
+	return 0;
+}
-- 
2.17.1




More information about the opensbi mailing list