Once watchdog is started, WDT cycle setting register(WDTSET) cannot be changed. However we can reconfigure the new value for WDSET, after a module reset. Otherwise it will ignore the writes and will hold the previous value instead of the updated one. This patch add support for set_timeout callback by doing module reset, which allows us to update WDTSET register. Based on the watchdog timer state, it may restart WDT with the modified values. Signed-off-by: Biju Das <biju.das.jz@xxxxxxxxxxxxxx> --- V1->V2: * Updated commit description * Removed stop/start and started using reset() instead. * After reset, Start WDT based on watchdog timer state. --- drivers/watchdog/rzg2l_wdt.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/drivers/watchdog/rzg2l_wdt.c b/drivers/watchdog/rzg2l_wdt.c index 0e62d7be153c..d1b5cb70d56c 100644 --- a/drivers/watchdog/rzg2l_wdt.c +++ b/drivers/watchdog/rzg2l_wdt.c @@ -110,6 +110,33 @@ static int rzg2l_wdt_stop(struct watchdog_device *wdev) return reset_control_reset(priv->rstc); } +static int rzg2l_wdt_set_timeout(struct watchdog_device *wdev, unsigned int timeout) +{ + struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev); + int ret; + + wdev->timeout = timeout; + + /* + * We need to reset the module for updating WDTSET register + * If watchdog is active, then decrement the PM counter to make + * it balanced, after reset operation. + */ + if (watchdog_active(wdev)) + pm_runtime_put(wdev->parent); + + /* Reset the module for updating WDTSET register */ + ret = reset_control_reset(priv->rstc); + if (watchdog_active(wdev)) { + if (ret) + pm_runtime_get_sync(wdev->parent); + else + rzg2l_wdt_start(wdev); + } + + return ret; +} + static int rzg2l_wdt_restart(struct watchdog_device *wdev, unsigned long action, void *data) { @@ -153,6 +180,7 @@ static const struct watchdog_ops rzg2l_wdt_ops = { .start = rzg2l_wdt_start, .stop = rzg2l_wdt_stop, .ping = rzg2l_wdt_ping, + .set_timeout = rzg2l_wdt_set_timeout, .restart = rzg2l_wdt_restart, }; -- 2.17.1