Lines Matching refs:wdt

146 static int starfive_wdt_enable_clock(struct starfive_wdt *wdt)
150 ret = clk_prepare_enable(wdt->apb_clk);
152 return dev_err_probe(wdt->wdd.parent, ret, "failed to enable apb clock\n");
154 ret = clk_prepare_enable(wdt->core_clk);
156 return dev_err_probe(wdt->wdd.parent, ret, "failed to enable core clock\n");
161 static void starfive_wdt_disable_clock(struct starfive_wdt *wdt)
163 clk_disable_unprepare(wdt->core_clk);
164 clk_disable_unprepare(wdt->apb_clk);
167 static inline int starfive_wdt_get_clock(struct starfive_wdt *wdt)
169 struct device *dev = wdt->wdd.parent;
171 wdt->apb_clk = devm_clk_get(dev, "apb");
172 if (IS_ERR(wdt->apb_clk))
173 return dev_err_probe(dev, PTR_ERR(wdt->apb_clk), "failed to get apb clock\n");
175 wdt->core_clk = devm_clk_get(dev, "core");
176 if (IS_ERR(wdt->core_clk))
177 return dev_err_probe(dev, PTR_ERR(wdt->core_clk), "failed to get core clock\n");
198 static u32 starfive_wdt_ticks_to_sec(struct starfive_wdt *wdt, u32 ticks)
200 return DIV_ROUND_CLOSEST(ticks, wdt->freq);
204 static void starfive_wdt_unlock(struct starfive_wdt *wdt)
205 __acquires(&wdt->lock)
207 spin_lock(&wdt->lock);
208 writel(wdt->variant->unlock_key, wdt->base + wdt->variant->unlock);
211 static void starfive_wdt_lock(struct starfive_wdt *wdt)
212 __releases(&wdt->lock)
214 writel(~wdt->variant->unlock_key, wdt->base + wdt->variant->unlock);
215 spin_unlock(&wdt->lock);
219 static void starfive_wdt_enable_reset(struct starfive_wdt *wdt)
223 val = readl(wdt->base + wdt->variant->control);
224 val |= STARFIVE_WDT_RESET_EN << wdt->variant->enrst_shift;
225 writel(val, wdt->base + wdt->variant->control);
229 static bool starfive_wdt_raise_irq_status(struct starfive_wdt *wdt)
231 return !!readl(wdt->base + wdt->variant->int_status);
235 static int starfive_wdt_wait_int_free(struct starfive_wdt *wdt)
239 return readl_poll_timeout_atomic(wdt->base + wdt->variant->int_clr, value,
240 !(value & BIT(wdt->variant->intclr_ava_shift)),
245 static int starfive_wdt_int_clr(struct starfive_wdt *wdt)
249 if (wdt->variant->intclr_check) {
250 ret = starfive_wdt_wait_int_free(wdt);
252 return dev_err_probe(wdt->wdd.parent, ret,
255 writel(STARFIVE_WDT_INTCLR, wdt->base + wdt->variant->int_clr);
260 static inline void starfive_wdt_set_count(struct starfive_wdt *wdt, u32 val)
262 writel(val, wdt->base + wdt->variant->load);
265 static inline u32 starfive_wdt_get_count(struct starfive_wdt *wdt)
267 return readl(wdt->base + wdt->variant->value);
271 static inline void starfive_wdt_enable(struct starfive_wdt *wdt)
275 val = readl(wdt->base + wdt->variant->enable);
276 val |= STARFIVE_WDT_ENABLE << wdt->variant->en_shift;
277 writel(val, wdt->base + wdt->variant->enable);
281 static inline void starfive_wdt_disable(struct starfive_wdt *wdt)
285 val = readl(wdt->base + wdt->variant->enable);
286 val &= ~(STARFIVE_WDT_ENABLE << wdt->variant->en_shift);
287 writel(val, wdt->base + wdt->variant->enable);
290 static inline void starfive_wdt_set_reload_count(struct starfive_wdt *wdt, u32 count)
292 starfive_wdt_set_count(wdt, count);
295 if (wdt->variant->reload)
296 writel(0x1, wdt->base + wdt->variant->reload);
299 static unsigned int starfive_wdt_max_timeout(struct starfive_wdt *wdt)
301 if (wdt->variant->double_timeout)
302 return DIV_ROUND_UP(STARFIVE_WDT_MAXCNT, (wdt->freq / 2)) - 1;
304 return DIV_ROUND_UP(STARFIVE_WDT_MAXCNT, wdt->freq) - 1;
309 struct starfive_wdt *wdt = watchdog_get_drvdata(wdd);
316 count = starfive_wdt_get_count(wdt);
317 if (wdt->variant->double_timeout && !starfive_wdt_raise_irq_status(wdt))
318 count += wdt->count;
320 return starfive_wdt_ticks_to_sec(wdt, count);
325 struct starfive_wdt *wdt = watchdog_get_drvdata(wdd);
328 starfive_wdt_unlock(wdt);
329 ret = starfive_wdt_int_clr(wdt);
333 starfive_wdt_set_reload_count(wdt, wdt->count);
337 starfive_wdt_lock(wdt);
341 static int starfive_wdt_start(struct starfive_wdt *wdt)
345 starfive_wdt_unlock(wdt);
347 starfive_wdt_disable(wdt);
349 starfive_wdt_enable_reset(wdt);
350 ret = starfive_wdt_int_clr(wdt);
354 starfive_wdt_set_count(wdt, wdt->count);
355 starfive_wdt_enable(wdt);
358 starfive_wdt_lock(wdt);
362 static void starfive_wdt_stop(struct starfive_wdt *wdt)
364 starfive_wdt_unlock(wdt);
365 starfive_wdt_disable(wdt);
366 starfive_wdt_lock(wdt);
371 struct starfive_wdt *wdt = watchdog_get_drvdata(wdd);
377 return starfive_wdt_start(wdt);
382 struct starfive_wdt *wdt = watchdog_get_drvdata(wdd);
384 starfive_wdt_stop(wdt);
391 struct starfive_wdt *wdt = watchdog_get_drvdata(wdd);
392 unsigned long count = timeout * wdt->freq;
395 if (wdt->variant->double_timeout)
398 wdt->count = count;
401 starfive_wdt_unlock(wdt);
402 starfive_wdt_disable(wdt);
403 starfive_wdt_set_reload_count(wdt, wdt->count);
404 starfive_wdt_enable(wdt);
405 starfive_wdt_lock(wdt);
428 struct starfive_wdt *wdt;
431 wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
432 if (!wdt)
435 wdt->base = devm_platform_ioremap_resource(pdev, 0);
436 if (IS_ERR(wdt->base))
437 return dev_err_probe(&pdev->dev, PTR_ERR(wdt->base), "error mapping registers\n");
439 wdt->wdd.parent = &pdev->dev;
440 ret = starfive_wdt_get_clock(wdt);
444 platform_set_drvdata(pdev, wdt);
452 ret = starfive_wdt_enable_clock(wdt);
461 watchdog_set_drvdata(&wdt->wdd, wdt);
462 wdt->wdd.info = &starfive_wdt_info;
463 wdt->wdd.ops = &starfive_wdt_ops;
464 wdt->variant = of_device_get_match_data(&pdev->dev);
465 spin_lock_init(&wdt->lock);
467 wdt->freq = clk_get_rate(wdt->core_clk);
468 if (!wdt->freq) {
474 wdt->wdd.min_timeout = 1;
475 wdt->wdd.max_timeout = starfive_wdt_max_timeout(wdt);
476 wdt->wdd.timeout = STARFIVE_WDT_DEFAULT_TIME;
477 watchdog_init_timeout(&wdt->wdd, heartbeat, &pdev->dev);
478 starfive_wdt_set_timeout(&wdt->wdd, wdt->wdd.timeout);
480 watchdog_set_nowayout(&wdt->wdd, nowayout);
481 watchdog_stop_on_reboot(&wdt->wdd);
482 watchdog_stop_on_unregister(&wdt->wdd);
485 ret = starfive_wdt_start(wdt);
488 set_bit(WDOG_HW_RUNNING, &wdt->wdd.status);
490 starfive_wdt_stop(wdt);
493 ret = watchdog_register_device(&wdt->wdd);
508 starfive_wdt_disable_clock(wdt);
516 struct starfive_wdt *wdt = platform_get_drvdata(pdev);
518 starfive_wdt_stop(wdt);
519 watchdog_unregister_device(&wdt->wdd);
525 starfive_wdt_disable_clock(wdt);
530 struct starfive_wdt *wdt = platform_get_drvdata(pdev);
532 starfive_wdt_pm_stop(&wdt->wdd);
537 struct starfive_wdt *wdt = dev_get_drvdata(dev);
540 wdt->reload = starfive_wdt_get_count(wdt);
543 starfive_wdt_stop(wdt);
550 struct starfive_wdt *wdt = dev_get_drvdata(dev);
557 starfive_wdt_unlock(wdt);
559 starfive_wdt_set_reload_count(wdt, wdt->reload);
560 starfive_wdt_lock(wdt);
562 if (watchdog_active(&wdt->wdd))
563 return starfive_wdt_start(wdt);
570 struct starfive_wdt *wdt = dev_get_drvdata(dev);
572 starfive_wdt_disable_clock(wdt);
579 struct starfive_wdt *wdt = dev_get_drvdata(dev);
581 return starfive_wdt_enable_clock(wdt);
590 { .compatible = "starfive,jh7100-wdt", .data = &starfive_wdt_jh7100_variant },
591 { .compatible = "starfive,jh7110-wdt", .data = &starfive_wdt_jh7110_variant },
601 .name = "starfive-wdt",