aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAtsushi Nemoto <anemo@mba.ocn.ne.jp>2008-08-19 09:55:15 -0400
committerRalf Baechle <ralf@linux-mips.org>2008-10-11 11:18:44 -0400
commit496a3b5c2c188e8af07261792b3d4e6cf1c1dab9 (patch)
tree8b84a2f249c27d6804b3db9068f679d178c8d504
parentd75a40e90e9eb08c2159e719a90a7922dab231d3 (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.c15
-rw-r--r--arch/mips/txx9/generic/setup_tx4927.c28
-rw-r--r--arch/mips/txx9/generic/setup_tx4938.c28
-rw-r--r--include/asm-mips/txx9/generic.h1
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
448void 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 */
448void __init txx9_spi_init(int busid, unsigned long base, int irq) 463void __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
24static void __init tx4927_wdr_init(void) 25static 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
42static 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
37static struct resource tx4927_sdram_resource[4]; 63static struct resource tx4927_sdram_resource[4];
38 64
39void __init tx4927_setup(void) 65void __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
174void __init tx4927_time_init(unsigned int tmrnr) 202void __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
24static void __init tx4938_wdr_init(void) 25static 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
42static 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
37static struct resource tx4938_sdram_resource[4]; 63static struct resource tx4938_sdram_resource[4];
38static struct resource tx4938_sram_resource; 64static 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
234void __init tx4938_time_init(unsigned int tmrnr) 262void __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);
45char *prom_getcmdline(void); 45char *prom_getcmdline(void);
46const char *prom_getenv(const char *name); 46const char *prom_getenv(const char *name);
47void txx9_wdt_init(unsigned long base); 47void txx9_wdt_init(unsigned long base);
48void txx9_wdt_now(unsigned long base);
48void txx9_spi_init(int busid, unsigned long base, int irq); 49void txx9_spi_init(int busid, unsigned long base, int irq);
49void txx9_ethaddr_init(unsigned int id, unsigned char *ethaddr); 50void txx9_ethaddr_init(unsigned int id, unsigned char *ethaddr);
50void txx9_sio_init(unsigned long baseaddr, int irq, 51void txx9_sio_init(unsigned long baseaddr, int irq,