diff options
Diffstat (limited to 'drivers/watchdog/mt7621_wdt.c')
-rw-r--r-- | drivers/watchdog/mt7621_wdt.c | 34 |
1 files changed, 21 insertions, 13 deletions
diff --git a/drivers/watchdog/mt7621_wdt.c b/drivers/watchdog/mt7621_wdt.c index db38f80..5c4a764 100644 --- a/drivers/watchdog/mt7621_wdt.c +++ b/drivers/watchdog/mt7621_wdt.c @@ -105,6 +105,11 @@ static int mt7621_wdt_bootcause(void) return 0; } +static int mt7621_wdt_is_running(struct watchdog_device *w) +{ + return !!(rt_wdt_r32(TIMER_REG_TMR1CTL) & TMR1CTL_ENABLE); +} + static const struct watchdog_info mt7621_wdt_info = { .identity = "Mediatek Watchdog", .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, @@ -128,7 +133,6 @@ static struct watchdog_device mt7621_wdt_dev = { static int mt7621_wdt_probe(struct platform_device *pdev) { struct resource *res; - int ret; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); mt7621_wdt_base = devm_ioremap_resource(&pdev->dev, res); @@ -144,17 +148,22 @@ static int mt7621_wdt_probe(struct platform_device *pdev) watchdog_init_timeout(&mt7621_wdt_dev, mt7621_wdt_dev.max_timeout, &pdev->dev); watchdog_set_nowayout(&mt7621_wdt_dev, nowayout); - - ret = watchdog_register_device(&mt7621_wdt_dev); - - return 0; -} - -static int mt7621_wdt_remove(struct platform_device *pdev) -{ - watchdog_unregister_device(&mt7621_wdt_dev); - - return 0; + if (mt7621_wdt_is_running(&mt7621_wdt_dev)) { + /* + * Make sure to apply timeout from watchdog core, taking + * the prescaler of this driver here into account (the + * boot loader might be using a different prescaler). + * + * To avoid spurious resets because of different scaling, + * we first disable the watchdog, set the new prescaler + * and timeout, and then re-enable the watchdog. + */ + mt7621_wdt_stop(&mt7621_wdt_dev); + mt7621_wdt_start(&mt7621_wdt_dev); + set_bit(WDOG_HW_RUNNING, &mt7621_wdt_dev.status); + } + + return devm_watchdog_register_device(&pdev->dev, &mt7621_wdt_dev); } static void mt7621_wdt_shutdown(struct platform_device *pdev) @@ -170,7 +179,6 @@ MODULE_DEVICE_TABLE(of, mt7621_wdt_match); static struct platform_driver mt7621_wdt_driver = { .probe = mt7621_wdt_probe, - .remove = mt7621_wdt_remove, .shutdown = mt7621_wdt_shutdown, .driver = { .name = KBUILD_MODNAME, |