diff options
-rw-r--r-- | arch/arm/mach-at91/clock.c | 48 | ||||
-rw-r--r-- | arch/arm/mach-at91/include/mach/at91_wdt.h | 10 | ||||
-rw-r--r-- | drivers/watchdog/at91sam9_wdt.c | 10 |
3 files changed, 58 insertions, 10 deletions
diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c index 64cbc3d1ed..1d3df2c09d 100644 --- a/arch/arm/mach-at91/clock.c +++ b/arch/arm/mach-at91/clock.c @@ -5,12 +5,17 @@ */ #include <common.h> +#include <dm.h> +#include <wdt.h> #include <asm/io.h> #include <asm/arch/hardware.h> #include <asm/arch/at91_pmc.h> +#include <asm/arch/at91_wdt.h> #define EN_UPLL_TIMEOUT 500 +static struct udevice *watchdog_dev __attribute__((section(".data"))) = NULL; + void at91_periph_clk_enable(int id) { struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; @@ -118,3 +123,46 @@ void at91_pllicpr_init(u32 icpr) writel(icpr, &pmc->pllicpr); } + +/* Called by macro WATCHDOG_RESET */ +void watchdog_reset(void) +{ + static ulong next_reset; + ulong now; + + if (!watchdog_dev) + return; + + now = get_timer(0); + + /* Do not reset the watchdog too often */ + if (now > next_reset) { + next_reset = now + 1000; /* reset every 1000ms */ + wdt_reset(watchdog_dev); + } +} + +int arch_early_init_r(void) +{ + struct at91_wdt_priv *priv; + + /* Init watchdog */ + if (uclass_get_device_by_seq(UCLASS_WDT, 0, &watchdog_dev)) { + debug("Watchdog: Not found by seq!\n"); + if (uclass_get_device(UCLASS_WDT, 0, &watchdog_dev)) { + puts("Watchdog: Not found!\n"); + return 0; + } + } + + priv = dev_get_priv(watchdog_dev); + if (!priv) { + printf("Watchdog: priv not available!\n"); + return 0; + } + + wdt_start(watchdog_dev, priv->timeout * 1000, 0); + printf("Watchdog: Started\n"); + + return 0; +} diff --git a/arch/arm/mach-at91/include/mach/at91_wdt.h b/arch/arm/mach-at91/include/mach/at91_wdt.h index cd2272367b..a8fc73b3d1 100644 --- a/arch/arm/mach-at91/include/mach/at91_wdt.h +++ b/arch/arm/mach-at91/include/mach/at91_wdt.h @@ -25,6 +25,12 @@ typedef struct at91_wdt { u32 sr; } at91_wdt_t; +struct at91_wdt_priv { + void __iomem *regs; + u32 regval; + u32 timeout; +}; + #endif /* Watchdog Control Register */ @@ -43,4 +49,8 @@ typedef struct at91_wdt { #define AT91_WDT_MR_WDDBGHLT 0x10000000 #define AT91_WDT_MR_WDIDLEHLT 0x20000000 +/* Hardware timeout in seconds */ +#define WDT_MAX_TIMEOUT 16 +#define WDT_DEFAULT_TIMEOUT 2 + #endif diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c index a9fd547e2f..000769d46d 100644 --- a/drivers/watchdog/at91sam9_wdt.c +++ b/drivers/watchdog/at91sam9_wdt.c @@ -31,16 +31,6 @@ DECLARE_GLOBAL_DATA_PTR; */ #define WDT_SEC2TICKS(s) (((s) << 8) - 1) -/* Hardware timeout in seconds */ -#define WDT_MAX_TIMEOUT 16 -#define WDT_DEFAULT_TIMEOUT 2 - -struct at91_wdt_priv { - void __iomem *regs; - u32 regval; - u32 timeout; -}; - /* * Set the watchdog time interval in 1/256Hz (write-once) * Counter is 12 bit. |