Lines Matching +full:probe +full:- +full:reset

1 // SPDX-License-Identifier: GPL-2.0+
3 * drivers/char/watchdog/sp805-wdt.c
28 #include <linux/reset.h>
37 #define MODULE_NAME "sp805-wdt"
87 u32 wdtcontrol = readl_relaxed(wdt->base + WDTCONTROL); in wdt_is_running()
92 /* This routine finds load value that will reset system in required timeout */
98 rate = wdt->rate; in wdt_setload()
106 load = div_u64(rate, 2) * timeout - 1; in wdt_setload()
111 spin_lock(&wdt->lock); in wdt_setload()
112 wdt->load_val = load; in wdt_setload()
114 wdd->timeout = div_u64((load + 1) * 2 + (rate / 2), rate); in wdt_setload()
115 spin_unlock(&wdt->lock); in wdt_setload()
120 /* returns number of seconds left for reset to occur */
126 spin_lock(&wdt->lock); in wdt_timeleft()
127 load = readl_relaxed(wdt->base + WDTVALUE); in wdt_timeleft()
130 if (!(readl_relaxed(wdt->base + WDTRIS) & INT_MASK)) in wdt_timeleft()
131 load += wdt->load_val + 1; in wdt_timeleft()
132 spin_unlock(&wdt->lock); in wdt_timeleft()
134 return div_u64(load, wdt->rate); in wdt_timeleft()
142 writel_relaxed(UNLOCK, wdt->base + WDTLOCK); in wdt_restart()
143 writel_relaxed(0, wdt->base + WDTCONTROL); in wdt_restart()
144 writel_relaxed(0, wdt->base + WDTLOAD); in wdt_restart()
145 writel_relaxed(INT_ENABLE | RESET_ENABLE, wdt->base + WDTCONTROL); in wdt_restart()
148 readl_relaxed(wdt->base + WDTLOCK); in wdt_restart()
160 ret = clk_prepare_enable(wdt->clk); in wdt_config()
162 dev_err(&wdt->adev->dev, "clock enable fail"); in wdt_config()
167 spin_lock(&wdt->lock); in wdt_config()
169 writel_relaxed(UNLOCK, wdt->base + WDTLOCK); in wdt_config()
170 writel_relaxed(wdt->load_val, wdt->base + WDTLOAD); in wdt_config()
171 writel_relaxed(INT_MASK, wdt->base + WDTINTCLR); in wdt_config()
174 writel_relaxed(INT_ENABLE | RESET_ENABLE, wdt->base + in wdt_config()
177 writel_relaxed(LOCK, wdt->base + WDTLOCK); in wdt_config()
180 readl_relaxed(wdt->base + WDTLOCK); in wdt_config()
181 spin_unlock(&wdt->lock); in wdt_config()
191 /* enables watchdog timers reset */
197 /* disables watchdog timers reset */
202 spin_lock(&wdt->lock); in wdt_disable()
204 writel_relaxed(UNLOCK, wdt->base + WDTLOCK); in wdt_disable()
205 writel_relaxed(0, wdt->base + WDTCONTROL); in wdt_disable()
206 writel_relaxed(LOCK, wdt->base + WDTLOCK); in wdt_disable()
209 readl_relaxed(wdt->base + WDTLOCK); in wdt_disable()
210 spin_unlock(&wdt->lock); in wdt_disable()
212 clk_disable_unprepare(wdt->clk); in wdt_disable()
240 wdt = devm_kzalloc(&adev->dev, sizeof(*wdt), GFP_KERNEL); in sp805_wdt_probe()
242 ret = -ENOMEM; in sp805_wdt_probe()
246 wdt->base = devm_ioremap_resource(&adev->dev, &adev->res); in sp805_wdt_probe()
247 if (IS_ERR(wdt->base)) in sp805_wdt_probe()
248 return PTR_ERR(wdt->base); in sp805_wdt_probe()
251 * When driver probe with ACPI device, clock devices in sp805_wdt_probe()
253 * clock-frequency property given in _DSD object. in sp805_wdt_probe()
255 device_property_read_u64(&adev->dev, "clock-frequency", &rate); in sp805_wdt_probe()
257 wdt->clk = devm_clk_get_optional(&adev->dev, NULL); in sp805_wdt_probe()
258 if (IS_ERR(wdt->clk)) in sp805_wdt_probe()
259 return dev_err_probe(&adev->dev, PTR_ERR(wdt->clk), "Clock not found\n"); in sp805_wdt_probe()
261 wdt->rate = clk_get_rate(wdt->clk); in sp805_wdt_probe()
262 if (!wdt->rate) in sp805_wdt_probe()
263 wdt->rate = rate; in sp805_wdt_probe()
264 if (!wdt->rate) { in sp805_wdt_probe()
265 dev_err(&adev->dev, "no clock-frequency property\n"); in sp805_wdt_probe()
266 return -ENODEV; in sp805_wdt_probe()
269 rst = devm_reset_control_get_optional_exclusive(&adev->dev, NULL); in sp805_wdt_probe()
271 return dev_err_probe(&adev->dev, PTR_ERR(rst), "Can not get reset\n"); in sp805_wdt_probe()
275 wdt->adev = adev; in sp805_wdt_probe()
276 wdt->wdd.info = &wdt_info; in sp805_wdt_probe()
277 wdt->wdd.ops = &wdt_ops; in sp805_wdt_probe()
278 wdt->wdd.parent = &adev->dev; in sp805_wdt_probe()
280 spin_lock_init(&wdt->lock); in sp805_wdt_probe()
281 watchdog_set_nowayout(&wdt->wdd, nowayout); in sp805_wdt_probe()
282 watchdog_set_drvdata(&wdt->wdd, wdt); in sp805_wdt_probe()
283 watchdog_set_restart_priority(&wdt->wdd, 128); in sp805_wdt_probe()
284 watchdog_stop_on_unregister(&wdt->wdd); in sp805_wdt_probe()
287 * If 'timeout-sec' devicetree property is specified, use that. in sp805_wdt_probe()
290 wdt->wdd.timeout = DEFAULT_TIMEOUT; in sp805_wdt_probe()
291 watchdog_init_timeout(&wdt->wdd, 0, &adev->dev); in sp805_wdt_probe()
292 wdt_setload(&wdt->wdd, wdt->wdd.timeout); in sp805_wdt_probe()
295 * If HW is already running, enable/reset the wdt and set the running in sp805_wdt_probe()
298 if (wdt_is_running(&wdt->wdd)) { in sp805_wdt_probe()
299 wdt_enable(&wdt->wdd); in sp805_wdt_probe()
300 set_bit(WDOG_HW_RUNNING, &wdt->wdd.status); in sp805_wdt_probe()
303 watchdog_stop_on_reboot(&wdt->wdd); in sp805_wdt_probe()
304 ret = watchdog_register_device(&wdt->wdd); in sp805_wdt_probe()
309 dev_info(&adev->dev, "registration successful\n"); in sp805_wdt_probe()
313 dev_err(&adev->dev, "Probe Failed!!!\n"); in sp805_wdt_probe()
321 watchdog_unregister_device(&wdt->wdd); in sp805_wdt_remove()
322 watchdog_set_drvdata(&wdt->wdd, NULL); in sp805_wdt_remove()
329 if (watchdog_active(&wdt->wdd)) in sp805_wdt_suspend()
330 return wdt_disable(&wdt->wdd); in sp805_wdt_suspend()
339 if (watchdog_active(&wdt->wdd)) in sp805_wdt_resume()
340 return wdt_enable(&wdt->wdd); in sp805_wdt_resume()
368 .probe = sp805_wdt_probe,