]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
watchdog: ulp_wdog: Use driver model for reset_cpu()
authorAlice Guo <alice.guo@nxp.com>
Tue, 19 May 2026 06:22:07 +0000 (14:22 +0800)
committerFabio Estevam <festevam@gmail.com>
Fri, 5 Jun 2026 11:58:00 +0000 (08:58 -0300)
Replace hardcoded WDOG_BASE_ADDR with driver model based dynamic address
lookup from device tree, allowing reset_cpu() to dynamically locate
watchdog devices from device tree.

This change also enables CONFIG_WDT for relevant boards and ensures the
watchdog nodes are available for driver model usage.

- Remove hardcoded WDOG_BASE_ADDR from hw_watchdog_* functions
- Reimplement reset_cpu() using UCLASS_WDT device iteration
- Add ulp_wdt_expire_now() callback for standard WDT interface
- Pass wdog register pointer to hw_watchdog_set_timeout()
- Enable CONFIG_WDT for boards using ULP watchdog
- Remove wdog3 status = "disabled" overrides from U-Boot device tree
  overlays, as the watchdog device needs to be accessible for driver
  model based reset functionality.

Signed-off-by: Alice Guo <alice.guo@nxp.com>
Acked-by: Francesco Dolcini <francesco.dolcini@toradex.com> # Toradex boards
Reviewed-by: Peng Fan <peng.fan@nxp.com>
15 files changed:
arch/arm/dts/imx8ulp-evk-u-boot.dtsi
arch/arm/dts/imx943-evk-u-boot.dtsi
arch/arm/dts/imx95-15x15-evk-u-boot.dtsi
arch/arm/dts/imx95-19x19-evk-u-boot.dtsi
arch/arm/dts/imx95-toradex-smarc-dev-u-boot.dtsi
arch/arm/dts/imx95-verdin-wifi-dev-u-boot.dtsi
configs/imx8ulp_evk_defconfig
configs/imx93-phycore_defconfig
configs/imx943_evk_defconfig
configs/imx95_15x15_evk_defconfig
configs/imx95_evk.config
configs/mx7ulp_com_defconfig
configs/toradex-smarc-imx95_defconfig
configs/verdin-imx95_defconfig
drivers/watchdog/ulp_wdog.c

index 860994129aeacbeb513fa2c79819f17ba7b8639d..ac130b54738753c12e51e86e2564620cd26dc8f3 100644 (file)
        status = "disabled";
 };
 
-&wdog3 {
-       status = "disabled";
-};
-
 &per_bridge4 {
        bootph-pre-ram;
 };
index 247a7ed6838f2ee51a18922cf805bcdfaebeaf5f..3b3619d2232792edc1567fde2305a81f07a18d2b 100644 (file)
        bootph-pre-ram;
 };
 
-&wdog3 {
-       status = "disabled";
-};
-
 &xspi1 {
        bootph-pre-ram;
        pinctrl-names = "default";
index 514dd729be9397747e15b400fd774f09e8a7380f..34b4073ff35502c0780bbb65f83d3e206c204071 100644 (file)
        bootph-pre-ram;
 };
 
-&wdog3 {
-       status = "disabled";
-};
-
 &pinctrl_uart1 {
        bootph-pre-ram;
 };
index 8b59831b7ca061b7ae616cd5ebb7f1af48e54192..1083d863c4d6c8f0401d5fd27df693317e17e886 100644 (file)
        bootph-pre-ram;
 };
 
-&wdog3 {
-       status = "disabled";
-};
-
 &pinctrl_uart1 {
        bootph-pre-ram;
 };
index 24952579a67029688ad3a062d108cb84481be726..e4eda61e5c47c926a034ddca473f8425eabac630 100644 (file)
 &usdhc2 {
        bootph-pre-ram;
 };
-
-&wdog3 {
-       status = "disabled";
-};
index 45633765c0f8594af3b791b36c8eca29a92ae684..8ab70cf7399aaf33440dc583850ba7a427c15e14 100644 (file)
 &usdhc1 {
        bootph-pre-ram;
 };
