diff options
author | Kumar Gala <galak@freescale.com> | 2005-09-03 18:55:33 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@evo.osdl.org> | 2005-09-05 03:05:56 -0400 |
commit | a2f40ccd294d14e5aca464c1913e8e0d8de35fca (patch) | |
tree | d900ebdbf37656d77acf7934db40021b21d49fde /arch/ppc | |
parent | 886b9fa49900b055e20cd98f379fda49835d1ee6 (diff) |
[PATCH] ppc32: Added support for the Book-E style Watchdog Timer
PowerPC 40x and Book-E processors support a watchdog timer at the processor
core level. The timer has implementation dependent timeout frequencies
that can be configured by software.
One the first Watchdog timeout we get a critical exception. It is left to
board specific code to determine what should happen at this point. If
nothing is done and another timeout period expires the processor may
attempt to reset the machine.
Command line parameters:
wdt=0 : disable watchdog (default)
wdt=1 : enable watchdog
wdt_period=N : N sets the value of the Watchdog Timer Period.
The Watchdog Timer Period meaning is implementation specific. Check
User Manual for the processor for more details.
This patch is based off of work done by Takeharu Kato.
Signed-off-by: Matt McClintock <msm@freescale.com>
Signed-off-by: Kumar Gala <kumar.gala@freescale.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/ppc')
-rw-r--r-- | arch/ppc/kernel/head_44x.S | 4 | ||||
-rw-r--r-- | arch/ppc/kernel/head_4xx.S | 4 | ||||
-rw-r--r-- | arch/ppc/kernel/head_fsl_booke.S | 5 | ||||
-rw-r--r-- | arch/ppc/kernel/setup.c | 24 | ||||
-rw-r--r-- | arch/ppc/kernel/traps.c | 19 | ||||
-rw-r--r-- | arch/ppc/syslib/ppc4xx_setup.c | 25 |
6 files changed, 54 insertions, 27 deletions
diff --git a/arch/ppc/kernel/head_44x.S b/arch/ppc/kernel/head_44x.S index 69ff3a9961e8..9e68e32edb60 100644 --- a/arch/ppc/kernel/head_44x.S +++ b/arch/ppc/kernel/head_44x.S | |||
@@ -462,7 +462,11 @@ interrupt_base: | |||
462 | 462 | ||
463 | /* Watchdog Timer Interrupt */ | 463 | /* Watchdog Timer Interrupt */ |
464 | /* TODO: Add watchdog support */ | 464 | /* TODO: Add watchdog support */ |
465 | #ifdef CONFIG_BOOKE_WDT | ||
466 | CRITICAL_EXCEPTION(0x1020, WatchdogTimer, WatchdogException) | ||
467 | #else | ||
465 | CRITICAL_EXCEPTION(0x1020, WatchdogTimer, UnknownException) | 468 | CRITICAL_EXCEPTION(0x1020, WatchdogTimer, UnknownException) |
469 | #endif | ||
466 | 470 | ||
467 | /* Data TLB Error Interrupt */ | 471 | /* Data TLB Error Interrupt */ |
468 | START_EXCEPTION(DataTLBError) | 472 | START_EXCEPTION(DataTLBError) |
diff --git a/arch/ppc/kernel/head_4xx.S b/arch/ppc/kernel/head_4xx.S index 23fb51819ba5..0a5e723d3be6 100644 --- a/arch/ppc/kernel/head_4xx.S +++ b/arch/ppc/kernel/head_4xx.S | |||
@@ -448,7 +448,9 @@ label: | |||
448 | 448 | ||
449 | /* 0x1020 - Watchdog Timer (WDT) Exception | 449 | /* 0x1020 - Watchdog Timer (WDT) Exception |
450 | */ | 450 | */ |
451 | 451 | #ifdef CONFIG_BOOKE_WDT | |
452 | CRITICAL_EXCEPTION(0x1020, WDTException, WatchdogException) | ||
453 | #else | ||
452 | CRITICAL_EXCEPTION(0x1020, WDTException, UnknownException) | 454 | CRITICAL_EXCEPTION(0x1020, WDTException, UnknownException) |
453 | #endif | 455 | #endif |
454 | 456 | ||
diff --git a/arch/ppc/kernel/head_fsl_booke.S b/arch/ppc/kernel/head_fsl_booke.S index eb804b7a3cb2..4028f4c7d978 100644 --- a/arch/ppc/kernel/head_fsl_booke.S +++ b/arch/ppc/kernel/head_fsl_booke.S | |||
@@ -564,8 +564,11 @@ interrupt_base: | |||
564 | EXCEPTION(0x3100, FixedIntervalTimer, UnknownException, EXC_XFER_EE) | 564 | EXCEPTION(0x3100, FixedIntervalTimer, UnknownException, EXC_XFER_EE) |
565 | 565 | ||
566 | /* Watchdog Timer Interrupt */ | 566 | /* Watchdog Timer Interrupt */ |
567 | /* TODO: Add watchdog support */ | 567 | #ifdef CONFIG_BOOKE_WDT |
568 | CRITICAL_EXCEPTION(0x3200, WatchdogTimer, WatchdogException) | ||
569 | #else | ||
568 | CRITICAL_EXCEPTION(0x3200, WatchdogTimer, UnknownException) | 570 | CRITICAL_EXCEPTION(0x3200, WatchdogTimer, UnknownException) |
571 | #endif | ||
569 | 572 | ||
570 | /* Data TLB Error Interrupt */ | 573 | /* Data TLB Error Interrupt */ |
571 | START_EXCEPTION(DataTLBError) | 574 | START_EXCEPTION(DataTLBError) |
diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c index 929e5d1cc7fe..cf74a744e375 100644 --- a/arch/ppc/kernel/setup.c +++ b/arch/ppc/kernel/setup.c | |||
@@ -615,6 +615,30 @@ machine_init(unsigned long r3, unsigned long r4, unsigned long r5, | |||
615 | if (ppc_md.progress) | 615 | if (ppc_md.progress) |
616 | ppc_md.progress("id mach(): done", 0x200); | 616 | ppc_md.progress("id mach(): done", 0x200); |
617 | } | 617 | } |
618 | #ifdef CONFIG_BOOKE_WDT | ||
619 | /* Checks wdt=x and wdt_period=xx command-line option */ | ||
620 | int __init early_parse_wdt(char *p) | ||
621 | { | ||
622 | extern u32 wdt_enable; | ||
623 | |||
624 | if (p && strncmp(p, "0", 1) != 0) | ||
625 | wdt_enable = 1; | ||
626 | |||
627 | return 0; | ||
628 | } | ||
629 | early_param("wdt", early_parse_wdt); | ||
630 | |||
631 | int __init early_parse_wdt_period (char *p) | ||
632 | { | ||
633 | extern u32 wdt_period; | ||
634 | |||
635 | if (p) | ||
636 | wdt_period = simple_strtoul(p, NULL, 0); | ||
637 | |||
638 | return 0; | ||
639 | } | ||
640 | early_param("wdt_period", early_parse_wdt_period); | ||
641 | #endif /* CONFIG_BOOKE_WDT */ | ||
618 | 642 | ||
619 | /* Checks "l2cr=xxxx" command-line option */ | 643 | /* Checks "l2cr=xxxx" command-line option */ |
620 | int __init ppc_setup_l2cr(char *str) | 644 | int __init ppc_setup_l2cr(char *str) |
diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c index 9e6ae5696650..d87423d1003a 100644 --- a/arch/ppc/kernel/traps.c +++ b/arch/ppc/kernel/traps.c | |||
@@ -904,6 +904,25 @@ void SPEFloatingPointException(struct pt_regs *regs) | |||
904 | } | 904 | } |
905 | #endif | 905 | #endif |
906 | 906 | ||
907 | #ifdef CONFIG_BOOKE_WDT | ||
908 | /* | ||
909 | * Default handler for a Watchdog exception, | ||
910 | * spins until a reboot occurs | ||
911 | */ | ||
912 | void __attribute__ ((weak)) WatchdogHandler(struct pt_regs *regs) | ||
913 | { | ||
914 | /* Generic WatchdogHandler, implement your own */ | ||
915 | mtspr(SPRN_TCR, mfspr(SPRN_TCR)&(~TCR_WIE)); | ||
916 | return; | ||
917 | } | ||
918 | |||
919 | void WatchdogException(struct pt_regs *regs) | ||
920 | { | ||
921 | printk (KERN_EMERG "PowerPC Book-E Watchdog Exception\n"); | ||
922 | WatchdogHandler(regs); | ||
923 | } | ||
924 | #endif | ||
925 | |||
907 | void __init trap_init(void) | 926 | void __init trap_init(void) |
908 | { | 927 | { |
909 | } | 928 | } |
diff --git a/arch/ppc/syslib/ppc4xx_setup.c b/arch/ppc/syslib/ppc4xx_setup.c index 795b966e696a..b843c4fef25e 100644 --- a/arch/ppc/syslib/ppc4xx_setup.c +++ b/arch/ppc/syslib/ppc4xx_setup.c | |||
@@ -48,10 +48,6 @@ | |||
48 | extern void abort(void); | 48 | extern void abort(void); |
49 | extern void ppc4xx_find_bridges(void); | 49 | extern void ppc4xx_find_bridges(void); |
50 | 50 | ||
51 | extern void ppc4xx_wdt_heartbeat(void); | ||
52 | extern int wdt_enable; | ||
53 | extern unsigned long wdt_period; | ||
54 | |||
55 | /* Global Variables */ | 51 | /* Global Variables */ |
56 | bd_t __res; | 52 | bd_t __res; |
57 | 53 | ||
@@ -257,22 +253,6 @@ ppc4xx_init(unsigned long r3, unsigned long r4, unsigned long r5, | |||
257 | *(char *) (r7 + KERNELBASE) = 0; | 253 | *(char *) (r7 + KERNELBASE) = 0; |
258 | strcpy(cmd_line, (char *) (r6 + KERNELBASE)); | 254 | strcpy(cmd_line, (char *) (r6 + KERNELBASE)); |
259 | } | 255 | } |
260 | #if defined(CONFIG_PPC405_WDT) | ||
261 | /* Look for wdt= option on command line */ | ||
262 | if (strstr(cmd_line, "wdt=")) { | ||
263 | int valid_wdt = 0; | ||
264 | char *p, *q; | ||
265 | for (q = cmd_line; (p = strstr(q, "wdt=")) != 0;) { | ||
266 | q = p + 4; | ||
267 | if (p > cmd_line && p[-1] != ' ') | ||
268 | continue; | ||
269 | wdt_period = simple_strtoul(q, &q, 0); | ||
270 | valid_wdt = 1; | ||
271 | ++q; | ||
272 | } | ||
273 | wdt_enable = valid_wdt; | ||
274 | } | ||
275 | #endif | ||
276 | 256 | ||
277 | /* Initialize machine-dependent vectors */ | 257 | /* Initialize machine-dependent vectors */ |
278 | 258 | ||
@@ -287,11 +267,6 @@ ppc4xx_init(unsigned long r3, unsigned long r4, unsigned long r5, | |||
287 | 267 | ||
288 | ppc_md.calibrate_decr = ppc4xx_calibrate_decr; | 268 | ppc_md.calibrate_decr = ppc4xx_calibrate_decr; |
289 | 269 | ||
290 | #ifdef CONFIG_PPC405_WDT | ||
291 | ppc_md.heartbeat = ppc4xx_wdt_heartbeat; | ||
292 | #endif | ||
293 | ppc_md.heartbeat_count = 0; | ||
294 | |||
295 | ppc_md.find_end_of_memory = ppc4xx_find_end_of_memory; | 270 | ppc_md.find_end_of_memory = ppc4xx_find_end_of_memory; |
296 | ppc_md.setup_io_mappings = ppc4xx_map_io; | 271 | ppc_md.setup_io_mappings = ppc4xx_map_io; |
297 | 272 | ||