Skip to contentSkip to conversation

Syscon reboot and poweroff drivers

PATCH New Anup Patel 3 participants 13 messages Jul 21, 2023 – Jul 31, 2023 SiFive drivers

lore
Share & tools
lore

Anup Patel

author
#0 lore raw

cover Syscon reboot and poweroff drivers

This series adds syscon reboot and poweroff drivers which replaces the SiFive Test reset driver. These new drivers need a lightweight or simple regmap framework which is also added by this series.

These patches can also be found in the syscon_reboot_v1 branch at:
https://github.com/avpatel/opensbi.git

Anup Patel (6):
include: sbi_utils: Remove driver pointer from struct i2c_adapter
lib: utils/regmap: Add generic regmap access library
lib: utils/regmap: Add simple FDT based regmap framework
lib: utils/regmap: Add simple FDT based syscon regmap driver
lib: utils/reset: Add syscon based reboot and poweroff
lib: utils/reset: Remove SiFive Test reset driver

 include/sbi_utils/i2c/i2c.h                |   3 -
 include/sbi_utils/regmap/fdt_regmap.h      |  31 +++
 include/sbi_utils/regmap/regmap.h          |  67 ++++++
 include/sbi_utils/sys/sifive_test.h        |  17 --
 lib/utils/Kconfig                          |   2 +
 lib/utils/i2c/fdt_i2c_dw.c                 |   3 -
 lib/utils/i2c/fdt_i2c_sifive.c             |   3 -
 lib/utils/regmap/Kconfig                   |  22 ++
 lib/utils/regmap/fdt_regmap.c              |  94 ++++++++
 lib/utils/regmap/fdt_regmap_drivers.carray |   3 +
 lib/utils/regmap/fdt_regmap_syscon.c       | 262 +++++++++++++++++++++
 lib/utils/regmap/objects.mk                |  16 ++
 lib/utils/regmap/regmap.c                  | 114 +++++++++
 lib/utils/reset/Kconfig                    |  10 +-
 lib/utils/reset/fdt_reset_sifive_test.c    |  36 ---
 lib/utils/reset/fdt_reset_syscon.c         | 167 +++++++++++++
 lib/utils/reset/objects.mk                 |   7 +-
 lib/utils/sys/Kconfig                      |   4 -
 lib/utils/sys/objects.mk                   |   1 -
 lib/utils/sys/sifive_test.c                |  65 -----
 platform/generic/configs/defconfig         |   6 +-
 21 files changed, 791 insertions(+), 142 deletions(-)
 create mode 100644 include/sbi_utils/regmap/fdt_regmap.h
 create mode 100644 include/sbi_utils/regmap/regmap.h
 delete mode 100644 include/sbi_utils/sys/sifive_test.h
 create mode 100644 lib/utils/regmap/Kconfig
 create mode 100644 lib/utils/regmap/fdt_regmap.c
 create mode 100644 lib/utils/regmap/fdt_regmap_drivers.carray
 create mode 100644 lib/utils/regmap/fdt_regmap_syscon.c
 create mode 100644 lib/utils/regmap/objects.mk
 create mode 100644 lib/utils/regmap/regmap.c
 delete mode 100644 lib/utils/reset/fdt_reset_sifive_test.c
 create mode 100644 lib/utils/reset/fdt_reset_syscon.c
 delete mode 100644 lib/utils/sys/sifive_test.c
Signature · 1 line
2.34.1
author
#1 lore raw

PATCH 1/6 include: sbi_utils: Remove driver pointer from struct i2c_adapter

The "driver" pointer in struct i2c_adapter is not used anywhere so let us remove it.

---
 include/sbi_utils/i2c/i2c.h    | 3 ---
 lib/utils/i2c/fdt_i2c_dw.c     | 3 ---
 lib/utils/i2c/fdt_i2c_sifive.c | 3 ---
 3 files changed, 9 deletions(-)
