aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRay Jui <ray.jui@broadcom.com>2018-05-28 14:01:35 -0400
committerWim Van Sebroeck <wim@linux-watchdog.org>2018-08-02 09:57:11 -0400
commitfa5072ed8f530df5a04511721d19b61a6cf8c96c (patch)
treed7a1dd98aea48ac19aae6e4b18fc3142201e4d03
parentb800885888406f33edfec0eb1cb752292f23de83 (diff)
watchdog: sp805: set WDOG_HW_RUNNING when appropriate
If the watchdog hardware is already enabled during the boot process, when the Linux watchdog driver loads, it should reset the watchdog and tell the watchdog framework. As a result, ping can be generated from the watchdog framework, until the userspace watchdog daemon takes over control Signed-off-by: Ray Jui <ray.jui@broadcom.com> Reviewed-by: Vladimir Olovyannikov <vladimir.olovyannikov@broadcom.com> Reviewed-by: Scott Branden <scott.branden@broadcom.com> Reviewed-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org>
-rw-r--r--drivers/watchdog/sp805_wdt.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/drivers/watchdog/sp805_wdt.c b/drivers/watchdog/sp805_wdt.c
index b240195597c1..b202138b7ecb 100644
--- a/drivers/watchdog/sp805_wdt.c
+++ b/drivers/watchdog/sp805_wdt.c
@@ -42,6 +42,7 @@
42 /* control register masks */ 42 /* control register masks */
43 #define INT_ENABLE (1 << 0) 43 #define INT_ENABLE (1 << 0)
44 #define RESET_ENABLE (1 << 1) 44 #define RESET_ENABLE (1 << 1)
45 #define ENABLE_MASK (INT_ENABLE | RESET_ENABLE)
45#define WDTINTCLR 0x00C 46#define WDTINTCLR 0x00C
46#define WDTRIS 0x010 47#define WDTRIS 0x010
47#define WDTMIS 0x014 48#define WDTMIS 0x014
@@ -74,6 +75,15 @@ module_param(nowayout, bool, 0);
74MODULE_PARM_DESC(nowayout, 75MODULE_PARM_DESC(nowayout,
75 "Set to 1 to keep watchdog running after device release"); 76 "Set to 1 to keep watchdog running after device release");
76 77
78/* returns true if wdt is running; otherwise returns false */
79static bool wdt_is_running(struct watchdog_device *wdd)
80{
81 struct sp805_wdt *wdt = watchdog_get_drvdata(wdd);
82 u32 wdtcontrol = readl_relaxed(wdt->base + WDTCONTROL);
83
84 return (wdtcontrol & ENABLE_MASK) == ENABLE_MASK;
85}
86
77/* This routine finds load value that will reset system in required timout */ 87/* This routine finds load value that will reset system in required timout */
78static int wdt_setload(struct watchdog_device *wdd, unsigned int timeout) 88static int wdt_setload(struct watchdog_device *wdd, unsigned int timeout)
79{ 89{
@@ -253,6 +263,15 @@ sp805_wdt_probe(struct amba_device *adev, const struct amba_id *id)
253 watchdog_init_timeout(&wdt->wdd, 0, &adev->dev); 263 watchdog_init_timeout(&wdt->wdd, 0, &adev->dev);
254 wdt_setload(&wdt->wdd, wdt->wdd.timeout); 264 wdt_setload(&wdt->wdd, wdt->wdd.timeout);
255 265
266 /*
267 * If HW is already running, enable/reset the wdt and set the running
268 * bit to tell the wdt subsystem
269 */
270 if (wdt_is_running(&wdt->wdd)) {
271 wdt_enable(&wdt->wdd);
272 set_bit(WDOG_HW_RUNNING, &wdt->wdd.status);
273 }
274
256 ret = watchdog_register_device(&wdt->wdd); 275 ret = watchdog_register_device(&wdt->wdd);
257 if (ret) { 276 if (ret) {
258 dev_err(&adev->dev, "watchdog_register_device() failed: %d\n", 277 dev_err(&adev->dev, "watchdog_register_device() failed: %d\n",