Lines Matching +full:clk +full:- +full:delay +full:- +full:cycles

1 // SPDX-License-Identifier: GPL-2.0
5 * Copyright (C) 2015-17 Wolfram Sang, Sang Engineering <wsa@sang-engineering.com>
6 * Copyright (C) 2015-17 Renesas Electronics Corporation
9 #include <linux/clk.h>
10 #include <linux/delay.h>
36 DIV_ROUND_UP((d) * (p)->clk_rate, clk_divs[(p)->cks])
38 /* d is 16 bit, clk_divs 12 bit -> no 32 bit overflow */
39 #define DIV_BY_CLKS_PER_SEC(p, d) ((d) * clk_divs[(p)->cks] / (p)->clk_rate)
62 writel_relaxed(val, priv->base + reg); in rwdt_write()
69 rwdt_write(priv, 65536 - MUL_BY_CLKS_PER_SEC(priv, wdev->timeout), RWTCNT); in rwdt_init_timeout()
74 static void rwdt_wait_cycles(struct rwdt_priv *priv, unsigned int cycles) in rwdt_wait_cycles() argument
76 unsigned int delay; in rwdt_wait_cycles() local
78 delay = DIV_ROUND_UP(cycles * 1000000, priv->clk_rate); in rwdt_wait_cycles()
80 usleep_range(delay, 2 * delay); in rwdt_wait_cycles()
88 pm_runtime_get_sync(wdev->parent); in rwdt_start()
91 val = readb_relaxed(priv->base + RWTCSRA) & ~RWTCSRA_TME; in rwdt_start()
93 /* Delay 2 cycles before setting watchdog counter */ in rwdt_start()
97 rwdt_write(priv, priv->cks, RWTCSRA); in rwdt_start()
100 while (readb_relaxed(priv->base + RWTCSRA) & RWTCSRA_WRFLG) in rwdt_start()
103 rwdt_write(priv, priv->cks | RWTCSRA_TME, RWTCSRA); in rwdt_start()
112 rwdt_write(priv, priv->cks, RWTCSRA); in rwdt_stop()
113 /* Delay 3 cycles before disabling module clock */ in rwdt_stop()
115 pm_runtime_put(wdev->parent); in rwdt_stop()
123 u16 val = readw_relaxed(priv->base + RWTCNT); in rwdt_get_timeleft()
125 return DIV_BY_CLKS_PER_SEC(priv, 65536 - val); in rwdt_get_timeleft()
155 * Watchdog-reset integration is broken on early revisions of R-Car Gen2 SoCs
178 if (attr && setup_max_cpus > (uintptr_t)attr->data) { in rwdt_blacklisted()
179 dev_info(dev, "Watchdog blacklisted on %s %s\n", attr->soc_id, in rwdt_blacklisted()
180 attr->revision); in rwdt_blacklisted()
192 struct device *dev = &pdev->dev; in rwdt_probe()
194 struct clk *clk; in rwdt_probe() local
200 return -ENODEV; in rwdt_probe()
204 return -ENOMEM; in rwdt_probe()
206 priv->base = devm_platform_ioremap_resource(pdev, 0); in rwdt_probe()
207 if (IS_ERR(priv->base)) in rwdt_probe()
208 return PTR_ERR(priv->base); in rwdt_probe()
210 clk = devm_clk_get(dev, NULL); in rwdt_probe()
211 if (IS_ERR(clk)) in rwdt_probe()
212 return PTR_ERR(clk); in rwdt_probe()
216 priv->clk_rate = clk_get_rate(clk); in rwdt_probe()
217 csra = readb_relaxed(priv->base + RWTCSRA); in rwdt_probe()
218 priv->wdev.bootstatus = csra & RWTCSRA_WOVF ? WDIOF_CARDRESET : 0; in rwdt_probe()
221 if (!priv->clk_rate) { in rwdt_probe()
222 ret = -ENOENT; in rwdt_probe()
226 for (i = ARRAY_SIZE(clk_divs) - 1; i >= 0; i--) { in rwdt_probe()
227 clks_per_sec = priv->clk_rate / clk_divs[i]; in rwdt_probe()
229 priv->cks = i; in rwdt_probe()
236 ret = -ERANGE; in rwdt_probe()
240 priv->wdev.info = &rwdt_ident; in rwdt_probe()
241 priv->wdev.ops = &rwdt_ops; in rwdt_probe()
242 priv->wdev.parent = dev; in rwdt_probe()
243 priv->wdev.min_timeout = 1; in rwdt_probe()
244 priv->wdev.max_timeout = DIV_BY_CLKS_PER_SEC(priv, 65536); in rwdt_probe()
245 priv->wdev.timeout = min(priv->wdev.max_timeout, RWDT_DEFAULT_TIMEOUT); in rwdt_probe()
248 watchdog_set_drvdata(&priv->wdev, priv); in rwdt_probe()
249 watchdog_set_nowayout(&priv->wdev, nowayout); in rwdt_probe()
250 watchdog_set_restart_priority(&priv->wdev, 0); in rwdt_probe()
251 watchdog_stop_on_unregister(&priv->wdev); in rwdt_probe()
254 watchdog_init_timeout(&priv->wdev, 0, dev); in rwdt_probe()
259 rwdt_start(&priv->wdev); in rwdt_probe()
260 set_bit(WDOG_HW_RUNNING, &priv->wdev.status); in rwdt_probe()
263 ret = watchdog_register_device(&priv->wdev); in rwdt_probe()
278 watchdog_unregister_device(&priv->wdev); in rwdt_remove()
279 pm_runtime_disable(&pdev->dev); in rwdt_remove()
288 if (watchdog_active(&priv->wdev)) in rwdt_suspend()
289 rwdt_stop(&priv->wdev); in rwdt_suspend()
298 if (watchdog_active(&priv->wdev)) in rwdt_resume()
299 rwdt_start(&priv->wdev); in rwdt_resume()
307 { .compatible = "renesas,rcar-gen2-wdt", },
308 { .compatible = "renesas,rcar-gen3-wdt", },
326 MODULE_AUTHOR("Wolfram Sang <wsa@sang-engineering.com>");