int "Watchdog timeout in msec"
default 128000 if ARCH_MX31 || ARCH_MX5 || ARCH_MX6
default 128000 if ARCH_MX7 || ARCH_VF610
+ default 30000 if ARCH_SNAPDRAGON
default 30000 if ARCH_SOCFPGA
default 16000 if ARCH_SUNXI
default 5376 if ULP_WATCHDOG
config WDT_QCOM
bool "Qualcomm watchdog timer support"
depends on WDT && ARCH_SNAPDRAGON
+ imply WATCHDOG
help
Select this to enable Qualcomm watchdog timer, which can be found on
some Qualcomm chips.
#include <dm.h>
#include <dm/device_compat.h>
#include <wdt.h>
+#include <clk.h>
#include <asm/io.h>
struct qcom_wdt {
void __iomem *base;
+ ulong clk_rate;
const u32 *layout;
};
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;
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;
}