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

Reply via email to