mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH] i.MX watchdog support
@ 2012-10-05 10:29 Sascha Hauer
  2012-10-05 10:29 ` [PATCH 1/3] watchdog: Add " Sascha Hauer
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Sascha Hauer @ 2012-10-05 10:29 UTC (permalink / raw)
  To: barebox


The following adds support for the i.MX watchdog unit. The device
is registered on all i.MX SoCs and finally used as the reset source
for i.MX. This replaces the non-driver based reset_cpu function.

----------------------------------------------------------------
Sascha Hauer (3):
      watchdog: Add i.MX watchdog support
      ARM i.MX: Add watchdog devices to SoCs
      ARM i.MX/watchdog: Make i.MX watchdog driver the reset source on i.MX

 arch/arm/Kconfig                |    1 +
 arch/arm/mach-imx/clocksource.c |   37 -------
 arch/arm/mach-imx/imx1.c        |    1 +
 arch/arm/mach-imx/imx21.c       |    1 +
 arch/arm/mach-imx/imx25.c       |    1 +
 arch/arm/mach-imx/imx27.c       |    1 +
 arch/arm/mach-imx/imx31.c       |    1 +
 arch/arm/mach-imx/imx35.c       |    1 +
 arch/arm/mach-imx/imx51.c       |    1 +
 arch/arm/mach-imx/imx53.c       |    1 +
 arch/arm/mach-imx/imx6.c        |    1 +
 drivers/watchdog/Kconfig        |    9 ++
 drivers/watchdog/Makefile       |    1 +
 drivers/watchdog/imxwd.c        |  201 +++++++++++++++++++++++++++++++++++++++
 14 files changed, 221 insertions(+), 37 deletions(-)
 create mode 100644 drivers/watchdog/imxwd.c

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/3] watchdog: Add i.MX watchdog support
  2012-10-05 10:29 [PATCH] i.MX watchdog support Sascha Hauer
@ 2012-10-05 10:29 ` Sascha Hauer
  2012-10-05 10:29 ` [PATCH 2/3] ARM i.MX: Add watchdog devices to SoCs Sascha Hauer
  2012-10-05 10:30 ` [PATCH 3/3] ARM i.MX/watchdog: Make i.MX watchdog driver the reset source on i.MX Sascha Hauer
  2 siblings, 0 replies; 4+ messages in thread
From: Sascha Hauer @ 2012-10-05 10:29 UTC (permalink / raw)
  To: barebox

This adds a driver for the watchdog found on i.MX1-i.MX6.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/watchdog/Kconfig  |    6 ++
 drivers/watchdog/Makefile |    1 +
 drivers/watchdog/imxwd.c  |  180 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 187 insertions(+)
 create mode 100644 drivers/watchdog/imxwd.c

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 8fdc7a5..645b5c7 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -12,4 +12,10 @@ config WATCHDOG_MXS28
 	help
 	  Add support for watchdog management for the i.MX28 SoC.
 
+config WATCHDOG_IMX
+	bool "i.MX watchdog"
+	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 b29103b..e655454 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -1,2 +1,3 @@
 obj-$(CONFIG_WATCHDOG) += wd_core.o
 obj-$(CONFIG_WATCHDOG_MXS28) += im28wd.o
