Lines Matching full:wdt
146 static int starfive_wdt_enable_clock(struct starfive_wdt *wdt) in starfive_wdt_enable_clock() argument
150 ret = clk_prepare_enable(wdt->apb_clk); in starfive_wdt_enable_clock()
152 return dev_err_probe(wdt->wdd.parent, ret, "failed to enable apb clock\n"); in starfive_wdt_enable_clock()
154 ret = clk_prepare_enable(wdt->core_clk); in starfive_wdt_enable_clock()
156 return dev_err_probe(wdt->wdd.parent, ret, "failed to enable core clock\n"); in starfive_wdt_enable_clock()
161 static void starfive_wdt_disable_clock(struct starfive_wdt *wdt) in starfive_wdt_disable_clock() argument
163 clk_disable_unprepare(wdt->core_clk); in starfive_wdt_disable_clock()
164 clk_disable_unprepare(wdt->apb_clk); in starfive_wdt_disable_clock()
167 static inline int starfive_wdt_get_clock(struct starfive_wdt *wdt) in starfive_wdt_get_clock() argument
169 struct device *dev = wdt->wdd.parent; in starfive_wdt_get_clock()
171 wdt->apb_clk = devm_clk_get(dev, "apb"); in starfive_wdt_get_clock()
172 if (IS_ERR(wdt->apb_clk)) in starfive_wdt_get_clock()
173 return dev_err_probe(dev, PTR_ERR(wdt->apb_clk), "failed to get apb clock\n"); in starfive_wdt_get_clock()
175 wdt->core_clk = devm_clk_get(dev, "core"); in starfive_wdt_get_clock()
176 if (IS_ERR(wdt->core_clk)) in starfive_wdt_get_clock()
177 return dev_err_probe(dev, PTR_ERR(wdt->core_clk), "failed to get core clock\n"); in starfive_wdt_get_clock()
198 static u32 starfive_wdt_ticks_to_sec(struct starfive_wdt *wdt, u32 ticks) in starfive_wdt_ticks_to_sec() argument
200 return DIV_ROUND_CLOSEST(ticks, wdt->freq); in starfive_wdt_ticks_to_sec()
204 static void starfive_wdt_unlock(struct starfive_wdt *wdt) in starfive_wdt_unlock() argument
206 spin_lock(&wdt->lock); in starfive_wdt_unlock()
207 writel(wdt->variant->unlock_key, wdt->base + wdt->variant->unlock); in starfive_wdt_unlock()
210 static void starfive_wdt_lock(struct starfive_wdt *wdt) in starfive_wdt_lock() argument
212 writel(~wdt->variant->unlock_key, wdt->base + wdt->variant->unlock); in starfive_wdt_lock()
213 spin_unlock(&wdt->lock); in starfive_wdt_lock()
217 static void starfive_wdt_enable_reset(struct starfive_wdt *wdt) in starfive_wdt_enable_reset() argument
221 val = readl(wdt->base + wdt->variant->control); in starfive_wdt_enable_reset()
222 val |= STARFIVE_WDT_RESET_EN << wdt->variant->enrst_shift; in starfive_wdt_enable_reset()
223 writel(val, wdt->base + wdt->variant->control); in starfive_wdt_enable_reset()
227 static bool starfive_wdt_raise_irq_status(struct starfive_wdt *wdt) in starfive_wdt_raise_irq_status() argument
229 return !!readl(wdt->base + wdt->variant->int_status); in starfive_wdt_raise_irq_status()
233 static int starfive_wdt_wait_int_free(struct starfive_wdt *wdt) in starfive_wdt_wait_int_free() argument
237 return readl_poll_timeout_atomic(wdt->base + wdt->variant->int_clr, value, in starfive_wdt_wait_int_free()
238 !(value & BIT(wdt->variant->intclr_ava_shift)), in starfive_wdt_wait_int_free()
243 static int starfive_wdt_int_clr(struct starfive_wdt *wdt) in starfive_wdt_int_clr() argument
247 if (wdt->variant->intclr_check) { in starfive_wdt_int_clr()
248 ret = starfive_wdt_wait_int_free(wdt); in starfive_wdt_int_clr()
250 return dev_err_probe(wdt->wdd.parent, ret, in starfive_wdt_int_clr()
253 writel(STARFIVE_WDT_INTCLR, wdt->base + wdt->variant->int_clr); in starfive_wdt_int_clr()
258 static inline void starfive_wdt_set_count(struct starfive_wdt *wdt, u32 val) in starfive_wdt_set_count() argument
260 writel(val, wdt->base + wdt->variant->load); in starfive_wdt_set_count()
263 static inline u32 starfive_wdt_get_count(struct starfive_wdt *wdt) in starfive_wdt_get_count() argument
265 return readl(wdt->base + wdt->variant->value); in starfive_wdt_get_count()
269 static inline void starfive_wdt_enable(struct starfive_wdt *wdt) in starfive_wdt_enable() argument
273 val = readl(wdt->base + wdt->variant->enable); in starfive_wdt_enable()
274 val |= STARFIVE_WDT_ENABLE << wdt->variant->en_shift; in starfive_wdt_enable()
275 writel(val, wdt->base + wdt->variant->enable); in starfive_wdt_enable()
279 static inline void starfive_wdt_disable(struct starfive_wdt *wdt) in starfive_wdt_disable() argument
283 val = readl(wdt->base + wdt->variant->enable); in starfive_wdt_disable()
284 val &= ~(STARFIVE_WDT_ENABLE << wdt->variant->en_shift); in starfive_wdt_disable()
285 writel(val, wdt->base + wdt->variant->enable); in starfive_wdt_disable()
288 static inline void starfive_wdt_set_reload_count(struct starfive_wdt *wdt, u32 count) in starfive_wdt_set_reload_count() argument
290 starfive_wdt_set_count(wdt, count); in starfive_wdt_set_reload_count()
293 if (wdt->variant->reload) in starfive_wdt_set_reload_count()
294 writel(0x1, wdt->base + wdt->variant->reload); in starfive_wdt_set_reload_count()
297 static unsigned int starfive_wdt_max_timeout(struct starfive_wdt *wdt) in starfive_wdt_max_timeout() argument
299 if (wdt->variant->double_timeout) in starfive_wdt_max_timeout()
300 return DIV_ROUND_UP(STARFIVE_WDT_MAXCNT, (wdt->freq / 2)) - 1; in starfive_wdt_max_timeout()
302 return DIV_ROUND_UP(STARFIVE_WDT_MAXCNT, wdt->freq) - 1; in starfive_wdt_max_timeout()
307 struct starfive_wdt *wdt = watchdog_get_drvdata(wdd); in starfive_wdt_get_timeleft() local
314 count = starfive_wdt_get_count(wdt); in starfive_wdt_get_timeleft()
315 if (wdt->variant->double_timeout && !starfive_wdt_raise_irq_status(wdt)) in starfive_wdt_get_timeleft()
316 count += wdt->count; in starfive_wdt_get_timeleft()
318 return starfive_wdt_ticks_to_sec(wdt, count); in starfive_wdt_get_timeleft()
323 struct starfive_wdt *wdt = watchdog_get_drvdata(wdd); in starfive_wdt_keepalive() local
326 starfive_wdt_unlock(wdt); in starfive_wdt_keepalive()
327 ret = starfive_wdt_int_clr(wdt); in starfive_wdt_keepalive()
331 starfive_wdt_set_reload_count(wdt, wdt->count); in starfive_wdt_keepalive()
335 starfive_wdt_lock(wdt); in starfive_wdt_keepalive()
339 static int starfive_wdt_start(struct starfive_wdt *wdt) in starfive_wdt_start() argument
343 starfive_wdt_unlock(wdt); in starfive_wdt_start()
345 starfive_wdt_disable(wdt); in starfive_wdt_start()
347 starfive_wdt_enable_reset(wdt); in starfive_wdt_start()
348 ret = starfive_wdt_int_clr(wdt); in starfive_wdt_start()
352 starfive_wdt_set_count(wdt, wdt->count); in starfive_wdt_start()
353 starfive_wdt_enable(wdt); in starfive_wdt_start()
356 starfive_wdt_lock(wdt); in starfive_wdt_start()
360 static void starfive_wdt_stop(struct starfive_wdt *wdt) in starfive_wdt_stop() argument
362 starfive_wdt_unlock(wdt); in starfive_wdt_stop()
363 starfive_wdt_disable(wdt); in starfive_wdt_stop()
364 starfive_wdt_lock(wdt); in starfive_wdt_stop()
369 struct starfive_wdt *wdt = watchdog_get_drvdata(wdd); in starfive_wdt_pm_start() local
375 return starfive_wdt_start(wdt); in starfive_wdt_pm_start()
380 struct starfive_wdt *wdt = watchdog_get_drvdata(wdd); in starfive_wdt_pm_stop() local
382 starfive_wdt_stop(wdt); in starfive_wdt_pm_stop()
389 struct starfive_wdt *wdt = watchdog_get_drvdata(wdd); in starfive_wdt_set_timeout() local
390 unsigned long count = timeout * wdt->freq; in starfive_wdt_set_timeout()
393 if (wdt->variant->double_timeout) in starfive_wdt_set_timeout()
396 wdt->count = count; in starfive_wdt_set_timeout()
399 starfive_wdt_unlock(wdt); in starfive_wdt_set_timeout()
400 starfive_wdt_disable(wdt); in starfive_wdt_set_timeout()
401 starfive_wdt_set_reload_count(wdt, wdt->count); in starfive_wdt_set_timeout()
402 starfive_wdt_enable(wdt); in starfive_wdt_set_timeout()
403 starfive_wdt_lock(wdt); in starfive_wdt_set_timeout()
426 struct starfive_wdt *wdt; in starfive_wdt_probe() local
429 wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL); in starfive_wdt_probe()
430 if (!wdt) in starfive_wdt_probe()
433 wdt->base = devm_platform_ioremap_resource(pdev, 0); in starfive_wdt_probe()
434 if (IS_ERR(wdt->base)) in starfive_wdt_probe()
435 return dev_err_probe(&pdev->dev, PTR_ERR(wdt->base), "error mapping registers\n"); in starfive_wdt_probe()
437 wdt->wdd.parent = &pdev->dev; in starfive_wdt_probe()
438 ret = starfive_wdt_get_clock(wdt); in starfive_wdt_probe()
442 platform_set_drvdata(pdev, wdt); in starfive_wdt_probe()
450 ret = starfive_wdt_enable_clock(wdt); in starfive_wdt_probe()
459 watchdog_set_drvdata(&wdt->wdd, wdt); in starfive_wdt_probe()
460 wdt->wdd.info = &starfive_wdt_info; in starfive_wdt_probe()
461 wdt->wdd.ops = &starfive_wdt_ops; in starfive_wdt_probe()
462 wdt->variant = of_device_get_match_data(&pdev->dev); in starfive_wdt_probe()
463 spin_lock_init(&wdt->lock); in starfive_wdt_probe()
465 wdt->freq = clk_get_rate(wdt->core_clk); in starfive_wdt_probe()
466 if (!wdt->freq) { in starfive_wdt_probe()
472 wdt->wdd.min_timeout = 1; in starfive_wdt_probe()
473 wdt->wdd.max_timeout = starfive_wdt_max_timeout(wdt); in starfive_wdt_probe()
474 wdt->wdd.timeout = STARFIVE_WDT_DEFAULT_TIME; in starfive_wdt_probe()
475 watchdog_init_timeout(&wdt->wdd, heartbeat, &pdev->dev); in starfive_wdt_probe()
476 starfive_wdt_set_timeout(&wdt->wdd, wdt->wdd.timeout); in starfive_wdt_probe()
478 watchdog_set_nowayout(&wdt->wdd, nowayout); in starfive_wdt_probe()
479 watchdog_stop_on_reboot(&wdt->wdd); in starfive_wdt_probe()
480 watchdog_stop_on_unregister(&wdt->wdd); in starfive_wdt_probe()
483 ret = starfive_wdt_start(wdt); in starfive_wdt_probe()
486 set_bit(WDOG_HW_RUNNING, &wdt->wdd.status); in starfive_wdt_probe()
488 starfive_wdt_stop(wdt); in starfive_wdt_probe()
491 ret = watchdog_register_device(&wdt->wdd); in starfive_wdt_probe()
501 starfive_wdt_disable_clock(wdt); in starfive_wdt_probe()
509 struct starfive_wdt *wdt = platform_get_drvdata(pdev); in starfive_wdt_remove() local
511 starfive_wdt_stop(wdt); in starfive_wdt_remove()
512 watchdog_unregister_device(&wdt->wdd); in starfive_wdt_remove()
518 starfive_wdt_disable_clock(wdt); in starfive_wdt_remove()
525 struct starfive_wdt *wdt = platform_get_drvdata(pdev); in starfive_wdt_shutdown() local
527 starfive_wdt_pm_stop(&wdt->wdd); in starfive_wdt_shutdown()
532 struct starfive_wdt *wdt = dev_get_drvdata(dev); in starfive_wdt_suspend() local
535 wdt->reload = starfive_wdt_get_count(wdt); in starfive_wdt_suspend()
538 starfive_wdt_stop(wdt); in starfive_wdt_suspend()
545 struct starfive_wdt *wdt = dev_get_drvdata(dev); in starfive_wdt_resume() local
552 starfive_wdt_unlock(wdt); in starfive_wdt_resume()
554 starfive_wdt_set_reload_count(wdt, wdt->reload); in starfive_wdt_resume()
555 starfive_wdt_lock(wdt); in starfive_wdt_resume()
557 return starfive_wdt_start(wdt); in starfive_wdt_resume()
562 struct starfive_wdt *wdt = dev_get_drvdata(dev); in starfive_wdt_runtime_suspend() local
564 starfive_wdt_disable_clock(wdt); in starfive_wdt_runtime_suspend()
571 struct starfive_wdt *wdt = dev_get_drvdata(dev); in starfive_wdt_runtime_resume() local
573 return starfive_wdt_enable_clock(wdt); in starfive_wdt_runtime_resume()
582 { .compatible = "starfive,jh7100-wdt", .data = &starfive_wdt_jh7100_variant },
583 { .compatible = "starfive,jh7110-wdt", .data = &starfive_wdt_jh7110_variant },
593 .name = "starfive-wdt",