Commit 8d2fa171 authored by Harald Geyer's avatar Harald Geyer Committed by Wim Van Sebroeck

watchdog: stmp3xxx: Stop the watchdog on system halt

This allows the system to actually halt even if userspace forgot to
disable the watchdog first. Old behaviour was that the watchdog forced
the system to boot again.
Signed-off-by: default avatarHarald Geyer <harald@ccbib.org>
Signed-off-by: default avatarGuenter Roeck <linux@roeck-us.net>
Signed-off-by: default avatarWim Van Sebroeck <wim@iguana.be>
parent bdecfcdb
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
#include <linux/watchdog.h> #include <linux/watchdog.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/stmp3xxx_rtc_wdt.h> #include <linux/stmp3xxx_rtc_wdt.h>
#include <linux/notifier.h>
#include <linux/reboot.h>
#define WDOG_TICK_RATE 1000 /* 1 kHz clock */ #define WDOG_TICK_RATE 1000 /* 1 kHz clock */
#define STMP3XXX_DEFAULT_TIMEOUT 19 #define STMP3XXX_DEFAULT_TIMEOUT 19
...@@ -69,6 +71,28 @@ static struct watchdog_device stmp3xxx_wdd = { ...@@ -69,6 +71,28 @@ static struct watchdog_device stmp3xxx_wdd = {
.status = WATCHDOG_NOWAYOUT_INIT_STATUS, .status = WATCHDOG_NOWAYOUT_INIT_STATUS,
}; };
static int wdt_notify_sys(struct notifier_block *nb, unsigned long code,
void *unused)
{
struct device *dev = watchdog_get_drvdata(&stmp3xxx_wdd);
struct stmp3xxx_wdt_pdata *pdata = dev_get_platdata(dev);
switch (code) {
case SYS_DOWN: /* keep enabled, system might crash while going down */
break;
case SYS_HALT: /* allow the system to actually halt */
case SYS_POWER_OFF:
wdt_stop(&stmp3xxx_wdd);
break;
}
return NOTIFY_DONE;
}
static struct notifier_block wdt_notifier = {
.notifier_call = wdt_notify_sys,
};
static int stmp3xxx_wdt_probe(struct platform_device *pdev) static int stmp3xxx_wdt_probe(struct platform_device *pdev)
{ {
int ret; int ret;
...@@ -84,6 +108,9 @@ static int stmp3xxx_wdt_probe(struct platform_device *pdev) ...@@ -84,6 +108,9 @@ static int stmp3xxx_wdt_probe(struct platform_device *pdev)
return ret; return ret;
} }
if (register_reboot_notifier(&wdt_notifier))
dev_warn(&pdev->dev, "cannot register reboot notifier\n");
dev_info(&pdev->dev, "initialized watchdog with heartbeat %ds\n", dev_info(&pdev->dev, "initialized watchdog with heartbeat %ds\n",
stmp3xxx_wdd.timeout); stmp3xxx_wdd.timeout);
return 0; return 0;
...@@ -91,6 +118,7 @@ static int stmp3xxx_wdt_probe(struct platform_device *pdev) ...@@ -91,6 +118,7 @@ static int stmp3xxx_wdt_probe(struct platform_device *pdev)
static int stmp3xxx_wdt_remove(struct platform_device *pdev) static int stmp3xxx_wdt_remove(struct platform_device *pdev)
{ {
unregister_reboot_notifier(&wdt_notifier);
watchdog_unregister_device(&stmp3xxx_wdd); watchdog_unregister_device(&stmp3xxx_wdd);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment