[RFC PATCH v8 08/10] watchdog: retu: Convert to use infrastructure triggered keepalives

From: Guenter Roeck
Date: Sun Feb 28 2016 - 16:12:42 EST


The watchdog infrastructure now supports handling watchdog keepalive
if the watchdog is running while the watchdog device is closed.
Convert the driver to use this infrastructure.

Signed-off-by: Guenter Roeck <linux@xxxxxxxxxxxx>
---
v8: max_hw_timeout_ms -> max_hw_heartbeat_ms
Rebased to v4.5-rc5
v7: Set max_hw_timeout_ms
Rebased to v4.5-rc1
v6: Rename WDOG_RUNNING to WDOG_HW_RUNNING
Rebased to v4.4-rc2
v5: Rebased to v4.4-rc1
v4: No changes
v3: No changes
v2: No changes
---
drivers/watchdog/retu_wdt.c | 80 +++++----------------------------------------
1 file changed, 8 insertions(+), 72 deletions(-)

diff --git a/drivers/watchdog/retu_wdt.c b/drivers/watchdog/retu_wdt.c
index 39cd51df2ffc..fd827b0ec689 100644
--- a/drivers/watchdog/retu_wdt.c
+++ b/drivers/watchdog/retu_wdt.c
@@ -28,69 +28,22 @@
/* Watchdog timer values in seconds */
#define RETU_WDT_MAX_TIMER 63

-struct retu_wdt_dev {
- struct retu_dev *rdev;
- struct device *dev;
- struct delayed_work ping_work;
-};
-
-/*
- * Since Retu watchdog cannot be disabled in hardware, we must kick it
- * with a timer until userspace watchdog software takes over. If
- * CONFIG_WATCHDOG_NOWAYOUT is set, we never start the feeding.
- */
-static void retu_wdt_ping_enable(struct retu_wdt_dev *wdev)
-{
- retu_write(wdev->rdev, RETU_REG_WATCHDOG, RETU_WDT_MAX_TIMER);
- schedule_delayed_work(&wdev->ping_work,
- round_jiffies_relative(RETU_WDT_MAX_TIMER * HZ / 2));
-}
-
-static void retu_wdt_ping_disable(struct retu_wdt_dev *wdev)
-{
- retu_write(wdev->rdev, RETU_REG_WATCHDOG, RETU_WDT_MAX_TIMER);
- cancel_delayed_work_sync(&wdev->ping_work);
-}
-
-static void retu_wdt_ping_work(struct work_struct *work)
-{
- struct retu_wdt_dev *wdev = container_of(to_delayed_work(work),
- struct retu_wdt_dev, ping_work);
- retu_wdt_ping_enable(wdev);
-}
-
static int retu_wdt_start(struct watchdog_device *wdog)
{
- struct retu_wdt_dev *wdev = watchdog_get_drvdata(wdog);
+ struct retu_dev *rdev = watchdog_get_drvdata(wdog);

- retu_wdt_ping_disable(wdev);
+ set_bit(WDOG_HW_RUNNING, &wdog->status);

- return retu_write(wdev->rdev, RETU_REG_WATCHDOG, wdog->timeout);
-}
-
-static int retu_wdt_stop(struct watchdog_device *wdog)
-{
- struct retu_wdt_dev *wdev = watchdog_get_drvdata(wdog);
-
- retu_wdt_ping_enable(wdev);
-
- return 0;
-}
-
-static int retu_wdt_ping(struct watchdog_device *wdog)
-{
- struct retu_wdt_dev *wdev = watchdog_get_drvdata(wdog);
-
- return retu_write(wdev->rdev, RETU_REG_WATCHDOG, wdog->timeout);
+ return retu_write(rdev, RETU_REG_WATCHDOG, wdog->timeout);
}

static int retu_wdt_set_timeout(struct watchdog_device *wdog,
unsigned int timeout)
{
- struct retu_wdt_dev *wdev = watchdog_get_drvdata(wdog);
+ struct retu_dev *rdev = watchdog_get_drvdata(wdog);

wdog->timeout = timeout;
- return retu_write(wdev->rdev, RETU_REG_WATCHDOG, wdog->timeout);
+ return retu_write(rdev, RETU_REG_WATCHDOG, wdog->timeout);
}

static const struct watchdog_info retu_wdt_info = {
@@ -101,8 +54,6 @@ static const struct watchdog_info retu_wdt_info = {
static const struct watchdog_ops retu_wdt_ops = {
.owner = THIS_MODULE,
.start = retu_wdt_start,
- .stop = retu_wdt_stop,
- .ping = retu_wdt_ping,
.set_timeout = retu_wdt_set_timeout,
};

@@ -111,40 +62,27 @@ static int retu_wdt_probe(struct platform_device *pdev)
struct retu_dev *rdev = dev_get_drvdata(pdev->dev.parent);
bool nowayout = WATCHDOG_NOWAYOUT;
struct watchdog_device *retu_wdt;
- struct retu_wdt_dev *wdev;
int ret;

retu_wdt = devm_kzalloc(&pdev->dev, sizeof(*retu_wdt), GFP_KERNEL);
if (!retu_wdt)
return -ENOMEM;

- wdev = devm_kzalloc(&pdev->dev, sizeof(*wdev), GFP_KERNEL);
- if (!wdev)
- return -ENOMEM;
-
retu_wdt->info = &retu_wdt_info;
retu_wdt->ops = &retu_wdt_ops;
retu_wdt->timeout = RETU_WDT_MAX_TIMER;
retu_wdt->min_timeout = 0;
- retu_wdt->max_timeout = RETU_WDT_MAX_TIMER;
+ retu_wdt->max_hw_heartbeat_ms = RETU_WDT_MAX_TIMER * 1000;
retu_wdt->parent = &pdev->dev;

- watchdog_set_drvdata(retu_wdt, wdev);
+ watchdog_set_drvdata(retu_wdt, rdev);
watchdog_set_nowayout(retu_wdt, nowayout);

- wdev->rdev = rdev;
- wdev->dev = &pdev->dev;
-
- INIT_DELAYED_WORK(&wdev->ping_work, retu_wdt_ping_work);
-
ret = watchdog_register_device(retu_wdt);
if (ret < 0)
return ret;

- if (nowayout)
- retu_wdt_ping(retu_wdt);
- else
- retu_wdt_ping_enable(wdev);
+ retu_wdt_start(retu_wdt);

platform_set_drvdata(pdev, retu_wdt);

@@ -154,10 +92,8 @@ static int retu_wdt_probe(struct platform_device *pdev)
static int retu_wdt_remove(struct platform_device *pdev)
{
struct watchdog_device *wdog = platform_get_drvdata(pdev);
- struct retu_wdt_dev *wdev = watchdog_get_drvdata(wdog);

watchdog_unregister_device(wdog);
- cancel_delayed_work_sync(&wdev->ping_work);

return 0;
}
--
2.5.0