Lines Matching full:wdt
87 * WDT reset request. On old SoCs it's usually called MASK_WDT_RESET_REQUEST,
97 * register. If 'mask_bit' bit is set, PMU will disable WDT reset when
147 * @cnt_en_reg: Offset in pmureg for the register that enables WDT counter.
167 struct clk *src_clk; /* for WDT counter */
267 { .compatible = "samsung,s3c2410-wdt",
269 { .compatible = "samsung,s3c6410-wdt",
271 { .compatible = "samsung,exynos5250-wdt",
273 { .compatible = "samsung,exynos5420-wdt",
275 { .compatible = "samsung,exynos7-wdt",
277 { .compatible = "samsung,exynos850-wdt",
279 { .compatible = "samsung,exynosautov9-wdt",
288 .name = "s3c2410-wdt",
297 static inline unsigned long s3c2410wdt_get_freq(struct s3c2410_wdt *wdt) in s3c2410wdt_get_freq() argument
299 return clk_get_rate(wdt->src_clk ? wdt->src_clk : wdt->bus_clk); in s3c2410wdt_get_freq()
302 static inline unsigned int s3c2410wdt_max_timeout(struct s3c2410_wdt *wdt) in s3c2410wdt_max_timeout() argument
304 const unsigned long freq = s3c2410wdt_get_freq(wdt); in s3c2410wdt_max_timeout()
310 static int s3c2410wdt_disable_wdt_reset(struct s3c2410_wdt *wdt, bool mask) in s3c2410wdt_disable_wdt_reset() argument
312 const u32 mask_val = BIT(wdt->drv_data->mask_bit); in s3c2410wdt_disable_wdt_reset()
316 ret = regmap_update_bits(wdt->pmureg, wdt->drv_data->disable_reg, in s3c2410wdt_disable_wdt_reset()
319 dev_err(wdt->dev, "failed to update reg(%d)\n", ret); in s3c2410wdt_disable_wdt_reset()
324 static int s3c2410wdt_mask_wdt_reset(struct s3c2410_wdt *wdt, bool mask) in s3c2410wdt_mask_wdt_reset() argument
326 const u32 mask_val = BIT(wdt->drv_data->mask_bit); in s3c2410wdt_mask_wdt_reset()
327 const bool val_inv = wdt->drv_data->mask_reset_inv; in s3c2410wdt_mask_wdt_reset()
331 ret = regmap_update_bits(wdt->pmureg, wdt->drv_data->mask_reset_reg, in s3c2410wdt_mask_wdt_reset()
334 dev_err(wdt->dev, "failed to update reg(%d)\n", ret); in s3c2410wdt_mask_wdt_reset()
339 static int s3c2410wdt_enable_counter(struct s3c2410_wdt *wdt, bool en) in s3c2410wdt_enable_counter() argument
341 const u32 mask_val = BIT(wdt->drv_data->cnt_en_bit); in s3c2410wdt_enable_counter()
345 ret = regmap_update_bits(wdt->pmureg, wdt->drv_data->cnt_en_reg, in s3c2410wdt_enable_counter()
348 dev_err(wdt->dev, "failed to update reg(%d)\n", ret); in s3c2410wdt_enable_counter()
353 static int s3c2410wdt_enable(struct s3c2410_wdt *wdt, bool en) in s3c2410wdt_enable() argument
357 if (wdt->drv_data->quirks & QUIRK_HAS_PMU_AUTO_DISABLE) { in s3c2410wdt_enable()
358 ret = s3c2410wdt_disable_wdt_reset(wdt, !en); in s3c2410wdt_enable()
363 if (wdt->drv_data->quirks & QUIRK_HAS_PMU_MASK_RESET) { in s3c2410wdt_enable()
364 ret = s3c2410wdt_mask_wdt_reset(wdt, !en); in s3c2410wdt_enable()
369 if (wdt->drv_data->quirks & QUIRK_HAS_PMU_CNT_EN) { in s3c2410wdt_enable()
370 ret = s3c2410wdt_enable_counter(wdt, en); in s3c2410wdt_enable()
380 struct s3c2410_wdt *wdt = watchdog_get_drvdata(wdd); in s3c2410wdt_keepalive() local
383 spin_lock_irqsave(&wdt->lock, flags); in s3c2410wdt_keepalive()
384 writel(wdt->count, wdt->reg_base + S3C2410_WTCNT); in s3c2410wdt_keepalive()
385 spin_unlock_irqrestore(&wdt->lock, flags); in s3c2410wdt_keepalive()
390 static void __s3c2410wdt_stop(struct s3c2410_wdt *wdt) in __s3c2410wdt_stop() argument
394 wtcon = readl(wdt->reg_base + S3C2410_WTCON); in __s3c2410wdt_stop()
396 writel(wtcon, wdt->reg_base + S3C2410_WTCON); in __s3c2410wdt_stop()
401 struct s3c2410_wdt *wdt = watchdog_get_drvdata(wdd); in s3c2410wdt_stop() local
404 spin_lock_irqsave(&wdt->lock, flags); in s3c2410wdt_stop()
405 __s3c2410wdt_stop(wdt); in s3c2410wdt_stop()
406 spin_unlock_irqrestore(&wdt->lock, flags); in s3c2410wdt_stop()
414 struct s3c2410_wdt *wdt = watchdog_get_drvdata(wdd); in s3c2410wdt_start() local
417 spin_lock_irqsave(&wdt->lock, flags); in s3c2410wdt_start()
419 __s3c2410wdt_stop(wdt); in s3c2410wdt_start()
421 wtcon = readl(wdt->reg_base + S3C2410_WTCON); in s3c2410wdt_start()
432 dev_dbg(wdt->dev, "Starting watchdog: count=0x%08x, wtcon=%08lx\n", in s3c2410wdt_start()
433 wdt->count, wtcon); in s3c2410wdt_start()
435 writel(wdt->count, wdt->reg_base + S3C2410_WTDAT); in s3c2410wdt_start()
436 writel(wdt->count, wdt->reg_base + S3C2410_WTCNT); in s3c2410wdt_start()
437 writel(wtcon, wdt->reg_base + S3C2410_WTCON); in s3c2410wdt_start()
438 spin_unlock_irqrestore(&wdt->lock, flags); in s3c2410wdt_start()
446 struct s3c2410_wdt *wdt = watchdog_get_drvdata(wdd); in s3c2410wdt_set_heartbeat() local
447 unsigned long freq = s3c2410wdt_get_freq(wdt); in s3c2410wdt_set_heartbeat()
458 dev_dbg(wdt->dev, "Heartbeat: count=%d, timeout=%d, freq=%lu\n", in s3c2410wdt_set_heartbeat()
470 dev_err(wdt->dev, "timeout %d too big\n", timeout); in s3c2410wdt_set_heartbeat()
475 dev_dbg(wdt->dev, "Heartbeat: timeout=%d, divisor=%d, count=%d (%08x)\n", in s3c2410wdt_set_heartbeat()
479 wdt->count = count; in s3c2410wdt_set_heartbeat()
482 wtcon = readl(wdt->reg_base + S3C2410_WTCON); in s3c2410wdt_set_heartbeat()
486 writel(count, wdt->reg_base + S3C2410_WTDAT); in s3c2410wdt_set_heartbeat()
487 writel(wtcon, wdt->reg_base + S3C2410_WTCON); in s3c2410wdt_set_heartbeat()
497 struct s3c2410_wdt *wdt = watchdog_get_drvdata(wdd); in s3c2410wdt_restart() local
498 void __iomem *wdt_base = wdt->reg_base; in s3c2410wdt_restart()
545 struct s3c2410_wdt *wdt = platform_get_drvdata(param); in s3c2410wdt_irq() local
547 dev_info(wdt->dev, "watchdog timer expired (irq)\n"); in s3c2410wdt_irq()
549 s3c2410wdt_keepalive(&wdt->wdt_device); in s3c2410wdt_irq()
551 if (wdt->drv_data->quirks & QUIRK_HAS_WTCLRINT_REG) in s3c2410wdt_irq()
552 writel(0x1, wdt->reg_base + S3C2410_WTCLRINT); in s3c2410wdt_irq()
557 static inline unsigned int s3c2410wdt_get_bootstatus(struct s3c2410_wdt *wdt) in s3c2410wdt_get_bootstatus() argument
562 if (!(wdt->drv_data->quirks & QUIRK_HAS_PMU_RST_STAT)) in s3c2410wdt_get_bootstatus()
565 ret = regmap_read(wdt->pmureg, wdt->drv_data->rst_stat_reg, &rst_stat); in s3c2410wdt_get_bootstatus()
567 dev_warn(wdt->dev, "Couldn't get RST_STAT register\n"); in s3c2410wdt_get_bootstatus()
568 else if (rst_stat & BIT(wdt->drv_data->rst_stat_bit)) in s3c2410wdt_get_bootstatus()
575 s3c2410_get_wdt_drv_data(struct platform_device *pdev, struct s3c2410_wdt *wdt) in s3c2410_get_wdt_drv_data() argument
613 wdt->drv_data = variant; in s3c2410_get_wdt_drv_data()
625 struct s3c2410_wdt *wdt; in s3c2410wdt_probe() local
630 wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL); in s3c2410wdt_probe()
631 if (!wdt) in s3c2410wdt_probe()
634 wdt->dev = dev; in s3c2410wdt_probe()
635 spin_lock_init(&wdt->lock); in s3c2410wdt_probe()
636 wdt->wdt_device = s3c2410_wdd; in s3c2410wdt_probe()
638 ret = s3c2410_get_wdt_drv_data(pdev, wdt); in s3c2410wdt_probe()
642 if (wdt->drv_data->quirks & QUIRKS_HAVE_PMUREG) { in s3c2410wdt_probe()
643 wdt->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node, in s3c2410wdt_probe()
645 if (IS_ERR(wdt->pmureg)) in s3c2410wdt_probe()
646 return dev_err_probe(dev, PTR_ERR(wdt->pmureg), in s3c2410wdt_probe()
655 wdt->reg_base = devm_platform_ioremap_resource(pdev, 0); in s3c2410wdt_probe()
656 if (IS_ERR(wdt->reg_base)) in s3c2410wdt_probe()
657 return PTR_ERR(wdt->reg_base); in s3c2410wdt_probe()
659 wdt->bus_clk = devm_clk_get_enabled(dev, "watchdog"); in s3c2410wdt_probe()
660 if (IS_ERR(wdt->bus_clk)) in s3c2410wdt_probe()
661 return dev_err_probe(dev, PTR_ERR(wdt->bus_clk), "failed to get bus clock\n"); in s3c2410wdt_probe()
667 wdt->src_clk = devm_clk_get_optional_enabled(dev, "watchdog_src"); in s3c2410wdt_probe()
668 if (IS_ERR(wdt->src_clk)) in s3c2410wdt_probe()
669 return dev_err_probe(dev, PTR_ERR(wdt->src_clk), "failed to get source clock\n"); in s3c2410wdt_probe()
671 wdt->wdt_device.min_timeout = 1; in s3c2410wdt_probe()
672 wdt->wdt_device.max_timeout = s3c2410wdt_max_timeout(wdt); in s3c2410wdt_probe()
674 watchdog_set_drvdata(&wdt->wdt_device, wdt); in s3c2410wdt_probe()
679 watchdog_init_timeout(&wdt->wdt_device, tmr_margin, dev); in s3c2410wdt_probe()
680 ret = s3c2410wdt_set_heartbeat(&wdt->wdt_device, in s3c2410wdt_probe()
681 wdt->wdt_device.timeout); in s3c2410wdt_probe()
683 ret = s3c2410wdt_set_heartbeat(&wdt->wdt_device, in s3c2410wdt_probe()
697 watchdog_set_nowayout(&wdt->wdt_device, nowayout); in s3c2410wdt_probe()
698 watchdog_set_restart_priority(&wdt->wdt_device, 128); in s3c2410wdt_probe()
700 wdt->wdt_device.bootstatus = s3c2410wdt_get_bootstatus(wdt); in s3c2410wdt_probe()
701 wdt->wdt_device.parent = dev; in s3c2410wdt_probe()
712 s3c2410wdt_start(&wdt->wdt_device); in s3c2410wdt_probe()
713 set_bit(WDOG_HW_RUNNING, &wdt->wdt_device.status); in s3c2410wdt_probe()
715 s3c2410wdt_stop(&wdt->wdt_device); in s3c2410wdt_probe()
718 ret = devm_watchdog_register_device(dev, &wdt->wdt_device); in s3c2410wdt_probe()
722 ret = s3c2410wdt_enable(wdt, true); in s3c2410wdt_probe()
726 ret = devm_add_action_or_reset(dev, s3c2410wdt_wdt_disable_action, wdt); in s3c2410wdt_probe()
730 platform_set_drvdata(pdev, wdt); in s3c2410wdt_probe()
734 wtcon = readl(wdt->reg_base + S3C2410_WTCON); in s3c2410wdt_probe()
746 struct s3c2410_wdt *wdt = platform_get_drvdata(dev); in s3c2410wdt_shutdown() local
748 s3c2410wdt_enable(wdt, false); in s3c2410wdt_shutdown()
749 s3c2410wdt_stop(&wdt->wdt_device); in s3c2410wdt_shutdown()
755 struct s3c2410_wdt *wdt = dev_get_drvdata(dev); in s3c2410wdt_suspend() local
758 wdt->wtcon_save = readl(wdt->reg_base + S3C2410_WTCON); in s3c2410wdt_suspend()
759 wdt->wtdat_save = readl(wdt->reg_base + S3C2410_WTDAT); in s3c2410wdt_suspend()
761 ret = s3c2410wdt_enable(wdt, false); in s3c2410wdt_suspend()
766 s3c2410wdt_stop(&wdt->wdt_device); in s3c2410wdt_suspend()
774 struct s3c2410_wdt *wdt = dev_get_drvdata(dev); in s3c2410wdt_resume() local
777 writel(wdt->wtdat_save, wdt->reg_base + S3C2410_WTDAT); in s3c2410wdt_resume()
778 writel(wdt->wtdat_save, wdt->reg_base + S3C2410_WTCNT);/* Reset count */ in s3c2410wdt_resume()
779 writel(wdt->wtcon_save, wdt->reg_base + S3C2410_WTCON); in s3c2410wdt_resume()
781 ret = s3c2410wdt_enable(wdt, true); in s3c2410wdt_resume()
786 (wdt->wtcon_save & S3C2410_WTCON_ENABLE) ? "en" : "dis"); in s3c2410wdt_resume()
799 .name = "s3c2410-wdt",