Lines Matching +full:reset +full:- +full:on +full:- +full:timeout
1 // SPDX-License-Identifier: GPL-2.0-or-later
5 * Copyright (c) 2014 Oleksij Rempel <linux@rempel-privat.de>
16 #include <linux/reset.h>
25 /* This bit set if timeout reached. Cleared by SW. */
27 /* HW Reset on timeout */
35 * depends on used clock: T = WDCLK * (0xff + 1) * 4
71 iowrite32(0xaa, priv->iobase + HW_WDFEED); in asm9260_wdt_feed()
72 iowrite32(0x55, priv->iobase + HW_WDFEED); in asm9260_wdt_feed()
82 counter = ioread32(priv->iobase + HW_WDTV); in asm9260_wdt_gettimeleft()
84 return counter / priv->wdt_freq; in asm9260_wdt_gettimeleft()
92 counter = wdd->timeout * priv->wdt_freq; in asm9260_wdt_updatetimeout()
94 iowrite32(counter, priv->iobase + HW_WDTC); in asm9260_wdt_updatetimeout()
104 if (priv->mode == HW_RESET) in asm9260_wdt_enable()
107 iowrite32(BM_MOD_WDEN | mode, priv->iobase + HW_WDMOD); in asm9260_wdt_enable()
120 /* The only way to disable WD is to reset it. */ in asm9260_wdt_disable()
121 reset_control_assert(priv->rst); in asm9260_wdt_disable()
122 reset_control_deassert(priv->rst); in asm9260_wdt_disable()
129 wdd->timeout = to; in asm9260_wdt_settimeout()
139 iowrite32(BM_MOD_WDEN | BM_MOD_WDRESET, priv->iobase + HW_WDMOD); in asm9260_wdt_sys_reset()
141 iowrite32(0xff, priv->iobase + HW_WDTC); in asm9260_wdt_sys_reset()
143 asm9260_wdt_feed(&priv->wdd); in asm9260_wdt_sys_reset()
145 * Then write wrong pattern to the feed to trigger reset in asm9260_wdt_sys_reset()
148 iowrite32(0xff, priv->iobase + HW_WDFEED); in asm9260_wdt_sys_reset()
158 stat = ioread32(priv->iobase + HW_WDMOD); in asm9260_wdt_irq()
162 if (priv->mode == DEBUG) { in asm9260_wdt_irq()
163 dev_info(priv->dev, "Watchdog Timeout. Do nothing.\n"); in asm9260_wdt_irq()
165 dev_info(priv->dev, "Watchdog Timeout. Doing SW Reset.\n"); in asm9260_wdt_irq()
208 priv->clk = devm_clk_get(priv->dev, "mod"); in asm9260_wdt_get_dt_clks()
209 if (IS_ERR(priv->clk)) { in asm9260_wdt_get_dt_clks()
210 dev_err(priv->dev, "Failed to get \"mod\" clk\n"); in asm9260_wdt_get_dt_clks()
211 return PTR_ERR(priv->clk); in asm9260_wdt_get_dt_clks()
215 priv->clk_ahb = devm_clk_get(priv->dev, "ahb"); in asm9260_wdt_get_dt_clks()
216 if (IS_ERR(priv->clk_ahb)) { in asm9260_wdt_get_dt_clks()
217 dev_err(priv->dev, "Failed to get \"ahb\" clk\n"); in asm9260_wdt_get_dt_clks()
218 return PTR_ERR(priv->clk_ahb); in asm9260_wdt_get_dt_clks()
221 err = clk_prepare_enable(priv->clk_ahb); in asm9260_wdt_get_dt_clks()
223 dev_err(priv->dev, "Failed to enable ahb_clk!\n"); in asm9260_wdt_get_dt_clks()
226 err = devm_add_action_or_reset(priv->dev, in asm9260_wdt_get_dt_clks()
228 priv->clk_ahb); in asm9260_wdt_get_dt_clks()
232 err = clk_set_rate(priv->clk, CLOCK_FREQ); in asm9260_wdt_get_dt_clks()
234 dev_err(priv->dev, "Failed to set rate!\n"); in asm9260_wdt_get_dt_clks()
238 err = clk_prepare_enable(priv->clk); in asm9260_wdt_get_dt_clks()
240 dev_err(priv->dev, "Failed to enable clk!\n"); in asm9260_wdt_get_dt_clks()
243 err = devm_add_action_or_reset(priv->dev, in asm9260_wdt_get_dt_clks()
245 priv->clk); in asm9260_wdt_get_dt_clks()
250 clk = clk_get_rate(priv->clk); in asm9260_wdt_get_dt_clks()
252 dev_err(priv->dev, "Failed, clk is 0!\n"); in asm9260_wdt_get_dt_clks()
253 return -EINVAL; in asm9260_wdt_get_dt_clks()
256 priv->wdt_freq = clk / 2; in asm9260_wdt_get_dt_clks()
267 priv->mode = HW_RESET; in asm9260_wdt_get_dt_mode()
269 ret = of_property_read_string(priv->dev->of_node, in asm9260_wdt_get_dt_mode()
275 priv->mode = HW_RESET; in asm9260_wdt_get_dt_mode()
277 priv->mode = SW_RESET; in asm9260_wdt_get_dt_mode()
279 priv->mode = DEBUG; in asm9260_wdt_get_dt_mode()
281 dev_warn(priv->dev, "unknown reset-type: %s. Using default \"hw\" mode.", in asm9260_wdt_get_dt_mode()
287 struct device *dev = &pdev->dev; in asm9260_wdt_probe()
295 return -ENOMEM; in asm9260_wdt_probe()
297 priv->dev = dev; in asm9260_wdt_probe()
299 priv->iobase = devm_platform_ioremap_resource(pdev, 0); in asm9260_wdt_probe()
300 if (IS_ERR(priv->iobase)) in asm9260_wdt_probe()
301 return PTR_ERR(priv->iobase); in asm9260_wdt_probe()
303 priv->rst = devm_reset_control_get_exclusive(dev, "wdt_rst"); in asm9260_wdt_probe()
304 if (IS_ERR(priv->rst)) in asm9260_wdt_probe()
305 return PTR_ERR(priv->rst); in asm9260_wdt_probe()
311 wdd = &priv->wdd; in asm9260_wdt_probe()
312 wdd->info = &asm9260_wdt_ident; in asm9260_wdt_probe()
313 wdd->ops = &asm9260_wdt_ops; in asm9260_wdt_probe()
314 wdd->min_timeout = 1; in asm9260_wdt_probe()
315 wdd->max_timeout = BM_WDTC_MAX(priv->wdt_freq); in asm9260_wdt_probe()
316 wdd->parent = dev; in asm9260_wdt_probe()
321 * If 'timeout-sec' unspecified in devicetree, assume a 30 second in asm9260_wdt_probe()
322 * default, unless the max timeout is less than 30 seconds, then use in asm9260_wdt_probe()
325 wdd->timeout = ASM9260_WDT_DEFAULT_TIMEOUT; in asm9260_wdt_probe()
330 if (priv->mode != HW_RESET) in asm9260_wdt_probe()
331 priv->irq = platform_get_irq(pdev, 0); in asm9260_wdt_probe()
333 if (priv->irq > 0) { in asm9260_wdt_probe()
338 ret = devm_request_irq(dev, priv->irq, asm9260_wdt_irq, 0, in asm9260_wdt_probe()
339 pdev->name, priv); in asm9260_wdt_probe()
354 dev_info(dev, "Watchdog enabled (timeout: %d sec, mode: %s)\n", in asm9260_wdt_probe()
355 wdd->timeout, mode_name[priv->mode]); in asm9260_wdt_probe()
360 { .compatible = "alphascale,asm9260-wdt"},
367 .name = "asm9260-wdt",
375 MODULE_AUTHOR("Oleksij Rempel <linux@rempel-privat.de>");