summaryrefslogtreecommitdiff
path: root/drivers/watchdog
diff options
context:
space:
mode:
authorBai Ping <ping.bai@nxp.com>2016-12-05 14:31:53 +0800
committerLeonard Crestez <leonard.crestez@nxp.com>2018-08-24 12:41:33 +0300
commit97f34bdff71c64a88f7651c23d4d784c091dfd2f (patch)
tree0638799303922150c614a972b30f15c6d9a94c43 /drivers/watchdog
parent2340b4fbeb8da24448fd395a1363a48cf703d9e5 (diff)
MLK-13564 driver: watchdog: Add system reboot support on imx7ulp
Add system reboot for i.MX7ULP. As there is no other way to reboot the system, so use wdog restart handler to trigger the system reboot. Signed-off-by: Bai Ping <ping.bai@nxp.com>
Diffstat (limited to 'drivers/watchdog')
-rw-r--r--drivers/watchdog/imx7ulp_wdt.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/drivers/watchdog/imx7ulp_wdt.c b/drivers/watchdog/imx7ulp_wdt.c
index 55769b1a44f5..845c900b5bcb 100644
--- a/drivers/watchdog/imx7ulp_wdt.c
+++ b/drivers/watchdog/imx7ulp_wdt.c
@@ -12,6 +12,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/reboot.h>
#include <linux/watchdog.h>
#define WDOG_CS 0x0
@@ -36,6 +37,7 @@ struct imx7ulp_wdt {
void __iomem *base;
int rate;
struct watchdog_device wdd;
+ struct notifier_block restart_handler;
};
static inline void imx7ulp_wdt_enable(void __iomem *base, bool enable)
@@ -119,6 +121,25 @@ static const struct watchdog_info imx7ulp_wdt_info = {
| WDIOF_MAGICCLOSE,
};
+static int imx7ulp_wdt_restart_handler(struct notifier_block *this,
+ unsigned long action, void *data)
+{
+ struct imx7ulp_wdt *wdt = container_of(this, struct imx7ulp_wdt, restart_handler);
+
+ local_irq_disable();
+
+ imx7ulp_wdt_enable(wdt->base, true);
+ imx7ulp_wdt_set_timeout(&wdt->wdd, 1);
+
+ local_irq_enable();
+
+ /* wait for wdog to fire */
+ while(true)
+ ;
+
+ return NOTIFY_DONE;
+}
+
static inline void imx7ulp_wdt_init(void __iomem *base, unsigned int timeout)
{
u32 val;
@@ -191,6 +212,15 @@ static int imx7ulp_wdt_probe(struct platform_device *pdev)
return err;
}
+ wdt->restart_handler.notifier_call = imx7ulp_wdt_restart_handler;
+ wdt->restart_handler.priority = 128;
+ err = register_restart_handler(&wdt->restart_handler);
+ if (err) {
+ dev_err(&pdev->dev, "cannot register restart handler\n");
+ watchdog_unregister_device(&wdt->wdd);
+ return err;
+ }
+
return 0;
}
@@ -246,6 +276,7 @@ static const struct of_device_id imx7ulp_wdt_dt_ids[] = {
{ .compatible = "fsl,imx7ulp-wdt", },
{ /*sentinel */ }
};
+MODULE_DEVICE_TABLE(of, imx7ulp_wdt_dt_ids);
static struct platform_driver imx7ulp_wdt_driver = {
.probe = imx7ulp_wdt_probe,