-
-&wdog3 {
-       status = "disabled";
-};
index baa8c1e469557d56c2ed3b184de1d9200a4781e8..2101532833ec51363cc8231dcde6d92f32de45bb 100644 (file)
@@ -92,3 +92,4 @@ CONFIG_SPI=y
 CONFIG_DM_SPI=y
 CONFIG_NXP_FSPI=y
 CONFIG_ULP_WATCHDOG=y
+CONFIG_WDT=y
index 0634378149db30f8100cc2c5e4b71d30a5f0e99b..f87581d4ddc7a338ebdd521173ffa303033de0f0 100644 (file)
@@ -156,6 +156,7 @@ CONFIG_USB_GADGET_VENDOR_NUM=0x1fc9
 CONFIG_USB_GADGET_PRODUCT_NUM=0x0152
 CONFIG_CI_UDC=y
 CONFIG_ULP_WATCHDOG=y
+CONFIG_WDT=y
 # CONFIG_RSA is not set
 # CONFIG_SPL_SHA256 is not set
 CONFIG_LZO=y
index 70265f13bba5bce7ce4e0d81f33f7b89a84d3c86..b60d39a1fa2282eed20ddf4d6b1ff0607df86749 100644 (file)
@@ -151,3 +151,4 @@ CONFIG_USB_GADGET_PRODUCT_NUM=0xa4a5
 CONFIG_SDP_LOADADDR=0x90400000
 CONFIG_SPL_USB_SDP_SUPPORT=y
 CONFIG_ULP_WATCHDOG=y
+CONFIG_WDT=y
index e9cd289d31f753ee14971a882595a587dae5df59..3c18956ffe99e3f4242ae74475b05dcb76a881ea 100644 (file)
@@ -147,5 +147,6 @@ CONFIG_SPI=y
 CONFIG_DM_SPI=y
 CONFIG_NXP_FSPI=y
 CONFIG_ULP_WATCHDOG=y
+CONFIG_WDT=y
 CONFIG_LZO=y
 CONFIG_BZIP2=y
index 30ad2e60313cadc031fec4273138de844168419b..743778d9554c3bbe10bc2c0ab1c8cdde4869dd6f 100644 (file)
@@ -151,3 +151,4 @@ CONFIG_NXP_FSPI=y
 CONFIG_ULP_WATCHDOG=y
 CONFIG_LZO=y
 CONFIG_BZIP2=y
+CONFIG_WDT=y
index d63168fe8866ceacfed91b2c8efedf010badac9f..c9c3f6b5f263119f64dc70b4e94db3851f1b91e9 100644 (file)
@@ -63,3 +63,4 @@ CONFIG_USB_GADGET_PRODUCT_NUM=0xa4a5
 CONFIG_CI_UDC=y
 CONFIG_USB_GADGET_DOWNLOAD=y
 CONFIG_ULP_WATCHDOG=y
+CONFIG_WDT=y
index caf0718fc135cf3eed41555241c16ff166377892..9363eb5cbb637ddadc75a9214443602513cfb4ee 100644 (file)
@@ -175,5 +175,6 @@ CONFIG_USB_GADGET_OS_DESCRIPTORS=y
 CONFIG_CI_UDC=y
 CONFIG_SDP_LOADADDR=0x90400000
 CONFIG_ULP_WATCHDOG=y
+CONFIG_WDT=y
 # CONFIG_SPL_SHA1 is not set
 CONFIG_LZO=y
index 50515250d1734e22abc574b0b016cd16ce0e3db8..ea1ebb0c492491ece92d07e82c204e256bccf499 100644 (file)
@@ -180,5 +180,6 @@ CONFIG_USB_GADGET_PRODUCT_NUM=0x4000
 CONFIG_USB_GADGET_OS_DESCRIPTORS=y
 CONFIG_SDP_LOADADDR=0x90400000
 CONFIG_ULP_WATCHDOG=y
+CONFIG_WDT=y
 # CONFIG_SPL_SHA1 is not set
 CONFIG_LZO=y
index 83f19dc0e86b332b43b47bd39efaedbd0f05fe24..e3a89031c44815b51d52b3fc237013e80c8186b0 100644 (file)
@@ -7,6 +7,7 @@
 #include <asm/io.h>
 #include <asm/arch/imx-regs.h>
 #include <dm.h>
