Syscon reboot and poweroff drivers
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
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
@@ -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
@@ -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
@@ -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
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_adapteris not used anywhere so let us remove it.Signed-off-by Anup Patel <[email protected]>
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@@ -15,9 +15,6 @@?
?/** Representation of a I2C adapter */
?structi2c_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@@ -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@@ -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
PATCH 2/6 lib: utils/regmap: Add generic regmap access library
In reply to Anup PatelWe 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
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.
Signed-off-by Anup Patel <[email protected]>
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 100644lib/utils/regmap/Kconfig?create mode 100644lib/utils/regmap/objects.mk?create mode 100644lib/utils/regmap/regmap.cinclude/sbi_utils/regmap/regmap.h new file +67
-0@@ -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@@ -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@@ -0,0 +1,9 @@ +# SPDX-License-Identifier: BSD-2-Clause + +menu "Regmap Support" + +config REGMAP +???????bool "Regmap support" +???????default n + +endmenulib/utils/regmap/objects.mk new file +10
-0@@ -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.olib/utils/regmap/regmap.c new file +114
-0@@ -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, ®_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@@ -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=yplatform/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=ySignature · 1 line
2.34.1
PATCH 3/6 lib: utils/regmap: Add simple FDT based regmap framework
In reply to Anup PatelWe 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
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()andfdt_regmap_get()called by the regmap client drivers.Signed-off-by Anup Patel <[email protected]>
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 100644lib/utils/regmap/fdt_regmap.c?create mode 100644lib/utils/regmap/fdt_regmap_drivers.carrayinclude/sbi_utils/regmap/fdt_regmap.h new file +31
-0@@ -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@@ -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 nlib/utils/regmap/fdt_regmap.c new file +94
-0@@ -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@@ -0,0 +1,3 @@ +HEADER: sbi_utils/regmap/fdt_regmap.h +TYPE: struct fdt_regmap +NAME: fdt_regmap_driverslib/utils/regmap/objects.mk +0
-0@@ -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.oplatform/generic/configs/defconfig +0
-0@@ -18,7 +18,7 @@ CONFIG_FDT_IRQCHIP=y?CONFIG_FDT_IRQCHIP_APLIC=y
?CONFIG_FDT_IRQCHIP_IMSIC=y
?CONFIG_FDT_IRQCHIP_PLIC=yplatform/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=ySignature · 1 line
2.34.1
PATCH 4/6 lib: utils/regmap: Add simple FDT based syscon regmap driver
In reply to Anup PatelLet 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
@@ -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
@@ -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
@@ -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
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.
Signed-off-by Anup Patel <[email protected]>
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 100644lib/utils/regmap/fdt_regmap_syscon.clib/utils/regmap/Kconfig +0
-0@@ -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 nlib/utils/regmap/fdt_regmap_syscon.c new file +262
-0@@ -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@@ -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.oplatform/generic/configs/defconfig +0
-0@@ -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=ySignature · 1 line
2.34.1
PATCH 5/6 lib: utils/reset: Add syscon based reboot and poweroff
In reply to Anup PatelLet 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
@@ -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
@@ -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
@@ -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
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.
Signed-off-by Anup Patel <[email protected]>
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 100644lib/utils/reset/fdt_reset_syscon.clib/utils/reset/Kconfig +0
-0@@ -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 nlib/utils/reset/fdt_reset_syscon.c new file +167
-0@@ -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@@ -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.oplatform/generic/configs/defconfig +0
-0@@ -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=ySignature · 1 line
2.34.1
PATCH 6/6 lib: utils/reset: Remove SiFive Test reset driver
In reply to Anup PatelThe 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
Anup Patel
Appliedcover Syscon reboot and poweroff drivers
In reply to Anup PatelQuoted 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_v1branch at:
https://github.com/avpatel/opensbi.git
Quoted 7 lines
Anup Patel (6):
include:sbi_utils: Remove driver pointer from structi2c_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