include/sbi_utils/i2c/i2c.h +0 -3
index 5a70364..93a44f4 100644
@@ -15,9 +15,6 @@
 
 /** Representation of a I2C adapter */
 struct i2c_adapter {
-	/** Pointer to I2C driver owning this I2C adapter */
-	void *driver;
-
 	/** Unique ID of the I2C adapter assigned by the driver */
 	int id;
 
lib/utils/i2c/fdt_i2c_dw.c +0 -3
index 99b2ddb..358ad3c 100644
@@ -15,8 +15,6 @@
 #include <sbi_utils/i2c/dw_i2c.h>
 #include <sbi_utils/i2c/fdt_i2c.h>
 
-extern struct fdt_i2c_adapter fdt_i2c_adapter_dw;
-
 static int fdt_dw_i2c_init(void *fdt, int nodeoff,
 			     const struct fdt_match *match)
 {
@@ -35,7 +33,6 @@ static int fdt_dw_i2c_init(void *fdt, int nodeoff,
 	}
 
 	adapter->addr = addr;
-	adapter->adapter.driver = &fdt_i2c_adapter_dw;
 
 	rc = dw_i2c_init(&adapter->adapter, nodeoff);
 	if (rc) {
lib/utils/i2c/fdt_i2c_sifive.c +0 -3
index b85b245..1174062 100644
@@ -46,8 +46,6 @@ struct sifive_i2c_adapter {
 	struct i2c_adapter adapter;
 };
 
-extern struct fdt_i2c_adapter fdt_i2c_adapter_sifive;
-
 static inline void sifive_i2c_setreg(struct sifive_i2c_adapter *adap,
 				     uint8_t reg, uint8_t value)
 {
@@ -250,7 +248,6 @@ static int sifive_i2c_init(void *fdt, int nodeoff,
 	}
 
 	adapter->addr = addr;
-	adapter->adapter.driver = &fdt_i2c_adapter_sifive;
 	adapter->adapter.id = nodeoff;
 	adapter->adapter.write = sifive_i2c_adapter_write;
 	adapter->adapter.read = sifive_i2c_adapter_read;
Signature · 1 line
2.34.1
#2 lore raw

PATCH 1/6 include: sbi_utils: Remove driver pointer from struct i2c_adapter

? 2023-07-21???? 22:40 +0530?Anup Patel???

Quoted 4 lines

The "driver" pointer in struct i2c_adapter is not used anywhere so let us remove it.

Look good to me.

Quoted 66 lines

---

?include/sbi_utils/i2c/i2c.h??? | 3 ---
?lib/utils/i2c/fdt_i2c_dw.c???? | 3 ---
?lib/utils/i2c/fdt_i2c_sifive.c | 3 ---

?3 files changed, 9 deletions(-)

include/sbi_utils/i2c/i2c.h +0 -0
index 5a70364..93a44f4 100644
@@ -15,9 +15,6 @@

?
?/** Representation of a I2C adapter */
?struct i2c_adapter {
-???????/** Pointer to I2C driver owning this I2C adapter */ -???????void *driver;
-
????????/** Unique ID of the I2C adapter assigned by the driver */ ????????int id;
?

lib/utils/i2c/fdt_i2c_dw.c +0 -0
index 99b2ddb..358ad3c 100644
@@ -15,8 +15,6 @@

?#include <sbi_utils/i2c/dw_i2c.h>
?#include <sbi_utils/i2c/fdt_i2c.h>
?

lib/utils/i2c/fdt_i2c_dw.c +0 -2
-extern struct fdt_i2c_adapter fdt_i2c_adapter_dw;
-

?static int fdt_dw_i2c_init(void *fdt, int nodeoff, ???????????????????????????? const struct fdt_match *match) ?{

lib/utils/i2c/fdt_i2c_dw.c +0 -0
@@ -35,7 +33,6 @@ static int fdt_dw_i2c_init(void *fdt, int nodeoff,
 ????????}

?
????????adapter->addr = addr; -???????adapter->adapter.driver = &fdt_i2c_adapter_dw; ?
????????rc = dw_i2c_init(&adapter->adapter, nodeoff); ????????if (rc) {

lib/utils/i2c/fdt_i2c_sifive.c +0 -0
index b85b245..1174062 100644
@@ -46,8 +46,6 @@ struct sifive_i2c_adapter {
 ????????struct i2c_adapter adapter;
 ?};

?

lib/utils/i2c/fdt_i2c_sifive.c +0 -2
-extern struct fdt_i2c_adapter fdt_i2c_adapter_sifive;
-

?static inline void sifive_i2c_setreg(struct sifive_i2c_adapter *adap, ???????????????????????????????????? uint8_t reg, uint8_t value) ?{

lib/utils/i2c/fdt_i2c_sifive.c +0 -0
@@ -250,7 +248,6 @@ static int sifive_i2c_init(void *fdt, int nodeoff,
 ????????}

?
????????adapter->addr = addr; -???????adapter->adapter.driver = &fdt_i2c_adapter_sifive; ????????adapter->adapter.id = nodeoff; ????????adapter->adapter.write = sifive_i2c_adapter_write; ????????adapter->adapter.read = sifive_i2c_adapter_read;

Signature · 1 line
2.34.1
author
#3 lore raw

PATCH 2/6 lib: utils/regmap: Add generic regmap access library

In reply to Anup Patel

We add generic regmap access library which is independent of hardware description format (FDT or ACPI). The OpenSBI platform support or regmap drivers can register regmap instances which can be discovered by different regmap clients based on the unique ID of regmap instances.

---
 include/sbi_utils/regmap/regmap.h  |  67 +++++++++++++++++
 lib/utils/Kconfig                  |   2 +
 lib/utils/regmap/Kconfig           |   9 +++
 lib/utils/regmap/objects.mk        |  10 +++
 lib/utils/regmap/regmap.c          | 114 +++++++++++++++++++++++++++++
 platform/generic/configs/defconfig |   3 +-
 6 files changed, 204 insertions(+), 1 deletion(-)
 create mode 100644 include/sbi_utils/regmap/regmap.h
 create mode 100644 lib/utils/regmap/Kconfig
 create mode 100644 lib/utils/regmap/objects.mk
 create mode 100644 lib/utils/regmap/regmap.c
include/sbi_utils/regmap/regmap.h new file +67 -0
new file mode 100644
index 0000000..58084fd
@@ -0,0 +1,67 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2023 Ventana Micro Systems Inc.
+ *
+ * Authors:
+ *   Anup Patel <[email protected]>
+ */
+
+#ifndef __REGMAP_H__
+#define __REGMAP_H__
+
+#include <sbi/sbi_types.h>
+#include <sbi/sbi_list.h>
+
+/** Representation of a regmap instance */
+struct regmap {
+	/** Uniquie ID of the regmap instance assigned by the driver */
+	unsigned int id;
+
+	/** Configuration of regmap registers */
+	int reg_shift;
+	int reg_stride;
+	unsigned int reg_base;
+	unsigned int reg_max;
+
+	/** Read a regmap register */
+	int (*reg_read)(struct regmap *rmap, unsigned int reg,
+			unsigned int *val);
+
+	/** Write a regmap register */
+	int (*reg_write)(struct regmap *rmap, unsigned int reg,
+			 unsigned int val);
+
+	/** Read-modify-write a regmap register */
+	int (*reg_update_bits)(struct regmap *rmap, unsigned int reg,
+			       unsigned int mask, unsigned int val);
+
+	/** List */
+	struct sbi_dlist node;
+};
+
+static inline struct regmap *to_regmap(struct sbi_dlist *node)
+{
+	return container_of(node, struct regmap, node);
+}
+
+/** Find a registered regmap instance */
+struct regmap *regmap_find(unsigned int id);
+
+/** Register a regmap instance */
+int regmap_add(struct regmap *rmap);
+
+/** Un-register a regmap instance */
+void regmap_remove(struct regmap *rmap);
+
+/** Read a register in a regmap instance */
+int regmap_read(struct regmap *rmap, unsigned int reg, unsigned int *val);
+
+/** Write a register in a regmap instance */
+int regmap_write(struct regmap *rmap, unsigned int reg, unsigned int val);
+
+/** Read-modify-write a register in a regmap instance */
+int regmap_update_bits(struct regmap *rmap, unsigned int reg,
+		       unsigned int mask, unsigned int val);
+
+#endif
lib/utils/Kconfig +2 -0
index 5a71e75..de8b4eb 100644
@@ -14,6 +14,8 @@ source "$(OPENSBI_SRC_DIR)/lib/utils/irqchip/Kconfig"
 
 source "$(OPENSBI_SRC_DIR)/lib/utils/libfdt/Kconfig"
 
+source "$(OPENSBI_SRC_DIR)/lib/utils/regmap/Kconfig"
+
 source "$(OPENSBI_SRC_DIR)/lib/utils/reset/Kconfig"
 
 source "$(OPENSBI_SRC_DIR)/lib/utils/serial/Kconfig"
lib/utils/regmap/Kconfig new file +9 -0
new file mode 100644
index 0000000..8db5c8b
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: BSD-2-Clause
+
+menu "Regmap Support"
+
+config REGMAP
+	bool "Regmap support"
+	default n
+
+endmenu
lib/utils/regmap/objects.mk new file +10 -0
new file mode 100644
index 0000000..5d1bead
@@ -0,0 +1,10 @@
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2023 Ventana Micro Systems Inc.
+#
+# Authors:
+#   Anup Patel <[email protected]>
+#
+
+libsbiutils-objs-$(CONFIG_REGMAP) += regmap/regmap.o
lib/utils/regmap/regmap.c new file +114 -0

114 lines not on this page · raw message

platform/generic/configs/defconfig +2 -1
index 671281b..d8793ea 100644
@@ -18,6 +18,7 @@ CONFIG_FDT_IRQCHIP=y
 CONFIG_FDT_IRQCHIP_APLIC=y
 CONFIG_FDT_IRQCHIP_IMSIC=y
 CONFIG_FDT_IRQCHIP_PLIC=y
+CONFIG_REGMAP=y
 CONFIG_FDT_RESET=y
 CONFIG_FDT_RESET_ATCWDT200=y
 CONFIG_FDT_RESET_GPIO=y
@@ -35,7 +36,7 @@ CONFIG_FDT_SERIAL_SIFIVE=y
 CONFIG_FDT_SERIAL_LITEX=y
 CONFIG_FDT_SERIAL_UART8250=y
 CONFIG_FDT_SERIAL_XILINX_UARTLITE=y
+CONFIG_SERIAL_SEMIHOSTING=y
 CONFIG_FDT_TIMER=y
 CONFIG_FDT_TIMER_MTIMER=y
 CONFIG_FDT_TIMER_PLMT=y
-CONFIG_SERIAL_SEMIHOSTING=y
Signature · 1 line
2.34.1
#4 lore raw

PATCH 2/6 lib: utils/regmap: Add generic regmap access library

? 2023-07-21???? 22:40 +0530?Anup Patel???

Quoted 7 lines

We add generic regmap access library which is independent of hardware description format (FDT or ACPI). The OpenSBI platform support or regmap drivers can register regmap instances which can be discovered by different regmap clients based on the unique ID of regmap instances.

Look good to me.

Quoted 275 lines

---

?include/sbi_utils/regmap/regmap.h? |? 67 +++++++++++++++++
?lib/utils/Kconfig????????????????? |?? 2 +
?lib/utils/regmap/Kconfig?????????? |?? 9 +++
?lib/utils/regmap/objects.mk??????? |? 10 +++
?lib/utils/regmap/regmap.c????????? | 114 +++++++++++++++++++++++++++++
?platform/generic/configs/defconfig |?? 3 +-

?6 files changed, 204 insertions(+), 1 deletion(-) ?create mode 100644 include/sbi_utils/regmap/regmap.h ?create mode 100644 lib/utils/regmap/Kconfig ?create mode 100644 lib/utils/regmap/objects.mk ?create mode 100644 lib/utils/regmap/regmap.c

include/sbi_utils/regmap/regmap.h new file +67 -0
new file mode 100644
index 0000000..58084fd
@@ -0,0 +1,67 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2023 Ventana Micro Systems Inc.
+ *
+ * Authors:
+ *?? Anup Patel <[email protected]>
+ */
+
+#ifndef __REGMAP_H__
+#define __REGMAP_H__
+
+#include <sbi/sbi_types.h>
+#include <sbi/sbi_list.h>
+
+/** Representation of a regmap instance */
+struct regmap {
+???????/** Uniquie ID of the regmap instance assigned by the driver */
+???????unsigned int id;
+
+???????/** Configuration of regmap registers */
+???????int reg_shift;
+???????int reg_stride;
+???????unsigned int reg_base;
+???????unsigned int reg_max;
+
+???????/** Read a regmap register */
+???????int (*reg_read)(struct regmap *rmap, unsigned int reg,
+???????????????????????unsigned int *val);
+
+???????/** Write a regmap register */
+???????int (*reg_write)(struct regmap *rmap, unsigned int reg,
+??????????????????????? unsigned int val);
+
+???????/** Read-modify-write a regmap register */
+???????int (*reg_update_bits)(struct regmap *rmap, unsigned int reg,
+????????????????????????????? unsigned int mask, unsigned int val);
+
+???????/** List */
+???????struct sbi_dlist node;
+};
+
+static inline struct regmap *to_regmap(struct sbi_dlist *node)
+{
+???????return container_of(node, struct regmap, node);
+}
+
+/** Find a registered regmap instance */
+struct regmap *regmap_find(unsigned int id);
+
+/** Register a regmap instance */
+int regmap_add(struct regmap *rmap);
+
+/** Un-register a regmap instance */
+void regmap_remove(struct regmap *rmap);
+
+/** Read a register in a regmap instance */
+int regmap_read(struct regmap *rmap, unsigned int reg, unsigned int *val);
+
+/** Write a register in a regmap instance */
+int regmap_write(struct regmap *rmap, unsigned int reg, unsigned int val);
+
+/** Read-modify-write a register in a regmap instance */
+int regmap_update_bits(struct regmap *rmap, unsigned int reg,
+????????????????????? unsigned int mask, unsigned int val);
+
+#endif
lib/utils/Kconfig +0 -0
index 5a71e75..de8b4eb 100644
@@ -14,6 +14,8 @@ source "$(OPENSBI_SRC_DIR)/lib/utils/irqchip/Kconfig"

?
?source "$(OPENSBI_SRC_DIR)/lib/utils/libfdt/Kconfig" ?

lib/utils/Kconfig +2 -0
+source "$(OPENSBI_SRC_DIR)/lib/utils/regmap/Kconfig"
+

?source "$(OPENSBI_SRC_DIR)/lib/utils/reset/Kconfig" ?
?source "$(OPENSBI_SRC_DIR)/lib/utils/serial/Kconfig"

lib/utils/regmap/Kconfig new file +9 -0
new file mode 100644
index 0000000..8db5c8b
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: BSD-2-Clause
+
+menu "Regmap Support"
+
+config REGMAP
+???????bool "Regmap support"
+???????default n
+
+endmenu
lib/utils/regmap/objects.mk new file +10 -0
new file mode 100644
index 0000000..5d1bead
@@ -0,0 +1,10 @@
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2023 Ventana Micro Systems Inc.
+#
+# Authors:
+#?? Anup Patel <[email protected]>
+#
+
+libsbiutils-objs-$(CONFIG_REGMAP) += regmap/regmap.o
lib/utils/regmap/regmap.c new file +114 -0
new file mode 100644
index 0000000..a2180c8
@@ -0,0 +1,114 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2023 Ventana Micro Systems Inc.
+ *
+ * Authors:
+ *?? Anup Patel <[email protected]>
+ */
+
+#include <sbi/sbi_error.h>
+#include <sbi_utils/regmap/regmap.h>
+
+static SBI_LIST_HEAD(regmap_list);
+
+struct regmap *regmap_find(unsigned int id)
+{
+???????struct sbi_dlist *pos;
+
+???????sbi_list_for_each(pos, &(regmap_list)) {
+???????????????struct regmap *rmap = to_regmap(pos);
+
+???????????????if (rmap->id == id)
+???????????????????????return rmap;
+???????}
+
+???????return NULL;
+}
+
+int regmap_add(struct regmap *rmap)
+{
+???????if (!rmap)
+???????????????return SBI_EINVAL;
+???????if (regmap_find(rmap->id))
+???????????????return SBI_EALREADY;
+
+???????sbi_list_add(&(rmap->node), &(regmap_list));
+
+???????return 0;
+}
+
+void regmap_remove(struct regmap *rmap)
+{
+???????if (!rmap)
+???????????????return;
+
+???????sbi_list_del(&(rmap->node));
+}
+
+static bool regmap_reg_valid(struct regmap *rmap, unsigned int reg)
+{
+???????if ((reg >= rmap->reg_max) ||
+?????????? (reg & (rmap->reg_stride - 1)))
+???????????????return false;
+???????return true;
+}
+
+static unsigned int regmap_reg_addr(struct regmap *rmap, unsigned int reg)
+{
+???????reg += rmap->reg_base;
+
+???????if (rmap->reg_shift > 0)
+???????????????reg >>= rmap->reg_shift;
+???????else if (rmap->reg_shift < 0)
+???????????????reg <<= -(rmap->reg_shift);
+
+???????return reg;
+}
+
+int regmap_read(struct regmap *rmap, unsigned int reg, unsigned int *val)
+{
+???????if (!rmap || !regmap_reg_valid(rmap, reg))
+???????????????return SBI_EINVAL;
+???????if (!rmap->reg_read)
+???????????????return SBI_ENOSYS;
+
+???????return rmap->reg_read(rmap, regmap_reg_addr(rmap, reg), val);
+}
+
+int regmap_write(struct regmap *rmap, unsigned int reg, unsigned int val)
+{
+???????if (!rmap || !regmap_reg_valid(rmap, reg))
+???????????????return SBI_EINVAL;
+???????if (!rmap->reg_write)
+???????????????return SBI_ENOSYS;
+
+???????return rmap->reg_write(rmap, regmap_reg_addr(rmap, reg), val);
+}
+
+int regmap_update_bits(struct regmap *rmap, unsigned int reg,
+????????????????????? unsigned int mask, unsigned int val)
+{
+???????int rc;
+???????unsigned int reg_val;
+
+???????if (!rmap || !regmap_reg_valid(rmap, reg))
+???????????????return SBI_EINVAL;
+
+???????if (rmap->reg_update_bits) {
+???????????????return rmap->reg_update_bits(rmap, regmap_reg_addr(rmap, reg),
+??????????????????????????????????????????? mask, val);
+???????} else if (rmap->reg_read && rmap->reg_write) {
+???????????????reg = regmap_reg_addr(rmap, reg);
+
+???????????????rc = rmap->reg_read(rmap, reg, &reg_val);
+???????????????if (rc)
+???????????????????????return rc;
+
+???????????????reg_val &= ~mask;
+???????????????reg_val |= val & mask;
+???????????????return rmap->reg_write(rmap, reg, reg_val);
+???????}
+
+???????return SBI_ENOSYS;
+}
platform/generic/configs/defconfig +0 -0
index 671281b..d8793ea 100644
@@ -18,6 +18,7 @@ CONFIG_FDT_IRQCHIP=y

?CONFIG_FDT_IRQCHIP_APLIC=y
?CONFIG_FDT_IRQCHIP_IMSIC=y
?CONFIG_FDT_IRQCHIP_PLIC=y
+CONFIG_REGMAP=y
?CONFIG_FDT_RESET=y
?CONFIG_FDT_RESET_ATCWDT200=y
?CONFIG_FDT_RESET_GPIO=y

platform/generic/configs/defconfig +0 -0
@@ -35,7 +36,7 @@ CONFIG_FDT_SERIAL_SIFIVE=y

?CONFIG_FDT_SERIAL_LITEX=y
?CONFIG_FDT_SERIAL_UART8250=y
?CONFIG_FDT_SERIAL_XILINX_UARTLITE=y
+CONFIG_SERIAL_SEMIHOSTING=y
?CONFIG_FDT_TIMER=y
?CONFIG_FDT_TIMER_MTIMER=y
?CONFIG_FDT_TIMER_PLMT=y
-CONFIG_SERIAL_SEMIHOSTING=y

Signature · 1 line
2.34.1
author
#5 lore raw

PATCH 3/6 lib: utils/regmap: Add simple FDT based regmap framework

In reply to Anup Patel

We add a simple FDT based regmap framework which is built on top of generic regmap library. The phandle of FDT regmap DT node is treated as unique regmap ID. The FDT based regmap drivers will be probed on-demand from fdt_regmap_get_by_phandle() and fdt_regmap_get() called by the regmap client drivers.

---
 include/sbi_utils/regmap/fdt_regmap.h      | 31 +++++++
 lib/utils/regmap/Kconfig                   |  6 ++
 lib/utils/regmap/fdt_regmap.c              | 94 ++++++++++++++++++++++
 lib/utils/regmap/fdt_regmap_drivers.carray |  3 +
 lib/utils/regmap/objects.mk                |  3 +
 platform/generic/configs/defconfig         |  2 +-
 6 files changed, 138 insertions(+), 1 deletion(-)
 create mode 100644 include/sbi_utils/regmap/fdt_regmap.h
 create mode 100644 lib/utils/regmap/fdt_regmap.c
 create mode 100644 lib/utils/regmap/fdt_regmap_drivers.carray
include/sbi_utils/regmap/fdt_regmap.h new file +31 -0
new file mode 100644
index 0000000..0672162
@@ -0,0 +1,31 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2023 Ventana Micro Systems Inc.
+ *
+ * Authors:
+ *   Anup Patel <[email protected]>
+ */
+
+#ifndef __FDT_REGMAP_H__
+#define __FDT_REGMAP_H__
+
+#include <sbi_utils/regmap/regmap.h>
+
+struct fdt_phandle_args;
+
+/** FDT based regmap driver */
+struct fdt_regmap {
+	const struct fdt_match *match_table;
+	int (*init)(void *fdt, int nodeoff, u32 phandle,
+		    const struct fdt_match *match);
+};
+
+/** Get regmap instance based on phandle */
+int fdt_regmap_get_by_phandle(void *fdt, u32 phandle,
+			      struct regmap **out_rmap);
+
+/** Get regmap instance based on "regmap' property of the specified DT node */
+int fdt_regmap_get(void *fdt, int nodeoff, struct regmap **out_rmap);
+
+#endif
lib/utils/regmap/Kconfig +6 -0
index 8db5c8b..b1ff501 100644
@@ -2,6 +2,12 @@
 
 menu "Regmap Support"
 
+config FDT_REGMAP
+	bool "FDT based regmap drivers"
+	depends on FDT
+	select REGMAP
+	default n
+
 config REGMAP
 	bool "Regmap support"
 	default n
lib/utils/regmap/fdt_regmap.c new file +94 -0

94 lines not on this page · raw message

lib/utils/regmap/fdt_regmap_drivers.carray new file +3 -0
new file mode 100644
index 0000000..c2f1c9d
@@ -0,0 +1,3 @@
+HEADER: sbi_utils/regmap/fdt_regmap.h
+TYPE: struct fdt_regmap
+NAME: fdt_regmap_drivers
lib/utils/regmap/objects.mk +3 -0
index 5d1bead..5ce2373 100644
@@ -7,4 +7,7 @@
 #   Anup Patel <[email protected]>
 #
 
+libsbiutils-objs-$(CONFIG_FDT_REGMAP) += regmap/fdt_regmap.o
+libsbiutils-objs-$(CONFIG_FDT_REGMAP) += regmap/fdt_regmap_drivers.o
+
 libsbiutils-objs-$(CONFIG_REGMAP) += regmap/regmap.o
platform/generic/configs/defconfig +1 -1
index d8793ea..ad585e3 100644
@@ -18,7 +18,7 @@ CONFIG_FDT_IRQCHIP=y
 CONFIG_FDT_IRQCHIP_APLIC=y
 CONFIG_FDT_IRQCHIP_IMSIC=y
 CONFIG_FDT_IRQCHIP_PLIC=y
-CONFIG_REGMAP=y
+CONFIG_FDT_REGMAP=y
 CONFIG_FDT_RESET=y
 CONFIG_FDT_RESET_ATCWDT200=y
 CONFIG_FDT_RESET_GPIO=y
Signature · 1 line
2.34.1
#6 lore raw

PATCH 3/6 lib: utils/regmap: Add simple FDT based regmap framework

? 2023-07-21???? 22:40 +0530?Anup Patel???

Quoted 7 lines

We add a simple FDT based regmap framework which is built on top of generic regmap library. The phandle of FDT regmap DT node is treated as unique regmap ID. The FDT based regmap drivers will be probed on-demand from fdt_regmap_get_by_phandle() and fdt_regmap_get() called by the regmap client drivers.

Look good to me.

Quoted 204 lines

---

?include/sbi_utils/regmap/fdt_regmap.h????? | 31 +++++++
?lib/utils/regmap/Kconfig?????????????????? |? 6 ++
?lib/utils/regmap/fdt_regmap.c????????????? | 94 ++++++++++++++++++++++
?lib/utils/regmap/fdt_regmap_drivers.carray |? 3 +
?lib/utils/regmap/objects.mk??????????????? |? 3 +
?platform/generic/configs/defconfig???????? |? 2 +-

?6 files changed, 138 insertions(+), 1 deletion(-) ?create mode 100644 include/sbi_utils/regmap/fdt_regmap.h ?create mode 100644 lib/utils/regmap/fdt_regmap.c ?create mode 100644 lib/utils/regmap/fdt_regmap_drivers.carray

include/sbi_utils/regmap/fdt_regmap.h new file +31 -0
new file mode 100644
index 0000000..0672162
@@ -0,0 +1,31 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2023 Ventana Micro Systems Inc.
+ *
+ * Authors:
+ *?? Anup Patel <[email protected]>
+ */
+
+#ifndef __FDT_REGMAP_H__
+#define __FDT_REGMAP_H__
+
+#include <sbi_utils/regmap/regmap.h>
+
+struct fdt_phandle_args;
+
+/** FDT based regmap driver */
+struct fdt_regmap {
+???????const struct fdt_match *match_table;
+???????int (*init)(void *fdt, int nodeoff, u32 phandle,
+?????????????????? const struct fdt_match *match);
+};
+
+/** Get regmap instance based on phandle */
+int fdt_regmap_get_by_phandle(void *fdt, u32 phandle,
+???????????????????????????? struct regmap **out_rmap);
+
+/** Get regmap instance based on "regmap' property of the specified DT node */
+int fdt_regmap_get(void *fdt, int nodeoff, struct regmap **out_rmap);
+
+#endif
lib/utils/regmap/Kconfig +0 -0
index 8db5c8b..b1ff501 100644
@@ -2,6 +2,12 @@

?
?menu "Regmap Support"
?

lib/utils/regmap/Kconfig +6 -0
+config FDT_REGMAP
+???????bool "FDT based regmap drivers"
+???????depends on FDT
+???????select REGMAP
+???????default n
+

?config REGMAP
????????bool "Regmap support"
????????default n

lib/utils/regmap/fdt_regmap.c new file +94 -0
new file mode 100644
index 0000000..fffac1d
@@ -0,0 +1,94 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2023 Ventana Micro Systems Inc.
+ *
+ * Authors:
+ *?? Anup Patel <[email protected]>
+ */
+
+#include <libfdt.h>
+#include <sbi/sbi_error.h>
+#include <sbi_utils/fdt/fdt_helper.h>
+#include <sbi_utils/regmap/fdt_regmap.h>
+
+/* List of FDT regmap drivers generated at compile time */
+extern struct fdt_regmap *fdt_regmap_drivers[];
+extern unsigned long fdt_regmap_drivers_size;
+
+static int fdt_regmap_init(void *fdt, int nodeoff, u32 phandle)
+{
+???????int pos, rc;
+???????struct fdt_regmap *drv;
+???????const struct fdt_match *match;
+
+???????/* Try all I2C drivers one-by-one */
+???????for (pos = 0; pos < fdt_regmap_drivers_size; pos++) {
+???????????????drv = fdt_regmap_drivers[pos];
+???????????????match = fdt_match_node(fdt, nodeoff, drv->match_table);
+???????????????if (match && drv->init) {
+???????????????????????rc = drv->init(fdt, nodeoff, phandle, match);
+???????????????????????if (rc == SBI_ENODEV)
+???????????????????????????????continue;
+???????????????????????if (rc)
+???????????????????????????????return rc;
+???????????????????????return 0;
+???????????????}
+???????}
+
+???????return SBI_ENOSYS;
+}
+
+static int fdt_regmap_find(void *fdt, int nodeoff, u32 phandle,
+????????????????????????? struct regmap **out_rmap)
+{
+???????int rc;
+???????struct regmap *rmap = regmap_find(phandle);
+
+???????if (!rmap) {
+???????????????/* Regmap not found so initialize matching driver */
+???????????????rc = fdt_regmap_init(fdt, nodeoff, phandle);
+???????????????if (rc)
+???????????????????????return rc;
+
+???????????????/* Try to find regmap again */
+???????????????rmap = regmap_find(phandle);
+???????????????if (!rmap)
+???????????????????????return SBI_ENOSYS;
+???????}
+
+???????if (out_rmap)
+???????????????*out_rmap = rmap;
+
+???????return 0;
+}
+
+int fdt_regmap_get_by_phandle(void *fdt, u32 phandle,
+???????????????????????????? struct regmap **out_rmap)
+{
+???????int pnodeoff;
+
+???????if (!fdt || !out_rmap)
+???????????????return SBI_EINVAL;
+
+???????pnodeoff = fdt_node_offset_by_phandle(fdt, phandle);
+???????if (pnodeoff < 0)
+???????????????return pnodeoff;
+
+???????return fdt_regmap_find(fdt, pnodeoff, phandle, out_rmap);
+}
+
+int fdt_regmap_get(void *fdt, int nodeoff, struct regmap **out_rmap)
+{
+???????int len;
+???????const fdt32_t *val;
+
+???????if (!fdt || (nodeoff < 0) || !out_rmap)
+???????????????return SBI_EINVAL;
+
+???????val = fdt_getprop(fdt, nodeoff, "regmap", &len);
+???????if (!val)
+???????????????return SBI_ENOENT;
+
+???????return fdt_regmap_get_by_phandle(fdt, fdt32_to_cpu(*val), out_rmap);
+}
lib/utils/regmap/fdt_regmap_drivers.carray new file +3 -0
new file mode 100644
index 0000000..c2f1c9d
@@ -0,0 +1,3 @@
+HEADER: sbi_utils/regmap/fdt_regmap.h
+TYPE: struct fdt_regmap
+NAME: fdt_regmap_drivers
lib/utils/regmap/objects.mk +0 -0
index 5d1bead..5ce2373 100644
@@ -7,4 +7,7 @@

?#?? Anup Patel <[email protected]>
?#
?

lib/utils/regmap/objects.mk +3 -0
+libsbiutils-objs-$(CONFIG_FDT_REGMAP) += regmap/fdt_regmap.o
+libsbiutils-objs-$(CONFIG_FDT_REGMAP) += regmap/fdt_regmap_drivers.o
+

?libsbiutils-objs-$(CONFIG_REGMAP) += regmap/regmap.o

platform/generic/configs/defconfig +0 -0
index d8793ea..ad585e3 100644
@@ -18,7 +18,7 @@ CONFIG_FDT_IRQCHIP=y

?CONFIG_FDT_IRQCHIP_APLIC=y
?CONFIG_FDT_IRQCHIP_IMSIC=y
?CONFIG_FDT_IRQCHIP_PLIC=y

platform/generic/configs/defconfig +1 -1
-CONFIG_REGMAP=y
+CONFIG_FDT_REGMAP=y

?CONFIG_FDT_RESET=y
?CONFIG_FDT_RESET_ATCWDT200=y
?CONFIG_FDT_RESET_GPIO=y

Signature · 1 line
2.34.1
author
#7 lore raw

PATCH 4/6 lib: utils/regmap: Add simple FDT based syscon regmap driver

In reply to Anup Patel

Let us add a simple FDT based system regmap driver which follows the device tree bindings already defined in the Linux kernel.

---
 lib/utils/regmap/Kconfig             |   7 +
 lib/utils/regmap/fdt_regmap_syscon.c | 262 +++++++++++++++++++++++++++
 lib/utils/regmap/objects.mk          |   3 +
 platform/generic/configs/defconfig   |   1 +
 4 files changed, 273 insertions(+)
 create mode 100644 lib/utils/regmap/fdt_regmap_syscon.c
lib/utils/regmap/Kconfig +7 -0
index b1ff501..62d9f93 100644
@@ -8,6 +8,13 @@ config FDT_REGMAP
 	select REGMAP
 	default n
 
+if FDT_REGMAP
+
+config FDT_REGMAP_SYSCON
+	bool "Syscon regmap FDT driver"
+	default n
+endif
+
 config REGMAP
 	bool "Regmap support"
 	default n
lib/utils/regmap/fdt_regmap_syscon.c new file +262 -0

262 lines not on this page · raw message

lib/utils/regmap/objects.mk +3 -0
index 5ce2373..5bd139f 100644
@@ -10,4 +10,7 @@
 libsbiutils-objs-$(CONFIG_FDT_REGMAP) += regmap/fdt_regmap.o
 libsbiutils-objs-$(CONFIG_FDT_REGMAP) += regmap/fdt_regmap_drivers.o
 
+carray-fdt_regmap_drivers-$(CONFIG_FDT_REGMAP_SYSCON) += fdt_regmap_syscon
+libsbiutils-objs-$(CONFIG_FDT_REGMAP_SYSCON) += regmap/fdt_regmap_syscon.o
+
 libsbiutils-objs-$(CONFIG_REGMAP) += regmap/regmap.o
platform/generic/configs/defconfig +1 -0
index ad585e3..b767290 100644
@@ -19,6 +19,7 @@ CONFIG_FDT_IRQCHIP_APLIC=y
 CONFIG_FDT_IRQCHIP_IMSIC=y
 CONFIG_FDT_IRQCHIP_PLIC=y
 CONFIG_FDT_REGMAP=y
+CONFIG_FDT_REGMAP_SYSCON=y
 CONFIG_FDT_RESET=y
 CONFIG_FDT_RESET_ATCWDT200=y
 CONFIG_FDT_RESET_GPIO=y
Signature · 1 line
2.34.1
#8 lore raw

PATCH 4/6 lib: utils/regmap: Add simple FDT based syscon regmap driver

? 2023-07-21???? 22:40 +0530?Anup Patel???

Quoted 4 lines

Let us add a simple FDT based system regmap driver which follows the device tree bindings already defined in the Linux kernel.

Look good to me.

Quoted 322 lines

---

?lib/utils/regmap/Kconfig???????????? |?? 7 +
?lib/utils/regmap/fdt_regmap_syscon.c | 262 +++++++++++++++++++++++++++
?lib/utils/regmap/objects.mk????????? |?? 3 +
?platform/generic/configs/defconfig?? |?? 1 +

?4 files changed, 273 insertions(+)
?create mode 100644 lib/utils/regmap/fdt_regmap_syscon.c

lib/utils/regmap/Kconfig +0 -0
index b1ff501..62d9f93 100644
@@ -8,6 +8,13 @@ config FDT_REGMAP

????????select REGMAP
????????default n
?

lib/utils/regmap/Kconfig +7 -0
+if FDT_REGMAP
+
+config FDT_REGMAP_SYSCON
+???????bool "Syscon regmap FDT driver"
+???????default n
+endif
+

?config REGMAP
????????bool "Regmap support"
????????default n

lib/utils/regmap/fdt_regmap_syscon.c new file +262 -0
new file mode 100644
index 0000000..29263dd
@@ -0,0 +1,262 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2023 Ventana Micro Systems Inc.
+ *
+ * Authors:
+ *?? Anup Patel <[email protected]>
+ */
+
+#include <libfdt.h>
+#include <sbi/riscv_io.h>
+#include <sbi/sbi_byteorder.h>
+#include <sbi/sbi_error.h>
+#include <sbi/sbi_heap.h>
+#include <sbi_utils/fdt/fdt_helper.h>
+#include <sbi_utils/regmap/fdt_regmap.h>
+
+enum syscon_regmap_endian {
+???????SYSCON_ENDIAN_NATIVE = 0,
+???????SYSCON_ENDIAN_LITTLE,
+???????SYSCON_ENDIAN_BIG,
+???????SYSCON_ENDIAN_MAX
+};
+
+struct syscon_regmap {
+???????u32 reg_io_width;
+???????enum syscon_regmap_endian reg_endian;
+???????unsigned long addr;
+???????struct regmap rmap;
+};
+
+#define to_syscon_regmap(__rmap)???????\
+???????container_of((__rmap), struct syscon_regmap, rmap)
+
+static int regmap_syscon_read_8(struct regmap *rmap, unsigned int reg,
+???????????????????????????????unsigned int *val)
+{
+???????struct syscon_regmap *srm = to_syscon_regmap(rmap);
+
+???????*val = readb((volatile void *)(srm->addr + reg));
+???????return 0;
+}
+
+static int regmap_syscon_write_8(struct regmap *rmap, unsigned int reg,
+??????????????????????????????? unsigned int val)
+{
+???????struct syscon_regmap *srm = to_syscon_regmap(rmap);
+
+???????writeb(val, (volatile void *)(srm->addr + reg));
+???????return 0;
+}
+
+static int regmap_syscon_read_16(struct regmap *rmap, unsigned int reg,
+???????????????????????????????unsigned int *val)
+{
+???????struct syscon_regmap *srm = to_syscon_regmap(rmap);
+
+???????*val = readw((volatile void *)(srm->addr + reg));
+???????return 0;
+}
+
+static int regmap_syscon_write_16(struct regmap *rmap, unsigned int reg,
+??????????????????????????????? unsigned int val)
+{
+???????struct syscon_regmap *srm = to_syscon_regmap(rmap);
+
+???????writew(val, (volatile void *)(srm->addr + reg));
+???????return 0;
+}
+
+static int regmap_syscon_read_32(struct regmap *rmap, unsigned int reg,
+???????????????????????????????unsigned int *val)
+{
+???????struct syscon_regmap *srm = to_syscon_regmap(rmap);
+
+???????*val = readl((volatile void *)(srm->addr + reg));
+???????return 0;
+}
+
+static int regmap_syscon_write_32(struct regmap *rmap, unsigned int reg,
+??????????????????????????????? unsigned int val)
+{
+???????struct syscon_regmap *srm = to_syscon_regmap(rmap);
+
+???????writel(val, (volatile void *)(srm->addr + reg));
+???????return 0;
+}
+
+static int regmap_syscon_read_le16(struct regmap *rmap, unsigned int reg,
+????????????????????????????????? unsigned int *val)
+{
+???????struct syscon_regmap *srm = to_syscon_regmap(rmap);
+
+???????*val = le16_to_cpu(readw((volatile void *)(srm->addr + reg)));
+???????return 0;
+}
+
+static int regmap_syscon_write_le16(struct regmap *rmap, unsigned int reg,
+?????????????????????????????????? unsigned int val)
+{
+???????struct syscon_regmap *srm = to_syscon_regmap(rmap);
+
+???????writew(cpu_to_le16(val), (volatile void *)(srm->addr + reg));
+???????return 0;
+}
+
+static int regmap_syscon_read_le32(struct regmap *rmap, unsigned int reg,
+????????????????????????????????? unsigned int *val)
+{
+???????struct syscon_regmap *srm = to_syscon_regmap(rmap);
+
+???????*val = le32_to_cpu(readl((volatile void *)(srm->addr + reg)));
+???????return 0;
+}
+
+static int regmap_syscon_write_le32(struct regmap *rmap, unsigned int reg,
+?????????????????????????????????? unsigned int val)
+{
+???????struct syscon_regmap *srm = to_syscon_regmap(rmap);
+
+???????writel(cpu_to_le32(val), (volatile void *)(srm->addr + reg));
+???????return 0;
+}
+
+static int regmap_syscon_read_be16(struct regmap *rmap, unsigned int reg,
+????????????????????????????????? unsigned int *val)
+{
+???????struct syscon_regmap *srm = to_syscon_regmap(rmap);
+
+???????*val = be16_to_cpu(readl((volatile void *)(srm->addr + reg)));
+???????return 0;
+}
+
+static int regmap_syscon_write_be16(struct regmap *rmap, unsigned int reg,
+?????????????????????????????????? unsigned int val)
+{
+???????struct syscon_regmap *srm = to_syscon_regmap(rmap);
+
+???????writel(cpu_to_be16(val), (volatile void *)(srm->addr + reg));
+???????return 0;
+}
+
+static int regmap_syscon_read_be32(struct regmap *rmap, unsigned int reg,
+????????????????????????????????? unsigned int *val)
+{
+???????struct syscon_regmap *srm = to_syscon_regmap(rmap);
+
+???????*val = be32_to_cpu(readl((volatile void *)(srm->addr + reg)));
+???????return 0;
+}
+
+static int regmap_syscon_write_be32(struct regmap *rmap, unsigned int reg,
+?????????????????????????????????? unsigned int val)
+{
+???????struct syscon_regmap *srm = to_syscon_regmap(rmap);
+
+???????writel(cpu_to_be32(val), (volatile void *)(srm->addr + reg));
+???????return 0;
+}
+
+static int regmap_syscon_init(void *fdt, int nodeoff, u32 phandle,
+???????????????????????????? const struct fdt_match *match)
+{
+???????struct syscon_regmap *srm;
+???????uint64_t addr, size;
+???????const fdt32_t *val;
+???????int rc, len;
+
+???????srm = sbi_zalloc(sizeof(*srm));
+???????if (!srm)
+???????????????return SBI_ENOMEM;
+
+???????val = fdt_getprop(fdt, nodeoff, "reg-io-width", &len);
+???????srm->reg_io_width = val ? fdt32_to_cpu(*val) : 4;
+
+???????if (fdt_getprop(fdt, nodeoff, "native-endian", &len))
+???????????????srm->reg_endian = SYSCON_ENDIAN_NATIVE;
+???????else if (fdt_getprop(fdt, nodeoff, "little-endian", &len))
+???????????????srm->reg_endian = SYSCON_ENDIAN_LITTLE;
+???????else if (fdt_getprop(fdt, nodeoff, "big-endian", &len))
+???????????????srm->reg_endian = SYSCON_ENDIAN_BIG;
+???????else
+???????????????srm->reg_endian = SYSCON_ENDIAN_NATIVE;
+
+???????rc = fdt_get_node_addr_size(fdt, nodeoff, 0, &addr, &size);
+???????if (rc)
+???????????????goto fail_free_syscon;
+???????srm->addr = addr;
+
+???????srm->rmap.id = phandle;
+???????srm->rmap.reg_shift = 0;
+???????srm->rmap.reg_stride = srm->reg_io_width * 8;
+???????srm->rmap.reg_base = 0;
+???????srm->rmap.reg_max = size / srm->reg_io_width;
+???????switch (srm->reg_io_width) {
+???????case 1:
+???????????????srm->rmap.reg_read = regmap_syscon_read_8;
+???????????????srm->rmap.reg_write = regmap_syscon_write_8;
+???????????????break;
+???????case 2:
+???????????????switch (srm->reg_endian) {
+???????????????case SYSCON_ENDIAN_NATIVE:
+???????????????????????srm->rmap.reg_read = regmap_syscon_read_16;
+???????????????????????srm->rmap.reg_write = regmap_syscon_write_16;
+???????????????????????break;
+???????????????case SYSCON_ENDIAN_LITTLE:
+???????????????????????srm->rmap.reg_read = regmap_syscon_read_le16;
+???????????????????????srm->rmap.reg_write = regmap_syscon_write_le16;
+???????????????????????break;
+???????????????case SYSCON_ENDIAN_BIG:
+???????????????????????srm->rmap.reg_read = regmap_syscon_read_be16;
+???????????????????????srm->rmap.reg_write = regmap_syscon_write_be16;
+???????????????????????break;
+???????????????default:
+???????????????????????rc = SBI_EINVAL;
+???????????????????????goto fail_free_syscon;
+???????????????}
+???????????????break;
+???????case 4:
+???????????????switch (srm->reg_endian) {
+???????????????case SYSCON_ENDIAN_NATIVE:
+???????????????????????srm->rmap.reg_read = regmap_syscon_read_32;
+???????????????????????srm->rmap.reg_write = regmap_syscon_write_32;
+???????????????????????break;
+???????????????case SYSCON_ENDIAN_LITTLE:
+???????????????????????srm->rmap.reg_read = regmap_syscon_read_le32;
+???????????????????????srm->rmap.reg_write = regmap_syscon_write_le32;
+???????????????????????break;
+???????????????case SYSCON_ENDIAN_BIG:
+???????????????????????srm->rmap.reg_read = regmap_syscon_read_be32;
+???????????????????????srm->rmap.reg_write = regmap_syscon_write_be32;
+???????????????????????break;
+???????????????default:
+???????????????????????rc = SBI_EINVAL;
+???????????????????????goto fail_free_syscon;
+???????????????}
+???????????????break;
+???????default:
+???????????????rc = SBI_EINVAL;
+???????????????goto fail_free_syscon;
+???????}
+
+???????rc = regmap_add(&srm->rmap);
+???????if (rc)
+???????????????goto fail_free_syscon;
+
+???????return 0;
+
+fail_free_syscon:
+???????sbi_free(srm);
+???????return rc;
+}
+
+static const struct fdt_match regmap_syscon_match[] = {
+???????{ .compatible = "syscon" },
+???????{ },
+};
+
+struct fdt_regmap fdt_regmap_syscon = {
+???????.match_table = regmap_syscon_match,
+???????.init = regmap_syscon_init,
+};
lib/utils/regmap/objects.mk +0 -0
index 5ce2373..5bd139f 100644
@@ -10,4 +10,7 @@

?libsbiutils-objs-$(CONFIG_FDT_REGMAP) += regmap/fdt_regmap.o ?libsbiutils-objs-$(CONFIG_FDT_REGMAP) += regmap/fdt_regmap_drivers.o ?

lib/utils/regmap/objects.mk +3 -0
+carray-fdt_regmap_drivers-$(CONFIG_FDT_REGMAP_SYSCON) += fdt_regmap_syscon
+libsbiutils-objs-$(CONFIG_FDT_REGMAP_SYSCON) += regmap/fdt_regmap_syscon.o
+

?libsbiutils-objs-$(CONFIG_REGMAP) += regmap/regmap.o

platform/generic/configs/defconfig +0 -0
index ad585e3..b767290 100644
@@ -19,6 +19,7 @@ CONFIG_FDT_IRQCHIP_APLIC=y

?CONFIG_FDT_IRQCHIP_IMSIC=y
?CONFIG_FDT_IRQCHIP_PLIC=y
?CONFIG_FDT_REGMAP=y
+CONFIG_FDT_REGMAP_SYSCON=y
?CONFIG_FDT_RESET=y
?CONFIG_FDT_RESET_ATCWDT200=y
?CONFIG_FDT_RESET_GPIO=y

Signature · 1 line
2.34.1
author
#9 lore raw

PATCH 5/6 lib: utils/reset: Add syscon based reboot and poweroff

In reply to Anup Patel

Let us have common FDT based reset driver for syscon reboot and poweroff. The device tree bindings for syscon reboot and poweroff are already available in the Linux kernel sources.

---
 lib/utils/reset/Kconfig            |   5 +
 lib/utils/reset/fdt_reset_syscon.c | 167 +++++++++++++++++++++++++++++
 lib/utils/reset/objects.mk         |   4 +
 platform/generic/configs/defconfig |   1 +
 4 files changed, 177 insertions(+)
 create mode 100644 lib/utils/reset/fdt_reset_syscon.c
lib/utils/reset/Kconfig +5 -0
index 4748cc8..c0b9640 100644
@@ -33,6 +33,11 @@ config FDT_RESET_SUNXI_WDT
 	bool "Sunxi WDT FDT reset driver"
 	default n
 
+config FDT_RESET_SYSCON
+	bool "Syscon FDT reset driver"
+	depends on FDT_REGMAP
+	default n
+
 config FDT_RESET_THEAD
 	bool "T-HEAD FDT reset driver"
 	default n
lib/utils/reset/fdt_reset_syscon.c new file +167 -0

167 lines not on this page · raw message

lib/utils/reset/objects.mk +4 -0
index c9f851c..17287a5 100644
@@ -26,6 +26,10 @@ libsbiutils-objs-$(CONFIG_FDT_RESET_SIFIVE_TEST) += reset/fdt_reset_sifive_test.
 carray-fdt_reset_drivers-$(CONFIG_FDT_RESET_SUNXI_WDT) += fdt_reset_sunxi_wdt
 libsbiutils-objs-$(CONFIG_FDT_RESET_SUNXI_WDT) += reset/fdt_reset_sunxi_wdt.o
 
+carray-fdt_reset_drivers-$(CONFIG_FDT_RESET_SYSCON) += fdt_syscon_poweroff
+carray-fdt_reset_drivers-$(CONFIG_FDT_RESET_SYSCON) += fdt_syscon_reboot
+libsbiutils-objs-$(CONFIG_FDT_RESET_SYSCON) += reset/fdt_reset_syscon.o
+
 carray-fdt_reset_drivers-$(CONFIG_FDT_RESET_THEAD) += fdt_reset_thead
 libsbiutils-objs-$(CONFIG_FDT_RESET_THEAD) += reset/fdt_reset_thead.o
 libsbiutils-objs-$(CONFIG_FDT_RESET_THEAD) += reset/fdt_reset_thead_asm.o
platform/generic/configs/defconfig +1 -0
index b767290..5008c7e 100644
@@ -26,6 +26,7 @@ CONFIG_FDT_RESET_GPIO=y
 CONFIG_FDT_RESET_HTIF=y
 CONFIG_FDT_RESET_SIFIVE_TEST=y
 CONFIG_FDT_RESET_SUNXI_WDT=y
+CONFIG_FDT_RESET_SYSCON=y
 CONFIG_FDT_RESET_THEAD=y
 CONFIG_FDT_SERIAL=y
 CONFIG_FDT_SERIAL_CADENCE=y
Signature · 1 line
2.34.1
#10 lore raw

PATCH 5/6 lib: utils/reset: Add syscon based reboot and poweroff

? 2023-07-21???? 22:40 +0530?Anup Patel???

Quoted 5 lines

Let us have common FDT based reset driver for syscon reboot and poweroff. The device tree bindings for syscon reboot and poweroff are already available in the Linux kernel sources.

Look good to me.

Quoted 228 lines

---

?lib/utils/reset/Kconfig??????????? |?? 5 +
?lib/utils/reset/fdt_reset_syscon.c | 167 +++++++++++++++++++++++++++++
?lib/utils/reset/objects.mk???????? |?? 4 +
?platform/generic/configs/defconfig |?? 1 +

?4 files changed, 177 insertions(+)
?create mode 100644 lib/utils/reset/fdt_reset_syscon.c

lib/utils/reset/Kconfig +0 -0
index 4748cc8..c0b9640 100644
@@ -33,6 +33,11 @@ config FDT_RESET_SUNXI_WDT

????????bool "Sunxi WDT FDT reset driver"
????????default n
?

lib/utils/reset/Kconfig +5 -0
+config FDT_RESET_SYSCON
+???????bool "Syscon FDT reset driver"
+???????depends on FDT_REGMAP
+???????default n
+

?config FDT_RESET_THEAD
????????bool "T-HEAD FDT reset driver"
????????default n

lib/utils/reset/fdt_reset_syscon.c new file +167 -0
new file mode 100644
index 0000000..bae9ec5
@@ -0,0 +1,167 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2023 Ventana Micro Systems Inc.
+ *
+ * Authors:
+ *?? Anup Patel <[email protected]>
+ */
+
+#include <libfdt.h>
+#include <sbi/sbi_ecall_interface.h>
+#include <sbi/sbi_error.h>
+#include <sbi/sbi_hart.h>
+#include <sbi/sbi_system.h>
+#include <sbi_utils/fdt/fdt_helper.h>
+#include <sbi_utils/regmap/fdt_regmap.h>
+#include <sbi_utils/reset/fdt_reset.h>
+
+struct syscon_reset {
+???????struct regmap *rmap;
+???????u32 priority;
+???????u32 offset;
+???????u32 value;
+???????u32 mask;
+};
+
+static struct syscon_reset poweroff;
+static struct syscon_reset reboot;
+
+static struct syscon_reset *syscon_reset_get(bool is_reboot, u32 type)
+{
+???????struct syscon_reset *reset = NULL;
+
+???????switch (type) {
+???????case SBI_SRST_RESET_TYPE_SHUTDOWN:
+???????????????if (!is_reboot)
+???????????????????????reset = &poweroff;
+???????????????break;
+???????case SBI_SRST_RESET_TYPE_COLD_REBOOT:
+???????case SBI_SRST_RESET_TYPE_WARM_REBOOT:
+???????????????if (is_reboot)
+???????????????????????reset = &reboot;
+???????????????break;
+???????}
+
+???????if (reset && !reset->rmap)
+???????????????reset = NULL;
+
+???????return reset;
+}
+
+static void syscon_reset_exec(struct syscon_reset *reset)
+{
+???????/* Issue the reset through regmap */
+???????if (reset)
+???????????????regmap_update_bits(reset->rmap, reset->offset,
+????????????????????????????????? reset->mask, reset->value);
+
+???????/* hang !!! */
+???????sbi_hart_hang();
+}
+
+static int syscon_poweroff_check(u32 type, u32 reason)
+{
+???????struct syscon_reset *reset = syscon_reset_get(false, type);
+
+???????return (reset) ? reset->priority : 0;
+}
+
+static void syscon_do_poweroff(u32 type, u32 reason)
+{
+???????syscon_reset_exec(syscon_reset_get(false, type));
+}
+
+static struct sbi_system_reset_device syscon_poweroff = {
+???????.name = "syscon-poweroff",
+???????.system_reset_check = syscon_poweroff_check,
+???????.system_reset = syscon_do_poweroff
+};
+
+static int syscon_reboot_check(u32 type, u32 reason)
+{
+???????struct syscon_reset *reset = syscon_reset_get(true, type);
+
+???????return (reset) ? reset->priority : 0;
+}
+
+static void syscon_do_reboot(u32 type, u32 reason)
+{
+???????syscon_reset_exec(syscon_reset_get(true, type));
+}
+
+static struct sbi_system_reset_device syscon_reboot = {
+???????.name = "syscon-reboot",
+???????.system_reset_check = syscon_reboot_check,
+???????.system_reset = syscon_do_reboot
+};
+
+static int syscon_reset_init(void *fdt, int nodeoff,
+????????????????????????? const struct fdt_match *match)
+{
+???????int rc, len;
+???????const fdt32_t *val, *mask;
+???????bool is_reboot = (ulong)match->data;
+???????struct syscon_reset *reset = (is_reboot) ? &reboot : &poweroff;
+
+???????if (reset->rmap)
+???????????????return SBI_EALREADY;
+
+???????rc = fdt_regmap_get(fdt, nodeoff, &reset->rmap);
+???????if (rc)
+???????????????return rc;
+
+???????val = fdt_getprop(fdt, nodeoff, "priority", &len);
+???????reset->priority = (val && len > 0) ? fdt32_to_cpu(*val) : 192;
+
+???????val = fdt_getprop(fdt, nodeoff, "offset", &len);
+???????if (val && len > 0)
+???????????????reset->offset = fdt32_to_cpu(*val);
+???????else
+???????????????return SBI_EINVAL;
+
+???????val = fdt_getprop(fdt, nodeoff, "value", &len);
+???????mask = fdt_getprop(fdt, nodeoff, "mask", &len);
+???????if (!val && !mask)
+???????????????return SBI_EINVAL;
+
+???????if (!val) {
+???????????????/* support old binding */
+???????????????reset->value = fdt32_to_cpu(*mask);
+???????????????reset->mask = 0xFFFFFFFF;
+???????} else if (!mask) {
+???????????????/* support value without mask */
+???????????????reset->value = fdt32_to_cpu(*val);
+???????????????reset->mask = 0xFFFFFFFF;
+???????} else {
+???????????????reset->value = fdt32_to_cpu(*val);
+???????????????reset->mask = fdt32_to_cpu(*mask);
+???????}
+
+???????if (is_reboot)
+???????????????sbi_system_reset_add_device(&syscon_reboot);
+???????else
+???????????????sbi_system_reset_add_device(&syscon_poweroff);
+
+???????return 0;
+}
+
+static const struct fdt_match syscon_poweroff_match[] = {
+???????{ .compatible = "syscon-poweroff", .data = (const void *)false },
+???????{ },
+};
+
+struct fdt_reset fdt_syscon_poweroff = {
+???????.match_table = syscon_poweroff_match,
+???????.init = syscon_reset_init,
+};
+
+static const struct fdt_match syscon_reboot_match[] = {
+???????{ .compatible = "syscon-reboot", .data = (const void *)true },
+???????{ },
+};
+
+struct fdt_reset fdt_syscon_reboot = {
+???????.match_table = syscon_reboot_match,
+???????.init = syscon_reset_init,
+};
lib/utils/reset/objects.mk +0 -0
index c9f851c..17287a5 100644
@@ -26,6 +26,10 @@ libsbiutils-objs-$(CONFIG_FDT_RESET_SIFIVE_TEST) += reset/fdt_reset_sifive_test.

?carray-fdt_reset_drivers-$(CONFIG_FDT_RESET_SUNXI_WDT) += fdt_reset_sunxi_wdt ?libsbiutils-objs-$(CONFIG_FDT_RESET_SUNXI_WDT) += reset/fdt_reset_sunxi_wdt.o ?

lib/utils/reset/objects.mk +4 -0
+carray-fdt_reset_drivers-$(CONFIG_FDT_RESET_SYSCON) += fdt_syscon_poweroff
+carray-fdt_reset_drivers-$(CONFIG_FDT_RESET_SYSCON) += fdt_syscon_reboot
+libsbiutils-objs-$(CONFIG_FDT_RESET_SYSCON) += reset/fdt_reset_syscon.o
+

?carray-fdt_reset_drivers-$(CONFIG_FDT_RESET_THEAD) += fdt_reset_thead ?libsbiutils-objs-$(CONFIG_FDT_RESET_THEAD) += reset/fdt_reset_thead.o ?libsbiutils-objs-$(CONFIG_FDT_RESET_THEAD) += reset/fdt_reset_thead_asm.o

platform/generic/configs/defconfig +0 -0
index b767290..5008c7e 100644
@@ -26,6 +26,7 @@ CONFIG_FDT_RESET_GPIO=y

?CONFIG_FDT_RESET_HTIF=y
?CONFIG_FDT_RESET_SIFIVE_TEST=y
?CONFIG_FDT_RESET_SUNXI_WDT=y
+CONFIG_FDT_RESET_SYSCON=y
?CONFIG_FDT_RESET_THEAD=y
?CONFIG_FDT_SERIAL=y
?CONFIG_FDT_SERIAL_CADENCE=y

Signature · 1 line
2.34.1
author
#11 lore raw

PATCH 6/6 lib: utils/reset: Remove SiFive Test reset driver

In reply to Anup Patel

The functionality of SiFive Test reset driver is easily available through Syscon reset driver so let us remove the SiFive Test driver.

---
 include/sbi_utils/sys/sifive_test.h     | 17 -------
 lib/utils/reset/Kconfig                 |  5 --
 lib/utils/reset/fdt_reset_sifive_test.c | 36 --------------
 lib/utils/reset/objects.mk              |  3 --
 lib/utils/sys/Kconfig                   |  4 --
 lib/utils/sys/objects.mk                |  1 -
 lib/utils/sys/sifive_test.c             | 65 -------------------------
 platform/generic/configs/defconfig      |  1 -
 8 files changed, 132 deletions(-)
 delete mode 100644 include/sbi_utils/sys/sifive_test.h
 delete mode 100644 lib/utils/reset/fdt_reset_sifive_test.c
 delete mode 100644 lib/utils/sys/sifive_test.c
include/sbi_utils/sys/sifive_test.h deleted +0 -17
deleted file mode 100644
index 0a09499..0000000
@@ -1,17 +0,0 @@
-/*
- * SPDX-License-Identifier: BSD-3-Clause
- *
- * Copyright (c) 2020 Western Digital Corporation or its affiliates.
- *
- * Authors:
- *   Anup Patel <[email protected]>
- */
-
-#ifndef __SYS_SIFIVE_TEST_H__
-#define __SYS_SIFIVE_TEST_H__
-
-#include <sbi/sbi_types.h>
-
-int sifive_test_init(unsigned long base);
-
-#endif
lib/utils/reset/Kconfig +0 -5
index c0b9640..23f50c4 100644
@@ -24,11 +24,6 @@ config FDT_RESET_HTIF
 	select SYS_HTIF
 	default n
 
-config FDT_RESET_SIFIVE_TEST
-	bool "SiFive Test FDT reset driver"
-	select SYS_SIFIVE_TEST
-	default n
-
 config FDT_RESET_SUNXI_WDT
 	bool "Sunxi WDT FDT reset driver"
 	default n
lib/utils/reset/fdt_reset_sifive_test.c deleted +0 -36
deleted file mode 100644
index 7e0eba3..0000000
@@ -1,36 +0,0 @@
-/*
- * SPDX-License-Identifier: BSD-2-Clause
- *
- * Copyright (c) 2020 Western Digital Corporation or its affiliates.
- *
- * Authors:
- *   Anup Patel <[email protected]>
- */
-
-#include <sbi/sbi_scratch.h>
-#include <sbi_utils/fdt/fdt_helper.h>
-#include <sbi_utils/reset/fdt_reset.h>
-#include <sbi_utils/sys/sifive_test.h>
-
-static int sifive_test_reset_init(void *fdt, int nodeoff,
-				  const struct fdt_match *match)
-{
-	int rc;
-	uint64_t addr;
-
-	rc = fdt_get_node_addr_size(fdt, nodeoff, 0, &addr, NULL);
-	if (rc)
-		return rc;
-
-	return sifive_test_init(addr);
-}
-
-static const struct fdt_match sifive_test_reset_match[] = {
-	{ .compatible = "sifive,test1" },
-	{ },
-};
-
-struct fdt_reset fdt_reset_sifive_test = {
-	.match_table = sifive_test_reset_match,
-	.init = sifive_test_reset_init,
-};
lib/utils/reset/objects.mk +0 -3
index 17287a5..ea9cedc 100644
@@ -20,9 +20,6 @@ libsbiutils-objs-$(CONFIG_FDT_RESET_GPIO) += reset/fdt_reset_gpio.o
 carray-fdt_reset_drivers-$(CONFIG_FDT_RESET_HTIF) += fdt_reset_htif
 libsbiutils-objs-$(CONFIG_FDT_RESET_HTIF) += reset/fdt_reset_htif.o
 
-carray-fdt_reset_drivers-$(CONFIG_FDT_RESET_SIFIVE_TEST) += fdt_reset_sifive_test
-libsbiutils-objs-$(CONFIG_FDT_RESET_SIFIVE_TEST) += reset/fdt_reset_sifive_test.o
-
 carray-fdt_reset_drivers-$(CONFIG_FDT_RESET_SUNXI_WDT) += fdt_reset_sunxi_wdt
 libsbiutils-objs-$(CONFIG_FDT_RESET_SUNXI_WDT) += reset/fdt_reset_sunxi_wdt.o
 
lib/utils/sys/Kconfig +0 -4
index 76190f8..a22191c 100644
@@ -10,8 +10,4 @@ config SYS_HTIF
 	bool "Host transfere interface (HTIF) support"
 	default n
 
-config SYS_SIFIVE_TEST
-	bool "SiFive test support"
-	default n
-
 endmenu
lib/utils/sys/objects.mk +0 -1
index 03d6740..409d7e8 100644
@@ -8,5 +8,4 @@
 #
 
 libsbiutils-objs-$(CONFIG_SYS_HTIF) += sys/htif.o
-libsbiutils-objs-$(CONFIG_SYS_SIFIVE_TEST) += sys/sifive_test.o
 libsbiutils-objs-$(CONFIG_SYS_ATCSMU) += sys/atcsmu.o
lib/utils/sys/sifive_test.c deleted +0 -65

65 lines not on this page · raw message

platform/generic/configs/defconfig +0 -1
index 5008c7e..634d410 100644
@@ -24,7 +24,6 @@ CONFIG_FDT_RESET=y
 CONFIG_FDT_RESET_ATCWDT200=y
 CONFIG_FDT_RESET_GPIO=y
 CONFIG_FDT_RESET_HTIF=y
-CONFIG_FDT_RESET_SIFIVE_TEST=y
 CONFIG_FDT_RESET_SUNXI_WDT=y
 CONFIG_FDT_RESET_SYSCON=y
 CONFIG_FDT_RESET_THEAD=y
Signature · 1 line
2.34.1
Applied
#12 lore raw

cover Syscon reboot and poweroff drivers

In reply to Anup Patel
Quoted 8 lines · On Fri, Jul 21, 2023 at 10:40?PM Anup Patel <[email protected]> wrote:

This series adds syscon reboot and poweroff drivers which replaces the SiFive Test reset driver. These new drivers need a lightweight or simple regmap framework which is also added by this series.

These patches can also be found in the syscon_reboot_v1 branch at:
https://github.com/avpatel/opensbi.git

Quoted 7 lines

Anup Patel (6):
include: sbi_utils: Remove driver pointer from struct i2c_adapter
lib: utils/regmap: Add generic regmap access library
lib: utils/regmap: Add simple FDT based regmap framework
lib: utils/regmap: Add simple FDT based syscon regmap driver
lib: utils/reset: Add syscon based reboot and poweroff
lib: utils/reset: Remove SiFive Test reset driver

Applied this series to the riscv/opensbi repo.

Regards,
Anup

Quoted 39 lines
 include/sbi_utils/i2c/i2c.h                |   3 -
 include/sbi_utils/regmap/fdt_regmap.h      |  31 +++
 include/sbi_utils/regmap/regmap.h          |  67 ++++++
 include/sbi_utils/sys/sifive_test.h        |  17 --
 lib/utils/Kconfig                          |   2 +
 lib/utils/i2c/fdt_i2c_dw.c                 |   3 -
 lib/utils/i2c/fdt_i2c_sifive.c             |   3 -
 lib/utils/regmap/Kconfig                   |  22 ++
 lib/utils/regmap/fdt_regmap.c              |  94 ++++++++
 lib/utils/regmap/fdt_regmap_drivers.carray |   3 +
 lib/utils/regmap/fdt_regmap_syscon.c       | 262 +++++++++++++++++++++
 lib/utils/regmap/objects.mk                |  16 ++
 lib/utils/regmap/regmap.c                  | 114 +++++++++
 lib/utils/reset/Kconfig                    |  10 +-
 lib/utils/reset/fdt_reset_sifive_test.c    |  36 ---
 lib/utils/reset/fdt_reset_syscon.c         | 167 +++++++++++++
 lib/utils/reset/objects.mk                 |   7 +-
 lib/utils/sys/Kconfig                      |   4 -
 lib/utils/sys/objects.mk                   |   1 -
 lib/utils/sys/sifive_test.c                |  65 -----
 platform/generic/configs/defconfig         |   6 +-
 21 files changed, 791 insertions(+), 142 deletions(-)
 create mode 100644 include/sbi_utils/regmap/fdt_regmap.h
 create mode 100644 include/sbi_utils/regmap/regmap.h
 delete mode 100644 include/sbi_utils/sys/sifive_test.h
 create mode 100644 lib/utils/regmap/Kconfig
 create mode 100644 lib/utils/regmap/fdt_regmap.c
 create mode 100644 lib/utils/regmap/fdt_regmap_drivers.carray
 create mode 100644 lib/utils/regmap/fdt_regmap_syscon.c
 create mode 100644 lib/utils/regmap/objects.mk
 create mode 100644 lib/utils/regmap/regmap.c
 delete mode 100644 lib/utils/reset/fdt_reset_sifive_test.c
 create mode 100644 lib/utils/reset/fdt_reset_syscon.c
 delete mode 100644 lib/utils/sys/sifive_test.c

--
2.34.1