diff options
author | Atsushi Nemoto <anemo@mba.ocn.ne.jp> | 2008-08-19 09:55:15 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2008-10-11 11:18:44 -0400 |
commit | 496a3b5c2c188e8af07261792b3d4e6cf1c1dab9 (patch) | |
tree | 8b84a2f249c27d6804b3db9068f679d178c8d504 | |
parent | d75a40e90e9eb08c2159e719a90a7922dab231d3 (diff) |
MIPS: TXx9: Default machine_restart using watchdog reset
Add default machine_restart routine using watchdog reset of TX4927 and
TX4938.
Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-rw-r--r-- | arch/mips/txx9/generic/setup.c | 15 | ||||
-rw-r--r-- | arch/mips/txx9/generic/setup_tx4927.c | 28 | ||||
-rw-r--r-- | arch/mips/txx9/generic/setup_tx4938.c | 28 | ||||
-rw-r--r-- | include/asm-mips/txx9/generic.h | 1 |
4 files changed, 72 insertions, 0 deletions
diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c index cfa3ccf493bb..118d716f7832 100644 --- a/arch/mips/txx9/generic/setup.c +++ b/arch/mips/txx9/generic/setup.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <asm/r4kcache.h> | 29 | #include <asm/r4kcache.h> |
30 | #include <asm/txx9/generic.h> | 30 | #include <asm/txx9/generic.h> |
31 | #include <asm/txx9/pci.h> | 31 | #include <asm/txx9/pci.h> |
32 | #include <asm/txx9tmr.h> | ||
32 | #ifdef CONFIG_CPU_TX49XX | 33 | #ifdef CONFIG_CPU_TX49XX |
33 | #include <asm/txx9/tx4938.h> | 34 | #include <asm/txx9/tx4938.h> |
34 | #endif | 35 | #endif |
@@ -444,6 +445,20 @@ void __init txx9_wdt_init(unsigned long base) | |||
444 | platform_device_register_simple("txx9wdt", -1, &res, 1); | 445 | platform_device_register_simple("txx9wdt", -1, &res, 1); |
445 | } | 446 | } |
446 | 447 | ||
448 | void txx9_wdt_now(unsigned long base) | ||
449 | { | ||
450 | struct txx9_tmr_reg __iomem *tmrptr = | ||
451 | ioremap(base, sizeof(struct txx9_tmr_reg)); | ||
452 | /* disable watch dog timer */ | ||
453 | __raw_writel(TXx9_TMWTMR_WDIS | TXx9_TMWTMR_TWC, &tmrptr->wtmr); | ||
454 | __raw_writel(0, &tmrptr->tcr); | ||
455 | /* kick watchdog */ | ||
456 | __raw_writel(TXx9_TMWTMR_TWIE, &tmrptr->wtmr); | ||
457 | __raw_writel(1, &tmrptr->cpra); /* immediate */ | ||
458 | __raw_writel(TXx9_TMTCR_TCE | TXx9_TMTCR_CCDE | TXx9_TMTCR_TMODE_WDOG, | ||
459 | &tmrptr->tcr); | ||
460 | } | ||
461 | |||
447 | /* SPI support */ | 462 | /* SPI support */ |
448 | void __init txx9_spi_init(int busid, unsigned long base, int irq) | 463 | void __init txx9_spi_init(int busid, unsigned long base, int irq) |
449 | { | 464 | { |
diff --git a/arch/mips/txx9/generic/setup_tx4927.c b/arch/mips/txx9/generic/setup_tx4927.c index 0840ef930e40..7189675f6a29 100644 --- a/arch/mips/txx9/generic/setup_tx4927.c +++ b/arch/mips/txx9/generic/setup_tx4927.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
16 | #include <linux/param.h> | 16 | #include <linux/param.h> |
17 | #include <linux/mtd/physmap.h> | 17 | #include <linux/mtd/physmap.h> |
18 | #include <asm/reboot.h> | ||
18 | #include <asm/txx9irq.h> | 19 | #include <asm/txx9irq.h> |
19 | #include <asm/txx9tmr.h> | 20 | #include <asm/txx9tmr.h> |
20 | #include <asm/txx9pio.h> | 21 | #include <asm/txx9pio.h> |
@@ -23,6 +24,10 @@ | |||
23 | 24 | ||
24 | static void __init tx4927_wdr_init(void) | 25 | static void __init tx4927_wdr_init(void) |
25 | { | 26 | { |
27 | /* report watchdog reset status */ | ||
28 | if (____raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_WDRST) | ||
29 | pr_warning("Watchdog reset detected at 0x%lx\n", | ||
30 | read_c0_errorepc()); | ||
26 | /* clear WatchDogReset (W1C) */ | 31 | /* clear WatchDogReset (W1C) */ |
27 | tx4927_ccfg_set(TX4927_CCFG_WDRST); | 32 | tx4927_ccfg_set(TX4927_CCFG_WDRST); |
28 | /* do reset on watchdog */ | 33 | /* do reset on watchdog */ |
@@ -34,6 +39,27 @@ void __init tx4927_wdt_init(void) | |||
34 | txx9_wdt_init(TX4927_TMR_REG(2) & 0xfffffffffULL); | 39 | txx9_wdt_init(TX4927_TMR_REG(2) & 0xfffffffffULL); |
35 | } | 40 | } |
36 | 41 | ||
42 | static void tx4927_machine_restart(char *command) | ||
43 | { | ||
44 | local_irq_disable(); | ||
45 | pr_emerg("Rebooting (with %s watchdog reset)...\n", | ||
46 | (____raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_WDREXEN) ? | ||
47 | "external" : "internal"); | ||
48 | /* clear watchdog status */ | ||
49 | tx4927_ccfg_set(TX4927_CCFG_WDRST); /* W1C */ | ||
50 | txx9_wdt_now(TX4927_TMR_REG(2) & 0xfffffffffULL); | ||
51 | while (!(____raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_WDRST)) | ||
52 | ; | ||
53 | mdelay(10); | ||
54 | if (____raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_WDREXEN) { | ||
55 | pr_emerg("Rebooting (with internal watchdog reset)...\n"); | ||
56 | /* External WDRST failed. Do internal watchdog reset */ | ||
57 | tx4927_ccfg_clear(TX4927_CCFG_WDREXEN); | ||
58 | } | ||
59 | /* fallback */ | ||
60 | (*_machine_halt)(); | ||
61 | } | ||
62 | |||
37 | static struct resource tx4927_sdram_resource[4]; | 63 | static struct resource tx4927_sdram_resource[4]; |
38 | 64 | ||
39 | void __init tx4927_setup(void) | 65 | void __init tx4927_setup(void) |
@@ -169,6 +195,8 @@ void __init tx4927_setup(void) | |||
169 | txx9_gpio_init(TX4927_PIO_REG & 0xfffffffffULL, 0, TX4927_NUM_PIO); | 195 | txx9_gpio_init(TX4927_PIO_REG & 0xfffffffffULL, 0, TX4927_NUM_PIO); |
170 | __raw_writel(0, &tx4927_pioptr->maskcpu); | 196 | __raw_writel(0, &tx4927_pioptr->maskcpu); |
171 | __raw_writel(0, &tx4927_pioptr->maskext); | 197 | __raw_writel(0, &tx4927_pioptr->maskext); |
198 | |||
199 | _machine_restart = tx4927_machine_restart; | ||
172 | } | 200 | } |
173 | 201 | ||
174 | void __init tx4927_time_init(unsigned int tmrnr) | 202 | void __init tx4927_time_init(unsigned int tmrnr) |
diff --git a/arch/mips/txx9/generic/setup_tx4938.c b/arch/mips/txx9/generic/setup_tx4938.c index 630a7aac61f6..4fbc85a8597f 100644 --- a/arch/mips/txx9/generic/setup_tx4938.c +++ b/arch/mips/txx9/generic/setup_tx4938.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
16 | #include <linux/param.h> | 16 | #include <linux/param.h> |
17 | #include <linux/mtd/physmap.h> | 17 | #include <linux/mtd/physmap.h> |
18 | #include <asm/reboot.h> | ||
18 | #include <asm/txx9irq.h> | 19 | #include <asm/txx9irq.h> |
19 | #include <asm/txx9tmr.h> | 20 | #include <asm/txx9tmr.h> |
20 | #include <asm/txx9pio.h> | 21 | #include <asm/txx9pio.h> |
@@ -23,6 +24,10 @@ | |||
23 | 24 | ||
24 | static void __init tx4938_wdr_init(void) | 25 | static void __init tx4938_wdr_init(void) |
25 | { | 26 | { |
27 | /* report watchdog reset status */ | ||
28 | if (____raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_WDRST) | ||
29 | pr_warning("Watchdog reset detected at 0x%lx\n", | ||
30 | read_c0_errorepc()); | ||
26 | /* clear WatchDogReset (W1C) */ | 31 | /* clear WatchDogReset (W1C) */ |
27 | tx4938_ccfg_set(TX4938_CCFG_WDRST); | 32 | tx4938_ccfg_set(TX4938_CCFG_WDRST); |
28 | /* do reset on watchdog */ | 33 | /* do reset on watchdog */ |
@@ -34,6 +39,27 @@ void __init tx4938_wdt_init(void) | |||
34 | txx9_wdt_init(TX4938_TMR_REG(2) & 0xfffffffffULL); | 39 | txx9_wdt_init(TX4938_TMR_REG(2) & 0xfffffffffULL); |
35 | } | 40 | } |
36 | 41 | ||
42 | static void tx4938_machine_restart(char *command) | ||
43 | { | ||
44 | local_irq_disable(); | ||
45 | pr_emerg("Rebooting (with %s watchdog reset)...\n", | ||
46 | (____raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_WDREXEN) ? | ||
47 | "external" : "internal"); | ||
48 | /* clear watchdog status */ | ||
49 | tx4938_ccfg_set(TX4938_CCFG_WDRST); /* W1C */ | ||
50 | txx9_wdt_now(TX4938_TMR_REG(2) & 0xfffffffffULL); | ||
51 | while (!(____raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_WDRST)) | ||
52 | ; | ||
53 | mdelay(10); | ||
54 | if (____raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_WDREXEN) { | ||
55 | pr_emerg("Rebooting (with internal watchdog reset)...\n"); | ||
56 | /* External WDRST failed. Do internal watchdog reset */ | ||
57 | tx4938_ccfg_clear(TX4938_CCFG_WDREXEN); | ||
58 | } | ||
59 | /* fallback */ | ||
60 | (*_machine_halt)(); | ||
61 | } | ||
62 | |||
37 | static struct resource tx4938_sdram_resource[4]; | 63 | static struct resource tx4938_sdram_resource[4]; |
38 | static struct resource tx4938_sram_resource; | 64 | static struct resource tx4938_sram_resource; |
39 | 65 | ||
@@ -229,6 +255,8 @@ void __init tx4938_setup(void) | |||
229 | TX4938_CLKCTR_ETH1CKD); | 255 | TX4938_CLKCTR_ETH1CKD); |
230 | } | 256 | } |
231 | } | 257 | } |
258 | |||
259 | _machine_restart = tx4938_machine_restart; | ||
232 | } | 260 | } |
233 | 261 | ||
234 | void __init tx4938_time_init(unsigned int tmrnr) | 262 | void __init tx4938_time_init(unsigned int tmrnr) |
diff --git a/include/asm-mips/txx9/generic.h b/include/asm-mips/txx9/generic.h index 1982c4437b1d..1e1a9f2d2379 100644 --- a/include/asm-mips/txx9/generic.h +++ b/include/asm-mips/txx9/generic.h | |||
@@ -45,6 +45,7 @@ extern int (*txx9_irq_dispatch)(int pending); | |||
45 | char *prom_getcmdline(void); | 45 | char *prom_getcmdline(void); |
46 | const char *prom_getenv(const char *name); | 46 | const char *prom_getenv(const char *name); |
47 | void txx9_wdt_init(unsigned long base); | 47 | void txx9_wdt_init(unsigned long base); |
48 | void txx9_wdt_now(unsigned long base); | ||
48 | void txx9_spi_init(int busid, unsigned long base, int irq); | 49 | void txx9_spi_init(int busid, unsigned long base, int irq); |
49 | void txx9_ethaddr_init(unsigned int id, unsigned char *ethaddr); | 50 | void txx9_ethaddr_init(unsigned int id, unsigned char *ethaddr); |
50 | void txx9_sio_init(unsigned long baseaddr, int irq, | 51 | void txx9_sio_init(unsigned long baseaddr, int irq, |