+obj-$(CONFIG_WATCHDOG_IMX) += imxwd.o
diff --git a/drivers/watchdog/imxwd.c b/drivers/watchdog/imxwd.c
new file mode 100644
index 0000000..43e4803
--- /dev/null
+++ b/drivers/watchdog/imxwd.c
@@ -0,0 +1,180 @@
+/*
+ * (c) 2012 Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <io.h>
+#include <errno.h>
+#include <malloc.h>
+#include <watchdog.h>
+#include <reset_source.h>
+
+struct imx_wd {
+	struct watchdog wd;
+	void __iomem *base;
+	struct device_d *dev;
+	int (*set_timeout)(struct imx_wd *, unsigned);
+};
+
+#define to_imx_wd(h) container_of(h, struct imx_wd, wd)
+
+#define IMX1_WDOG_WCR	0x00 /* Watchdog Control Register */
+#define IMX1_WDOG_WSR	0x04 /* Watchdog Service Register */
+#define IMX1_WDOG_WSTR	0x08 /* Watchdog Status Register  */
+#define IMX1_WDOG_WCR_WDE	(1 << 0)
+#define IMX1_WDOG_WCR_WHALT	(1 << 15)
+
+#define IMX21_WDOG_WCR	0x00 /* Watchdog Control Register */
+#define IMX21_WDOG_WSR	0x02 /* Watchdog Service Register */
+#define IMX21_WDOG_WSTR	0x04 /* Watchdog Status Register  */
+#define IMX21_WDOG_WCR_WDE	(1 << 2)
+#define IMX21_WDOG_WCR_SRS	(1 << 4)
+#define IMX21_WDOG_WCR_WDA	(1 << 5)
+
+static int imx1_watchdog_set_timeout(struct imx_wd *priv, int timeout)
+{
+	u16 val;
+
+	dev_dbg(priv->dev, "%s: %d\n", __func__, timeout);
+
+	if (timeout > 64)
+		return -EINVAL;
+
+	if (!timeout) {
+		writew(IMX1_WDOG_WCR_WHALT, priv->base + IMX1_WDOG_WCR);
+		return 0;
+	}
+
+	if (timeout > 0)
+		val = (timeout * 2 - 1) << 8;
+	else
+		val = 0;
+
+	writew(val, priv->base + IMX1_WDOG_WCR);
+	writew(IMX1_WDOG_WCR_WDE | val, priv->base + IMX1_WDOG_WCR);
+
+	/* Write Service Sequence */
+	writew(0x5555, priv->base + IMX1_WDOG_WSR);
+	writew(0xaaaa, priv->base + IMX1_WDOG_WSR);
+
+	return 0;
+}
+
+static int imx21_watchdog_set_timeout(struct imx_wd *priv, int timeout)
+{
+	u16 val;
+
+	dev_dbg(priv->dev, "%s: %d\n", __func__, timeout);
+
+	if (!timeout || timeout > 128)
+		return -EINVAL;
+
+	if (timeout > 0)
+		val = ((timeout * 2 - 1) << 8) | IMX21_WDOG_WCR_SRS |
+			IMX21_WDOG_WCR_WDA;
+	else
+		val = 0;
+
+	writew(val, priv->base + IMX21_WDOG_WCR);
+	writew(IMX21_WDOG_WCR_WDE | val, priv->base + IMX21_WDOG_WCR);
+
+	/* Write Service Sequence */
+	writew(0x5555, priv->base + IMX21_WDOG_WSR);
+	writew(0xaaaa, priv->base + IMX21_WDOG_WSR);
+
+	return 0;
+}
+
+static int imx_watchdog_set_timeout(struct watchdog *wd, unsigned timeout)
+{
+	struct imx_wd *priv = (struct imx_wd *)to_imx_wd(wd);
+
+	return priv->set_timeout(priv, timeout);
+}
+
+static int imx_wd_probe(struct device_d *dev)
+{
+	struct imx_wd *priv;
+	void *fn;
+	int ret;
+
+	ret = dev_get_drvdata(dev, (unsigned long *)&fn);
+	if (ret)
+		return ret;
+
+	priv = xzalloc(sizeof(struct imx_wd));
+	priv->base = dev_request_mem_region(dev, 0);
+	priv->set_timeout = fn;
+	priv->wd.set_timeout = imx_watchdog_set_timeout;
+	priv->dev = dev;
+
+	ret = watchdog_register(&priv->wd);
+	if (ret)
+		goto on_error;
+
+	dev->priv = priv;
+
+	return 0;
+
+on_error:
+	free(priv);
+	return ret;
+}
+
+static void imx_wd_remove(struct device_d *dev)
+{
+	struct imx_wd *priv = dev->priv;
+
+	watchdog_deregister(&priv->wd);
+	free(priv);
+}
+
+static __maybe_unused struct of_device_id imx_wdt_dt_ids[] = {
+	{
+		.compatible = "fsl,imx1-wdt",
+		.data = (unsigned long)&imx1_watchdog_set_timeout,
+	}, {
+		.compatible = "fsl,imx21-wdt",
+		.data = (unsigned long)&imx21_watchdog_set_timeout,
+	}, {
+		/* sentinel */
+	}
+};
+
+static struct platform_device_id imx_wdt_ids[] = {
+	{
+		.name = "imx1-wdt",
+		.driver_data = (unsigned long)&imx1_watchdog_set_timeout,
+	}, {
+		.name = "imx21-wdt",
+		.driver_data = (unsigned long)&imx21_watchdog_set_timeout,
+	}, {
+		/* sentinel */
+	},
+};
+
+static struct driver_d imx_wd_driver = {
+	.name   = "imx-watchdog",
+	.probe  = imx_wd_probe,
+	.remove = imx_wd_remove,
+	.of_compatible = DRV_OF_COMPAT(imx_wdt_dt_ids),
+	.id_table = imx_wdt_ids,
+};
+
+static int imx_wd_init(void)
+{
+	return platform_driver_register(&imx_wd_driver);
+}
+
+device_initcall(imx_wd_init);
-- 
1.7.10.4


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 2/3] ARM i.MX: Add watchdog devices to SoCs
  2012-10-05 10:29 [PATCH] i.MX watchdog support Sascha Hauer
  2012-10-05 10:29 ` [PATCH 1/3] watchdog: Add " Sascha Hauer
@ 2012-10-05 10:29 ` Sascha Hauer
  2012-10-05 10:30 ` [PATCH 3/3] ARM i.MX/watchdog: Make i.MX watchdog driver the reset source on i.MX Sascha Hauer
  2 siblings, 0 replies; 4+ messages in thread
From: Sascha Hauer @ 2012-10-05 10:29 UTC (permalink / raw)
  To: barebox

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/mach-imx/imx1.c  |    1 +
 arch/arm/mach-imx/imx21.c |    1 +
 arch/arm/mach-imx/imx25.c |    1 +
 arch/arm/mach-imx/imx27.c |    1 +
 arch/arm/mach-imx/imx31.c |    1 +
 arch/arm/mach-imx/imx35.c |    1 +
 arch/arm/mach-imx/imx51.c |    1 +
 arch/arm/mach-imx/imx53.c |    1 +
 arch/arm/mach-imx/imx6.c  |    1 +
 9 files changed, 9 insertions(+)

diff --git a/arch/arm/mach-imx/imx1.c b/arch/arm/mach-imx/imx1.c
index 790e453..2b2b924 100644
--- a/arch/arm/mach-imx/imx1.c
+++ b/arch/arm/mach-imx/imx1.c
@@ -31,6 +31,7 @@ static int imx1_init(void)
 	add_generic_device("imx1-gpio", 1, NULL, MX1_GPIO2_BASE_ADDR, 0x100, IORESOURCE_MEM, NULL);
 	add_generic_device("imx1-gpio", 2, NULL, MX1_GPIO3_BASE_ADDR, 0x100, IORESOURCE_MEM, NULL);
 	add_generic_device("imx1-gpio", 3, NULL, MX1_GPIO4_BASE_ADDR, 0x100, IORESOURCE_MEM, NULL);
+	add_generic_device("imx1-wdt", 0, NULL, MX1_WDT_BASE_ADDR, 0x100, IORESOURCE_MEM, NULL);
 
 	return 0;
 }
diff --git a/arch/arm/mach-imx/imx21.c b/arch/arm/mach-imx/imx21.c
index 7ed0809..01a9cfb 100644
--- a/arch/arm/mach-imx/imx21.c
+++ b/arch/arm/mach-imx/imx21.c
@@ -41,6 +41,7 @@ static int imx21_init(void)
 	add_generic_device("imx-gpio", 3, NULL, MX21_GPIO4_BASE_ADDR, 0x100, IORESOURCE_MEM, NULL);
 	add_generic_device("imx-gpio", 4, NULL, MX21_GPIO5_BASE_ADDR, 0x100, IORESOURCE_MEM, NULL);
 	add_generic_device("imx-gpio", 5, NULL, MX21_GPIO6_BASE_ADDR, 0x100, IORESOURCE_MEM, NULL);
+	add_generic_device("imx21-wdt", 0, NULL, MX21_WDOG_BASE_ADDR, 0x100, IORESOURCE_MEM, NULL);
 
 	return 0;
 }
diff --git a/arch/arm/mach-imx/imx25.c b/arch/arm/mach-imx/imx25.c
index 5e6532a..8aa553b 100644
--- a/arch/arm/mach-imx/imx25.c
+++ b/arch/arm/mach-imx/imx25.c
@@ -67,6 +67,7 @@ static int imx25_init(void)
 	add_generic_device("imx31-gpio", 1, NULL, MX25_GPIO2_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
 	add_generic_device("imx31-gpio", 2, NULL, MX25_GPIO3_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
 	add_generic_device("imx31-gpio", 3, NULL, MX25_GPIO4_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
+	add_generic_device("imx21-wdt", 0, NULL, MX25_WDOG_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
 
 	return 0;
 }
diff --git a/arch/arm/mach-imx/imx27.c b/arch/arm/mach-imx/imx27.c
index 8116e6f..ad5edd7 100644
--- a/arch/arm/mach-imx/imx27.c
+++ b/arch/arm/mach-imx/imx27.c
@@ -86,6 +86,7 @@ static int imx27_init(void)
 	add_generic_device("imx1-gpio", 3, NULL, MX27_GPIO4_BASE_ADDR, 0x100, IORESOURCE_MEM, NULL);
 	add_generic_device("imx1-gpio", 4, NULL, MX27_GPIO5_BASE_ADDR, 0x100, IORESOURCE_MEM, NULL);
 	add_generic_device("imx1-gpio", 5, NULL, MX27_GPIO6_BASE_ADDR, 0x100, IORESOURCE_MEM, NULL);
+	add_generic_device("imx21-wdt", 0, NULL, MX27_WDOG_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
 
 	return 0;
 }
diff --git a/arch/arm/mach-imx/imx31.c b/arch/arm/mach-imx/imx31.c
index 90eee0a..2a9fe6e 100644
--- a/arch/arm/mach-imx/imx31.c
+++ b/arch/arm/mach-imx/imx31.c
@@ -36,6 +36,7 @@ static int imx31_init(void)
 	add_generic_device("imx-gpio", 0, NULL, MX31_GPIO1_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
 	add_generic_device("imx-gpio", 1, NULL, MX31_GPIO2_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
 	add_generic_device("imx-gpio", 2, NULL, MX31_GPIO3_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
+	add_generic_device("imx21-wdt", 0, NULL, MX31_WDOG_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
 
 	return 0;
 }
diff --git a/arch/arm/mach-imx/imx35.c b/arch/arm/mach-imx/imx35.c
index 722dd4c..aeca70d 100644
--- a/arch/arm/mach-imx/imx35.c
+++ b/arch/arm/mach-imx/imx35.c
@@ -66,6 +66,7 @@ static int imx35_init(void)
 	add_generic_device("imx-gpio", 0, NULL, MX35_GPIO1_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
 	add_generic_device("imx-gpio", 1, NULL, MX35_GPIO2_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
 	add_generic_device("imx-gpio", 2, NULL, MX35_GPIO3_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
+	add_generic_device("imx21-wdt", 0, NULL, MX35_WDOG_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL);
 
 	return 0;
 }
diff --git a/arch/arm/mach-imx/imx51.c b/arch/arm/mach-imx/imx51.c
index 8709c43..805365e 100644
--- a/arch/arm/mach-imx/imx51.c
+++ b/arch/arm/mach-imx/imx51.c
@@ -80,6 +80,7 @@ static int imx51_init(void)
 	add_generic_device("imx31-gpio", 1, NULL, MX51_GPIO2_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
 	add_generic_device("imx31-gpio", 2, NULL, MX51_GPIO3_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
 	add_generic_device("imx31-gpio", 3, NULL, MX51_GPIO4_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
+	add_generic_device("imx21-wdt", 0, NULL, MX51_WDOG_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
 
 	return 0;
 }
diff --git a/arch/arm/mach-imx/imx53.c b/arch/arm/mach-imx/imx53.c
index 88b4274..3ddbeb2 100644
--- a/arch/arm/mach-imx/imx53.c
+++ b/arch/arm/mach-imx/imx53.c
@@ -79,6 +79,7 @@ static int imx53_init(void)
 	add_generic_device("imx31-gpio", 4, NULL, MX53_GPIO5_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
 	add_generic_device("imx31-gpio", 5, NULL, MX53_GPIO6_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
 	add_generic_device("imx31-gpio", 6, NULL, MX53_GPIO7_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
+	add_generic_device("imx21-wdt", 0, NULL, MX53_WDOG1_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
 
 	return 0;
 }
diff --git a/arch/arm/mach-imx/imx6.c b/arch/arm/mach-imx/imx6.c
index a5ec364..81f1bb1 100644
--- a/arch/arm/mach-imx/imx6.c
+++ b/arch/arm/mach-imx/imx6.c
@@ -63,6 +63,7 @@ static int imx6_init(void)
 	add_generic_device("imx31-gpio", 4, NULL, MX6_GPIO5_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL);
 	add_generic_device("imx31-gpio", 5, NULL, MX6_GPIO6_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL);
 	add_generic_device("imx31-gpio", 6, NULL, MX6_GPIO7_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL);
+	add_generic_device("imx21-wdt", 0, NULL, MX6_WDOG1_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL);
 
 	return 0;
 }
-- 
1.7.10.4


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 3/3] ARM i.MX/watchdog: Make i.MX watchdog driver the reset source on i.MX
  2012-10-05 10:29 [PATCH] i.MX watchdog support Sascha Hauer
  2012-10-05 10:29 ` [PATCH 1/3] watchdog: Add " Sascha Hauer
  2012-10-05 10:29 ` [PATCH 2/3] ARM i.MX: Add watchdog devices to SoCs Sascha Hauer
@ 2012-10-05 10:30 ` Sascha Hauer
  2 siblings, 0 replies; 4+ messages in thread
