The CV1800B system reset driver uses hard-coded RTC register addresses. Initialize a register map from the RTC node shared with its parent device instead. Require the RTC driver that binds the sysreset child. Preserve the existing reset requests, including the warm-reset sequence used for SYSRESET_COLD.
Reviewed-by: Hiago De Franco <[email protected]> Reviewed-by: Yao Zi <[email protected]> Signed-off-by: Zhuxu Ran <[email protected]> --- drivers/sysreset/Kconfig | 6 ++-- drivers/sysreset/sysreset_cv1800b.c | 72 +++++++++++++++++++++---------------- 2 files changed, 46 insertions(+), 32 deletions(-) diff --git a/drivers/sysreset/Kconfig b/drivers/sysreset/Kconfig index 16ef434a8d9..c9f2a552b47 100644 --- a/drivers/sysreset/Kconfig +++ b/drivers/sysreset/Kconfig @@ -60,9 +60,11 @@ config SYSRESET_CMD_POWEROFF endif config SYSRESET_CV1800B - bool "Enable support for Sophgo cv1800b System Reset" + bool "Enable support for Sophgo CV1800B system reset" + depends on RTC_CV1800B help - Enable system reset support for Sophgo cv1800b SoC. + Enable system reset and power control through the RTC subsystem + found on Sophgo CV1800 series SoCs. config POWEROFF_GPIO bool "Enable support for GPIO poweroff driver" diff --git a/drivers/sysreset/sysreset_cv1800b.c b/drivers/sysreset/sysreset_cv1800b.c index 9cd62772ef4..74ba2c2bd8f 100644 --- a/drivers/sysreset/sysreset_cv1800b.c +++ b/drivers/sysreset/sysreset_cv1800b.c @@ -1,32 +1,34 @@ // SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2024, Kongyang Liu <[email protected]> + * Copyright (c) 2026, Zhuxu Ran <[email protected]> */ #include <dm.h> -#include <stdbool.h> +#include <regmap.h> #include <sysreset.h> -#include <wait_bit.h> -#include <linux/io.h> +#include <linux/bitops.h> +#include <linux/err.h> #include <linux/errno.h> -#define REG_RTC_BASE (void *)0x05026000 -#define REG_RTC_CTRL_BASE (void *)0x05025000 -#define REG_RTC_EN_SHDN_REQ (REG_RTC_BASE + 0xc0) -#define REG_RTC_EN_PWR_CYC_REQ (REG_RTC_BASE + 0xc8) -#define REG_RTC_EN_WARM_RST_REQ (REG_RTC_BASE + 0xcc) -#define REG_RTC_CTRL_UNLOCKKEY (REG_RTC_CTRL_BASE + 0x4) -#define REG_RTC_CTRL (REG_RTC_CTRL_BASE + 0x8) +#define REG_RTC_CTRL_UNLOCKKEY 0x0004 +#define REG_RTC_CTRL 0x0008 +#define REG_RTC_EN_SHDN_REQ 0x10C0 +#define REG_RTC_EN_PWR_CYC_REQ 0x10C8 +#define REG_RTC_EN_WARM_RST_REQ 0x10CC -#define CTRL_UNLOCKKEY_MAGIC 0xAB18 +#define CTRL_UNLOCKKEY_MAGIC 0xAB18 -/* REG_RTC_CTRL */ -#define BIT_REQ_SHDN BIT(0) -#define BIT_REQ_PWR_CYC BIT(3) -#define BIT_REQ_WARM_RST BIT(4) +#define BIT_REQ_SHDN BIT(0) +#define BIT_REQ_PWR_CYC BIT(3) +#define BIT_REQ_WARM_RST BIT(4) -static struct { - void *pre_req_reg; +struct cv1800b_sysreset_priv { + struct regmap *regmap; +}; + +static const struct { + u32 pre_req_reg; u32 req_bit; } reset_info[SYSRESET_COUNT] = { [SYSRESET_WARM] = { REG_RTC_EN_WARM_RST_REQ, BIT_REQ_WARM_RST }, @@ -37,28 +39,38 @@ static struct { static int cv1800b_sysreset_request(struct udevice *dev, enum sysreset_t type) { - u32 reg; + struct cv1800b_sysreset_priv *priv = dev_get_priv(dev); + + if (type >= SYSRESET_COUNT) + return -EINVAL; - writel(1, reset_info[type].pre_req_reg); - writel(CTRL_UNLOCKKEY_MAGIC, REG_RTC_CTRL_UNLOCKKEY); - reg = readl(REG_RTC_CTRL); - writel(0xFFFF0800 | reset_info[type].req_bit, REG_RTC_CTRL); + regmap_write(priv->regmap, reset_info[type].pre_req_reg, 1); + regmap_write(priv->regmap, REG_RTC_CTRL_UNLOCKKEY, CTRL_UNLOCKKEY_MAGIC); + regmap_write(priv->regmap, REG_RTC_CTRL, + 0xFFFF0800 | reset_info[type].req_bit); return -EINPROGRESS; } +static int cv1800b_sysreset_probe(struct udevice *dev) +{ + struct cv1800b_sysreset_priv *priv = dev_get_priv(dev); + + priv->regmap = devm_regmap_init(dev, NULL, NULL, NULL); + if (IS_ERR(priv->regmap)) + return PTR_ERR(priv->regmap); + + return 0; +} + static struct sysreset_ops cv1800b_sysreset = { .request = cv1800b_sysreset_request, }; -static const struct udevice_id cv1800b_sysreset_ids[] = { - { .compatible = "sophgo,cv1800b-sysreset", }, - {}, -}; - U_BOOT_DRIVER(sysreset_cv1800b) = { .name = "cv1800b_sysreset", - .id = UCLASS_SYSRESET, - .ops = &cv1800b_sysreset, - .of_match = cv1800b_sysreset_ids + .id = UCLASS_SYSRESET, + .probe = cv1800b_sysreset_probe, + .ops = &cv1800b_sysreset, + .priv_auto = sizeof(struct cv1800b_sysreset_priv), }; -- 2.56.0
