The binding used is the same as Linux's.
---
 doc/device-tree-bindings/watchdog/dw_wdt.txt | 24 +++++++
 drivers/watchdog/designware_wdt.c            | 67 ++++++++++++++++++++
 2 files changed, 91 insertions(+)
 create mode 100644 doc/device-tree-bindings/watchdog/dw_wdt.txt

diff --git a/doc/device-tree-bindings/watchdog/dw_wdt.txt 
b/doc/device-tree-bindings/watchdog/dw_wdt.txt
new file mode 100644
index 0000000000..eb0914420c
--- /dev/null
+++ b/doc/device-tree-bindings/watchdog/dw_wdt.txt
@@ -0,0 +1,24 @@
+Synopsys Designware Watchdog Timer
+
+Required Properties:
+
+- compatible   : Should contain "snps,dw-wdt"
+- reg          : Base address and size of the watchdog timer registers.
+- clocks       : phandle + clock-specifier for the clock that drives the
+               watchdog timer.
+
+Optional Properties:
+
+- interrupts   : The interrupt used for the watchdog timeout warning.
+- resets       : phandle pointing to the system reset controller with
+               line index for the watchdog.
+
+Example:
+
+       watchdog0: wd@ffd02000 {
+               compatible = "snps,dw-wdt";
+               reg = <0xffd02000 0x1000>;
+               interrupts = <0 171 4>;
+               clocks = <&per_base_clk>;
+               resets = <&rst WDT0_RESET>;
+       };
diff --git a/drivers/watchdog/designware_wdt.c 
b/drivers/watchdog/designware_wdt.c
index 61c4046f50..1f7f4f0103 100644
--- a/drivers/watchdog/designware_wdt.c
+++ b/drivers/watchdog/designware_wdt.c
@@ -5,8 +5,10 @@
 
 #include <common.h>
 #include <asm/io.h>
+#include <clk.h>
 #include <log2.h>
 #include <watchdog.h>
+#include <wdt.h>
 
 #define DW_WDT_CR      0x00
 #define DW_WDT_TORR    0x04
@@ -90,3 +92,68 @@ void hw_watchdog_init(void)
        designware_wdt_init(&wdt_priv, CONFIG_WATCHDOG_TIMEOUT_MSECS);
 }
 #endif
+
+#ifdef CONFIG_WDT
+static int dw_wdt_reset(struct udevice *dev)
+{
+       struct designware_wdt_priv *priv = dev_get_priv(dev);
+
+       designware_wdt_reset(priv);
+
+       return 0;
+}
+
+static int dw_wdt_start(struct udevice *dev, u64 timeout, ulong flags)
+{
+       struct designware_wdt_priv *priv = dev_get_priv(dev);
+
+       designware_wdt_init(priv, timeout);
+
+       return 0;
+}
+
+static int dw_wdt_probe(struct udevice *dev)
+{
+       int ret;
+       ulong rate;
+       struct clk clk;
+       struct designware_wdt_priv *priv = dev_get_priv(dev);
+
+       priv->base = dev_read_addr_ptr(dev);
+       if (!priv->base)
+               return -ENOENT;
+
+       ret = clk_get_by_index(dev, 0, &clk);
+       if (ret)
+               return ret;
+
+       rate = clk_get_rate(&clk);
+       if (IS_ERR_VALUE(rate)) {
+               clk_free(&clk);
+               return rate;
+       }
+       priv->clock_khz = rate / 1000;
+
+       return 0;
+}
+
+static const struct wdt_ops dw_wdt_ops = {
+       .start          = dw_wdt_start,
+       .reset          = dw_wdt_reset,
+};
+
+static const struct udevice_id dw_wdt_ids[] = {
+       { .compatible = "snps,dw-wdt" },
+       { },
+};
+
+U_BOOT_DRIVER(designware_wdt) = {
+       .name           = "designware_wdt",
+       .id             = UCLASS_WDT,
+       .of_match       = dw_wdt_ids,
+       .probe          = dw_wdt_probe,
+       .ops            = &dw_wdt_ops,
+       .priv_auto_alloc_size = sizeof(struct designware_wdt_priv),
+       .flags          = DM_FLAG_PRE_RELOC,
+};
+#endif /* WDT */
-- 
2.25.0

Reply via email to