From mboxrd@z Thu Jan 1 00:00:00 1970 From: Sean Anderson Date: Sun, 2 Feb 2020 12:13:35 -0500 Subject: [PATCH 4/4] wdt: Add DM support for Designware WDT In-Reply-To: <9b2bb704-e7ea-74ea-c854-60a44472b8ec@gmail.com> References: <9b2bb704-e7ea-74ea-c854-60a44472b8ec@gmail.com> Message-ID: <07f8931f-b143-e536-5e37-2096e8e88eba@gmail.com> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de 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 at 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 #include +#include #include #include +#include #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