aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/txx9
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/txx9')
-rw-r--r--arch/mips/txx9/Kconfig24
-rw-r--r--arch/mips/txx9/generic/Makefile2
-rw-r--r--arch/mips/txx9/generic/irq_tx4927.c11
-rw-r--r--arch/mips/txx9/generic/irq_tx4938.c11
-rw-r--r--arch/mips/txx9/generic/irq_tx4939.c215
-rw-r--r--arch/mips/txx9/generic/setup.c431
-rw-r--r--arch/mips/txx9/generic/setup_tx3927.c37
-rw-r--r--arch/mips/txx9/generic/setup_tx4927.c97
-rw-r--r--arch/mips/txx9/generic/setup_tx4938.c122
-rw-r--r--arch/mips/txx9/generic/setup_tx4939.c506
-rw-r--r--arch/mips/txx9/generic/spi_eeprom.c (renamed from arch/mips/txx9/rbtx4938/spi_eeprom.c)28
-rw-r--r--arch/mips/txx9/jmr3927/prom.c1
-rw-r--r--arch/mips/txx9/jmr3927/setup.c25
-rw-r--r--arch/mips/txx9/rbtx4927/irq.c11
-rw-r--r--arch/mips/txx9/rbtx4927/prom.c1
-rw-r--r--arch/mips/txx9/rbtx4927/setup.c25
-rw-r--r--arch/mips/txx9/rbtx4938/Makefile2
-rw-r--r--arch/mips/txx9/rbtx4938/irq.c8
-rw-r--r--arch/mips/txx9/rbtx4938/prom.c3
-rw-r--r--arch/mips/txx9/rbtx4938/setup.c63
-rw-r--r--arch/mips/txx9/rbtx4939/Makefile3
-rw-r--r--arch/mips/txx9/rbtx4939/irq.c96
-rw-r--r--arch/mips/txx9/rbtx4939/prom.c17
-rw-r--r--arch/mips/txx9/rbtx4939/setup.c307
24 files changed, 1959 insertions, 87 deletions
diff --git a/arch/mips/txx9/Kconfig b/arch/mips/txx9/Kconfig
index 840fe757c48d..17052db4161d 100644
--- a/arch/mips/txx9/Kconfig
+++ b/arch/mips/txx9/Kconfig
@@ -45,6 +45,14 @@ config TOSHIBA_RBTX4938
45 This Toshiba board is based on the TX4938 processor. Say Y here to 45 This Toshiba board is based on the TX4938 processor. Say Y here to
46 support this machine type 46 support this machine type
47 47
48config TOSHIBA_RBTX4939
49 bool "Toshiba RBTX4939 bobard"
50 depends on MACH_TX49XX
51 select SOC_TX4939
52 help
53 This Toshiba board is based on the TX4939 processor. Say Y here to
54 support this machine type
55
48config SOC_TX3927 56config SOC_TX3927
49 bool 57 bool
50 select CEVT_TXX9 58 select CEVT_TXX9
@@ -71,6 +79,13 @@ config SOC_TX4938
71 select PCI_TX4927 79 select PCI_TX4927
72 select GPIO_TXX9 80 select GPIO_TXX9
73 81
82config SOC_TX4939
83 bool
84 select CEVT_TXX9
85 select HAS_TXX9_SERIAL
86 select HW_HAS_PCI
87 select PCI_TX4927
88
74config TOSHIBA_FPCIB0 89config TOSHIBA_FPCIB0
75 bool "FPCIB0 Backplane Support" 90 bool "FPCIB0 Backplane Support"
76 depends on PCI && MACH_TXX9 91 depends on PCI && MACH_TXX9
@@ -94,16 +109,11 @@ config TOSHIBA_RBTX4938_MPLEX_NAND
94 bool "NAND" 109 bool "NAND"
95config TOSHIBA_RBTX4938_MPLEX_ATA 110config TOSHIBA_RBTX4938_MPLEX_ATA
96 bool "ATA" 111 bool "ATA"
112config TOSHIBA_RBTX4938_MPLEX_KEEP
113 bool "Keep firmware settings"
97 114
98endchoice 115endchoice
99 116
100config TX4938_NAND_BOOT
101 depends on EXPERIMENTAL && TOSHIBA_RBTX4938_MPLEX_NAND
102 bool "NAND Boot Support (EXPERIMENTAL)"
103 help
104 This is only for Toshiba RBTX4938 reference board, which has NAND IPL.
105 Select this option if you need to use NAND boot.
106
107endif 117endif
108 118
109config PCI_TX4927 119config PCI_TX4927
diff --git a/arch/mips/txx9/generic/Makefile b/arch/mips/txx9/generic/Makefile
index 9bb34af26b73..0030d23bef5b 100644
--- a/arch/mips/txx9/generic/Makefile
+++ b/arch/mips/txx9/generic/Makefile
@@ -7,6 +7,8 @@ obj-$(CONFIG_PCI) += pci.o
7obj-$(CONFIG_SOC_TX3927) += setup_tx3927.o irq_tx3927.o 7obj-$(CONFIG_SOC_TX3927) += setup_tx3927.o irq_tx3927.o
8obj-$(CONFIG_SOC_TX4927) += mem_tx4927.o setup_tx4927.o irq_tx4927.o 8obj-$(CONFIG_SOC_TX4927) += mem_tx4927.o setup_tx4927.o irq_tx4927.o
9obj-$(CONFIG_SOC_TX4938) += mem_tx4927.o setup_tx4938.o irq_tx4938.o 9obj-$(CONFIG_SOC_TX4938) += mem_tx4927.o setup_tx4938.o irq_tx4938.o
10obj-$(CONFIG_SOC_TX4939) += setup_tx4939.o irq_tx4939.o
10obj-$(CONFIG_TOSHIBA_FPCIB0) += smsc_fdc37m81x.o 11obj-$(CONFIG_TOSHIBA_FPCIB0) += smsc_fdc37m81x.o
12obj-$(CONFIG_SPI) += spi_eeprom.o
11 13
12EXTRA_CFLAGS += -Werror 14EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/txx9/generic/irq_tx4927.c b/arch/mips/txx9/generic/irq_tx4927.c
index cbea1fdde82b..ad2870def8f1 100644
--- a/arch/mips/txx9/generic/irq_tx4927.c
+++ b/arch/mips/txx9/generic/irq_tx4927.c
@@ -30,8 +30,19 @@
30 30
31void __init tx4927_irq_init(void) 31void __init tx4927_irq_init(void)
32{ 32{
33 int i;
34
33 mips_cpu_irq_init(); 35 mips_cpu_irq_init();
34 txx9_irq_init(TX4927_IRC_REG & 0xfffffffffULL); 36 txx9_irq_init(TX4927_IRC_REG & 0xfffffffffULL);
35 set_irq_chained_handler(MIPS_CPU_IRQ_BASE + TX4927_IRC_INT, 37 set_irq_chained_handler(MIPS_CPU_IRQ_BASE + TX4927_IRC_INT,
36 handle_simple_irq); 38 handle_simple_irq);
39 /* raise priority for errors, timers, SIO */
40 txx9_irq_set_pri(TX4927_IR_ECCERR, 7);
41 txx9_irq_set_pri(TX4927_IR_WTOERR, 7);
42 txx9_irq_set_pri(TX4927_IR_PCIERR, 7);
43 txx9_irq_set_pri(TX4927_IR_PCIPME, 7);
44 for (i = 0; i < TX4927_NUM_IR_TMR; i++)
45 txx9_irq_set_pri(TX4927_IR_TMR(i), 6);
46 for (i = 0; i < TX4927_NUM_IR_SIO; i++)
47 txx9_irq_set_pri(TX4927_IR_SIO(i), 5);
37} 48}
diff --git a/arch/mips/txx9/generic/irq_tx4938.c b/arch/mips/txx9/generic/irq_tx4938.c
index 6eac684bf190..025ae11359a8 100644
--- a/arch/mips/txx9/generic/irq_tx4938.c
+++ b/arch/mips/txx9/generic/irq_tx4938.c
@@ -18,8 +18,19 @@
18 18
19void __init tx4938_irq_init(void) 19void __init tx4938_irq_init(void)
20{ 20{
21 int i;
22
21 mips_cpu_irq_init(); 23 mips_cpu_irq_init();
22 txx9_irq_init(TX4938_IRC_REG & 0xfffffffffULL); 24 txx9_irq_init(TX4938_IRC_REG & 0xfffffffffULL);
23 set_irq_chained_handler(MIPS_CPU_IRQ_BASE + TX4938_IRC_INT, 25 set_irq_chained_handler(MIPS_CPU_IRQ_BASE + TX4938_IRC_INT,
24 handle_simple_irq); 26 handle_simple_irq);
27 /* raise priority for errors, timers, SIO */
28 txx9_irq_set_pri(TX4938_IR_ECCERR, 7);
29 txx9_irq_set_pri(TX4938_IR_WTOERR, 7);
30 txx9_irq_set_pri(TX4938_IR_PCIERR, 7);
31 txx9_irq_set_pri(TX4938_IR_PCIPME, 7);
32 for (i = 0; i < TX4938_NUM_IR_TMR; i++)
33 txx9_irq_set_pri(TX4938_IR_TMR(i), 6);
34 for (i = 0; i < TX4938_NUM_IR_SIO; i++)
35 txx9_irq_set_pri(TX4938_IR_SIO(i), 5);
25} 36}
diff --git a/arch/mips/txx9/generic/irq_tx4939.c b/arch/mips/txx9/generic/irq_tx4939.c
new file mode 100644
index 000000000000..013213a8706b
--- /dev/null
+++ b/arch/mips/txx9/generic/irq_tx4939.c
@@ -0,0 +1,215 @@
1/*
2 * TX4939 irq routines
3 * Based on linux/arch/mips/kernel/irq_txx9.c,
4 * and RBTX49xx patch from CELF patch archive.
5 *
6 * Copyright 2001, 2003-2005 MontaVista Software Inc.
7 * Author: MontaVista Software, Inc.
8 * ahennessy@mvista.com
9 * source@mvista.com
10 * Copyright (C) 2000-2001,2005-2007 Toshiba Corporation
11 *
12 * This file is subject to the terms and conditions of the GNU General Public
13 * License. See the file "COPYING" in the main directory of this archive
14 * for more details.
15 */
16/*
17 * TX4939 defines 64 IRQs.
18 * Similer to irq_txx9.c but different register layouts.
19 */
20#include <linux/init.h>
21#include <linux/interrupt.h>
22#include <linux/types.h>
23#include <asm/irq_cpu.h>
24#include <asm/txx9irq.h>
25#include <asm/txx9/tx4939.h>
26
27/* IRCER : Int. Control Enable */
28#define TXx9_IRCER_ICE 0x00000001
29
30/* IRCR : Int. Control */
31#define TXx9_IRCR_LOW 0x00000000
32#define TXx9_IRCR_HIGH 0x00000001
33#define TXx9_IRCR_DOWN 0x00000002
34#define TXx9_IRCR_UP 0x00000003
35#define TXx9_IRCR_EDGE(cr) ((cr) & 0x00000002)
36
37/* IRSCR : Int. Status Control */
38#define TXx9_IRSCR_EIClrE 0x00000100
39#define TXx9_IRSCR_EIClr_MASK 0x0000000f
40
41/* IRCSR : Int. Current Status */
42#define TXx9_IRCSR_IF 0x00010000
43
44#define irc_dlevel 0
45#define irc_elevel 1
46
47static struct {
48 unsigned char level;
49 unsigned char mode;
50} tx4939irq[TX4939_NUM_IR] __read_mostly;
51
52static void tx4939_irq_unmask(unsigned int irq)
53{
54 unsigned int irq_nr = irq - TXX9_IRQ_BASE;
55 u32 __iomem *lvlp;
56 int ofs;
57 if (irq_nr < 32) {
58 irq_nr--;
59 lvlp = &tx4939_ircptr->lvl[(irq_nr % 16) / 2].r;
60 } else {
61 irq_nr -= 32;
62 lvlp = &tx4939_ircptr->lvl[8 + (irq_nr % 16) / 2].r;
63 }
64 ofs = (irq_nr & 16) + (irq_nr & 1) * 8;
65 __raw_writel((__raw_readl(lvlp) & ~(0xff << ofs))
66 | (tx4939irq[irq_nr].level << ofs),
67 lvlp);
68}
69
70static inline void tx4939_irq_mask(unsigned int irq)
71{
72 unsigned int irq_nr = irq - TXX9_IRQ_BASE;
73 u32 __iomem *lvlp;
74 int ofs;
75 if (irq_nr < 32) {
76 irq_nr--;
77 lvlp = &tx4939_ircptr->lvl[(irq_nr % 16) / 2].r;
78 } else {
79 irq_nr -= 32;
80 lvlp = &tx4939_ircptr->lvl[8 + (irq_nr % 16) / 2].r;
81 }
82 ofs = (irq_nr & 16) + (irq_nr & 1) * 8;
83 __raw_writel((__raw_readl(lvlp) & ~(0xff << ofs))
84 | (irc_dlevel << ofs),
85 lvlp);
86 mmiowb();
87}
88
89static void tx4939_irq_mask_ack(unsigned int irq)
90{
91 unsigned int irq_nr = irq - TXX9_IRQ_BASE;
92
93 tx4939_irq_mask(irq);
94 if (TXx9_IRCR_EDGE(tx4939irq[irq_nr].mode)) {
95 irq_nr--;
96 /* clear edge detection */
97 __raw_writel((TXx9_IRSCR_EIClrE | (irq_nr & 0xf))
98 << (irq_nr & 0x10),
99 &tx4939_ircptr->edc.r);
100 }
101}
102
103static int tx4939_irq_set_type(unsigned int irq, unsigned int flow_type)
104{
105 unsigned int irq_nr = irq - TXX9_IRQ_BASE;
106 u32 cr;
107 u32 __iomem *crp;
108 int ofs;
109 int mode;
110
111 if (flow_type & IRQF_TRIGGER_PROBE)
112 return 0;
113 switch (flow_type & IRQF_TRIGGER_MASK) {
114 case IRQF_TRIGGER_RISING:
115 mode = TXx9_IRCR_UP;
116 break;
117 case IRQF_TRIGGER_FALLING:
118 mode = TXx9_IRCR_DOWN;
119 break;
120 case IRQF_TRIGGER_HIGH:
121 mode = TXx9_IRCR_HIGH;
122 break;
123 case IRQF_TRIGGER_LOW:
124 mode = TXx9_IRCR_LOW;
125 break;
126 default:
127 return -EINVAL;
128 }
129 if (irq_nr < 32) {
130 irq_nr--;
131 crp = &tx4939_ircptr->dm[(irq_nr & 8) >> 3].r;
132 } else {
133 irq_nr -= 32;
134 crp = &tx4939_ircptr->dm2[((irq_nr & 8) >> 3)].r;
135 }
136 ofs = (((irq_nr & 16) >> 1) | (irq_nr & (8 - 1))) * 2;
137 cr = __raw_readl(crp);
138 cr &= ~(0x3 << ofs);
139 cr |= (mode & 0x3) << ofs;
140 __raw_writel(cr, crp);
141 tx4939irq[irq_nr].mode = mode;
142 return 0;
143}
144
145static struct irq_chip tx4939_irq_chip = {
146 .name = "TX4939",
147 .ack = tx4939_irq_mask_ack,
148 .mask = tx4939_irq_mask,
149 .mask_ack = tx4939_irq_mask_ack,
150 .unmask = tx4939_irq_unmask,
151 .set_type = tx4939_irq_set_type,
152};
153
154static int tx4939_irq_set_pri(int irc_irq, int new_pri)
155{
156 int old_pri;
157
158 if ((unsigned int)irc_irq >= TX4939_NUM_IR)
159 return 0;
160 old_pri = tx4939irq[irc_irq].level;
161 tx4939irq[irc_irq].level = new_pri;
162 return old_pri;
163}
164
165void __init tx4939_irq_init(void)
166{
167 int i;
168
169 mips_cpu_irq_init();
170 /* disable interrupt control */
171 __raw_writel(0, &tx4939_ircptr->den.r);
172 __raw_writel(0, &tx4939_ircptr->maskint.r);
173 __raw_writel(0, &tx4939_ircptr->maskext.r);
174 /* irq_base + 0 is not used */
175 for (i = 1; i < TX4939_NUM_IR; i++) {
176 tx4939irq[i].level = 4; /* middle level */
177 tx4939irq[i].mode = TXx9_IRCR_LOW;
178 set_irq_chip_and_handler(TXX9_IRQ_BASE + i,
179 &tx4939_irq_chip, handle_level_irq);
180 }
181
182 /* mask all IRC interrupts */
183 __raw_writel(0, &tx4939_ircptr->msk.r);
184 for (i = 0; i < 16; i++)
185 __raw_writel(0, &tx4939_ircptr->lvl[i].r);
186 /* setup IRC interrupt mode (Low Active) */
187 for (i = 0; i < 2; i++)
188 __raw_writel(0, &tx4939_ircptr->dm[i].r);
189 for (i = 0; i < 2; i++)
190 __raw_writel(0, &tx4939_ircptr->dm2[i].r);
191 /* enable interrupt control */
192 __raw_writel(TXx9_IRCER_ICE, &tx4939_ircptr->den.r);
193 __raw_writel(irc_elevel, &tx4939_ircptr->msk.r);
194
195 set_irq_chained_handler(MIPS_CPU_IRQ_BASE + TX4939_IRC_INT,
196 handle_simple_irq);
197
198 /* raise priority for errors, timers, sio */
199 tx4939_irq_set_pri(TX4939_IR_WTOERR, 7);
200 tx4939_irq_set_pri(TX4939_IR_PCIERR, 7);
201 tx4939_irq_set_pri(TX4939_IR_PCIPME, 7);
202 for (i = 0; i < TX4939_NUM_IR_TMR; i++)
203 tx4939_irq_set_pri(TX4939_IR_TMR(i), 6);
204 for (i = 0; i < TX4939_NUM_IR_SIO; i++)
205 tx4939_irq_set_pri(TX4939_IR_SIO(i), 5);
206}
207
208int tx4939_irq(void)
209{
210 u32 csr = __raw_readl(&tx4939_ircptr->cs.r);
211
212 if (likely(!(csr & TXx9_IRCSR_IF)))
213 return TXX9_IRQ_BASE + (csr & (TX4939_NUM_IR - 1));
214 return -1;
215}
diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c
index fe6bee09cece..5526375010f8 100644
--- a/arch/mips/txx9/generic/setup.c
+++ b/arch/mips/txx9/generic/setup.c
@@ -22,11 +22,16 @@
22#include <linux/gpio.h> 22#include <linux/gpio.h>
23#include <linux/platform_device.h> 23#include <linux/platform_device.h>
24#include <linux/serial_core.h> 24#include <linux/serial_core.h>
25#include <linux/mtd/physmap.h>
26#include <linux/leds.h>
25#include <asm/bootinfo.h> 27#include <asm/bootinfo.h>
26#include <asm/time.h> 28#include <asm/time.h>
27#include <asm/reboot.h> 29#include <asm/reboot.h>
30#include <asm/r4kcache.h>
31#include <asm/sections.h>
28#include <asm/txx9/generic.h> 32#include <asm/txx9/generic.h>
29#include <asm/txx9/pci.h> 33#include <asm/txx9/pci.h>
34#include <asm/txx9tmr.h>
30#ifdef CONFIG_CPU_TX49XX 35#ifdef CONFIG_CPU_TX49XX
31#include <asm/txx9/tx4938.h> 36#include <asm/txx9/tx4938.h>
32#endif 37#endif
@@ -67,7 +72,12 @@ unsigned int txx9_master_clock;
67unsigned int txx9_cpu_clock; 72unsigned int txx9_cpu_clock;
68unsigned int txx9_gbus_clock; 73unsigned int txx9_gbus_clock;
69 74
75#ifdef CONFIG_CPU_TX39XX
76/* don't enable by default - see errata */
77int txx9_ccfg_toeon __initdata;
78#else
70int txx9_ccfg_toeon __initdata = 1; 79int txx9_ccfg_toeon __initdata = 1;
80#endif
71 81
72/* Minimum CLK support */ 82/* Minimum CLK support */
73 83
@@ -119,39 +129,232 @@ int irq_to_gpio(unsigned irq)
119EXPORT_SYMBOL(irq_to_gpio); 129EXPORT_SYMBOL(irq_to_gpio);
120#endif 130#endif
121 131
122extern struct txx9_board_vec jmr3927_vec; 132#define BOARD_VEC(board) extern struct txx9_board_vec board;
123extern struct txx9_board_vec rbtx4927_vec; 133#include <asm/txx9/boards.h>
124extern struct txx9_board_vec rbtx4937_vec; 134#undef BOARD_VEC
125extern struct txx9_board_vec rbtx4938_vec;
126 135
127struct txx9_board_vec *txx9_board_vec __initdata; 136struct txx9_board_vec *txx9_board_vec __initdata;
128static char txx9_system_type[32]; 137static char txx9_system_type[32];
129 138
130void __init prom_init_cmdline(void) 139static struct txx9_board_vec *board_vecs[] __initdata = {
140#define BOARD_VEC(board) &board,
141#include <asm/txx9/boards.h>
142#undef BOARD_VEC
143};
144
145static struct txx9_board_vec *__init find_board_byname(const char *name)
146{
147 int i;
148
149 /* search board_vecs table */
150 for (i = 0; i < ARRAY_SIZE(board_vecs); i++) {
151 if (strstr(board_vecs[i]->system, name))
152 return board_vecs[i];
153 }
154 return NULL;
155}
156
157static void __init prom_init_cmdline(void)
131{ 158{
132 int argc = (int)fw_arg0; 159 int argc = (int)fw_arg0;
133 char **argv = (char **)fw_arg1; 160 int *argv32 = (int *)fw_arg1;
134 int i; /* Always ignore the "-c" at argv[0] */ 161 int i; /* Always ignore the "-c" at argv[0] */
135#ifdef CONFIG_64BIT 162 char builtin[CL_SIZE];
136 char *fixed_argv[32];
137 for (i = 0; i < argc; i++)
138 fixed_argv[i] = (char *)(long)(*((__s32 *)argv + i));
139 argv = fixed_argv;
140#endif
141 163
142 /* ignore all built-in args if any f/w args given */ 164 /* ignore all built-in args if any f/w args given */
143 if (argc > 1) 165 /*
144 *arcs_cmdline = '\0'; 166 * But if built-in strings was started with '+', append them
167 * to command line args. If built-in was started with '-',
168 * ignore all f/w args.
169 */
170 builtin[0] = '\0';
171 if (arcs_cmdline[0] == '+')
172 strcpy(builtin, arcs_cmdline + 1);
173 else if (arcs_cmdline[0] == '-') {
174 strcpy(builtin, arcs_cmdline + 1);
175 argc = 0;
176 } else if (argc <= 1)
177 strcpy(builtin, arcs_cmdline);
178 arcs_cmdline[0] = '\0';
145 179
146 for (i = 1; i < argc; i++) { 180 for (i = 1; i < argc; i++) {
181 char *str = (char *)(long)argv32[i];
147 if (i != 1) 182 if (i != 1)
148 strcat(arcs_cmdline, " "); 183 strcat(arcs_cmdline, " ");
149 strcat(arcs_cmdline, argv[i]); 184 if (strchr(str, ' ')) {
185 strcat(arcs_cmdline, "\"");
186 strcat(arcs_cmdline, str);
187 strcat(arcs_cmdline, "\"");
188 } else
189 strcat(arcs_cmdline, str);
190 }
191 /* append saved builtin args */
192 if (builtin[0]) {
193 if (arcs_cmdline[0])
194 strcat(arcs_cmdline, " ");
195 strcat(arcs_cmdline, builtin);
150 } 196 }
151} 197}
152 198
153void __init prom_init(void) 199static int txx9_ic_disable __initdata;
200static int txx9_dc_disable __initdata;
201
202#if defined(CONFIG_CPU_TX49XX)
203/* flush all cache on very early stage (before 4k_cache_init) */
204static void __init early_flush_dcache(void)
154{ 205{
206 unsigned int conf = read_c0_config();
207 unsigned int dc_size = 1 << (12 + ((conf & CONF_DC) >> 6));
208 unsigned int linesz = 32;
209 unsigned long addr, end;
210
211 end = INDEX_BASE + dc_size / 4;
212 /* 4way, waybit=0 */
213 for (addr = INDEX_BASE; addr < end; addr += linesz) {
214 cache_op(Index_Writeback_Inv_D, addr | 0);
215 cache_op(Index_Writeback_Inv_D, addr | 1);
216 cache_op(Index_Writeback_Inv_D, addr | 2);
217 cache_op(Index_Writeback_Inv_D, addr | 3);
218 }
219}
220
221static void __init txx9_cache_fixup(void)
222{
223 unsigned int conf;
224
225 conf = read_c0_config();
226 /* flush and disable */
227 if (txx9_ic_disable) {
228 conf |= TX49_CONF_IC;
229 write_c0_config(conf);
230 }
231 if (txx9_dc_disable) {
232 early_flush_dcache();
233 conf |= TX49_CONF_DC;
234 write_c0_config(conf);
235 }
236
237 /* enable cache */
238 conf = read_c0_config();
239 if (!txx9_ic_disable)
240 conf &= ~TX49_CONF_IC;
241 if (!txx9_dc_disable)
242 conf &= ~TX49_CONF_DC;
243 write_c0_config(conf);
244
245 if (conf & TX49_CONF_IC)
246 pr_info("TX49XX I-Cache disabled.\n");
247 if (conf & TX49_CONF_DC)
248 pr_info("TX49XX D-Cache disabled.\n");
249}
250#elif defined(CONFIG_CPU_TX39XX)
251/* flush all cache on very early stage (before tx39_cache_init) */
252static void __init early_flush_dcache(void)
253{
254 unsigned int conf = read_c0_config();
255 unsigned int dc_size = 1 << (10 + ((conf & TX39_CONF_DCS_MASK) >>
256 TX39_CONF_DCS_SHIFT));
257 unsigned int linesz = 16;
258 unsigned long addr, end;
259
260 end = INDEX_BASE + dc_size / 2;
261 /* 2way, waybit=0 */
262 for (addr = INDEX_BASE; addr < end; addr += linesz) {
263 cache_op(Index_Writeback_Inv_D, addr | 0);
264 cache_op(Index_Writeback_Inv_D, addr | 1);
265 }
266}
267
268static void __init txx9_cache_fixup(void)
269{
270 unsigned int conf;
271
272 conf = read_c0_config();
273 /* flush and disable */
274 if (txx9_ic_disable) {
275 conf &= ~TX39_CONF_ICE;
276 write_c0_config(conf);
277 }
278 if (txx9_dc_disable) {
279 early_flush_dcache();
280 conf &= ~TX39_CONF_DCE;
281 write_c0_config(conf);
282 }
283
284 /* enable cache */
285 conf = read_c0_config();
286 if (!txx9_ic_disable)
287 conf |= TX39_CONF_ICE;
288 if (!txx9_dc_disable)
289 conf |= TX39_CONF_DCE;
290 write_c0_config(conf);
291
292 if (!(conf & TX39_CONF_ICE))
293 pr_info("TX39XX I-Cache disabled.\n");
294 if (!(conf & TX39_CONF_DCE))
295 pr_info("TX39XX D-Cache disabled.\n");
296}
297#else
298static inline void txx9_cache_fixup(void)
299{
300}
301#endif
302
303static void __init preprocess_cmdline(void)
304{
305 char cmdline[CL_SIZE];
306 char *s;
307
308 strcpy(cmdline, arcs_cmdline);
309 s = cmdline;
310 arcs_cmdline[0] = '\0';
311 while (s && *s) {
312 char *str = strsep(&s, " ");
313 if (strncmp(str, "board=", 6) == 0) {
314 txx9_board_vec = find_board_byname(str + 6);
315 continue;
316 } else if (strncmp(str, "masterclk=", 10) == 0) {
317 unsigned long val;
318 if (strict_strtoul(str + 10, 10, &val) == 0)
319 txx9_master_clock = val;
320 continue;
321 } else if (strcmp(str, "icdisable") == 0) {
322 txx9_ic_disable = 1;
323 continue;
324 } else if (strcmp(str, "dcdisable") == 0) {
325 txx9_dc_disable = 1;
326 continue;
327 } else if (strcmp(str, "toeoff") == 0) {
328 txx9_ccfg_toeon = 0;
329 continue;
330 } else if (strcmp(str, "toeon") == 0) {
331 txx9_ccfg_toeon = 1;
332 continue;
333 }
334 if (arcs_cmdline[0])
335 strcat(arcs_cmdline, " ");
336 strcat(arcs_cmdline, str);
337 }
338
339 txx9_cache_fixup();
340}
341
342static void __init select_board(void)
343{
344 const char *envstr;
345
346 /* first, determine by "board=" argument in preprocess_cmdline() */
347 if (txx9_board_vec)
348 return;
349 /* next, determine by "board" envvar */
350 envstr = prom_getenv("board");
351 if (envstr) {
352 txx9_board_vec = find_board_byname(envstr);
353 if (txx9_board_vec)
354 return;
355 }
356
357 /* select "default" board */
155#ifdef CONFIG_CPU_TX39XX 358#ifdef CONFIG_CPU_TX39XX
156 txx9_board_vec = &jmr3927_vec; 359 txx9_board_vec = &jmr3927_vec;
157#endif 360#endif
@@ -170,8 +373,20 @@ void __init prom_init(void)
170 txx9_board_vec = &rbtx4938_vec; 373 txx9_board_vec = &rbtx4938_vec;
171 break; 374 break;
172#endif 375#endif
376#ifdef CONFIG_TOSHIBA_RBTX4939
377 case 0x4939:
378 txx9_board_vec = &rbtx4939_vec;
379 break;
380#endif
173 } 381 }
174#endif 382#endif
383}
384
385void __init prom_init(void)
386{
387 prom_init_cmdline();
388 preprocess_cmdline();
389 select_board();
175 390
176 strcpy(txx9_system_type, txx9_board_vec->system); 391 strcpy(txx9_system_type, txx9_board_vec->system);
177 392
@@ -180,6 +395,11 @@ void __init prom_init(void)
180 395
181void __init prom_free_prom_memory(void) 396void __init prom_free_prom_memory(void)
182{ 397{
398 unsigned long saddr = PAGE_SIZE;
399 unsigned long eaddr = __pa_symbol(&_text);
400
401 if (saddr < eaddr)
402 free_init_pages("prom memory", saddr, eaddr);
183} 403}
184 404
185const char *get_system_type(void) 405const char *get_system_type(void)
@@ -192,6 +412,21 @@ char * __init prom_getcmdline(void)
192 return &(arcs_cmdline[0]); 412 return &(arcs_cmdline[0]);
193} 413}
194 414
415const char *__init prom_getenv(const char *name)
416{
417 const s32 *str = (const s32 *)fw_arg2;
418
419 if (!str)
420 return NULL;
421 /* YAMON style ("name", "value" pairs) */
422 while (str[0] && str[1]) {
423 if (!strcmp((const char *)(unsigned long)str[0], name))
424 return (const char *)(unsigned long)str[1];
425 str += 2;
426 }
427 return NULL;
428}
429
195static void __noreturn txx9_machine_halt(void) 430static void __noreturn txx9_machine_halt(void)
196{ 431{
197 local_irq_disable(); 432 local_irq_disable();
@@ -222,6 +457,20 @@ void __init txx9_wdt_init(unsigned long base)
222 platform_device_register_simple("txx9wdt", -1, &res, 1); 457 platform_device_register_simple("txx9wdt", -1, &res, 1);
223} 458}
224 459
460void txx9_wdt_now(unsigned long base)
461{
462 struct txx9_tmr_reg __iomem *tmrptr =
463 ioremap(base, sizeof(struct txx9_tmr_reg));
464 /* disable watch dog timer */
465 __raw_writel(TXx9_TMWTMR_WDIS | TXx9_TMWTMR_TWC, &tmrptr->wtmr);
466 __raw_writel(0, &tmrptr->tcr);
467 /* kick watchdog */
468 __raw_writel(TXx9_TMWTMR_TWIE, &tmrptr->wtmr);
469 __raw_writel(1, &tmrptr->cpra); /* immediate */
470 __raw_writel(TXx9_TMTCR_TCE | TXx9_TMTCR_CCDE | TXx9_TMTCR_TMODE_WDOG,
471 &tmrptr->tcr);
472}
473
225/* SPI support */ 474/* SPI support */
226void __init txx9_spi_init(int busid, unsigned long base, int irq) 475void __init txx9_spi_init(int busid, unsigned long base, int irq)
227{ 476{
@@ -372,3 +621,153 @@ static unsigned long __swizzle_addr_none(unsigned long port)
372unsigned long (*__swizzle_addr_b)(unsigned long port) = __swizzle_addr_none; 621unsigned long (*__swizzle_addr_b)(unsigned long port) = __swizzle_addr_none;
373EXPORT_SYMBOL(__swizzle_addr_b); 622EXPORT_SYMBOL(__swizzle_addr_b);
374#endif 623#endif
624
625void __init txx9_physmap_flash_init(int no, unsigned long addr,
626 unsigned long size,
627 const struct physmap_flash_data *pdata)
628{
629#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
630 struct resource res = {
631 .start = addr,
632 .end = addr + size - 1,
633 .flags = IORESOURCE_MEM,
634 };
635 struct platform_device *pdev;
636#ifdef CONFIG_MTD_PARTITIONS
637 static struct mtd_partition parts[2];
638 struct physmap_flash_data pdata_part;
639
640 /* If this area contained boot area, make separate partition */
641 if (pdata->nr_parts == 0 && !pdata->parts &&
642 addr < 0x1fc00000 && addr + size > 0x1fc00000 &&
643 !parts[0].name) {
644 parts[0].name = "boot";
645 parts[0].offset = 0x1fc00000 - addr;
646 parts[0].size = addr + size - 0x1fc00000;
647 parts[1].name = "user";
648 parts[1].offset = 0;
649 parts[1].size = 0x1fc00000 - addr;
650 pdata_part = *pdata;
651 pdata_part.nr_parts = ARRAY_SIZE(parts);
652 pdata_part.parts = parts;
653 pdata = &pdata_part;
654 }
655#endif
656 pdev = platform_device_alloc("physmap-flash", no);
657 if (!pdev ||
658 platform_device_add_resources(pdev, &res, 1) ||
659 platform_device_add_data(pdev, pdata, sizeof(*pdata)) ||
660 platform_device_add(pdev))
661 platform_device_put(pdev);
662#endif
663}
664
665#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
666static DEFINE_SPINLOCK(txx9_iocled_lock);
667
668#define TXX9_IOCLED_MAXLEDS 8
669
670struct txx9_iocled_data {
671 struct gpio_chip chip;
672 u8 cur_val;
673 void __iomem *mmioaddr;
674 struct gpio_led_platform_data pdata;
675 struct gpio_led leds[TXX9_IOCLED_MAXLEDS];
676 char names[TXX9_IOCLED_MAXLEDS][32];
677};
678
679static int txx9_iocled_get(struct gpio_chip *chip, unsigned int offset)
680{
681 struct txx9_iocled_data *data =
682 container_of(chip, struct txx9_iocled_data, chip);
683 return data->cur_val & (1 << offset);
684}
685
686static void txx9_iocled_set(struct gpio_chip *chip, unsigned int offset,
687 int value)
688{
689 struct txx9_iocled_data *data =
690 container_of(chip, struct txx9_iocled_data, chip);
691 unsigned long flags;
692 spin_lock_irqsave(&txx9_iocled_lock, flags);
693 if (value)
694 data->cur_val |= 1 << offset;
695 else
696 data->cur_val &= ~(1 << offset);
697 writeb(data->cur_val, data->mmioaddr);
698 mmiowb();
699 spin_unlock_irqrestore(&txx9_iocled_lock, flags);
700}
701
702static int txx9_iocled_dir_in(struct gpio_chip *chip, unsigned int offset)
703{
704 return 0;
705}
706
707static int txx9_iocled_dir_out(struct gpio_chip *chip, unsigned int offset,
708 int value)
709{
710 txx9_iocled_set(chip, offset, value);
711 return 0;
712}
713
714void __init txx9_iocled_init(unsigned long baseaddr,
715 int basenum, unsigned int num, int lowactive,
716 const char *color, char **deftriggers)
717{
718 struct txx9_iocled_data *iocled;
719 struct platform_device *pdev;
720 int i;
721 static char *default_triggers[] __initdata = {
722 "heartbeat",
723 "ide-disk",
724 "nand-disk",
725 NULL,
726 };
727
728 if (!deftriggers)
729 deftriggers = default_triggers;
730 iocled = kzalloc(sizeof(*iocled), GFP_KERNEL);
731 if (!iocled)
732 return;
733 iocled->mmioaddr = ioremap(baseaddr, 1);
734 if (!iocled->mmioaddr)
735 return;
736 iocled->chip.get = txx9_iocled_get;
737 iocled->chip.set = txx9_iocled_set;
738 iocled->chip.direction_input = txx9_iocled_dir_in;
739 iocled->chip.direction_output = txx9_iocled_dir_out;
740 iocled->chip.label = "iocled";
741 iocled->chip.base = basenum;
742 iocled->chip.ngpio = num;
743 if (gpiochip_add(&iocled->chip))
744 return;
745 if (basenum < 0)
746 basenum = iocled->chip.base;
747
748 pdev = platform_device_alloc("leds-gpio", basenum);
749 if (!pdev)
750 return;
751 iocled->pdata.num_leds = num;
752 iocled->pdata.leds = iocled->leds;
753 for (i = 0; i < num; i++) {
754 struct gpio_led *led = &iocled->leds[i];
755 snprintf(iocled->names[i], sizeof(iocled->names[i]),
756 "iocled:%s:%u", color, i);
757 led->name = iocled->names[i];
758 led->gpio = basenum + i;
759 led->active_low = lowactive;
760 if (deftriggers && *deftriggers)
761 led->default_trigger = *deftriggers++;
762 }
763 pdev->dev.platform_data = &iocled->pdata;
764 if (platform_device_add(pdev))
765 platform_device_put(pdev);
766}
767#else /* CONFIG_LEDS_GPIO */
768void __init txx9_iocled_init(unsigned long baseaddr,
769 int basenum, unsigned int num, int lowactive,
770 const char *color, char **deftriggers)
771{
772}
773#endif /* CONFIG_LEDS_GPIO */
diff --git a/arch/mips/txx9/generic/setup_tx3927.c b/arch/mips/txx9/generic/setup_tx3927.c
index 7bd963d37fc3..9505d58454c8 100644
--- a/arch/mips/txx9/generic/setup_tx3927.c
+++ b/arch/mips/txx9/generic/setup_tx3927.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/io.h> 17#include <linux/io.h>
18#include <linux/mtd/physmap.h>
18#include <asm/mipsregs.h> 19#include <asm/mipsregs.h>
19#include <asm/txx9irq.h> 20#include <asm/txx9irq.h>
20#include <asm/txx9tmr.h> 21#include <asm/txx9tmr.h>
@@ -32,11 +33,6 @@ void __init tx3927_setup(void)
32 int i; 33 int i;
33 unsigned int conf; 34 unsigned int conf;
34 35
35 /* don't enable - see errata */
36 txx9_ccfg_toeon = 0;
37 if (strstr(prom_getcmdline(), "toeon") != NULL)
38 txx9_ccfg_toeon = 1;
39
40 txx9_reg_res_init(TX3927_REV_PCODE(), TX3927_REG_BASE, 36 txx9_reg_res_init(TX3927_REV_PCODE(), TX3927_REG_BASE,
41 TX3927_REG_SIZE); 37 TX3927_REG_SIZE);
42 38
@@ -99,16 +95,14 @@ void __init tx3927_setup(void)
99 txx9_gpio_init(TX3927_PIO_REG, 0, 16); 95 txx9_gpio_init(TX3927_PIO_REG, 0, 16);
100 96
101 conf = read_c0_conf(); 97 conf = read_c0_conf();
102 if (!(conf & TX39_CONF_ICE)) 98 if (conf & TX39_CONF_DCE) {
103 printk(KERN_INFO "TX3927 I-Cache disabled.\n"); 99 if (!(conf & TX39_CONF_WBON))
104 if (!(conf & TX39_CONF_DCE)) 100 pr_info("TX3927 D-Cache WriteThrough.\n");
105 printk(KERN_INFO "TX3927 D-Cache disabled.\n"); 101 else if (!(conf & TX39_CONF_CWFON))
106 else if (!(conf & TX39_CONF_WBON)) 102 pr_info("TX3927 D-Cache WriteBack.\n");
107 printk(KERN_INFO "TX3927 D-Cache WriteThrough.\n"); 103 else
108 else if (!(conf & TX39_CONF_CWFON)) 104 pr_info("TX3927 D-Cache WriteBack (CWF) .\n");
109 printk(KERN_INFO "TX3927 D-Cache WriteBack.\n"); 105 }
110 else
111 printk(KERN_INFO "TX3927 D-Cache WriteBack (CWF) .\n");
112} 106}
113 107
114void __init tx3927_time_init(unsigned int evt_tmrnr, unsigned int src_tmrnr) 108void __init tx3927_time_init(unsigned int evt_tmrnr, unsigned int src_tmrnr)
@@ -128,3 +122,16 @@ void __init tx3927_sio_init(unsigned int sclk, unsigned int cts_mask)
128 TXX9_IRQ_BASE + TX3927_IR_SIO(i), 122 TXX9_IRQ_BASE + TX3927_IR_SIO(i),
129 i, sclk, (1 << i) & cts_mask); 123 i, sclk, (1 << i) & cts_mask);
130} 124}
125
126void __init tx3927_mtd_init(int ch)
127{
128 struct physmap_flash_data pdata = {
129 .width = TX3927_ROMC_WIDTH(ch) / 8,
130 };
131 unsigned long start = txx9_ce_res[ch].start;
132 unsigned long size = txx9_ce_res[ch].end - start + 1;
133
134 if (!(tx3927_romcptr->cr[ch] & 0x8))
135 return; /* disabled */
136 txx9_physmap_flash_init(ch, start, size, &pdata);
137}
diff --git a/arch/mips/txx9/generic/setup_tx4927.c b/arch/mips/txx9/generic/setup_tx4927.c
index f80d4b7a694d..914e93c62639 100644
--- a/arch/mips/txx9/generic/setup_tx4927.c
+++ b/arch/mips/txx9/generic/setup_tx4927.c
@@ -14,6 +14,10 @@
14#include <linux/ioport.h> 14#include <linux/ioport.h>
15#include <linux/delay.h> 15#include <linux/delay.h>
16#include <linux/param.h> 16#include <linux/param.h>
17#include <linux/ptrace.h>
18#include <linux/mtd/physmap.h>
19#include <asm/reboot.h>
20#include <asm/traps.h>
17#include <asm/txx9irq.h> 21#include <asm/txx9irq.h>
18#include <asm/txx9tmr.h> 22#include <asm/txx9tmr.h>
19#include <asm/txx9pio.h> 23#include <asm/txx9pio.h>
@@ -22,6 +26,10 @@
22 26
23static void __init tx4927_wdr_init(void) 27static void __init tx4927_wdr_init(void)
24{ 28{
29 /* report watchdog reset status */
30 if (____raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_WDRST)
31 pr_warning("Watchdog reset detected at 0x%lx\n",
32 read_c0_errorepc());
25 /* clear WatchDogReset (W1C) */ 33 /* clear WatchDogReset (W1C) */
26 tx4927_ccfg_set(TX4927_CCFG_WDRST); 34 tx4927_ccfg_set(TX4927_CCFG_WDRST);
27 /* do reset on watchdog */ 35 /* do reset on watchdog */
@@ -33,6 +41,47 @@ void __init tx4927_wdt_init(void)
33 txx9_wdt_init(TX4927_TMR_REG(2) & 0xfffffffffULL); 41 txx9_wdt_init(TX4927_TMR_REG(2) & 0xfffffffffULL);
34} 42}
35 43
44static void tx4927_machine_restart(char *command)
45{
46 local_irq_disable();
47 pr_emerg("Rebooting (with %s watchdog reset)...\n",
48 (____raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_WDREXEN) ?
49 "external" : "internal");
50 /* clear watchdog status */
51 tx4927_ccfg_set(TX4927_CCFG_WDRST); /* W1C */
52 txx9_wdt_now(TX4927_TMR_REG(2) & 0xfffffffffULL);
53 while (!(____raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_WDRST))
54 ;
55 mdelay(10);
56 if (____raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_WDREXEN) {
57 pr_emerg("Rebooting (with internal watchdog reset)...\n");
58 /* External WDRST failed. Do internal watchdog reset */
59 tx4927_ccfg_clear(TX4927_CCFG_WDREXEN);
60 }
61 /* fallback */
62 (*_machine_halt)();
63}
64
65void show_registers(struct pt_regs *regs);
66static int tx4927_be_handler(struct pt_regs *regs, int is_fixup)
67{
68 int data = regs->cp0_cause & 4;
69 console_verbose();
70 pr_err("%cBE exception at %#lx\n", data ? 'D' : 'I', regs->cp0_epc);
71 pr_err("ccfg:%llx, toea:%llx\n",
72 (unsigned long long)____raw_readq(&tx4927_ccfgptr->ccfg),
73 (unsigned long long)____raw_readq(&tx4927_ccfgptr->toea));
74#ifdef CONFIG_PCI
75 tx4927_report_pcic_status();
76#endif
77 show_registers(regs);
78 panic("BusError!");
79}
80static void __init tx4927_be_init(void)
81{
82 board_be_handler = tx4927_be_handler;
83}
84
36static struct resource tx4927_sdram_resource[4]; 85static struct resource tx4927_sdram_resource[4];
37 86
38void __init tx4927_setup(void) 87void __init tx4927_setup(void)
@@ -44,6 +93,7 @@ void __init tx4927_setup(void)
44 93
45 txx9_reg_res_init(TX4927_REV_PCODE(), TX4927_REG_BASE, 94 txx9_reg_res_init(TX4927_REV_PCODE(), TX4927_REG_BASE,
46 TX4927_REG_SIZE); 95 TX4927_REG_SIZE);
96 set_c0_config(TX49_CONF_CWFON);
47 97
48 /* SDRAMC,EBUSC are configured by PROM */ 98 /* SDRAMC,EBUSC are configured by PROM */
49 for (i = 0; i < 8; i++) { 99 for (i = 0; i < 8; i++) {
@@ -167,6 +217,9 @@ void __init tx4927_setup(void)
167 txx9_gpio_init(TX4927_PIO_REG & 0xfffffffffULL, 0, TX4927_NUM_PIO); 217 txx9_gpio_init(TX4927_PIO_REG & 0xfffffffffULL, 0, TX4927_NUM_PIO);
168 __raw_writel(0, &tx4927_pioptr->maskcpu); 218 __raw_writel(0, &tx4927_pioptr->maskcpu);
169 __raw_writel(0, &tx4927_pioptr->maskext); 219 __raw_writel(0, &tx4927_pioptr->maskext);
220
221 _machine_restart = tx4927_machine_restart;
222 board_be_init = tx4927_be_init;
170} 223}
171 224
172void __init tx4927_time_init(unsigned int tmrnr) 225void __init tx4927_time_init(unsigned int tmrnr)
@@ -186,3 +239,47 @@ void __init tx4927_sio_init(unsigned int sclk, unsigned int cts_mask)
186 TXX9_IRQ_BASE + TX4927_IR_SIO(i), 239 TXX9_IRQ_BASE + TX4927_IR_SIO(i),
187 i, sclk, (1 << i) & cts_mask); 240 i, sclk, (1 << i) & cts_mask);
188} 241}
242
243void __init tx4927_mtd_init(int ch)
244{
245 struct physmap_flash_data pdata = {
246 .width = TX4927_EBUSC_WIDTH(ch) / 8,
247 };
248 unsigned long start = txx9_ce_res[ch].start;
249 unsigned long size = txx9_ce_res[ch].end - start + 1;
250
251 if (!(TX4927_EBUSC_CR(ch) & 0x8))
252 return; /* disabled */
253 txx9_physmap_flash_init(ch, start, size, &pdata);
254}
255
256static void __init tx4927_stop_unused_modules(void)
257{
258 __u64 pcfg, rst = 0, ckd = 0;
259 char buf[128];
260
261 buf[0] = '\0';
262 local_irq_disable();
263 pcfg = ____raw_readq(&tx4927_ccfgptr->pcfg);
264 if (!(pcfg & TX4927_PCFG_SEL2)) {
265 rst |= TX4927_CLKCTR_ACLRST;
266 ckd |= TX4927_CLKCTR_ACLCKD;
267 strcat(buf, " ACLC");
268 }
269 if (rst | ckd) {
270 txx9_set64(&tx4927_ccfgptr->clkctr, rst);
271 txx9_set64(&tx4927_ccfgptr->clkctr, ckd);
272 }
273 local_irq_enable();
274 if (buf[0])
275 pr_info("%s: stop%s\n", txx9_pcode_str, buf);
276}
277
278static int __init tx4927_late_init(void)
279{
280 if (txx9_pcode != 0x4927)
281 return -ENODEV;
282 tx4927_stop_unused_modules();
283 return 0;
284}
285late_initcall(tx4927_late_init);
diff --git a/arch/mips/txx9/generic/setup_tx4938.c b/arch/mips/txx9/generic/setup_tx4938.c
index f3040b9ba059..af724e53ef91 100644
--- a/arch/mips/txx9/generic/setup_tx4938.c
+++ b/arch/mips/txx9/generic/setup_tx4938.c
@@ -14,6 +14,10 @@
14#include <linux/ioport.h> 14#include <linux/ioport.h>
15#include <linux/delay.h> 15#include <linux/delay.h>
16#include <linux/param.h> 16#include <linux/param.h>
17#include <linux/ptrace.h>
18#include <linux/mtd/physmap.h>
19#include <asm/reboot.h>
20#include <asm/traps.h>
17#include <asm/txx9irq.h> 21#include <asm/txx9irq.h>
18#include <asm/txx9tmr.h> 22#include <asm/txx9tmr.h>
19#include <asm/txx9pio.h> 23#include <asm/txx9pio.h>
@@ -22,6 +26,10 @@
22 26
23static void __init tx4938_wdr_init(void) 27static void __init tx4938_wdr_init(void)
24{ 28{
29 /* report watchdog reset status */
30 if (____raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_WDRST)
31 pr_warning("Watchdog reset detected at 0x%lx\n",
32 read_c0_errorepc());
25 /* clear WatchDogReset (W1C) */ 33 /* clear WatchDogReset (W1C) */
26 tx4938_ccfg_set(TX4938_CCFG_WDRST); 34 tx4938_ccfg_set(TX4938_CCFG_WDRST);
27 /* do reset on watchdog */ 35 /* do reset on watchdog */
@@ -33,6 +41,47 @@ void __init tx4938_wdt_init(void)
33 txx9_wdt_init(TX4938_TMR_REG(2) & 0xfffffffffULL); 41 txx9_wdt_init(TX4938_TMR_REG(2) & 0xfffffffffULL);
34} 42}
35 43
44static void tx4938_machine_restart(char *command)
45{
46 local_irq_disable();
47 pr_emerg("Rebooting (with %s watchdog reset)...\n",
48 (____raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_WDREXEN) ?
49 "external" : "internal");
50 /* clear watchdog status */
51 tx4938_ccfg_set(TX4938_CCFG_WDRST); /* W1C */
52 txx9_wdt_now(TX4938_TMR_REG(2) & 0xfffffffffULL);
53 while (!(____raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_WDRST))
54 ;
55 mdelay(10);
56 if (____raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_WDREXEN) {
57 pr_emerg("Rebooting (with internal watchdog reset)...\n");
58 /* External WDRST failed. Do internal watchdog reset */
59 tx4938_ccfg_clear(TX4938_CCFG_WDREXEN);
60 }
61 /* fallback */
62 (*_machine_halt)();
63}
64
65void show_registers(struct pt_regs *regs);
66static int tx4938_be_handler(struct pt_regs *regs, int is_fixup)
67{
68 int data = regs->cp0_cause & 4;
69 console_verbose();
70 pr_err("%cBE exception at %#lx\n", data ? 'D' : 'I', regs->cp0_epc);
71 pr_err("ccfg:%llx, toea:%llx\n",
72 (unsigned long long)____raw_readq(&tx4938_ccfgptr->ccfg),
73 (unsigned long long)____raw_readq(&tx4938_ccfgptr->toea));
74#ifdef CONFIG_PCI
75 tx4927_report_pcic_status();
76#endif
77 show_registers(regs);
78 panic("BusError!");
79}
80static void __init tx4938_be_init(void)
81{
82 board_be_handler = tx4938_be_handler;
83}
84
36static struct resource tx4938_sdram_resource[4]; 85static struct resource tx4938_sdram_resource[4];
37static struct resource tx4938_sram_resource; 86static struct resource tx4938_sram_resource;
38 87
@@ -47,6 +96,7 @@ void __init tx4938_setup(void)
47 96
48 txx9_reg_res_init(TX4938_REV_PCODE(), TX4938_REG_BASE, 97 txx9_reg_res_init(TX4938_REV_PCODE(), TX4938_REG_BASE,
49 TX4938_REG_SIZE); 98 TX4938_REG_SIZE);
99 set_c0_config(TX49_CONF_CWFON);
50 100
51 /* SDRAMC,EBUSC are configured by PROM */ 101 /* SDRAMC,EBUSC are configured by PROM */
52 for (i = 0; i < 8; i++) { 102 for (i = 0; i < 8; i++) {
@@ -227,6 +277,9 @@ void __init tx4938_setup(void)
227 TX4938_CLKCTR_ETH1CKD); 277 TX4938_CLKCTR_ETH1CKD);
228 } 278 }
229 } 279 }
280
281 _machine_restart = tx4938_machine_restart;
282 board_be_init = tx4938_be_init;
230} 283}
231 284
232void __init tx4938_time_init(unsigned int tmrnr) 285void __init tx4938_time_init(unsigned int tmrnr)
@@ -268,3 +321,72 @@ void __init tx4938_ethaddr_init(unsigned char *addr0, unsigned char *addr1)
268 if (addr1 && (pcfg & TX4938_PCFG_ETH1_SEL)) 321 if (addr1 && (pcfg & TX4938_PCFG_ETH1_SEL))
269 txx9_ethaddr_init(TXX9_IRQ_BASE + TX4938_IR_ETH1, addr1); 322 txx9_ethaddr_init(TXX9_IRQ_BASE + TX4938_IR_ETH1, addr1);
270} 323}
324
325void __init tx4938_mtd_init(int ch)
326{
327 struct physmap_flash_data pdata = {
328 .width = TX4938_EBUSC_WIDTH(ch) / 8,
329 };
330 unsigned long start = txx9_ce_res[ch].start;
331 unsigned long size = txx9_ce_res[ch].end - start + 1;
332
333 if (!(TX4938_EBUSC_CR(ch) & 0x8))
334 return; /* disabled */
335 txx9_physmap_flash_init(ch, start, size, &pdata);
336}
337
338static void __init tx4938_stop_unused_modules(void)
339{
340 __u64 pcfg, rst = 0, ckd = 0;
341 char buf[128];
342
343 buf[0] = '\0';
344 local_irq_disable();
345 pcfg = ____raw_readq(&tx4938_ccfgptr->pcfg);
346 switch (txx9_pcode) {
347 case 0x4937:
348 if (!(pcfg & TX4938_PCFG_SEL2)) {
349 rst |= TX4938_CLKCTR_ACLRST;
350 ckd |= TX4938_CLKCTR_ACLCKD;
351 strcat(buf, " ACLC");
352 }
353 break;
354 case 0x4938:
355 if (!(pcfg & TX4938_PCFG_SEL2) ||
356 (pcfg & TX4938_PCFG_ETH0_SEL)) {
357 rst |= TX4938_CLKCTR_ACLRST;
358 ckd |= TX4938_CLKCTR_ACLCKD;
359 strcat(buf, " ACLC");
360 }
361 if ((pcfg &
362 (TX4938_PCFG_ATA_SEL | TX4938_PCFG_ISA_SEL |
363 TX4938_PCFG_NDF_SEL))
364 != TX4938_PCFG_NDF_SEL) {
365 rst |= TX4938_CLKCTR_NDFRST;
366 ckd |= TX4938_CLKCTR_NDFCKD;
367 strcat(buf, " NDFMC");
368 }
369 if (!(pcfg & TX4938_PCFG_SPI_SEL)) {
370 rst |= TX4938_CLKCTR_SPIRST;
371 ckd |= TX4938_CLKCTR_SPICKD;
372 strcat(buf, " SPI");
373 }
374 break;
375 }
376 if (rst | ckd) {
377 txx9_set64(&tx4938_ccfgptr->clkctr, rst);
378 txx9_set64(&tx4938_ccfgptr->clkctr, ckd);
379 }
380 local_irq_enable();
381 if (buf[0])
382 pr_info("%s: stop%s\n", txx9_pcode_str, buf);
383}
384
385static int __init tx4938_late_init(void)
386{
387 if (txx9_pcode != 0x4937 && txx9_pcode != 0x4938)
388 return -ENODEV;
389 tx4938_stop_unused_modules();
390 return 0;
391}
392late_initcall(tx4938_late_init);
diff --git a/arch/mips/txx9/generic/setup_tx4939.c b/arch/mips/txx9/generic/setup_tx4939.c
new file mode 100644
index 000000000000..6c0049a5bbc1
--- /dev/null
+++ b/arch/mips/txx9/generic/setup_tx4939.c
@@ -0,0 +1,506 @@
1/*
2 * TX4939 setup routines
3 * Based on linux/arch/mips/txx9/generic/setup_tx4938.c,
4 * and RBTX49xx patch from CELF patch archive.
5 *
6 * 2003-2005 (c) MontaVista Software, Inc.
7 * (C) Copyright TOSHIBA CORPORATION 2000-2001, 2004-2007
8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file "COPYING" in the main directory of this archive
11 * for more details.
12 */
13#include <linux/init.h>
14#include <linux/ioport.h>
15#include <linux/delay.h>
16#include <linux/netdevice.h>
17#include <linux/notifier.h>
18#include <linux/sysdev.h>
19#include <linux/ethtool.h>
20#include <linux/param.h>
21#include <linux/ptrace.h>
22#include <linux/mtd/physmap.h>
23#include <linux/platform_device.h>
24#include <asm/bootinfo.h>
25#include <asm/reboot.h>
26#include <asm/traps.h>
27#include <asm/txx9irq.h>
28#include <asm/txx9tmr.h>
29#include <asm/txx9/generic.h>
30#include <asm/txx9/tx4939.h>
31
32static void __init tx4939_wdr_init(void)
33{
34 /* report watchdog reset status */
35 if (____raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_WDRST)
36 pr_warning("Watchdog reset detected at 0x%lx\n",
37 read_c0_errorepc());
38 /* clear WatchDogReset (W1C) */
39 tx4939_ccfg_set(TX4939_CCFG_WDRST);
40 /* do reset on watchdog */
41 tx4939_ccfg_set(TX4939_CCFG_WR);
42}
43
44void __init tx4939_wdt_init(void)
45{
46 txx9_wdt_init(TX4939_TMR_REG(2) & 0xfffffffffULL);
47}
48
49static void tx4939_machine_restart(char *command)
50{
51 local_irq_disable();
52 pr_emerg("Rebooting (with %s watchdog reset)...\n",
53 (____raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_WDREXEN) ?
54 "external" : "internal");
55 /* clear watchdog status */
56 tx4939_ccfg_set(TX4939_CCFG_WDRST); /* W1C */
57 txx9_wdt_now(TX4939_TMR_REG(2) & 0xfffffffffULL);
58 while (!(____raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_WDRST))
59 ;
60 mdelay(10);
61 if (____raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_WDREXEN) {
62 pr_emerg("Rebooting (with internal watchdog reset)...\n");
63 /* External WDRST failed. Do internal watchdog reset */
64 tx4939_ccfg_clear(TX4939_CCFG_WDREXEN);
65 }
66 /* fallback */
67 (*_machine_halt)();
68}
69
70void show_registers(struct pt_regs *regs);
71static int tx4939_be_handler(struct pt_regs *regs, int is_fixup)
72{
73 int data = regs->cp0_cause & 4;
74 console_verbose();
75 pr_err("%cBE exception at %#lx\n",
76 data ? 'D' : 'I', regs->cp0_epc);
77 pr_err("ccfg:%llx, toea:%llx\n",
78 (unsigned long long)____raw_readq(&tx4939_ccfgptr->ccfg),
79 (unsigned long long)____raw_readq(&tx4939_ccfgptr->toea));
80#ifdef CONFIG_PCI
81 tx4927_report_pcic_status();
82#endif
83 show_registers(regs);
84 panic("BusError!");
85}
86static void __init tx4939_be_init(void)
87{
88 board_be_handler = tx4939_be_handler;
89}
90
91static struct resource tx4939_sdram_resource[4];
92static struct resource tx4939_sram_resource;
93#define TX4939_SRAM_SIZE 0x800
94
95void __init tx4939_add_memory_regions(void)
96{
97 int i;
98 unsigned long start, size;
99 u64 win;
100
101 for (i = 0; i < 4; i++) {
102 if (!((__u32)____raw_readq(&tx4939_ddrcptr->winen) & (1 << i)))
103 continue;
104 win = ____raw_readq(&tx4939_ddrcptr->win[i]);
105 start = (unsigned long)(win >> 48);
106 size = (((unsigned long)(win >> 32) & 0xffff) + 1) - start;
107 add_memory_region(start << 20, size << 20, BOOT_MEM_RAM);
108 }
109}
110
111void __init tx4939_setup(void)
112{
113 int i;
114 __u32 divmode;
115 __u64 pcfg;
116 int cpuclk = 0;
117
118 txx9_reg_res_init(TX4939_REV_PCODE(), TX4939_REG_BASE,
119 TX4939_REG_SIZE);
120 set_c0_config(TX49_CONF_CWFON);
121
122 /* SDRAMC,EBUSC are configured by PROM */
123 for (i = 0; i < 4; i++) {
124 if (!(TX4939_EBUSC_CR(i) & 0x8))
125 continue; /* disabled */
126 txx9_ce_res[i].start = (unsigned long)TX4939_EBUSC_BA(i);
127 txx9_ce_res[i].end =
128 txx9_ce_res[i].start + TX4939_EBUSC_SIZE(i) - 1;
129 request_resource(&iomem_resource, &txx9_ce_res[i]);
130 }
131
132 /* clocks */
133 if (txx9_master_clock) {
134 /* calculate cpu_clock from master_clock */
135 divmode = (__u32)____raw_readq(&tx4939_ccfgptr->ccfg) &
136 TX4939_CCFG_MULCLK_MASK;
137 cpuclk = txx9_master_clock * 20 / 2;
138 switch (divmode) {
139 case TX4939_CCFG_MULCLK_8:
140 cpuclk = cpuclk / 3 * 4 /* / 6 * 8 */; break;
141 case TX4939_CCFG_MULCLK_9:
142 cpuclk = cpuclk / 2 * 3 /* / 6 * 9 */; break;
143 case TX4939_CCFG_MULCLK_10:
144 cpuclk = cpuclk / 3 * 5 /* / 6 * 10 */; break;
145 case TX4939_CCFG_MULCLK_11:
146 cpuclk = cpuclk / 6 * 11; break;
147 case TX4939_CCFG_MULCLK_12:
148 cpuclk = cpuclk * 2 /* / 6 * 12 */; break;
149 case TX4939_CCFG_MULCLK_13:
150 cpuclk = cpuclk / 6 * 13; break;
151 case TX4939_CCFG_MULCLK_14:
152 cpuclk = cpuclk / 3 * 7 /* / 6 * 14 */; break;
153 case TX4939_CCFG_MULCLK_15:
154 cpuclk = cpuclk / 2 * 5 /* / 6 * 15 */; break;
155 }
156 txx9_cpu_clock = cpuclk;
157 } else {
158 if (txx9_cpu_clock == 0)
159 txx9_cpu_clock = 400000000; /* 400MHz */
160 /* calculate master_clock from cpu_clock */
161 cpuclk = txx9_cpu_clock;
162 divmode = (__u32)____raw_readq(&tx4939_ccfgptr->ccfg) &
163 TX4939_CCFG_MULCLK_MASK;
164 switch (divmode) {
165 case TX4939_CCFG_MULCLK_8:
166 txx9_master_clock = cpuclk * 6 / 8; break;
167 case TX4939_CCFG_MULCLK_9:
168 txx9_master_clock = cpuclk * 6 / 9; break;
169 case TX4939_CCFG_MULCLK_10:
170 txx9_master_clock = cpuclk * 6 / 10; break;
171 case TX4939_CCFG_MULCLK_11:
172 txx9_master_clock = cpuclk * 6 / 11; break;
173 case TX4939_CCFG_MULCLK_12:
174 txx9_master_clock = cpuclk * 6 / 12; break;
175 case TX4939_CCFG_MULCLK_13:
176 txx9_master_clock = cpuclk * 6 / 13; break;
177 case TX4939_CCFG_MULCLK_14:
178 txx9_master_clock = cpuclk * 6 / 14; break;
179 case TX4939_CCFG_MULCLK_15:
180 txx9_master_clock = cpuclk * 6 / 15; break;
181 }
182 txx9_master_clock /= 10; /* * 2 / 20 */
183 }
184 /* calculate gbus_clock from cpu_clock */
185 divmode = (__u32)____raw_readq(&tx4939_ccfgptr->ccfg) &
186 TX4939_CCFG_YDIVMODE_MASK;
187 txx9_gbus_clock = txx9_cpu_clock;
188 switch (divmode) {
189 case TX4939_CCFG_YDIVMODE_2:
190 txx9_gbus_clock /= 2; break;
191 case TX4939_CCFG_YDIVMODE_3:
192 txx9_gbus_clock /= 3; break;
193 case TX4939_CCFG_YDIVMODE_5:
194 txx9_gbus_clock /= 5; break;
195 case TX4939_CCFG_YDIVMODE_6:
196 txx9_gbus_clock /= 6; break;
197 }
198 /* change default value to udelay/mdelay take reasonable time */
199 loops_per_jiffy = txx9_cpu_clock / HZ / 2;
200
201 /* CCFG */
202 tx4939_wdr_init();
203 /* clear BusErrorOnWrite flag (W1C) */
204 tx4939_ccfg_set(TX4939_CCFG_WDRST | TX4939_CCFG_BEOW);
205 /* enable Timeout BusError */
206 if (txx9_ccfg_toeon)
207 tx4939_ccfg_set(TX4939_CCFG_TOE);
208
209 /* DMA selection */
210 txx9_clear64(&tx4939_ccfgptr->pcfg, TX4939_PCFG_DMASEL_ALL);
211
212 /* Use external clock for external arbiter */
213 if (!(____raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_PCIARB))
214 txx9_clear64(&tx4939_ccfgptr->pcfg, TX4939_PCFG_PCICLKEN_ALL);
215
216 pr_info("%s -- %dMHz(M%dMHz,G%dMHz) CRIR:%08x CCFG:%llx PCFG:%llx\n",
217 txx9_pcode_str,
218 (cpuclk + 500000) / 1000000,
219 (txx9_master_clock + 500000) / 1000000,
220 (txx9_gbus_clock + 500000) / 1000000,
221 (__u32)____raw_readq(&tx4939_ccfgptr->crir),
222 (unsigned long long)____raw_readq(&tx4939_ccfgptr->ccfg),
223 (unsigned long long)____raw_readq(&tx4939_ccfgptr->pcfg));
224
225 pr_info("%s DDRC -- EN:%08x", txx9_pcode_str,
226 (__u32)____raw_readq(&tx4939_ddrcptr->winen));
227 for (i = 0; i < 4; i++) {
228 __u64 win = ____raw_readq(&tx4939_ddrcptr->win[i]);
229 if (!((__u32)____raw_readq(&tx4939_ddrcptr->winen) & (1 << i)))
230 continue; /* disabled */
231 printk(KERN_CONT " #%d:%016llx", i, (unsigned long long)win);
232 tx4939_sdram_resource[i].name = "DDR SDRAM";
233 tx4939_sdram_resource[i].start =
234 (unsigned long)(win >> 48) << 20;
235 tx4939_sdram_resource[i].end =
236 ((((unsigned long)(win >> 32) & 0xffff) + 1) <<
237 20) - 1;
238 tx4939_sdram_resource[i].flags = IORESOURCE_MEM;
239 request_resource(&iomem_resource, &tx4939_sdram_resource[i]);
240 }
241 printk(KERN_CONT "\n");
242
243 /* SRAM */
244 if (____raw_readq(&tx4939_sramcptr->cr) & 1) {
245 unsigned int size = TX4939_SRAM_SIZE;
246 tx4939_sram_resource.name = "SRAM";
247 tx4939_sram_resource.start =
248 (____raw_readq(&tx4939_sramcptr->cr) >> (39-11))
249 & ~(size - 1);
250 tx4939_sram_resource.end =
251 tx4939_sram_resource.start + TX4939_SRAM_SIZE - 1;
252 tx4939_sram_resource.flags = IORESOURCE_MEM;
253 request_resource(&iomem_resource, &tx4939_sram_resource);
254 }
255
256 /* TMR */
257 /* disable all timers */
258 for (i = 0; i < TX4939_NR_TMR; i++)
259 txx9_tmr_init(TX4939_TMR_REG(i) & 0xfffffffffULL);
260
261 /* DMA */
262 for (i = 0; i < 2; i++)
263 ____raw_writeq(TX4938_DMA_MCR_MSTEN,
264 (void __iomem *)(TX4939_DMA_REG(i) + 0x50));
265
266 /* set PCIC1 reset (required to prevent hangup on BIST) */
267 txx9_set64(&tx4939_ccfgptr->clkctr, TX4939_CLKCTR_PCI1RST);
268 pcfg = ____raw_readq(&tx4939_ccfgptr->pcfg);
269 if (pcfg & (TX4939_PCFG_ET0MODE | TX4939_PCFG_ET1MODE)) {
270 mdelay(1); /* at least 128 cpu clock */
271 /* clear PCIC1 reset */
272 txx9_clear64(&tx4939_ccfgptr->clkctr, TX4939_CLKCTR_PCI1RST);
273 } else {
274 pr_info("%s: stop PCIC1\n", txx9_pcode_str);
275 /* stop PCIC1 */
276 txx9_set64(&tx4939_ccfgptr->clkctr, TX4939_CLKCTR_PCI1CKD);
277 }
278 if (!(pcfg & TX4939_PCFG_ET0MODE)) {
279 pr_info("%s: stop ETH0\n", txx9_pcode_str);
280 txx9_set64(&tx4939_ccfgptr->clkctr, TX4939_CLKCTR_ETH0RST);
281 txx9_set64(&tx4939_ccfgptr->clkctr, TX4939_CLKCTR_ETH0CKD);
282 }
283 if (!(pcfg & TX4939_PCFG_ET1MODE)) {
284 pr_info("%s: stop ETH1\n", txx9_pcode_str);
285 txx9_set64(&tx4939_ccfgptr->clkctr, TX4939_CLKCTR_ETH1RST);
286 txx9_set64(&tx4939_ccfgptr->clkctr, TX4939_CLKCTR_ETH1CKD);
287 }
288
289 _machine_restart = tx4939_machine_restart;
290 board_be_init = tx4939_be_init;
291}
292
293void __init tx4939_time_init(unsigned int tmrnr)
294{
295 if (____raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_TINTDIS)
296 txx9_clockevent_init(TX4939_TMR_REG(tmrnr) & 0xfffffffffULL,
297 TXX9_IRQ_BASE + TX4939_IR_TMR(tmrnr),
298 TXX9_IMCLK);
299}
300
301void __init tx4939_sio_init(unsigned int sclk, unsigned int cts_mask)
302{
303 int i;
304 unsigned int ch_mask = 0;
305 __u64 pcfg = __raw_readq(&tx4939_ccfgptr->pcfg);
306
307 cts_mask |= ~1; /* only SIO0 have RTS/CTS */
308 if ((pcfg & TX4939_PCFG_SIO2MODE_MASK) != TX4939_PCFG_SIO2MODE_SIO0)
309 cts_mask |= 1 << 0; /* disable SIO0 RTS/CTS by PCFG setting */
310 if ((pcfg & TX4939_PCFG_SIO2MODE_MASK) != TX4939_PCFG_SIO2MODE_SIO2)
311 ch_mask |= 1 << 2; /* disable SIO2 by PCFG setting */
312 if (pcfg & TX4939_PCFG_SIO3MODE)
313 ch_mask |= 1 << 3; /* disable SIO3 by PCFG setting */
314 for (i = 0; i < 4; i++) {
315 if ((1 << i) & ch_mask)
316 continue;
317 txx9_sio_init(TX4939_SIO_REG(i) & 0xfffffffffULL,
318 TXX9_IRQ_BASE + TX4939_IR_SIO(i),
319 i, sclk, (1 << i) & cts_mask);
320 }
321}
322
323#if defined(CONFIG_TC35815) || defined(CONFIG_TC35815_MODULE)
324static int tx4939_get_eth_speed(struct net_device *dev)
325{
326 struct ethtool_cmd cmd = { ETHTOOL_GSET };
327 int speed = 100; /* default 100Mbps */
328 int err;
329 if (!dev->ethtool_ops || !dev->ethtool_ops->get_settings)
330 return speed;
331 err = dev->ethtool_ops->get_settings(dev, &cmd);
332 if (err < 0)
333 return speed;
334 speed = cmd.speed == SPEED_100 ? 100 : 10;
335 return speed;
336}
337static int tx4939_netdev_event(struct notifier_block *this,
338 unsigned long event,
339 void *ptr)
340{
341 struct net_device *dev = ptr;
342 if (event == NETDEV_CHANGE && netif_carrier_ok(dev)) {
343 __u64 bit = 0;
344 if (dev->irq == TXX9_IRQ_BASE + TX4939_IR_ETH(0))
345 bit = TX4939_PCFG_SPEED0;
346 else if (dev->irq == TXX9_IRQ_BASE + TX4939_IR_ETH(1))
347 bit = TX4939_PCFG_SPEED1;
348 if (bit) {
349 int speed = tx4939_get_eth_speed(dev);
350 if (speed == 100)
351 txx9_set64(&tx4939_ccfgptr->pcfg, bit);
352 else
353 txx9_clear64(&tx4939_ccfgptr->pcfg, bit);
354 }
355 }
356 return NOTIFY_DONE;
357}
358
359static struct notifier_block tx4939_netdev_notifier = {
360 .notifier_call = tx4939_netdev_event,
361 .priority = 1,
362};
363
364void __init tx4939_ethaddr_init(unsigned char *addr0, unsigned char *addr1)
365{
366 u64 pcfg = __raw_readq(&tx4939_ccfgptr->pcfg);
367
368 if (addr0 && (pcfg & TX4939_PCFG_ET0MODE))
369 txx9_ethaddr_init(TXX9_IRQ_BASE + TX4939_IR_ETH(0), addr0);
370 if (addr1 && (pcfg & TX4939_PCFG_ET1MODE))
371 txx9_ethaddr_init(TXX9_IRQ_BASE + TX4939_IR_ETH(1), addr1);
372 register_netdevice_notifier(&tx4939_netdev_notifier);
373}
374#else
375void __init tx4939_ethaddr_init(unsigned char *addr0, unsigned char *addr1)
376{
377}
378#endif
379
380void __init tx4939_mtd_init(int ch)
381{
382 struct physmap_flash_data pdata = {
383 .width = TX4939_EBUSC_WIDTH(ch) / 8,
384 };
385 unsigned long start = txx9_ce_res[ch].start;
386 unsigned long size = txx9_ce_res[ch].end - start + 1;
387
388 if (!(TX4939_EBUSC_CR(ch) & 0x8))
389 return; /* disabled */
390 txx9_physmap_flash_init(ch, start, size, &pdata);
391}
392
393#define TX4939_ATA_REG_PHYS(ch) (TX4939_ATA_REG(ch) & 0xfffffffffULL)
394void __init tx4939_ata_init(void)
395{
396 static struct resource ata0_res[] = {
397 {
398 .start = TX4939_ATA_REG_PHYS(0),
399 .end = TX4939_ATA_REG_PHYS(0) + 0x1000 - 1,
400 .flags = IORESOURCE_MEM,
401 }, {
402 .start = TXX9_IRQ_BASE + TX4939_IR_ATA(0),
403 .flags = IORESOURCE_IRQ,
404 },
405 };
406 static struct resource ata1_res[] = {
407 {
408 .start = TX4939_ATA_REG_PHYS(1),
409 .end = TX4939_ATA_REG_PHYS(1) + 0x1000 - 1,
410 .flags = IORESOURCE_MEM,
411 }, {
412 .start = TXX9_IRQ_BASE + TX4939_IR_ATA(1),
413 .flags = IORESOURCE_IRQ,
414 },
415 };
416 static struct platform_device ata0_dev = {
417 .name = "tx4939ide",
418 .id = 0,
419 .num_resources = ARRAY_SIZE(ata0_res),
420 .resource = ata0_res,
421 };
422 static struct platform_device ata1_dev = {
423 .name = "tx4939ide",
424 .id = 1,
425 .num_resources = ARRAY_SIZE(ata1_res),
426 .resource = ata1_res,
427 };
428 __u64 pcfg = __raw_readq(&tx4939_ccfgptr->pcfg);
429
430 if (pcfg & TX4939_PCFG_ATA0MODE)
431 platform_device_register(&ata0_dev);
432 if ((pcfg & (TX4939_PCFG_ATA1MODE |
433 TX4939_PCFG_ET1MODE |
434 TX4939_PCFG_ET0MODE)) == TX4939_PCFG_ATA1MODE)
435 platform_device_register(&ata1_dev);
436}
437
438static void __init tx4939_stop_unused_modules(void)
439{
440 __u64 pcfg, rst = 0, ckd = 0;
441 char buf[128];
442
443 buf[0] = '\0';
444 local_irq_disable();
445 pcfg = ____raw_readq(&tx4939_ccfgptr->pcfg);
446 if ((pcfg & TX4939_PCFG_I2SMODE_MASK) !=
447 TX4939_PCFG_I2SMODE_ACLC) {
448 rst |= TX4939_CLKCTR_ACLRST;
449 ckd |= TX4939_CLKCTR_ACLCKD;
450 strcat(buf, " ACLC");
451 }
452 if ((pcfg & TX4939_PCFG_I2SMODE_MASK) !=
453 TX4939_PCFG_I2SMODE_I2S &&
454 (pcfg & TX4939_PCFG_I2SMODE_MASK) !=
455 TX4939_PCFG_I2SMODE_I2S_ALT) {
456 rst |= TX4939_CLKCTR_I2SRST;
457 ckd |= TX4939_CLKCTR_I2SCKD;
458 strcat(buf, " I2S");
459 }
460 if (!(pcfg & TX4939_PCFG_ATA0MODE)) {
461 rst |= TX4939_CLKCTR_ATA0RST;
462 ckd |= TX4939_CLKCTR_ATA0CKD;
463 strcat(buf, " ATA0");
464 }
465 if (!(pcfg & TX4939_PCFG_ATA1MODE)) {
466 rst |= TX4939_CLKCTR_ATA1RST;
467 ckd |= TX4939_CLKCTR_ATA1CKD;
468 strcat(buf, " ATA1");
469 }
470 if (pcfg & TX4939_PCFG_SPIMODE) {
471 rst |= TX4939_CLKCTR_SPIRST;
472 ckd |= TX4939_CLKCTR_SPICKD;
473 strcat(buf, " SPI");
474 }
475 if (!(pcfg & (TX4939_PCFG_VSSMODE | TX4939_PCFG_VPSMODE))) {
476 rst |= TX4939_CLKCTR_VPCRST;
477 ckd |= TX4939_CLKCTR_VPCCKD;
478 strcat(buf, " VPC");
479 }
480 if ((pcfg & TX4939_PCFG_SIO2MODE_MASK) != TX4939_PCFG_SIO2MODE_SIO2) {
481 rst |= TX4939_CLKCTR_SIO2RST;
482 ckd |= TX4939_CLKCTR_SIO2CKD;
483 strcat(buf, " SIO2");
484 }
485 if (pcfg & TX4939_PCFG_SIO3MODE) {
486 rst |= TX4939_CLKCTR_SIO3RST;
487 ckd |= TX4939_CLKCTR_SIO3CKD;
488 strcat(buf, " SIO3");
489 }
490 if (rst | ckd) {
491 txx9_set64(&tx4939_ccfgptr->clkctr, rst);
492 txx9_set64(&tx4939_ccfgptr->clkctr, ckd);
493 }
494 local_irq_enable();
495 if (buf[0])
496 pr_info("%s: stop%s\n", txx9_pcode_str, buf);
497}
498
499static int __init tx4939_late_init(void)
500{
501 if (txx9_pcode != 0x4939)
502 return -ENODEV;
503 tx4939_stop_unused_modules();
504 return 0;
505}
506late_initcall(tx4939_late_init);
diff --git a/arch/mips/txx9/rbtx4938/spi_eeprom.c b/arch/mips/txx9/generic/spi_eeprom.c
index a7ea8b041c1d..75c347238f47 100644
--- a/arch/mips/txx9/rbtx4938/spi_eeprom.c
+++ b/arch/mips/txx9/generic/spi_eeprom.c
@@ -18,29 +18,31 @@
18#define AT250X0_PAGE_SIZE 8 18#define AT250X0_PAGE_SIZE 8
19 19
20/* register board information for at25 driver */ 20/* register board information for at25 driver */
21int __init spi_eeprom_register(int chipid) 21int __init spi_eeprom_register(int busid, int chipid, int size)
22{ 22{
23 static struct spi_eeprom eeprom = {
24 .name = "at250x0",
25 .byte_len = 128,
26 .page_size = AT250X0_PAGE_SIZE,
27 .flags = EE_ADDR1,
28 };
29 struct spi_board_info info = { 23 struct spi_board_info info = {
30 .modalias = "at25", 24 .modalias = "at25",
31 .max_speed_hz = 1500000, /* 1.5Mbps */ 25 .max_speed_hz = 1500000, /* 1.5Mbps */
32 .bus_num = 0, 26 .bus_num = busid,
33 .chip_select = chipid, 27 .chip_select = chipid,
34 .platform_data = &eeprom,
35 /* Mode 0: High-Active, Sample-Then-Shift */ 28 /* Mode 0: High-Active, Sample-Then-Shift */
36 }; 29 };
37 30 struct spi_eeprom *eeprom;
31 eeprom = kzalloc(sizeof(*eeprom), GFP_KERNEL);
32 if (!eeprom)
33 return -ENOMEM;
34 strcpy(eeprom->name, "at250x0");
35 eeprom->byte_len = size;
36 eeprom->page_size = AT250X0_PAGE_SIZE;
37 eeprom->flags = EE_ADDR1;
38 info.platform_data = eeprom;
38 return spi_register_board_info(&info, 1); 39 return spi_register_board_info(&info, 1);
39} 40}
40 41
41/* simple temporary spi driver to provide early access to seeprom. */ 42/* simple temporary spi driver to provide early access to seeprom. */
42 43
43static struct read_param { 44static struct read_param {
45 int busid;
44 int chipid; 46 int chipid;
45 int address; 47 int address;
46 unsigned char *buf; 48 unsigned char *buf;
@@ -57,7 +59,8 @@ static int __init early_seeprom_probe(struct spi_device *spi)
57 59
58 dev_info(&spi->dev, "spiclk %u KHz.\n", 60 dev_info(&spi->dev, "spiclk %u KHz.\n",
59 (spi->max_speed_hz + 500) / 1000); 61 (spi->max_speed_hz + 500) / 1000);
60 if (read_param->chipid != spi->chip_select) 62 if (read_param->busid != spi->master->bus_num ||
63 read_param->chipid != spi->chip_select)
61 return -ENODEV; 64 return -ENODEV;
62 while (len > 0) { 65 while (len > 0) {
63 /* spi_write_then_read can only work with small chunk */ 66 /* spi_write_then_read can only work with small chunk */
@@ -80,11 +83,12 @@ static struct spi_driver early_seeprom_driver __initdata = {
80 .probe = early_seeprom_probe, 83 .probe = early_seeprom_probe,
81}; 84};
82 85
83int __init spi_eeprom_read(int chipid, int address, 86int __init spi_eeprom_read(int busid, int chipid, int address,
84 unsigned char *buf, int len) 87 unsigned char *buf, int len)
85{ 88{
86 int ret; 89 int ret;
87 struct read_param param = { 90 struct read_param param = {
91 .busid = busid,
88 .chipid = chipid, 92 .chipid = chipid,
89 .address = address, 93 .address = address,
90 .buf = buf, 94 .buf = buf,
diff --git a/arch/mips/txx9/jmr3927/prom.c b/arch/mips/txx9/jmr3927/prom.c
index 70c4c8ec3e84..c899c0c087a0 100644
--- a/arch/mips/txx9/jmr3927/prom.c
+++ b/arch/mips/txx9/jmr3927/prom.c
@@ -47,7 +47,6 @@ void __init jmr3927_prom_init(void)
47 if ((tx3927_ccfgptr->ccfg & TX3927_CCFG_TLBOFF) == 0) 47 if ((tx3927_ccfgptr->ccfg & TX3927_CCFG_TLBOFF) == 0)
48 printk(KERN_ERR "TX3927 TLB off\n"); 48 printk(KERN_ERR "TX3927 TLB off\n");
49 49
50 prom_init_cmdline();
51 add_memory_region(0, JMR3927_SDRAM_SIZE, BOOT_MEM_RAM); 50 add_memory_region(0, JMR3927_SDRAM_SIZE, BOOT_MEM_RAM);
52 txx9_sio_putchar_init(TX3927_SIO_REG(1)); 51 txx9_sio_putchar_init(TX3927_SIO_REG(1));
53} 52}
diff --git a/arch/mips/txx9/jmr3927/setup.c b/arch/mips/txx9/jmr3927/setup.c
index 87db41be8a56..25e50a7be387 100644
--- a/arch/mips/txx9/jmr3927/setup.c
+++ b/arch/mips/txx9/jmr3927/setup.c
@@ -62,7 +62,6 @@ static void __init jmr3927_time_init(void)
62} 62}
63 63
64#define DO_WRITE_THROUGH 64#define DO_WRITE_THROUGH
65#define DO_ENABLE_CACHE
66 65
67static void jmr3927_board_init(void); 66static void jmr3927_board_init(void);
68 67
@@ -77,11 +76,6 @@ static void __init jmr3927_mem_setup(void)
77 /* cache setup */ 76 /* cache setup */
78 { 77 {
79 unsigned int conf; 78 unsigned int conf;
80#ifdef DO_ENABLE_CACHE
81 int mips_ic_disable = 0, mips_dc_disable = 0;
82#else
83 int mips_ic_disable = 1, mips_dc_disable = 1;
84#endif
85#ifdef DO_WRITE_THROUGH 79#ifdef DO_WRITE_THROUGH
86 int mips_config_cwfon = 0; 80 int mips_config_cwfon = 0;
87 int mips_config_wbon = 0; 81 int mips_config_wbon = 0;
@@ -91,10 +85,7 @@ static void __init jmr3927_mem_setup(void)
91#endif 85#endif
92 86
93 conf = read_c0_conf(); 87 conf = read_c0_conf();
94 conf &= ~(TX39_CONF_ICE | TX39_CONF_DCE | 88 conf &= ~(TX39_CONF_WBON | TX39_CONF_CWFON);
95 TX39_CONF_WBON | TX39_CONF_CWFON);
96 conf |= mips_ic_disable ? 0 : TX39_CONF_ICE;
97 conf |= mips_dc_disable ? 0 : TX39_CONF_DCE;
98 conf |= mips_config_wbon ? TX39_CONF_WBON : 0; 89 conf |= mips_config_wbon ? TX39_CONF_WBON : 0;
99 conf |= mips_config_cwfon ? TX39_CONF_CWFON : 0; 90 conf |= mips_config_cwfon ? TX39_CONF_CWFON : 0;
100 91
@@ -199,11 +190,25 @@ static void __init jmr3927_rtc_init(void)
199 platform_device_register_simple("rtc-ds1742", -1, &res, 1); 190 platform_device_register_simple("rtc-ds1742", -1, &res, 1);
200} 191}
201 192
193static void __init jmr3927_mtd_init(void)
194{
195 int i;
196
197 for (i = 0; i < 2; i++)
198 tx3927_mtd_init(i);
199}
200
202static void __init jmr3927_device_init(void) 201static void __init jmr3927_device_init(void)
203{ 202{
203 unsigned long iocled_base = JMR3927_IOC_LED_ADDR - IO_BASE;
204#ifdef __LITTLE_ENDIAN
205 iocled_base |= 1;
206#endif
204 __swizzle_addr_b = jmr3927_swizzle_addr_b; 207 __swizzle_addr_b = jmr3927_swizzle_addr_b;
205 jmr3927_rtc_init(); 208 jmr3927_rtc_init();
206 tx3927_wdt_init(); 209 tx3927_wdt_init();
210 jmr3927_mtd_init();
211 txx9_iocled_init(iocled_base, -1, 8, 1, "green", NULL);
207} 212}
208 213
209struct txx9_board_vec jmr3927_vec __initdata = { 214struct txx9_board_vec jmr3927_vec __initdata = {
diff --git a/arch/mips/txx9/rbtx4927/irq.c b/arch/mips/txx9/rbtx4927/irq.c
index 00cd5231da30..9c14ebb26cb4 100644
--- a/arch/mips/txx9/rbtx4927/irq.c
+++ b/arch/mips/txx9/rbtx4927/irq.c
@@ -133,15 +133,20 @@ static int toshiba_rbtx4927_irq_nested(int sw_irq)
133 u8 level3; 133 u8 level3;
134 134
135 level3 = readb(rbtx4927_imstat_addr) & 0x1f; 135 level3 = readb(rbtx4927_imstat_addr) & 0x1f;
136 if (level3) 136 if (unlikely(!level3))
137 sw_irq = RBTX4927_IRQ_IOC + fls(level3) - 1; 137 return -1;
138 return sw_irq; 138 return RBTX4927_IRQ_IOC + __fls8(level3);
139} 139}
140 140
141static void __init toshiba_rbtx4927_irq_ioc_init(void) 141static void __init toshiba_rbtx4927_irq_ioc_init(void)
142{ 142{
143 int i; 143 int i;
144 144
145 /* mask all IOC interrupts */
146 writeb(0, rbtx4927_imask_addr);
147 /* clear SoftInt interrupts */
148 writeb(0, rbtx4927_softint_addr);
149
145 for (i = RBTX4927_IRQ_IOC; 150 for (i = RBTX4927_IRQ_IOC;
146 i < RBTX4927_IRQ_IOC + RBTX4927_NR_IRQ_IOC; i++) 151 i < RBTX4927_IRQ_IOC + RBTX4927_NR_IRQ_IOC; i++)
147 set_irq_chip_and_handler(i, &toshiba_rbtx4927_irq_ioc_type, 152 set_irq_chip_and_handler(i, &toshiba_rbtx4927_irq_ioc_type,
diff --git a/arch/mips/txx9/rbtx4927/prom.c b/arch/mips/txx9/rbtx4927/prom.c
index 1dc0a5b1956b..cc97c6a6011b 100644
--- a/arch/mips/txx9/rbtx4927/prom.c
+++ b/arch/mips/txx9/rbtx4927/prom.c
@@ -36,7 +36,6 @@
36 36
37void __init rbtx4927_prom_init(void) 37void __init rbtx4927_prom_init(void)
38{ 38{
39 prom_init_cmdline();
40 add_memory_region(0, tx4927_get_mem_size(), BOOT_MEM_RAM); 39 add_memory_region(0, tx4927_get_mem_size(), BOOT_MEM_RAM);
41 txx9_sio_putchar_init(TX4927_SIO_REG(0) & 0xfffffffffULL); 40 txx9_sio_putchar_init(TX4927_SIO_REG(0) & 0xfffffffffULL);
42} 41}
diff --git a/arch/mips/txx9/rbtx4927/setup.c b/arch/mips/txx9/rbtx4927/setup.c
index 0d39bafea794..4a74423b2ba8 100644
--- a/arch/mips/txx9/rbtx4927/setup.c
+++ b/arch/mips/txx9/rbtx4927/setup.c
@@ -48,6 +48,7 @@
48#include <linux/ioport.h> 48#include <linux/ioport.h>
49#include <linux/platform_device.h> 49#include <linux/platform_device.h>
50#include <linux/delay.h> 50#include <linux/delay.h>
51#include <linux/gpio.h>
51#include <asm/io.h> 52#include <asm/io.h>
52#include <asm/reboot.h> 53#include <asm/reboot.h>
53#include <asm/txx9/generic.h> 54#include <asm/txx9/generic.h>
@@ -185,14 +186,8 @@ static void __init rbtx4937_clock_init(void);
185 186
186static void __init rbtx4927_mem_setup(void) 187static void __init rbtx4927_mem_setup(void)
187{ 188{
188 u32 cp0_config;
189 char *argptr; 189 char *argptr;
190 190
191 /* enable caches -- HCP5 does this, pmon does not */
192 cp0_config = read_c0_config();
193 cp0_config = cp0_config & ~(TX49_CONF_IC | TX49_CONF_DC);
194 write_c0_config(cp0_config);
195
196 if (TX4927_REV_PCODE() == 0x4927) { 191 if (TX4927_REV_PCODE() == 0x4927) {
197 rbtx4927_clock_init(); 192 rbtx4927_clock_init();
198 tx4927_setup(); 193 tx4927_setup();
@@ -212,6 +207,14 @@ static void __init rbtx4927_mem_setup(void)
212 set_io_port_base(KSEG1 + RBTX4927_ISA_IO_OFFSET); 207 set_io_port_base(KSEG1 + RBTX4927_ISA_IO_OFFSET);
213#endif 208#endif
214 209
210 /* TX4927-SIO DTR on (PIO[15]) */
211 gpio_request(15, "sio-dtr");
212 gpio_direction_output(15, 1);
213 gpio_request(0, "led");
214 gpio_direction_output(0, 1);
215 gpio_request(1, "led");
216 gpio_direction_output(1, 1);
217
215 tx4927_sio_init(0, 0); 218 tx4927_sio_init(0, 0);
216#ifdef CONFIG_SERIAL_TXX9_CONSOLE 219#ifdef CONFIG_SERIAL_TXX9_CONSOLE
217 argptr = prom_getcmdline(); 220 argptr = prom_getcmdline();
@@ -304,11 +307,21 @@ static void __init rbtx4927_ne_init(void)
304 platform_device_register_simple("ne", -1, res, ARRAY_SIZE(res)); 307 platform_device_register_simple("ne", -1, res, ARRAY_SIZE(res));
305} 308}
306 309
310static void __init rbtx4927_mtd_init(void)
311{
312 int i;
313
314 for (i = 0; i < 2; i++)
315 tx4927_mtd_init(i);
316}
317
307static void __init rbtx4927_device_init(void) 318static void __init rbtx4927_device_init(void)
308{ 319{
309 toshiba_rbtx4927_rtc_init(); 320 toshiba_rbtx4927_rtc_init();
310 rbtx4927_ne_init(); 321 rbtx4927_ne_init();
311 tx4927_wdt_init(); 322 tx4927_wdt_init();
323 rbtx4927_mtd_init();
324 txx9_iocled_init(RBTX4927_LED_ADDR - IO_BASE, -1, 3, 1, "green", NULL);
312} 325}
313 326
314struct txx9_board_vec rbtx4927_vec __initdata = { 327struct txx9_board_vec rbtx4927_vec __initdata = {
diff --git a/arch/mips/txx9/rbtx4938/Makefile b/arch/mips/txx9/rbtx4938/Makefile
index 9dcc52ae5b9d..f3e1f597b4f1 100644
--- a/arch/mips/txx9/rbtx4938/Makefile
+++ b/arch/mips/txx9/rbtx4938/Makefile
@@ -1,3 +1,3 @@
1obj-y += prom.o setup.o irq.o spi_eeprom.o 1obj-y += prom.o setup.o irq.o
2 2
3EXTRA_CFLAGS += -Werror 3EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/txx9/rbtx4938/irq.c b/arch/mips/txx9/rbtx4938/irq.c
index ca2f8306ce93..7d21befb8932 100644
--- a/arch/mips/txx9/rbtx4938/irq.c
+++ b/arch/mips/txx9/rbtx4938/irq.c
@@ -85,10 +85,10 @@ static int toshiba_rbtx4938_irq_nested(int sw_irq)
85 u8 level3; 85 u8 level3;
86 86
87 level3 = readb(rbtx4938_imstat_addr); 87 level3 = readb(rbtx4938_imstat_addr);
88 if (level3) 88 if (unlikely(!level3))
89 /* must use fls so onboard ATA has priority */ 89 return -1;
90 sw_irq = RBTX4938_IRQ_IOC + fls(level3) - 1; 90 /* must use fls so onboard ATA has priority */
91 return sw_irq; 91 return RBTX4938_IRQ_IOC + __fls8(level3);
92} 92}
93 93
94static void __init 94static void __init
diff --git a/arch/mips/txx9/rbtx4938/prom.c b/arch/mips/txx9/rbtx4938/prom.c
index d73123cd2ab9..bcb469247e8c 100644
--- a/arch/mips/txx9/rbtx4938/prom.c
+++ b/arch/mips/txx9/rbtx4938/prom.c
@@ -18,9 +18,6 @@
18 18
19void __init rbtx4938_prom_init(void) 19void __init rbtx4938_prom_init(void)
20{ 20{
21#ifndef CONFIG_TX4938_NAND_BOOT
22 prom_init_cmdline();
23#endif
24 add_memory_region(0, tx4938_get_mem_size(), BOOT_MEM_RAM); 21 add_memory_region(0, tx4938_get_mem_size(), BOOT_MEM_RAM);
25 txx9_sio_putchar_init(TX4938_SIO_REG(0) & 0xfffffffffULL); 22 txx9_sio_putchar_init(TX4938_SIO_REG(0) & 0xfffffffffULL);
26} 23}
diff --git a/arch/mips/txx9/rbtx4938/setup.c b/arch/mips/txx9/rbtx4938/setup.c
index 9ab48dec0fe8..e077cc4d3a59 100644
--- a/arch/mips/txx9/rbtx4938/setup.c
+++ b/arch/mips/txx9/rbtx4938/setup.c
@@ -15,6 +15,7 @@
15#include <linux/delay.h> 15#include <linux/delay.h>
16#include <linux/platform_device.h> 16#include <linux/platform_device.h>
17#include <linux/gpio.h> 17#include <linux/gpio.h>
18#include <linux/mtd/physmap.h>
18 19
19#include <asm/reboot.h> 20#include <asm/reboot.h>
20#include <asm/io.h> 21#include <asm/io.h>
@@ -110,6 +111,7 @@ static void __init rbtx4938_pci_setup(void)
110#define SEEPROM2_CS 0 /* IOC */ 111#define SEEPROM2_CS 0 /* IOC */
111#define SEEPROM3_CS 1 /* IOC */ 112#define SEEPROM3_CS 1 /* IOC */
112#define SRTC_CS 2 /* IOC */ 113#define SRTC_CS 2 /* IOC */
114#define SPI_BUSNO 0
113 115
114static int __init rbtx4938_ethaddr_init(void) 116static int __init rbtx4938_ethaddr_init(void)
115{ 117{
@@ -119,7 +121,7 @@ static int __init rbtx4938_ethaddr_init(void)
119 int i; 121 int i;
120 122
121 /* 0-3: "MAC\0", 4-9:eth0, 10-15:eth1, 16:sum */ 123 /* 0-3: "MAC\0", 4-9:eth0, 10-15:eth1, 16:sum */
122 if (spi_eeprom_read(SEEPROM1_CS, 0, dat, sizeof(dat))) { 124 if (spi_eeprom_read(SPI_BUSNO, SEEPROM1_CS, 0, dat, sizeof(dat))) {
123 printk(KERN_ERR "seeprom: read error.\n"); 125 printk(KERN_ERR "seeprom: read error.\n");
124 return -ENODEV; 126 return -ENODEV;
125 } else { 127 } else {
@@ -173,23 +175,30 @@ static void __init rbtx4938_mem_setup(void)
173#endif 175#endif
174 176
175#ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_PIO58_61 177#ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_PIO58_61
176 printk(KERN_INFO "PIOSEL: disabling both ata and nand selection\n"); 178 pr_info("PIOSEL: disabling both ATA and NAND selection\n");
177 txx9_clear64(&tx4938_ccfgptr->pcfg, 179 txx9_clear64(&tx4938_ccfgptr->pcfg,
178 TX4938_PCFG_NDF_SEL | TX4938_PCFG_ATA_SEL); 180 TX4938_PCFG_NDF_SEL | TX4938_PCFG_ATA_SEL);
179#endif 181#endif
180 182
181#ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_NAND 183#ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_NAND
182 printk(KERN_INFO "PIOSEL: enabling nand selection\n"); 184 pr_info("PIOSEL: enabling NAND selection\n");
183 txx9_set64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_NDF_SEL); 185 txx9_set64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_NDF_SEL);
184 txx9_clear64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_ATA_SEL); 186 txx9_clear64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_ATA_SEL);
185#endif 187#endif
186 188
187#ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_ATA 189#ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_ATA
188 printk(KERN_INFO "PIOSEL: enabling ata selection\n"); 190 pr_info("PIOSEL: enabling ATA selection\n");
189 txx9_set64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_ATA_SEL); 191 txx9_set64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_ATA_SEL);
190 txx9_clear64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_NDF_SEL); 192 txx9_clear64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_NDF_SEL);
191#endif 193#endif
192 194
195#ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_KEEP
196 pcfg = ____raw_readq(&tx4938_ccfgptr->pcfg);
197 pr_info("PIOSEL: NAND %s, ATA %s\n",
198 (pcfg & TX4938_PCFG_NDF_SEL) ? "enabled" : "disabled",
199 (pcfg & TX4938_PCFG_ATA_SEL) ? "enabled" : "disabled");
200#endif
201
193 rbtx4938_spi_setup(); 202 rbtx4938_spi_setup();
194 pcfg = ____raw_readq(&tx4938_ccfgptr->pcfg); /* updated */ 203 pcfg = ____raw_readq(&tx4938_ccfgptr->pcfg); /* updated */
195 /* fixup piosel */ 204 /* fixup piosel */
@@ -279,9 +288,9 @@ static int __init rbtx4938_spi_init(void)
279 .mode = SPI_MODE_1 | SPI_CS_HIGH, 288 .mode = SPI_MODE_1 | SPI_CS_HIGH,
280 }; 289 };
281 spi_register_board_info(&srtc_info, 1); 290 spi_register_board_info(&srtc_info, 1);
282 spi_eeprom_register(SEEPROM1_CS); 291 spi_eeprom_register(SPI_BUSNO, SEEPROM1_CS, 128);
283 spi_eeprom_register(16 + SEEPROM2_CS); 292 spi_eeprom_register(SPI_BUSNO, 16 + SEEPROM2_CS, 128);
284 spi_eeprom_register(16 + SEEPROM3_CS); 293 spi_eeprom_register(SPI_BUSNO, 16 + SEEPROM3_CS, 128);
285 gpio_request(16 + SRTC_CS, "rtc-rs5c348"); 294 gpio_request(16 + SRTC_CS, "rtc-rs5c348");
286 gpio_direction_output(16 + SRTC_CS, 0); 295 gpio_direction_output(16 + SRTC_CS, 0);
287 gpio_request(SEEPROM1_CS, "seeprom1"); 296 gpio_request(SEEPROM1_CS, "seeprom1");
@@ -290,10 +299,46 @@ static int __init rbtx4938_spi_init(void)
290 gpio_direction_output(16 + SEEPROM2_CS, 1); 299 gpio_direction_output(16 + SEEPROM2_CS, 1);
291 gpio_request(16 + SEEPROM3_CS, "seeprom3"); 300 gpio_request(16 + SEEPROM3_CS, "seeprom3");
292 gpio_direction_output(16 + SEEPROM3_CS, 1); 301 gpio_direction_output(16 + SEEPROM3_CS, 1);
293 tx4938_spi_init(0); 302 tx4938_spi_init(SPI_BUSNO);
294 return 0; 303 return 0;
295} 304}
296 305
306static void __init rbtx4938_mtd_init(void)
307{
308 struct physmap_flash_data pdata = {
309 .width = 4,
310 };
311
312 switch (readb(rbtx4938_bdipsw_addr) & 7) {
313 case 0:
314 /* Boot */
315 txx9_physmap_flash_init(0, 0x1fc00000, 0x400000, &pdata);
316 /* System */
317 txx9_physmap_flash_init(1, 0x1e000000, 0x1000000, &pdata);
318 break;
319 case 1:
320 /* System */
321 txx9_physmap_flash_init(0, 0x1f000000, 0x1000000, &pdata);
322 /* Boot */
323 txx9_physmap_flash_init(1, 0x1ec00000, 0x400000, &pdata);
324 break;
325 case 2:
326 /* Ext */
327 txx9_physmap_flash_init(0, 0x1f000000, 0x1000000, &pdata);
328 /* System */
329 txx9_physmap_flash_init(1, 0x1e000000, 0x1000000, &pdata);
330 /* Boot */
331 txx9_physmap_flash_init(2, 0x1dc00000, 0x400000, &pdata);
332 break;
333 case 3:
334 /* Boot */
335 txx9_physmap_flash_init(1, 0x1bc00000, 0x400000, &pdata);
336 /* System */
337 txx9_physmap_flash_init(2, 0x1a000000, 0x1000000, &pdata);
338 break;
339 }
340}
341
297static void __init rbtx4938_arch_init(void) 342static void __init rbtx4938_arch_init(void)
298{ 343{
299 gpiochip_add(&rbtx4938_spi_gpio_chip); 344 gpiochip_add(&rbtx4938_spi_gpio_chip);
@@ -306,6 +351,8 @@ static void __init rbtx4938_device_init(void)
306 rbtx4938_ethaddr_init(); 351 rbtx4938_ethaddr_init();
307 rbtx4938_ne_init(); 352 rbtx4938_ne_init();
308 tx4938_wdt_init(); 353 tx4938_wdt_init();
354 rbtx4938_mtd_init();
355 txx9_iocled_init(RBTX4938_LED_ADDR - IO_BASE, -1, 8, 1, "green", NULL);
309} 356}
310 357
311struct txx9_board_vec rbtx4938_vec __initdata = { 358struct txx9_board_vec rbtx4938_vec __initdata = {
diff --git a/arch/mips/txx9/rbtx4939/Makefile b/arch/mips/txx9/rbtx4939/Makefile
new file mode 100644
index 000000000000..3232cd03a7d6
--- /dev/null
+++ b/arch/mips/txx9/rbtx4939/Makefile
@@ -0,0 +1,3 @@
1obj-y += irq.o setup.o prom.o
2
3EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/txx9/rbtx4939/irq.c b/arch/mips/txx9/rbtx4939/irq.c
new file mode 100644
index 000000000000..500cc0a908e6
--- /dev/null
+++ b/arch/mips/txx9/rbtx4939/irq.c
@@ -0,0 +1,96 @@
1/*
2 * Toshiba RBTX4939 interrupt routines
3 * Based on linux/arch/mips/txx9/rbtx4938/irq.c,
4 * and RBTX49xx patch from CELF patch archive.
5 *
6 * Copyright (C) 2000-2001,2005-2006 Toshiba Corporation
7 * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
8 * terms of the GNU General Public License version 2. This program is
9 * licensed "as is" without any warranty of any kind, whether express
10 * or implied.
11 */
12#include <linux/init.h>
13#include <linux/interrupt.h>
14#include <asm/mipsregs.h>
15#include <asm/txx9/rbtx4939.h>
16
17/*
18 * RBTX4939 IOC controller definition
19 */
20
21static void rbtx4939_ioc_irq_unmask(unsigned int irq)
22{
23 int ioc_nr = irq - RBTX4939_IRQ_IOC;
24
25 writeb(readb(rbtx4939_ien_addr) | (1 << ioc_nr), rbtx4939_ien_addr);
26}
27
28static void rbtx4939_ioc_irq_mask(unsigned int irq)
29{
30 int ioc_nr = irq - RBTX4939_IRQ_IOC;
31
32 writeb(readb(rbtx4939_ien_addr) & ~(1 << ioc_nr), rbtx4939_ien_addr);
33 mmiowb();
34}
35
36static struct irq_chip rbtx4939_ioc_irq_chip = {
37 .name = "IOC",
38 .ack = rbtx4939_ioc_irq_mask,
39 .mask = rbtx4939_ioc_irq_mask,
40 .mask_ack = rbtx4939_ioc_irq_mask,
41 .unmask = rbtx4939_ioc_irq_unmask,
42};
43
44
45static inline int rbtx4939_ioc_irqroute(void)
46{
47 unsigned char istat = readb(rbtx4939_ifac2_addr);
48
49 if (unlikely(istat == 0))
50 return -1;
51 return RBTX4939_IRQ_IOC + __fls8(istat);
52}
53
54static int rbtx4939_irq_dispatch(int pending)
55{
56 int irq;
57
58 if (pending & CAUSEF_IP7)
59 return MIPS_CPU_IRQ_BASE + 7;
60 irq = tx4939_irq();
61 if (likely(irq >= 0)) {
62 /* redirect IOC interrupts */
63 switch (irq) {
64 case RBTX4939_IRQ_IOCINT:
65 irq = rbtx4939_ioc_irqroute();
66 break;
67 }
68 } else if (pending & CAUSEF_IP0)
69 irq = MIPS_CPU_IRQ_BASE + 0;
70 else if (pending & CAUSEF_IP1)
71 irq = MIPS_CPU_IRQ_BASE + 1;
72 else
73 irq = -1;
74 return irq;
75}
76
77void __init rbtx4939_irq_setup(void)
78{
79 int i;
80
81 /* mask all IOC interrupts */
82 writeb(0, rbtx4939_ien_addr);
83
84 /* clear SoftInt interrupts */
85 writeb(0, rbtx4939_softint_addr);
86
87 txx9_irq_dispatch = rbtx4939_irq_dispatch;
88
89 tx4939_irq_init();
90 for (i = RBTX4939_IRQ_IOC;
91 i < RBTX4939_IRQ_IOC + RBTX4939_NR_IRQ_IOC; i++)
92 set_irq_chip_and_handler(i, &rbtx4939_ioc_irq_chip,
93 handle_level_irq);
94
95 set_irq_chained_handler(RBTX4939_IRQ_IOCINT, handle_simple_irq);
96}
diff --git a/arch/mips/txx9/rbtx4939/prom.c b/arch/mips/txx9/rbtx4939/prom.c
new file mode 100644
index 000000000000..bd277ecb4ad6
--- /dev/null
+++ b/arch/mips/txx9/rbtx4939/prom.c
@@ -0,0 +1,17 @@
1/*
2 * rbtx4939 specific prom routines
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 */
8
9#include <linux/init.h>
10#include <asm/txx9/generic.h>
11#include <asm/txx9/rbtx4939.h>
12
13void __init rbtx4939_prom_init(void)
14{
15 tx4939_add_memory_regions();
16 txx9_sio_putchar_init(TX4939_SIO_REG(0) & 0xfffffffffULL);
17}
diff --git a/arch/mips/txx9/rbtx4939/setup.c b/arch/mips/txx9/rbtx4939/setup.c
new file mode 100644
index 000000000000..9855d7bccc20
--- /dev/null
+++ b/arch/mips/txx9/rbtx4939/setup.c
@@ -0,0 +1,307 @@
1/*
2 * Toshiba RBTX4939 setup routines.
3 * Based on linux/arch/mips/txx9/rbtx4938/setup.c,
4 * and RBTX49xx patch from CELF patch archive.
5 *
6 * Copyright (C) 2000-2001,2005-2007 Toshiba Corporation
7 * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
8 * terms of the GNU General Public License version 2. This program is
9 * licensed "as is" without any warranty of any kind, whether express
10 * or implied.
11 */
12#include <linux/init.h>
13#include <linux/kernel.h>
14#include <linux/types.h>
15#include <linux/platform_device.h>
16#include <linux/leds.h>
17#include <asm/reboot.h>
18#include <asm/txx9/generic.h>
19#include <asm/txx9/pci.h>
20#include <asm/txx9/rbtx4939.h>
21
22static void rbtx4939_machine_restart(char *command)
23{
24 local_irq_disable();
25 writeb(1, rbtx4939_reseten_addr);
26 writeb(1, rbtx4939_softreset_addr);
27 while (1)
28 ;
29}
30
31static void __init rbtx4939_time_init(void)
32{
33 tx4939_time_init(0);
34}
35
36static void __init rbtx4939_pci_setup(void)
37{
38#ifdef CONFIG_PCI
39 int extarb = !(__raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_PCIARB);
40 struct pci_controller *c = &txx9_primary_pcic;
41
42 register_pci_controller(c);
43
44 tx4939_report_pciclk();
45 tx4927_pcic_setup(tx4939_pcicptr, c, extarb);
46 if (!(__raw_readq(&tx4939_ccfgptr->pcfg) & TX4939_PCFG_ATA1MODE) &&
47 (__raw_readq(&tx4939_ccfgptr->pcfg) &
48 (TX4939_PCFG_ET0MODE | TX4939_PCFG_ET1MODE))) {
49 tx4939_report_pci1clk();
50
51 /* mem:64K(max), io:64K(max) (enough for ETH0,ETH1) */
52 c = txx9_alloc_pci_controller(NULL, 0, 0x10000, 0, 0x10000);
53 register_pci_controller(c);
54 tx4927_pcic_setup(tx4939_pcic1ptr, c, 0);
55 }
56
57 tx4939_setup_pcierr_irq();
58#endif /* CONFIG_PCI */
59}
60
61static unsigned long long default_ebccr[] __initdata = {
62 0x01c0000000007608ULL, /* 64M ROM */
63 0x017f000000007049ULL, /* 1M IOC */
64 0x0180000000408608ULL, /* ISA */
65 0,
66};
67
68static void __init rbtx4939_ebusc_setup(void)
69{
70 int i;
71 unsigned int sp;
72
73 /* use user-configured speed */
74 sp = TX4939_EBUSC_CR(0) & 0x30;
75 default_ebccr[0] |= sp;
76 default_ebccr[1] |= sp;
77 default_ebccr[2] |= sp;
78 /* initialise by myself */
79 for (i = 0; i < ARRAY_SIZE(default_ebccr); i++) {
80 if (default_ebccr[i])
81 ____raw_writeq(default_ebccr[i],
82 &tx4939_ebuscptr->cr[i]);
83 else
84 ____raw_writeq(____raw_readq(&tx4939_ebuscptr->cr[i])
85 & ~8,
86 &tx4939_ebuscptr->cr[i]);
87 }
88}
89
90static void __init rbtx4939_update_ioc_pen(void)
91{
92 __u64 pcfg = ____raw_readq(&tx4939_ccfgptr->pcfg);
93 __u64 ccfg = ____raw_readq(&tx4939_ccfgptr->ccfg);
94 __u8 pe1 = readb(rbtx4939_pe1_addr);
95 __u8 pe2 = readb(rbtx4939_pe2_addr);
96 __u8 pe3 = readb(rbtx4939_pe3_addr);
97 if (pcfg & TX4939_PCFG_ATA0MODE)
98 pe1 |= RBTX4939_PE1_ATA(0);
99 else
100 pe1 &= ~RBTX4939_PE1_ATA(0);
101 if (pcfg & TX4939_PCFG_ATA1MODE) {
102 pe1 |= RBTX4939_PE1_ATA(1);
103 pe1 &= ~(RBTX4939_PE1_RMII(0) | RBTX4939_PE1_RMII(1));
104 } else {
105 pe1 &= ~RBTX4939_PE1_ATA(1);
106 if (pcfg & TX4939_PCFG_ET0MODE)
107 pe1 |= RBTX4939_PE1_RMII(0);
108 else
109 pe1 &= ~RBTX4939_PE1_RMII(0);
110 if (pcfg & TX4939_PCFG_ET1MODE)
111 pe1 |= RBTX4939_PE1_RMII(1);
112 else
113 pe1 &= ~RBTX4939_PE1_RMII(1);
114 }
115 if (ccfg & TX4939_CCFG_PTSEL)
116 pe3 &= ~(RBTX4939_PE3_VP | RBTX4939_PE3_VP_P |
117 RBTX4939_PE3_VP_S);
118 else {
119 __u64 vmode = pcfg &
120 (TX4939_PCFG_VSSMODE | TX4939_PCFG_VPSMODE);
121 if (vmode == 0)
122 pe3 &= ~(RBTX4939_PE3_VP | RBTX4939_PE3_VP_P |
123 RBTX4939_PE3_VP_S);
124 else if (vmode == TX4939_PCFG_VPSMODE) {
125 pe3 |= RBTX4939_PE3_VP_P;
126 pe3 &= ~(RBTX4939_PE3_VP | RBTX4939_PE3_VP_S);
127 } else if (vmode == TX4939_PCFG_VSSMODE) {
128 pe3 |= RBTX4939_PE3_VP | RBTX4939_PE3_VP_S;
129 pe3 &= ~RBTX4939_PE3_VP_P;
130 } else {
131 pe3 |= RBTX4939_PE3_VP | RBTX4939_PE3_VP_P;
132 pe3 &= ~RBTX4939_PE3_VP_S;
133 }
134 }
135 if (pcfg & TX4939_PCFG_SPIMODE) {
136 if (pcfg & TX4939_PCFG_SIO2MODE_GPIO)
137 pe2 &= ~(RBTX4939_PE2_SIO2 | RBTX4939_PE2_SIO0);
138 else {
139 if (pcfg & TX4939_PCFG_SIO2MODE_SIO2) {
140 pe2 |= RBTX4939_PE2_SIO2;
141 pe2 &= ~RBTX4939_PE2_SIO0;
142 } else {
143 pe2 |= RBTX4939_PE2_SIO0;
144 pe2 &= ~RBTX4939_PE2_SIO2;
145 }
146 }
147 if (pcfg & TX4939_PCFG_SIO3MODE)
148 pe2 |= RBTX4939_PE2_SIO3;
149 else
150 pe2 &= ~RBTX4939_PE2_SIO3;
151 pe2 &= ~RBTX4939_PE2_SPI;
152 } else {
153 pe2 |= RBTX4939_PE2_SPI;
154 pe2 &= ~(RBTX4939_PE2_SIO3 | RBTX4939_PE2_SIO2 |
155 RBTX4939_PE2_SIO0);
156 }
157 if ((pcfg & TX4939_PCFG_I2SMODE_MASK) == TX4939_PCFG_I2SMODE_GPIO)
158 pe2 |= RBTX4939_PE2_GPIO;
159 else
160 pe2 &= ~RBTX4939_PE2_GPIO;
161 writeb(pe1, rbtx4939_pe1_addr);
162 writeb(pe2, rbtx4939_pe2_addr);
163 writeb(pe3, rbtx4939_pe3_addr);
164}
165
166#define RBTX4939_MAX_7SEGLEDS 8
167
168#if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE)
169static u8 led_val[RBTX4939_MAX_7SEGLEDS];
170struct rbtx4939_led_data {
171 struct led_classdev cdev;
172 char name[32];
173 unsigned int num;
174};
175
176/* Use "dot" in 7seg LEDs */
177static void rbtx4939_led_brightness_set(struct led_classdev *led_cdev,
178 enum led_brightness value)
179{
180 struct rbtx4939_led_data *led_dat =
181 container_of(led_cdev, struct rbtx4939_led_data, cdev);
182 unsigned int num = led_dat->num;
183 unsigned long flags;
184
185 local_irq_save(flags);
186 led_val[num] = (led_val[num] & 0x7f) | (value ? 0x80 : 0);
187 writeb(led_val[num], rbtx4939_7seg_addr(num / 4, num % 4));
188 local_irq_restore(flags);
189}
190
191static int __init rbtx4939_led_probe(struct platform_device *pdev)
192{
193 struct rbtx4939_led_data *leds_data;
194 int i;
195 static char *default_triggers[] __initdata = {
196 "heartbeat",
197 "ide-disk",
198 "nand-disk",
199 };
200
201 leds_data = kzalloc(sizeof(*leds_data) * RBTX4939_MAX_7SEGLEDS,
202 GFP_KERNEL);
203 if (!leds_data)
204 return -ENOMEM;
205 for (i = 0; i < RBTX4939_MAX_7SEGLEDS; i++) {
206 int rc;
207 struct rbtx4939_led_data *led_dat = &leds_data[i];
208
209 led_dat->num = i;
210 led_dat->cdev.brightness_set = rbtx4939_led_brightness_set;
211 sprintf(led_dat->name, "rbtx4939:amber:%u", i);
212 led_dat->cdev.name = led_dat->name;
213 if (i < ARRAY_SIZE(default_triggers))
214 led_dat->cdev.default_trigger = default_triggers[i];
215 rc = led_classdev_register(&pdev->dev, &led_dat->cdev);
216 if (rc < 0)
217 return rc;
218 led_dat->cdev.brightness_set(&led_dat->cdev, 0);
219 }
220 return 0;
221
222}
223
224static struct platform_driver rbtx4939_led_driver = {
225 .driver = {
226 .name = "rbtx4939-led",
227 .owner = THIS_MODULE,
228 },
229};
230
231static void __init rbtx4939_led_setup(void)
232{
233 platform_device_register_simple("rbtx4939-led", -1, NULL, 0);
234 platform_driver_probe(&rbtx4939_led_driver, rbtx4939_led_probe);
235}
236#else
237static inline void rbtx4939_led_setup(void)
238{
239}
240#endif
241
242static void __init rbtx4939_arch_init(void)
243{
244 rbtx4939_pci_setup();
245}
246
247static void __init rbtx4939_device_init(void)
248{
249#if defined(CONFIG_TC35815) || defined(CONFIG_TC35815_MODULE)
250 int i, j;
251 unsigned char ethaddr[2][6];
252 for (i = 0; i < 2; i++) {
253 unsigned long area = CKSEG1 + 0x1fff0000 + (i * 0x10);
254 if (readb(rbtx4939_bdipsw_addr) & 8) {
255 u16 buf[3];
256 area -= 0x03000000;
257 for (j = 0; j < 3; j++)
258 buf[j] = le16_to_cpup((u16 *)(area + j * 2));
259 memcpy(ethaddr[i], buf, 6);
260 } else
261 memcpy(ethaddr[i], (void *)area, 6);
262 }
263 tx4939_ethaddr_init(ethaddr[0], ethaddr[1]);
264#endif
265 rbtx4939_led_setup();
266 tx4939_wdt_init();
267 tx4939_ata_init();
268}
269
270static void __init rbtx4939_setup(void)
271{
272 rbtx4939_ebusc_setup();
273 /* always enable ATA0 */
274 txx9_set64(&tx4939_ccfgptr->pcfg, TX4939_PCFG_ATA0MODE);
275 rbtx4939_update_ioc_pen();
276 if (txx9_master_clock == 0)
277 txx9_master_clock = 20000000;
278 tx4939_setup();
279
280 _machine_restart = rbtx4939_machine_restart;
281
282 pr_info("RBTX4939 (Rev %02x) --- FPGA(Rev %02x) DIPSW:%02x,%02x\n",
283 readb(rbtx4939_board_rev_addr), readb(rbtx4939_ioc_rev_addr),
284 readb(rbtx4939_udipsw_addr), readb(rbtx4939_bdipsw_addr));
285
286#ifdef CONFIG_PCI
287 txx9_alloc_pci_controller(&txx9_primary_pcic, 0, 0, 0, 0);
288 txx9_board_pcibios_setup = tx4927_pcibios_setup;
289#else
290 set_io_port_base(RBTX4939_ETHER_BASE);
291#endif
292
293 tx4939_sio_init(TX4939_SCLK0(txx9_master_clock), 0);
294}
295
296struct txx9_board_vec rbtx4939_vec __initdata = {
297 .system = "Tothiba RBTX4939",
298 .prom_init = rbtx4939_prom_init,
299 .mem_setup = rbtx4939_setup,
300 .irq_setup = rbtx4939_irq_setup,
301 .time_init = rbtx4939_time_init,
302 .device_init = rbtx4939_device_init,
303 .arch_init = rbtx4939_arch_init,
304#ifdef CONFIG_PCI
305 .pci_map_irq = tx4939_pci_map_irq,
306#endif
307};