watchdog: dw_wdt: add stop watchdog operation

"Linux Kernel Mailing List" <[email protected]>
Newsgroups gmane.linux.kernel.commits.head
Message-ID <[email protected]>
Web:        https://git.kernel.org/torvalds/c/1bfe8889380890efe4943d125124f5a7b48571b0
Commit:     1bfe8889380890efe4943d125124f5a7b48571b0
Parent:     d4238aa458b8c3e64d6f124aafa5c230cae31d6a
Refname:    refs/heads/master
Author:     Oleksij Rempel <[email protected]>
AuthorDate: Tue Sep 26 08:11:22 2017 +0200
Committer:  Wim Van Sebroeck <[email protected]>
CommitDate: Thu Dec 28 20:44:55 2017 +0100

    watchdog: dw_wdt: add stop watchdog operation
    
    The only way of stopping the watchdog is by resetting it.
    Add the watchdog op for stopping the device and reset if
    a reset line is provided.
    
    At same time WDOG_HW_RUNNING should be remove from dw_wdt_start.
    As commented by Guenter Roeck:
    dw_wdt sets WDOG_HW_RUNNING in its open function. Result is
    that the kref_get() in watchdog_open() won't be executed. But then
    kref_put() in close will be called since the watchdog now does stop.
    This causes the imbalance.
    
    Signed-off-by: Oleksij Rempel <[email protected]>
    Cc: Wim Van Sebroeck <[email protected]>
    Cc: Guenter Roeck <[email protected]>
    Cc: [email protected]
    Reviewed-by: Guenter Roeck <[email protected]>
    Signed-off-by: Guenter Roeck <[email protected]>
    Signed-off-by: Wim Van Sebroeck <[email protected]>
---
 drivers/watchdog/dw_wdt.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/drivers/watchdog/dw_wdt.c b/drivers/watchdog/dw_wdt.c
index 36be987ff9ef..c2f4ff516230 100644
--- a/drivers/watchdog/dw_wdt.c
+++ b/drivers/watchdog/dw_wdt.c
@@ -127,14 +127,27 @@ static int dw_wdt_start(struct watchdog_device *wdd)
 
 	dw_wdt_set_timeout(wdd, wdd->timeout);
 
-	set_bit(WDOG_HW_RUNNING, &wdd->status);
-
 	writel(WDOG_CONTROL_REG_WDT_EN_MASK,
 	       dw_wdt->regs + WDOG_CONTROL_REG_OFFSET);
 
 	return 0;
 }
 
+static int dw_wdt_stop(struct watchdog_device *wdd)
+{
+	struct dw_wdt *dw_wdt = to_dw_wdt(wdd);
+
+	if (!dw_wdt->rst) {
+		set_bit(WDOG_HW_RUNNING, &wdd->status);
+		return 0;
+	}
+
+	reset_control_assert(dw_wdt->rst);
+	reset_control_deassert(dw_wdt->rst);
+
+	return 0;
+}
+
 static int dw_wdt_restart(struct watchdog_device *wdd,
 			  unsigned long action, void *data)
 {
@@ -173,6 +186,7 @@ static const struct watchdog_info dw_wdt_ident = {
 static const struct watchdog_ops dw_wdt_ops = {
 	.owner		= THIS_MODULE,
 	.start		= dw_wdt_start,
+	.stop		= dw_wdt_stop,
 	.ping		= dw_wdt_ping,
 	.set_timeout	= dw_wdt_set_timeout,
 	.get_timeleft	= dw_wdt_get_timeleft,
--
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.