lkml.org 
[lkml]   [2018]   [Mar]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL for 4.15 022/124] watchdog: dw_wdt: add stop watchdog operation
    Date
    From: Oleksij Rempel <o.rempel@pengutronix.de>

    [ Upstream commit 1bfe8889380890efe4943d125124f5a7b48571b0 ]

    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 <o.rempel@pengutronix.de>
    Cc: Wim Van Sebroeck <wim@iguana.be>
    Cc: Guenter Roeck <linux@roeck-us.net>
    Cc: linux-watchdog@vger.kernel.org
    Reviewed-by: Guenter Roeck <linux@roeck-us.net>
    Signed-off-by: Guenter Roeck <linux@roeck-us.net>
    Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
    Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
    ---
    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,
    --
    2.14.1
    \
     
     \ /
      Last update: 2018-03-19 23:40    [W:3.460 / U:0.004 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site