+#include <linux/delay.h>
 #include <wdt.h>
 
 /*
@@ -51,11 +52,9 @@ struct ulp_wdt_priv {
 #define CLK_RATE_1KHZ                  1000
 #define CLK_RATE_32KHZ                 125
 
-void hw_watchdog_set_timeout(u16 val)
+void hw_watchdog_set_timeout(struct wdog_regs *wdog, u16 val)
 {
        /* setting timeout value */
-       struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR;
-
        writel(val, &wdog->toval);
 }
 
@@ -89,7 +88,7 @@ void ulp_watchdog_init(struct wdog_regs *wdog, u16 timeout)
        while (!(readl(&wdog->cs) & WDGCS_ULK))
                ;
 
-       hw_watchdog_set_timeout(timeout);
+       hw_watchdog_set_timeout(wdog, timeout);
        writel(0, &wdog->win);
 
        /* setting 1-kHz clock source, enable counter running, and clear interrupt */
@@ -107,57 +106,20 @@ void ulp_watchdog_init(struct wdog_regs *wdog, u16 timeout)
        ulp_watchdog_reset(wdog);
 }
 
-void hw_watchdog_reset(void)
-{
-       struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR;
-
-       ulp_watchdog_reset(wdog);
-}
-
-void hw_watchdog_init(void)
-{
-       struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR;
-
-       ulp_watchdog_init(wdog, CONFIG_WATCHDOG_TIMEOUT_MSECS);
-}
-
-#if !CONFIG_IS_ENABLED(SYSRESET)
+#if !CONFIG_IS_ENABLED(SYSRESET) && CONFIG_IS_ENABLED(WDT)
 void reset_cpu(void)
 {
-       struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR;
-       u32 cmd32 = 0;
-
-       if (readl(&wdog->cs) & WDGCS_CMD32EN) {
-               writel(UNLOCK_WORD, &wdog->cnt);
-               cmd32 = WDGCS_CMD32EN;
-       } else {
-               dmb();
-               __raw_writel(UNLOCK_WORD0, &wdog->cnt);
-               __raw_writel(UNLOCK_WORD1, &wdog->cnt);
-               dmb();
-       }
+       struct udevice *wdt;
 
-       /* Wait WDOG Unlock */
-       while (!(readl(&wdog->cs) & WDGCS_ULK))
-               ;
+       for (uclass_first_device(UCLASS_WDT, &wdt);
+            wdt;
+            uclass_next_device(&wdt)) {
+               if (!dev_read_enabled(wdt))
+                       continue;
 
-       hw_watchdog_set_timeout(5); /* 5ms timeout for general; 40ms timeout for imx93 */
-       writel(0, &wdog->win);
-
-       /* enable counter running */
-       if (IS_ENABLED(CONFIG_ARCH_IMX9))
-               writel((cmd32 | WDGCS_WDGE | (WDG_LPO_CLK << 8) | WDOG_CS_PRES |
-                      WDGCS_INT), &wdog->cs);
-       else
-               writel((cmd32 | WDGCS_WDGE | (WDG_LPO_CLK << 8)), &wdog->cs);
-
-       /* Wait WDOG reconfiguration */
-       while (!(readl(&wdog->cs) & WDGCS_RCS))
-               ;
-
-       hw_watchdog_reset();
-
-       while (1);
+               wdt_expire_now(wdt, 0);
+               break;
+       }
 }
 #endif
 
@@ -184,6 +146,20 @@ static int ulp_wdt_reset(struct udevice *dev)
        return 0;
 }
 
+static int ulp_wdt_expire_now(struct udevice *dev, ulong flags)
+{
+       int ret;
+
+       /* 5ms timeout for all others; 40ms timeout for "fsl,imx93-wdt" */
+       ret = ulp_wdt_start(dev, 5, flags);
+       if (ret)
+               return ret;
+
+       mdelay(50);
+
+       return 0;
+}
+
 static int ulp_wdt_probe(struct udevice *dev)
 {
        struct ulp_wdt_priv *priv = dev_get_priv(dev);
@@ -202,6 +178,7 @@ static int ulp_wdt_probe(struct udevice *dev)
 static const struct wdt_ops ulp_wdt_ops = {
        .start = ulp_wdt_start,
        .reset = ulp_wdt_reset,
+       .expire_now = ulp_wdt_expire_now,
 };
 
 static const struct udevice_id ulp_wdt_ids[] = {