summaryrefslogtreecommitdiffstats
path: root/drivers/watchdog
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2012-10-05 12:06:41 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2012-10-05 12:24:04 +0200
commit797bc5d911282f7a80f6ba1acdf9bda36a1a70fa (patch)
tree905801b202e83051ec7ee62109aa79be44531808 /drivers/watchdog
parent83f87b14eb8e0f2551c183ec3299e9c02f2c38ae (diff)
downloadbarebox-797bc5d911282f7a80f6ba1acdf9bda36a1a70fa.tar.gz
ARM i.MX/watchdog: Make i.MX watchdog driver the reset source on i.MX
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
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 645b5c7..ba33617 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 e655454..f522b88 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 43e4803..7bbb86c 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[] = {