Skip to content

Commit

Permalink
watchdog: at91rm9200: implement restart handler
Browse files Browse the repository at this point in the history
Restarting the at91rm9200 is done through programming the watchdog and waiting
for it to reset.

Signed-off-by: Alexandre Belloni <[email protected]>
Reviewed-by: Guenter Roeck <[email protected]>
Signed-off-by: Nicolas Ferre <[email protected]>
  • Loading branch information
alexandrebelloni authored and Nicolas Ferre committed Mar 16, 2015
1 parent 8432f9e commit 9ab45f3
Showing 1 changed file with 32 additions and 0 deletions.
32 changes: 32 additions & 0 deletions drivers/watchdog/at91rm9200_wdt.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/init.h>
Expand All @@ -23,6 +24,7 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/platform_device.h>
#include <linux/reboot.h>
#include <linux/regmap.h>
#include <linux/types.h>
#include <linux/watchdog.h>
Expand Down Expand Up @@ -53,6 +55,27 @@ static unsigned long at91wdt_busy;

/* ......................................................................... */

static int at91rm9200_restart(struct notifier_block *this,
unsigned long mode, void *cmd)
{
/*
* Perform a hardware reset with the use of the Watchdog timer.
*/
regmap_write(regmap_st, AT91_ST_WDMR,
AT91_ST_RSTEN | AT91_ST_EXTEN | 1);
regmap_write(regmap_st, AT91_ST_CR, AT91_ST_WDRST);

mdelay(2000);

pr_emerg("Unable to restart system\n");
return NOTIFY_DONE;
}

static struct notifier_block at91rm9200_restart_nb = {
.notifier_call = at91rm9200_restart,
.priority = 192,
};

/*
* Disable the watchdog.
*/
Expand Down Expand Up @@ -228,15 +251,24 @@ static int at91wdt_probe(struct platform_device *pdev)
if (res)
return res;

res = register_restart_handler(&at91rm9200_restart_nb);
if (res)
dev_warn(dev, "failed to register restart handler\n");

pr_info("AT91 Watchdog Timer enabled (%d seconds%s)\n",
wdt_time, nowayout ? ", nowayout" : "");
return 0;
}

static int at91wdt_remove(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
int res;

res = unregister_restart_handler(&at91rm9200_restart_nb);
if (res)
dev_warn(dev, "failed to unregister restart handler\n");

res = misc_deregister(&at91wdt_miscdev);
if (!res)
at91wdt_miscdev.parent = NULL;
Expand Down

0 comments on commit 9ab45f3

Please sign in to comment.