|
@@ -72,10 +72,27 @@ static void softdog_fire(unsigned long data)
|
|
|
static struct timer_list softdog_ticktock =
|
|
|
TIMER_INITIALIZER(softdog_fire, 0, 0);
|
|
|
|
|
|
+static struct watchdog_device softdog_dev;
|
|
|
+
|
|
|
+static void softdog_pretimeout(unsigned long data)
|
|
|
+{
|
|
|
+ watchdog_notify_pretimeout(&softdog_dev);
|
|
|
+}
|
|
|
+
|
|
|
+static struct timer_list softdog_preticktock =
|
|
|
+ TIMER_INITIALIZER(softdog_pretimeout, 0, 0);
|
|
|
+
|
|
|
static int softdog_ping(struct watchdog_device *w)
|
|
|
{
|
|
|
if (!mod_timer(&softdog_ticktock, jiffies + (w->timeout * HZ)))
|
|
|
__module_get(THIS_MODULE);
|
|
|
+
|
|
|
+ if (w->pretimeout)
|
|
|
+ mod_timer(&softdog_preticktock, jiffies +
|
|
|
+ (w->timeout - w->pretimeout) * HZ);
|
|
|
+ else
|
|
|
+ del_timer(&softdog_preticktock);
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -84,12 +101,15 @@ static int softdog_stop(struct watchdog_device *w)
|
|
|
if (del_timer(&softdog_ticktock))
|
|
|
module_put(THIS_MODULE);
|
|
|
|
|
|
+ del_timer(&softdog_preticktock);
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
static struct watchdog_info softdog_info = {
|
|
|
.identity = "Software Watchdog",
|
|
|
- .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
|
|
|
+ .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE |
|
|
|
+ WDIOF_PRETIMEOUT,
|
|
|
};
|
|
|
|
|
|
static const struct watchdog_ops softdog_ops = {
|