aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRasmus Villemoes <rasmus.villemoes@prevas.dk>2016-12-12 04:48:43 -0500
committerGuenter Roeck <linux@roeck-us.net>2016-12-16 09:53:55 -0500
commit054ae19422859c394d5f26a8756ed57d332f6284 (patch)
treee08a660bf94481c1bf8edbead873374a4de7763c
parent1d8565ee4f5bd9fccb738e53d6b9fc7a559f7d2b (diff)
watchdog: bcm2835_wdt: set WDOG_HW_RUNNING bit when appropriate
A bootloader may start the watchdog device before handing control to the kernel - in that case, we should tell the kernel about it so the watchdog framework can keep it alive until userspace opens /dev/watchdog0. Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk> Reviewed-by: Guenter Roeck <linux@roeck-us.net> Acked-by: Eric Anholt <eric@anholt.net> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
-rw-r--r--drivers/watchdog/bcm2835_wdt.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/drivers/watchdog/bcm2835_wdt.c b/drivers/watchdog/bcm2835_wdt.c
index 4dddd8298a22..c32c45bd8b09 100644
--- a/drivers/watchdog/bcm2835_wdt.c
+++ b/drivers/watchdog/bcm2835_wdt.c
@@ -55,6 +55,15 @@ struct bcm2835_wdt {
55static unsigned int heartbeat; 55static unsigned int heartbeat;
56static bool nowayout = WATCHDOG_NOWAYOUT; 56static bool nowayout = WATCHDOG_NOWAYOUT;
57 57
58static bool bcm2835_wdt_is_running(struct bcm2835_wdt *wdt)
59{
60 uint32_t cur;
61
62 cur = readl(wdt->base + PM_RSTC);
63
64 return !!(cur & PM_RSTC_WRCFG_FULL_RESET);
65}
66
58static int bcm2835_wdt_start(struct watchdog_device *wdog) 67static int bcm2835_wdt_start(struct watchdog_device *wdog)
59{ 68{
60 struct bcm2835_wdt *wdt = watchdog_get_drvdata(wdog); 69 struct bcm2835_wdt *wdt = watchdog_get_drvdata(wdog);
@@ -181,6 +190,17 @@ static int bcm2835_wdt_probe(struct platform_device *pdev)
181 watchdog_init_timeout(&bcm2835_wdt_wdd, heartbeat, dev); 190 watchdog_init_timeout(&bcm2835_wdt_wdd, heartbeat, dev);
182 watchdog_set_nowayout(&bcm2835_wdt_wdd, nowayout); 191 watchdog_set_nowayout(&bcm2835_wdt_wdd, nowayout);
183 bcm2835_wdt_wdd.parent = &pdev->dev; 192 bcm2835_wdt_wdd.parent = &pdev->dev;
193 if (bcm2835_wdt_is_running(wdt)) {
194 /*
195 * The currently active timeout value (set by the
196 * bootloader) may be different from the module
197 * heartbeat parameter or the value in device
198 * tree. But we just need to set WDOG_HW_RUNNING,
199 * because then the framework will "immediately" ping
200 * the device, updating the timeout.
201 */
202 set_bit(WDOG_HW_RUNNING, &bcm2835_wdt_wdd.status);
203 }
184 err = watchdog_register_device(&bcm2835_wdt_wdd); 204 err = watchdog_register_device(&bcm2835_wdt_wdd);
185 if (err) { 205 if (err) {
186 dev_err(dev, "Failed to register watchdog device"); 206 dev_err(dev, "Failed to register watchdog device");