From: Sascha Hauer @ 2012-10-05 10:30 UTC (permalink / raw)
  To: barebox

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/Kconfig                |    1 +
 arch/arm/mach-imx/clocksource.c |   37 -------------------------------------
 drivers/watchdog/Kconfig        |    5 ++++-
 drivers/watchdog/Makefile       |    2 +-
 drivers/watchdog/imxwd.c        |   33 +++++++++++++++++++++++++++------
 5 files changed, 33 insertions(+), 45 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 8278c82..dc90c02 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -42,6 +42,7 @@ config ARCH_IMX
 	select GPIOLIB
 	select COMMON_CLK
 	select CLKDEV_LOOKUP
+	select WATCHDOG_IMX_RESET_SOURCE
 
 config ARCH_MXS
 	bool "Freescale i.MX23/28 (mxs) based"
diff --git a/arch/arm/mach-imx/clocksource.c b/arch/arm/mach-imx/clocksource.c
index 69a688c..e482fad 100644
--- a/arch/arm/mach-imx/clocksource.c
+++ b/arch/arm/mach-imx/clocksource.c
@@ -179,40 +179,3 @@ static int imx_gpt_init(void)
 	return platform_driver_register(&imx_gpt_driver);
 }
 coredevice_initcall(imx_gpt_init);
-
-/*
- * Watchdog Registers
- */
-#ifdef CONFIG_ARCH_IMX1
-#define WDOG_WCR	0x00 /* Watchdog Control Register */
-#define WDOG_WSR	0x04 /* Watchdog Service Register */
-#define WDOG_WSTR	0x08 /* Watchdog Status Register  */
-#define WDOG_WCR_WDE	(1 << 0)
-#else
-#define WDOG_WCR	0x00 /* Watchdog Control Register */
-#define WDOG_WSR	0x02 /* Watchdog Service Register */
-#define WDOG_WSTR	0x04 /* Watchdog Status Register  */
-#define WDOG_WCR_WDE	(1 << 2)
-#endif
-
-/*
- * Reset the cpu by setting up the watchdog timer and let it time out
- */
-void __noreturn reset_cpu (unsigned long addr)
-{
-	void __iomem *wdt = IOMEM(IMX_WDT_BASE);
-
-	/* Disable watchdog and set Time-Out field to 0 */
-	writew(0x0, wdt + WDOG_WCR);
-
-	/* Write Service Sequence */
-	writew(0x5555, wdt + WDOG_WSR);
-	writew(0xaaaa, wdt + WDOG_WSR);
-
-	/* Enable watchdog */
-	writew(WDOG_WCR_WDE, wdt + WDOG_WCR);
-
-	while (1);
-	/*NOTREACHED*/
-}
-EXPORT_SYMBOL(reset_cpu);
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[] = {
-- 
1.7.10.4


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2012-10-05 10:30 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-10-05 10:29 [PATCH] i.MX watchdog support Sascha Hauer
2012-10-05 10:29 ` [PATCH 1/3] watchdog: Add " Sascha Hauer
2012-10-05 10:29 ` [PATCH 2/3] ARM i.MX: Add watchdog devices to SoCs Sascha Hauer
2012-10-05 10:30 ` [PATCH 3/3] ARM i.MX/watchdog: Make i.MX watchdog driver the reset source on i.MX Sascha Hauer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox