Lines Matching +full:kpss +full:- +full:wdt

1 // SPDX-License-Identifier: GPL-2.0-only
54 static void __iomem *wdt_addr(struct qcom_wdt *wdt, enum wdt_reg reg) in wdt_addr() argument
56 return wdt->base + wdt->layout[reg]; in wdt_addr()
76 struct qcom_wdt *wdt = to_qcom_wdt(wdd); in qcom_wdt_start() local
77 unsigned int bark = wdd->timeout - wdd->pretimeout; in qcom_wdt_start()
79 writel(0, wdt_addr(wdt, WDT_EN)); in qcom_wdt_start()
80 writel(1, wdt_addr(wdt, WDT_RST)); in qcom_wdt_start()
81 writel(bark * wdt->rate, wdt_addr(wdt, WDT_BARK_TIME)); in qcom_wdt_start()
82 writel(wdd->timeout * wdt->rate, wdt_addr(wdt, WDT_BITE_TIME)); in qcom_wdt_start()
83 writel(QCOM_WDT_ENABLE, wdt_addr(wdt, WDT_EN)); in qcom_wdt_start()
89 struct qcom_wdt *wdt = to_qcom_wdt(wdd); in qcom_wdt_stop() local
91 writel(0, wdt_addr(wdt, WDT_EN)); in qcom_wdt_stop()
97 struct qcom_wdt *wdt = to_qcom_wdt(wdd); in qcom_wdt_ping() local
99 writel(1, wdt_addr(wdt, WDT_RST)); in qcom_wdt_ping()
106 wdd->timeout = timeout; in qcom_wdt_set_timeout()
113 wdd->pretimeout = timeout; in qcom_wdt_set_pretimeout()
120 struct qcom_wdt *wdt = to_qcom_wdt(wdd); in qcom_wdt_restart() local
125 * Setup BITE_TIME to be 128ms, and enable WDT. in qcom_wdt_restart()
127 timeout = 128 * wdt->rate / 1000; in qcom_wdt_restart()
129 writel(0, wdt_addr(wdt, WDT_EN)); in qcom_wdt_restart()
130 writel(1, wdt_addr(wdt, WDT_RST)); in qcom_wdt_restart()
131 writel(timeout, wdt_addr(wdt, WDT_BARK_TIME)); in qcom_wdt_restart()
132 writel(timeout, wdt_addr(wdt, WDT_BITE_TIME)); in qcom_wdt_restart()
133 writel(QCOM_WDT_ENABLE, wdt_addr(wdt, WDT_EN)); in qcom_wdt_restart()
146 struct qcom_wdt *wdt = to_qcom_wdt(wdd); in qcom_wdt_is_running() local
148 return (readl(wdt_addr(wdt, WDT_EN)) & QCOM_WDT_ENABLE); in qcom_wdt_is_running()
198 struct device *dev = &pdev->dev; in qcom_wdt_probe()
199 struct qcom_wdt *wdt; in qcom_wdt_probe() local
201 struct device_node *np = dev->of_node; in qcom_wdt_probe()
209 dev_err(dev, "Unsupported QCOM WDT module\n"); in qcom_wdt_probe()
210 return -ENODEV; in qcom_wdt_probe()
213 wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL); in qcom_wdt_probe()
214 if (!wdt) in qcom_wdt_probe()
215 return -ENOMEM; in qcom_wdt_probe()
219 return -ENOMEM; in qcom_wdt_probe()
222 if (of_property_read_u32(np, "cpu-offset", &percpu_offset)) in qcom_wdt_probe()
225 res->start += percpu_offset; in qcom_wdt_probe()
226 res->end += percpu_offset; in qcom_wdt_probe()
228 wdt->base = devm_ioremap_resource(dev, res); in qcom_wdt_probe()
229 if (IS_ERR(wdt->base)) in qcom_wdt_probe()
230 return PTR_ERR(wdt->base); in qcom_wdt_probe()
240 * not zero to avoid a divide-by-zero exception. in qcom_wdt_probe()
242 * WATCHDOG_CORE assumes units of seconds, if the WDT is clocked such in qcom_wdt_probe()
246 wdt->rate = clk_get_rate(clk); in qcom_wdt_probe()
247 if (wdt->rate == 0 || in qcom_wdt_probe()
248 wdt->rate > data->max_tick_count) { in qcom_wdt_probe()
250 return -EINVAL; in qcom_wdt_probe()
255 if (data->pretimeout && irq > 0) { in qcom_wdt_probe()
257 "wdt_bark", &wdt->wdd); in qcom_wdt_probe()
261 wdt->wdd.info = &qcom_wdt_pt_info; in qcom_wdt_probe()
262 wdt->wdd.pretimeout = 1; in qcom_wdt_probe()
264 if (irq == -EPROBE_DEFER) in qcom_wdt_probe()
265 return -EPROBE_DEFER; in qcom_wdt_probe()
267 wdt->wdd.info = &qcom_wdt_info; in qcom_wdt_probe()
270 wdt->wdd.ops = &qcom_wdt_ops; in qcom_wdt_probe()
271 wdt->wdd.min_timeout = 1; in qcom_wdt_probe()
272 wdt->wdd.max_timeout = data->max_tick_count / wdt->rate; in qcom_wdt_probe()
273 wdt->wdd.parent = dev; in qcom_wdt_probe()
274 wdt->layout = data->offset; in qcom_wdt_probe()
276 if (readl(wdt_addr(wdt, WDT_STS)) & 1) in qcom_wdt_probe()
277 wdt->wdd.bootstatus = WDIOF_CARDRESET; in qcom_wdt_probe()
280 * If 'timeout-sec' unspecified in devicetree, assume a 30 second in qcom_wdt_probe()
284 wdt->wdd.timeout = min(wdt->wdd.max_timeout, 30U); in qcom_wdt_probe()
285 watchdog_init_timeout(&wdt->wdd, 0, dev); in qcom_wdt_probe()
288 * If WDT is already running, call WDT start which in qcom_wdt_probe()
289 * will stop the WDT, set timeouts as bootloader in qcom_wdt_probe()
291 * to inform the WDT subsystem to ping the WDT in qcom_wdt_probe()
293 if (qcom_wdt_is_running(&wdt->wdd)) { in qcom_wdt_probe()
294 qcom_wdt_start(&wdt->wdd); in qcom_wdt_probe()
295 set_bit(WDOG_HW_RUNNING, &wdt->wdd.status); in qcom_wdt_probe()
298 ret = devm_watchdog_register_device(dev, &wdt->wdd); in qcom_wdt_probe()
302 platform_set_drvdata(pdev, wdt); in qcom_wdt_probe()
308 struct qcom_wdt *wdt = dev_get_drvdata(dev); in qcom_wdt_suspend() local
310 if (watchdog_active(&wdt->wdd)) in qcom_wdt_suspend()
311 qcom_wdt_stop(&wdt->wdd); in qcom_wdt_suspend()
318 struct qcom_wdt *wdt = dev_get_drvdata(dev); in qcom_wdt_resume() local
320 if (watchdog_active(&wdt->wdd)) in qcom_wdt_resume()
321 qcom_wdt_start(&wdt->wdd); in qcom_wdt_resume()
331 { .compatible = "qcom,apss-wdt-ipq5424", .data = &match_data_ipq5424 },
332 { .compatible = "qcom,kpss-timer", .data = &match_data_apcs_tmr },
333 { .compatible = "qcom,scss-timer", .data = &match_data_apcs_tmr },
334 { .compatible = "qcom,kpss-wdt", .data = &match_data_kpss },
349 MODULE_DESCRIPTION("QCOM KPSS Watchdog Driver");