* [PATCH] watchdog: gpio-wdt: ping already at startup for always running devices
@ 2015-07-31 7:21 Uwe Kleine-König
2015-07-31 17:18 ` Guenter Roeck
0 siblings, 1 reply; 2+ messages in thread
From: Uwe Kleine-König @ 2015-07-31 7:21 UTC (permalink / raw)
To: Wim Van Sebroeck, linux-watchdog; +Cc: kernel, Guenter Roeck
During probe for an always-running watchdog a timer is setup to
constantly ping the watchdog while the device is not open. The gpio to
ping the watchdog is setup to inactive.
For a watchdog with hw_algo = "toggle" this results in a ping depending
on the initial state of the gpio, for hw_algo = "level" no ping is
generated.
Make sure that the first automatic ping is sent immediately and not only
when the timer expires the first time. This makes the machine survive in
case more than half of the watchdog timeout is already elapsed. (Which
is very probable for the chip I'm faced with that has a timeout of one
second.)
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
---
drivers/watchdog/gpio_wdt.c | 60 ++++++++++++++++++++++-----------------------
1 file changed, 30 insertions(+), 30 deletions(-)
diff --git a/drivers/watchdog/gpio_wdt.c b/drivers/watchdog/gpio_wdt.c
index c2dff7d1b790..5d083528e6b9 100644
--- a/drivers/watchdog/gpio_wdt.c
+++ b/drivers/watchdog/gpio_wdt.c
@@ -50,12 +50,41 @@ static void gpio_wdt_disable(struct gpio_wdt_priv *priv)
gpio_direction_input(priv->gpio);
}
+static void gpio_wdt_hwping(unsigned long data)
+{
+ struct watchdog_device *wdd = (struct watchdog_device *)data;
+ struct gpio_wdt_priv *priv = watchdog_get_drvdata(wdd);
+
+ if (priv->armed && time_after(jiffies, priv->last_jiffies +
+ msecs_to_jiffies(wdd->timeout * 1000))) {
+ dev_crit(wdd->dev, "Timer expired. System will reboot soon!\n");
+ return;
+ }
+
+ /* Restart timer */
+ mod_timer(&priv->timer, jiffies + priv->hw_margin);
+
+ switch (priv->hw_algo) {
+ case HW_ALGO_TOGGLE:
+ /* Toggle output pin */
+ priv->state = !priv->state;
+ gpio_set_value_cansleep(priv->gpio, priv->state);
+ break;
+ case HW_ALGO_LEVEL:
+ /* Pulse */
+ gpio_set_value_cansleep(priv->gpio, !priv->active_low);
+ udelay(1);
+ gpio_set_value_cansleep(priv->gpio, priv->active_low);
+ break;
+ }
+}
+
static void gpio_wdt_start_impl(struct gpio_wdt_priv *priv)
{
priv->state = priv->active_low;
gpio_direction_output(priv->gpio, priv->state);
priv->last_jiffies = jiffies;
- mod_timer(&priv->timer, priv->last_jiffies + priv->hw_margin);
+ gpio_wdt_hwping((unsigned long)&priv->wdd);
}
static int gpio_wdt_start(struct watchdog_device *wdd)
@@ -97,35 +126,6 @@ static int gpio_wdt_set_timeout(struct watchdog_device *wdd, unsigned int t)
return gpio_wdt_ping(wdd);
}
-static void gpio_wdt_hwping(unsigned long data)
-{
- struct watchdog_device *wdd = (struct watchdog_device *)data;
- struct gpio_wdt_priv *priv = watchdog_get_drvdata(wdd);
-
- if (priv->armed && time_after(jiffies, priv->last_jiffies +
- msecs_to_jiffies(wdd->timeout * 1000))) {
- dev_crit(wdd->dev, "Timer expired. System will reboot soon!\n");
- return;
- }
-
- /* Restart timer */
- mod_timer(&priv->timer, jiffies + priv->hw_margin);
-
- switch (priv->hw_algo) {
- case HW_ALGO_TOGGLE:
- /* Toggle output pin */
- priv->state = !priv->state;
- gpio_set_value_cansleep(priv->gpio, priv->state);
- break;
- case HW_ALGO_LEVEL:
- /* Pulse */
- gpio_set_value_cansleep(priv->gpio, !priv->active_low);
- udelay(1);
- gpio_set_value_cansleep(priv->gpio, priv->active_low);
- break;
- }
-}
-
static int gpio_wdt_notify_sys(struct notifier_block *nb, unsigned long code,
void *unused)
{
--
2.1.4
^ permalink raw reply related [flat|nested] 2+ messages in thread* Re: [PATCH] watchdog: gpio-wdt: ping already at startup for always running devices
2015-07-31 7:21 [PATCH] watchdog: gpio-wdt: ping already at startup for always running devices Uwe Kleine-König
@ 2015-07-31 17:18 ` Guenter Roeck
0 siblings, 0 replies; 2+ messages in thread
From: Guenter Roeck @ 2015-07-31 17:18 UTC (permalink / raw)
To: Uwe Kleine-König; +Cc: Wim Van Sebroeck, linux-watchdog, kernel
On Fri, Jul 31, 2015 at 09:21:36AM +0200, Uwe Kleine-König wrote:
> During probe for an always-running watchdog a timer is setup to
> constantly ping the watchdog while the device is not open. The gpio to
> ping the watchdog is setup to inactive.
>
> For a watchdog with hw_algo = "toggle" this results in a ping depending
> on the initial state of the gpio, for hw_algo = "level" no ping is
> generated.
>
> Make sure that the first automatic ping is sent immediately and not only
> when the timer expires the first time. This makes the machine survive in
> case more than half of the watchdog timeout is already elapsed. (Which
> is very probable for the chip I'm faced with that has a timeout of one
> second.)
>
> Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Makes sense.
Reviewed-by: Guenter Roeck <linux@roeck-us.net>
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2015-07-31 17:18 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-07-31 7:21 [PATCH] watchdog: gpio-wdt: ping already at startup for always running devices Uwe Kleine-König
2015-07-31 17:18 ` Guenter Roeck
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox