From 797bc5d911282f7a80f6ba1acdf9bda36a1a70fa Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 5 Oct 2012 12:06:41 +0200 Subject: ARM i.MX/watchdog: Make i.MX watchdog driver the reset source on i.MX Signed-off-by: Sascha Hauer --- 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 8278c82e3a..dc90c02e76 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 69a688c09d..e482fad624 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 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[] = { -- cgit v1.2.3