Hi Michal,

On 05.04.19 14:07, Michal Simek wrote:

<snip>

+++ b/drivers/watchdog/wdt-uclass.c
@@ -10,6 +10,12 @@
  #include <dm/device-internal.h>
  #include <dm/lists.h>
+#ifndef WDT_DEFAULT_TIMEOUT
+#define WDT_DEFAULT_TIMEOUT    60
+#endif
+
+DECLARE_GLOBAL_DATA_PTR;
+
  int wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags)
  {
        const struct wdt_ops *ops = device_get_ops(dev);
@@ -63,6 +69,67 @@ int wdt_expire_now(struct udevice *dev, ulong flags)
        return ret;
  }
+#if defined(CONFIG_WATCHDOG)

This is not enough because you can enable it just for full u-boot but
not for SPL.

Why not? CONFIG_WATCHDOG can be enabled with or without
CONFIG_SPL_WATCHDOG_SUPPORT being enabled.

It means you should also handle CONFIG_SPL_WATCHDOG_SUPPORT
macros.

Just try to enable CADENCE_WDT, WDT and Watchdog for zcu100 and build

I just tried this for xilinx_zynqmp_zcu100_revC_defconfig. Per default
it has enabled:

$ grep 'WATCHDOG\|WDT' .config
# CONFIG_SPL_WATCHDOG_SUPPORT is not set
# CONFIG_SYSRESET_WATCHDOG is not set
CONFIG_WATCHDOG=y
# CONFIG_WATCHDOG_RESET_DISABLE is not set
# CONFIG_BCM2835_WDT is not set
# CONFIG_ULP_WATCHDOG is not set
CONFIG_WDT=y
# CONFIG_WDT_ASPEED is not set
# CONFIG_WDT_ORION is not set
CONFIG_WDT_CDNS=y
# CONFIG_XILINX_TB_WATCHDOG is not set
# CONFIG_IMX_WATCHDOG is not set
# CONFIG_WDT_AT91 is not set

I can also enable SPL_WATCHDOG_SUPPORT and it compiles without issues:

$ grep 'WATCHDOG\|WDT' .config
CONFIG_SPL_WATCHDOG_SUPPORT=y
# CONFIG_SYSRESET_WATCHDOG is not set
CONFIG_WATCHDOG=y
# CONFIG_WATCHDOG_RESET_DISABLE is not set
# CONFIG_BCM2835_WDT is not set
# CONFIG_ULP_WATCHDOG is not set
CONFIG_WDT=y
# CONFIG_WDT_ASPEED is not set
# CONFIG_WDT_ORION is not set
CONFIG_WDT_CDNS=y
# CONFIG_XILINX_TB_WATCHDOG is not set
# CONFIG_IMX_WATCHDOG is not set
# CONFIG_WDT_AT91 is not set

What am I missing?

+/*
+ * Called by macro WATCHDOG_RESET. This function be called *very* early,
+ * so we need to make sure, that the watchdog driver is ready before using
+ * it in this function.
+ */
+void watchdog_reset(void)
+{
+       static ulong next_reset;
+       ulong now;
+
+       /* Exit if GD is not ready or watchdog is not initialized yet */
+       if (!gd || !(gd->flags & GD_FLG_WDT_READY))
+               return;
+
+       /* Do not reset the watchdog too often */
+       now = get_timer(0);
+       if (now > next_reset) {
+               next_reset = now + 1000;        /* reset every 1000ms */
+               wdt_reset(gd->watchdog_dev);
+       }
+}
+
+static void watchdog_start(void)
+{
+       u32 timeout = WDT_DEFAULT_TIMEOUT;
+
+       /*
+        * Use only the first watchdog device in U-Boot to trigger the
+        * watchdog reset
+        */
+       if (gd->watchdog_dev) {

I hope that gd structure is cleared somewhere.

I had this also in mind with respect to BSS not being cleared very
early. Its cleared in board_init_f_init_reserve(), so quite early
before board_init_f() is called.
+               debug("Only one watchdog device used!\n");
+               return;
+       }
+
+       /*
+        * Init watchdog: This will call the probe function of the
+        * watchdog driver, enabling the use of the device
+        */
+       if (uclass_get_device(UCLASS_WDT, 0,
+                             (struct udevice **)&gd->watchdog_dev)) {
+               debug("Watchdog: Not found!\n");
+               return;
+       }

I think you should c&p what I have done in zynq/zynqmp. It means check
watchdog0 alias first because this is supposed to be the first primary
watchdog.

zynq/zynqmp/mb code
        if (uclass_get_device_by_seq(UCLASS_WDT, 0, &watchdog_dev)) {
                debug("Watchdog: Not found by seq!\n");
                if (uclass_get_device(UCLASS_WDT, 0, &watchdog_dev)) {
                        puts("Watchdog: Not found!\n");
                        return 0;
                }
        }

In my (internal) first version, I had exactly this code included. I
removed the first part, as it makes no real sense to call it at this
stage (wdt_post_bind() for the first WDT found in the system). My
understanding is, that wdt_post_bind() will get called for all WDT
found in the system. My current logic here is, to only register the
first WDT found to the global watchdog_dev in GD. To prevent that
multiple WDT are used to service the U-Boot watchdog via WATCHDOG_RESET.

Or does the DM subsystem automatically bind the watchdog0 alias first
in its binding sequence?

I do not have a system with multiple watchdogs here, so its not that
easy to test this. I could simulate this though somehow...


+
+       if (CONFIG_IS_ENABLED(OF_CONTROL)) {
+               timeout = dev_read_u32_default(gd->watchdog_dev, "timeout-sec",
+                                              WDT_DEFAULT_TIMEOUT);
+       }

You should remove them from drivers.

drivers/watchdog/at91sam9_wdt.c:119:    priv->timeout =
dev_read_u32_default(dev, "timeout-sec",
drivers/watchdog/cdns_wdt.c:238:        priv->timeout =
dev_read_u32_default(dev, "timeout-sec",

Yes, its on my plan. I've also some additions for the AT91 driver on
the list since a few days, which will most likely get applied before
this patch. I'll send a cleanup patch to remove those now superfluous
DT handling later.

Thanks,
Stefan
_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to