diff options
Diffstat (limited to 'drivers/watchdog/qcom-wdt.c')
-rw-r--r-- | drivers/watchdog/qcom-wdt.c | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/drivers/watchdog/qcom-wdt.c b/drivers/watchdog/qcom-wdt.c index 3601ba93774..adbb5aacdc3 100644 --- a/drivers/watchdog/qcom-wdt.c +++ b/drivers/watchdog/qcom-wdt.c @@ -13,6 +13,7 @@ #include <dm.h> #include <dm/device_compat.h> #include <wdt.h> +#include <clk.h> #include <asm/io.h> @@ -30,6 +31,7 @@ struct qcom_wdt_match_data { struct qcom_wdt { void __iomem *base; + ulong clk_rate; const u32 *layout; }; @@ -53,10 +55,14 @@ static void __iomem *wdt_addr(struct qcom_wdt *wdt, enum wdt_reg reg) int qcom_wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags) { struct qcom_wdt *wdt = dev_get_priv(dev); + ulong bark_timeout_s = ((timeout_ms - 1) * wdt->clk_rate) / 1000; + ulong bite_timeout_s = (timeout_ms * wdt->clk_rate) / 1000; writel(0, wdt_addr(wdt, WDT_EN)); - writel(1, wdt_addr(wdt, WDT_RST)); - writel(1, wdt_addr(wdt, WDT_EN)); + writel(BIT(0), wdt_addr(wdt, WDT_RST)); + writel(bark_timeout_s, wdt_addr(wdt, WDT_BARK_TIME)); + writel(bite_timeout_s, wdt_addr(wdt, WDT_BITE_TIME)); + writel(BIT(0), wdt_addr(wdt, WDT_EN)); if (readl(wdt_addr(wdt, WDT_EN)) != 1) { dev_err(dev, "Failed to enable Qualcomm watchdog!\n"); return -EIO; @@ -87,12 +93,26 @@ int qcom_wdt_reset(struct udevice *dev) static int qcom_wdt_probe(struct udevice *dev) { + struct clk clk; + long rate; + int ret; + struct qcom_wdt *wdt = dev_get_priv(dev); struct qcom_wdt_match_data *data = (void *)dev_get_driver_data(dev); wdt->base = dev_read_addr_ptr(dev); wdt->layout = data->offset; + ret = clk_get_by_index(dev, 0, &clk); + if (ret) + return ret; + + rate = clk_get_rate(&clk); + if (rate <= 0) + return rate < 0 ? (int)rate : -EINVAL; + + wdt->clk_rate = (ulong)rate; + return 0; } |