summaryrefslogtreecommitdiffstats
path: root/drivers/watchdog
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/watchdog')
-rw-r--r--drivers/watchdog/Kconfig5
-rw-r--r--drivers/watchdog/Makefile2
-rw-r--r--drivers/watchdog/imxwd.c33
3 files changed, 32 insertions, 8 deletions
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 645b5c7cd0..ba33617d22 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -1,3 +1,7 @@
+
+config WATCHDOG_IMX_RESET_SOURCE
+ bool
+
menuconfig WATCHDOG
bool "Watchdog support "
help
@@ -17,5 +21,4 @@ config WATCHDOG_IMX
depends on ARCH_IMX
help
Add support for watchdog found on Freescale i.MX SoCs.
-
endif
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index e655454bff..f522b88708 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -1,3 +1,3 @@
obj-$(CONFIG_WATCHDOG) += wd_core.o
obj-$(CONFIG_WATCHDOG_MXS28) += im28wd.o
-obj-$(CONFIG_WATCHDOG_IMX) += imxwd.o
+obj-$(CONFIG_WATCHDOG_IMX_RESET_SOURCE) += imxwd.o
diff --git a/drivers/watchdog/imxwd.c b/drivers/watchdog/imxwd.c
index 43e4803928..7bbb86c405 100644
--- a/drivers/watchdog/imxwd.c
+++ b/drivers/watchdog/imxwd.c
@@ -103,6 +103,18 @@ static int imx_watchdog_set_timeout(struct watchdog *wd, unsigned timeout)
return priv->set_timeout(priv, timeout);
}
+static struct imx_wd *reset_wd;
+
+void __noreturn reset_cpu(unsigned long addr)
+{
+ if (reset_wd)
+ reset_wd->set_timeout(reset_wd, -1);
+
+ mdelay(1000);
+
+ hang();
+}
+
static int imx_wd_probe(struct device_d *dev)
{
struct imx_wd *priv;
@@ -119,16 +131,22 @@ static int imx_wd_probe(struct device_d *dev)
priv->wd.set_timeout = imx_watchdog_set_timeout;
priv->dev = dev;
- ret = watchdog_register(&priv->wd);
- if (ret)
- goto on_error;
+ if (!reset_wd)
+ reset_wd = priv;
+
+ if (IS_ENABLED(CONFIG_WATCHDOG_IMX)) {
+ ret = watchdog_register(&priv->wd);
+ if (ret)
+ goto on_error;
+ }
dev->priv = priv;
return 0;
on_error:
- free(priv);
+ if (reset_wd && reset_wd != priv)
+ free(priv);
return ret;
}
@@ -136,8 +154,11 @@ static void imx_wd_remove(struct device_d *dev)
{
struct imx_wd *priv = dev->priv;
- watchdog_deregister(&priv->wd);
- free(priv);
+ if (IS_ENABLED(CONFIG_WATCHDOG_IMX))
+ watchdog_deregister(&priv->wd);
+
+ if (reset_wd && reset_wd != priv)
+ free(priv);
}
static __maybe_unused struct of_device_id imx_wdt_dt_ids[] = {