summaryrefslogtreecommitdiff
path: root/drivers/watchdog
diff options
context:
space:
mode:
authorBai Ping <ping.bai@nxp.com>2016-12-05 14:31:53 +0800
committerJason Liu <jason.hui.liu@nxp.com>2019-02-12 10:25:21 +0800
commit8ed3ec3401438267065e1eae1cc1417827fedf26 (patch)
tree4cab47dab42ab7f00beb504ab69aa9d731fa5496 /drivers/watchdog
parent102e5b2d3d7049085dda694ec9dd6ac3623cd5e8 (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,