aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/tx4938
diff options
context:
space:
mode:
authorAtsushi Nemoto <anemo@mba.ocn.ne.jp>2008-07-10 11:31:36 -0400
committerRalf Baechle <ralf@linux-mips.org>2008-07-15 13:44:35 -0400
commit22b1d707ffc99faebd86257ad19d5bb9fc624734 (patch)
tree9bd0bcd3878611d74db29e17f3c6e951f4656e61 /arch/mips/tx4938
parent14476007c90005c8992b786c15a59cca31f53268 (diff)
[MIPS] TXx9: Reorganize code
Move arch/mips/{jmr3927,tx4927,tx4938} into arch/mips/txx9/ tree. This will help more code sharing and maintainance. Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/tx4938')
-rw-r--r--arch/mips/tx4938/Kconfig24
-rw-r--r--arch/mips/tx4938/common/Makefile8
-rw-r--r--arch/mips/tx4938/common/dbgio.c48
-rw-r--r--arch/mips/tx4938/common/irq.c48
-rw-r--r--arch/mips/tx4938/common/prom.c124
-rw-r--r--arch/mips/tx4938/toshiba_rbtx4938/Makefile7
-rw-r--r--arch/mips/tx4938/toshiba_rbtx4938/irq.c161
-rw-r--r--arch/mips/tx4938/toshiba_rbtx4938/prom.c74
-rw-r--r--arch/mips/tx4938/toshiba_rbtx4938/setup.c1124
-rw-r--r--arch/mips/tx4938/toshiba_rbtx4938/spi_eeprom.c99
10 files changed, 0 insertions, 1717 deletions
diff --git a/arch/mips/tx4938/Kconfig b/arch/mips/tx4938/Kconfig
deleted file mode 100644
index d90e9cd85138..000000000000
--- a/arch/mips/tx4938/Kconfig
+++ /dev/null
@@ -1,24 +0,0 @@
1if TOSHIBA_RBTX4938
2
3comment "Multiplex Pin Select"
4choice
5 prompt "PIO[58:61]"
6 default TOSHIBA_RBTX4938_MPLEX_PIO58_61
7
8config TOSHIBA_RBTX4938_MPLEX_PIO58_61
9 bool "PIO"
10config TOSHIBA_RBTX4938_MPLEX_NAND
11 bool "NAND"
12config TOSHIBA_RBTX4938_MPLEX_ATA
13 bool "ATA"
14
15endchoice
16
17config TX4938_NAND_BOOT
18 depends on EXPERIMENTAL && TOSHIBA_RBTX4938_MPLEX_NAND
19 bool "NAND Boot Support (EXPERIMENTAL)"
20 help
21 This is only for Toshiba RBTX4938 reference board, which has NAND IPL.
22 Select this option if you need to use NAND boot.
23
24endif
diff --git a/arch/mips/tx4938/common/Makefile b/arch/mips/tx4938/common/Makefile
deleted file mode 100644
index 56aa1ed1ee0c..000000000000
--- a/arch/mips/tx4938/common/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
1#
2# Makefile for common code for Toshiba TX4927 based systems
3#
4
5obj-y += prom.o irq.o
6obj-$(CONFIG_KGDB) += dbgio.o
7
8EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/tx4938/common/dbgio.c b/arch/mips/tx4938/common/dbgio.c
deleted file mode 100644
index 33b9c672a322..000000000000
--- a/arch/mips/tx4938/common/dbgio.c
+++ /dev/null
@@ -1,48 +0,0 @@
1/*
2 * linux/arch/mips/tx4938/common/dbgio.c
3 *
4 * kgdb interface for gdb
5 *
6 * Author: MontaVista Software, Inc.
7 * source@mvista.com
8 *
9 * Copyright 2005 MontaVista Software Inc.
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 *
16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
24 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
25 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 * You should have received a copy of the GNU General Public License along
28 * with this program; if not, write to the Free Software Foundation, Inc.,
29 * 675 Mass Ave, Cambridge, MA 02139, USA.
30 *
31 * Support for TX4938 in 2.6 - Hiroshi DOYU <Hiroshi_DOYU@montavista.co.jp>
32 */
33
34#include <linux/types>
35
36extern u8 txx9_sio_kdbg_rd(void);
37extern int txx9_sio_kdbg_wr( u8 ch );
38
39u8 getDebugChar(void)
40{
41 return (txx9_sio_kdbg_rd());
42}
43
44int putDebugChar(u8 byte)
45{
46 return (txx9_sio_kdbg_wr(byte));
47}
48
diff --git a/arch/mips/tx4938/common/irq.c b/arch/mips/tx4938/common/irq.c
deleted file mode 100644
index c059b899d120..000000000000
--- a/arch/mips/tx4938/common/irq.c
+++ /dev/null
@@ -1,48 +0,0 @@
1/*
2 * linux/arch/mips/tx4938/common/irq.c
3 *
4 * Common tx4938 irq handler
5 * Copyright (C) 2000-2001 Toshiba Corporation
6 *
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 * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
13 */
14#include <linux/init.h>
15#include <linux/interrupt.h>
16#include <asm/irq_cpu.h>
17#include <asm/mipsregs.h>
18#include <asm/tx4938/rbtx4938.h>
19
20void __init
21tx4938_irq_init(void)
22{
23 mips_cpu_irq_init();
24 txx9_irq_init(TX4938_IRC_REG);
25 set_irq_chained_handler(TX4938_IRQ_NEST_PIC_ON_CP0, handle_simple_irq);
26}
27
28int toshiba_rbtx4938_irq_nested(int irq);
29
30asmlinkage void plat_irq_dispatch(void)
31{
32 unsigned int pending = read_c0_cause() & read_c0_status();
33
34 if (pending & STATUSF_IP7)
35 do_IRQ(TX4938_IRQ_CPU_TIMER);
36 else if (pending & STATUSF_IP2) {
37 int irq = txx9_irq();
38 if (irq == TX4938_IRQ_PIC_BEG + TX4938_IR_INT(0))
39 irq = toshiba_rbtx4938_irq_nested(irq);
40 if (irq >= 0)
41 do_IRQ(irq);
42 else
43 spurious_interrupt();
44 } else if (pending & STATUSF_IP1)
45 do_IRQ(TX4938_IRQ_USER1);
46 else if (pending & STATUSF_IP0)
47 do_IRQ(TX4938_IRQ_USER0);
48}
diff --git a/arch/mips/tx4938/common/prom.c b/arch/mips/tx4938/common/prom.c
deleted file mode 100644
index 20baeaeba4cd..000000000000
--- a/arch/mips/tx4938/common/prom.c
+++ /dev/null
@@ -1,124 +0,0 @@
1/*
2 * linux/arch/mips/tx4938/common/prom.c
3 *
4 * common tx4938 memory interface
5 * Copyright (C) 2000-2001 Toshiba Corporation
6 *
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 * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
13 */
14
15#include <linux/init.h>
16#include <linux/types.h>
17#include <linux/io.h>
18
19static unsigned int __init
20tx4938_process_sdccr(u64 * addr)
21{
22 u64 val;
23 unsigned int sdccr_ce;
24 unsigned int sdccr_rs;
25 unsigned int sdccr_cs;
26 unsigned int sdccr_mw;
27 unsigned int rs = 0;
28 unsigned int cs = 0;
29 unsigned int mw = 0;
30 unsigned int bc = 4;
31 unsigned int msize = 0;
32
33 val = ____raw_readq((void __iomem *)addr);
34
35 /* MVMCP -- need #defs for these bits masks */
36 sdccr_ce = ((val & (1 << 10)) >> 10);
37 sdccr_rs = ((val & (3 << 5)) >> 5);
38 sdccr_cs = ((val & (7 << 2)) >> 2);
39 sdccr_mw = ((val & (1 << 0)) >> 0);
40
41 if (sdccr_ce) {
42 switch (sdccr_rs) {
43 case 0:{
44 rs = 2048;
45 break;
46 }
47 case 1:{
48 rs = 4096;
49 break;
50 }
51 case 2:{
52 rs = 8192;
53 break;
54 }
55 default:{
56 rs = 0;
57 break;
58 }
59 }
60 switch (sdccr_cs) {
61 case 0:{
62 cs = 256;
63 break;
64 }
65 case 1:{
66 cs = 512;
67 break;
68 }
69 case 2:{
70 cs = 1024;
71 break;
72 }
73 case 3:{
74 cs = 2048;
75 break;
76 }
77 case 4:{
78 cs = 4096;
79 break;
80 }
81 default:{
82 cs = 0;
83 break;
84 }
85 }
86 switch (sdccr_mw) {
87 case 0:{
88 mw = 8;
89 break;
90 } /* 8 bytes = 64 bits */
91 case 1:{
92 mw = 4;
93 break;
94 } /* 4 bytes = 32 bits */
95 }
96 }
97
98 /* bytes per chip MB per chip bank count */
99 msize = (((rs * cs * mw) / (1024 * 1024)) * (bc));
100
101 /* MVMCP -- bc hard coded to 4 from table 9.3.1 */
102 /* boad supports bc=2 but no way to detect */
103
104 return (msize);
105}
106
107unsigned int __init
108tx4938_get_mem_size(void)
109{
110 unsigned int c0;
111 unsigned int c1;
112 unsigned int c2;
113 unsigned int c3;
114 unsigned int total;
115
116 /* MVMCP -- need #defs for these registers */
117 c0 = tx4938_process_sdccr((u64 *) 0xff1f8000);
118 c1 = tx4938_process_sdccr((u64 *) 0xff1f8008);
119 c2 = tx4938_process_sdccr((u64 *) 0xff1f8010);
120 c3 = tx4938_process_sdccr((u64 *) 0xff1f8018);
121 total = c0 + c1 + c2 + c3;
122
123 return (total);
124}
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/Makefile b/arch/mips/tx4938/toshiba_rbtx4938/Makefile
deleted file mode 100644
index 2316dd7dd1bd..000000000000
--- a/arch/mips/tx4938/toshiba_rbtx4938/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
1#
2# Makefile for common code for Toshiba TX4927 based systems
3#
4
5obj-y += prom.o setup.o irq.o spi_eeprom.o
6
7EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/irq.c b/arch/mips/tx4938/toshiba_rbtx4938/irq.c
deleted file mode 100644
index 4d6a8dc46c76..000000000000
--- a/arch/mips/tx4938/toshiba_rbtx4938/irq.c
+++ /dev/null
@@ -1,161 +0,0 @@
1/*
2 * linux/arch/mips/tx4938/toshiba_rbtx4938/irq.c
3 *
4 * Toshiba RBTX4938 specific interrupt handlers
5 * Copyright (C) 2000-2001 Toshiba Corporation
6 *
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 * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
13 */
14
15/*
16IRQ Device
17
1816 TX4938-CP0/00 Software 0
1917 TX4938-CP0/01 Software 1
2018 TX4938-CP0/02 Cascade TX4938-CP0
2119 TX4938-CP0/03 Multiplexed -- do not use
2220 TX4938-CP0/04 Multiplexed -- do not use
2321 TX4938-CP0/05 Multiplexed -- do not use
2422 TX4938-CP0/06 Multiplexed -- do not use
2523 TX4938-CP0/07 CPU TIMER
26
2724 TX4938-PIC/00
2825 TX4938-PIC/01
2926 TX4938-PIC/02 Cascade RBTX4938-IOC
3027 TX4938-PIC/03 RBTX4938 RTL-8019AS Ethernet
3128 TX4938-PIC/04
3229 TX4938-PIC/05 TX4938 ETH1
3330 TX4938-PIC/06 TX4938 ETH0
3431 TX4938-PIC/07
3532 TX4938-PIC/08 TX4938 SIO 0
3633 TX4938-PIC/09 TX4938 SIO 1
3734 TX4938-PIC/10 TX4938 DMA0
3835 TX4938-PIC/11 TX4938 DMA1
3936 TX4938-PIC/12 TX4938 DMA2
4037 TX4938-PIC/13 TX4938 DMA3
4138 TX4938-PIC/14
4239 TX4938-PIC/15
4340 TX4938-PIC/16 TX4938 PCIC
4441 TX4938-PIC/17 TX4938 TMR0
4542 TX4938-PIC/18 TX4938 TMR1
4643 TX4938-PIC/19 TX4938 TMR2
4744 TX4938-PIC/20
4845 TX4938-PIC/21
4946 TX4938-PIC/22 TX4938 PCIERR
5047 TX4938-PIC/23
5148 TX4938-PIC/24
5249 TX4938-PIC/25
5350 TX4938-PIC/26
5451 TX4938-PIC/27
5552 TX4938-PIC/28
5653 TX4938-PIC/29
5754 TX4938-PIC/30
5855 TX4938-PIC/31 TX4938 SPI
59
6056 RBTX4938-IOC/00 PCI-D
6157 RBTX4938-IOC/01 PCI-C
6258 RBTX4938-IOC/02 PCI-B
6359 RBTX4938-IOC/03 PCI-A
6460 RBTX4938-IOC/04 RTC
6561 RBTX4938-IOC/05 ATA
6662 RBTX4938-IOC/06 MODEM
6763 RBTX4938-IOC/07 SWINT
68*/
69#include <linux/init.h>
70#include <linux/interrupt.h>
71#include <asm/tx4938/rbtx4938.h>
72
73static void toshiba_rbtx4938_irq_ioc_enable(unsigned int irq);
74static void toshiba_rbtx4938_irq_ioc_disable(unsigned int irq);
75
76#define TOSHIBA_RBTX4938_IOC_NAME "RBTX4938-IOC"
77static struct irq_chip toshiba_rbtx4938_irq_ioc_type = {
78 .name = TOSHIBA_RBTX4938_IOC_NAME,
79 .ack = toshiba_rbtx4938_irq_ioc_disable,
80 .mask = toshiba_rbtx4938_irq_ioc_disable,
81 .mask_ack = toshiba_rbtx4938_irq_ioc_disable,
82 .unmask = toshiba_rbtx4938_irq_ioc_enable,
83};
84
85int
86toshiba_rbtx4938_irq_nested(int sw_irq)
87{
88 u8 level3;
89
90 level3 = readb(rbtx4938_imstat_addr);
91 if (level3)
92 /* must use fls so onboard ATA has priority */
93 sw_irq = TOSHIBA_RBTX4938_IRQ_IOC_BEG + fls(level3) - 1;
94
95 return sw_irq;
96}
97
98static struct irqaction toshiba_rbtx4938_irq_ioc_action = {
99 .handler = no_action,
100 .flags = 0,
101 .mask = CPU_MASK_NONE,
102 .name = TOSHIBA_RBTX4938_IOC_NAME,
103};
104
105/**********************************************************************************/
106/* Functions for ioc */
107/**********************************************************************************/
108static void __init
109toshiba_rbtx4938_irq_ioc_init(void)
110{
111 int i;
112
113 for (i = TOSHIBA_RBTX4938_IRQ_IOC_BEG;
114 i <= TOSHIBA_RBTX4938_IRQ_IOC_END; i++)
115 set_irq_chip_and_handler(i, &toshiba_rbtx4938_irq_ioc_type,
116 handle_level_irq);
117
118 setup_irq(RBTX4938_IRQ_IOCINT,
119 &toshiba_rbtx4938_irq_ioc_action);
120}
121
122static void
123toshiba_rbtx4938_irq_ioc_enable(unsigned int irq)
124{
125 unsigned char v;
126
127 v = readb(rbtx4938_imask_addr);
128 v |= (1 << (irq - TOSHIBA_RBTX4938_IRQ_IOC_BEG));
129 writeb(v, rbtx4938_imask_addr);
130 mmiowb();
131}
132
133static void
134toshiba_rbtx4938_irq_ioc_disable(unsigned int irq)
135{
136 unsigned char v;
137
138 v = readb(rbtx4938_imask_addr);
139 v &= ~(1 << (irq - TOSHIBA_RBTX4938_IRQ_IOC_BEG));
140 writeb(v, rbtx4938_imask_addr);
141 mmiowb();
142}
143
144void __init arch_init_irq(void)
145{
146 extern void tx4938_irq_init(void);
147
148 /* Now, interrupt control disabled, */
149 /* all IRC interrupts are masked, */
150 /* all IRC interrupt mode are Low Active. */
151
152 /* mask all IOC interrupts */
153 writeb(0, rbtx4938_imask_addr);
154
155 /* clear SoftInt interrupts */
156 writeb(0, rbtx4938_softint_addr);
157 tx4938_irq_init();
158 toshiba_rbtx4938_irq_ioc_init();
159 /* Onboard 10M Ether: High Active */
160 set_irq_type(RBTX4938_IRQ_ETHER, IRQF_TRIGGER_HIGH);
161}
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/prom.c b/arch/mips/tx4938/toshiba_rbtx4938/prom.c
deleted file mode 100644
index 1644bffa501a..000000000000
--- a/arch/mips/tx4938/toshiba_rbtx4938/prom.c
+++ /dev/null
@@ -1,74 +0,0 @@
1/*
2 * linux/arch/mips/tx4938/toshiba_rbtx4938/prom.c
3 *
4 * rbtx4938 specific prom routines
5 * Copyright (C) 2000-2001 Toshiba Corporation
6 *
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 * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
13 */
14
15#include <linux/init.h>
16#include <linux/mm.h>
17#include <linux/sched.h>
18#include <linux/bootmem.h>
19
20#include <asm/addrspace.h>
21#include <asm/bootinfo.h>
22#include <asm/tx4938/tx4938.h>
23
24void __init prom_init_cmdline(void)
25{
26 int argc = (int) fw_arg0;
27 char **argv = (char **) fw_arg1;
28 int i;
29
30 /* ignore all built-in args if any f/w args given */
31 if (argc > 1) {
32 *arcs_cmdline = '\0';
33 }
34
35 for (i = 1; i < argc; i++) {
36 if (i != 1) {
37 strcat(arcs_cmdline, " ");
38 }
39 strcat(arcs_cmdline, argv[i]);
40 }
41}
42
43void __init prom_init(void)
44{
45 extern int tx4938_get_mem_size(void);
46 int msize;
47#ifndef CONFIG_TX4938_NAND_BOOT
48 prom_init_cmdline();
49#endif
50
51 msize = tx4938_get_mem_size();
52 add_memory_region(0, msize << 20, BOOT_MEM_RAM);
53
54 return;
55}
56
57void __init prom_free_prom_memory(void)
58{
59}
60
61void __init prom_fixup_mem_map(unsigned long start, unsigned long end)
62{
63 return;
64}
65
66const char *get_system_type(void)
67{
68 return "Toshiba RBTX4938";
69}
70
71char * __init prom_getcmdline(void)
72{
73 return &(arcs_cmdline[0]);
74}
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/setup.c b/arch/mips/tx4938/toshiba_rbtx4938/setup.c
deleted file mode 100644
index 3a3659e8633a..000000000000
--- a/arch/mips/tx4938/toshiba_rbtx4938/setup.c
+++ /dev/null
@@ -1,1124 +0,0 @@
1/*
2 * linux/arch/mips/tx4938/toshiba_rbtx4938/setup.c
3 *
4 * Setup pointers to hardware-dependent routines.
5 * Copyright (C) 2000-2001 Toshiba Corporation
6 *
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 * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
13 */
14#include <linux/init.h>
15#include <linux/types.h>
16#include <linux/ioport.h>
17#include <linux/delay.h>
18#include <linux/interrupt.h>
19#include <linux/console.h>
20#include <linux/pci.h>
21#include <linux/pm.h>
22#include <linux/platform_device.h>
23#include <linux/clk.h>
24#include <linux/gpio.h>
25
26#include <asm/reboot.h>
27#include <asm/time.h>
28#include <asm/txx9tmr.h>
29#include <asm/io.h>
30#include <asm/bootinfo.h>
31#include <asm/tx4938/rbtx4938.h>
32#ifdef CONFIG_SERIAL_TXX9
33#include <linux/serial_core.h>
34#endif
35#include <linux/spi/spi.h>
36#include <asm/tx4938/spi.h>
37#include <asm/txx9pio.h>
38
39extern char * __init prom_getcmdline(void);
40static inline void tx4938_report_pcic_status1(struct tx4938_pcic_reg *pcicptr);
41
42/* These functions are used for rebooting or halting the machine*/
43extern void rbtx4938_machine_restart(char *command);
44extern void rbtx4938_machine_halt(void);
45extern void rbtx4938_machine_power_off(void);
46
47/* clocks */
48unsigned int txx9_master_clock;
49unsigned int txx9_cpu_clock;
50unsigned int txx9_gbus_clock;
51
52unsigned long rbtx4938_ce_base[8];
53unsigned long rbtx4938_ce_size[8];
54int txboard_pci66_mode;
55static int tx4938_pcic_trdyto; /* default: disabled */
56static int tx4938_pcic_retryto; /* default: disabled */
57static int tx4938_ccfg_toeon = 1;
58
59struct tx4938_pcic_reg *pcicptrs[4] = {
60 tx4938_pcicptr /* default setting for TX4938 */
61};
62
63static struct {
64 unsigned long base;
65 unsigned long size;
66} phys_regions[16] __initdata;
67static int num_phys_regions __initdata;
68
69#define PHYS_REGION_MINSIZE 0x10000
70
71void rbtx4938_machine_halt(void)
72{
73 printk(KERN_NOTICE "System Halted\n");
74 local_irq_disable();
75
76 while (1)
77 __asm__(".set\tmips3\n\t"
78 "wait\n\t"
79 ".set\tmips0");
80}
81
82void rbtx4938_machine_power_off(void)
83{
84 rbtx4938_machine_halt();
85 /* no return */
86}
87
88void rbtx4938_machine_restart(char *command)
89{
90 local_irq_disable();
91
92 printk("Rebooting...");
93 writeb(1, rbtx4938_softresetlock_addr);
94 writeb(1, rbtx4938_sfvol_addr);
95 writeb(1, rbtx4938_softreset_addr);
96 while(1)
97 ;
98}
99
100void __init
101txboard_add_phys_region(unsigned long base, unsigned long size)
102{
103 if (num_phys_regions >= ARRAY_SIZE(phys_regions)) {
104 printk("phys_region overflow\n");
105 return;
106 }
107 phys_regions[num_phys_regions].base = base;
108 phys_regions[num_phys_regions].size = size;
109 num_phys_regions++;
110}
111unsigned long __init
112txboard_find_free_phys_region(unsigned long begin, unsigned long end,
113 unsigned long size)
114{
115 unsigned long base;
116 int i;
117
118 for (base = begin / size * size; base < end; base += size) {
119 for (i = 0; i < num_phys_regions; i++) {
120 if (phys_regions[i].size &&
121 base <= phys_regions[i].base + (phys_regions[i].size - 1) &&
122 base + (size - 1) >= phys_regions[i].base)
123 break;
124 }
125 if (i == num_phys_regions)
126 return base;
127 }
128 return 0;
129}
130unsigned long __init
131txboard_find_free_phys_region_shrink(unsigned long begin, unsigned long end,
132 unsigned long *size)
133{
134 unsigned long sz, base;
135 for (sz = *size; sz >= PHYS_REGION_MINSIZE; sz /= 2) {
136 base = txboard_find_free_phys_region(begin, end, sz);
137 if (base) {
138 *size = sz;
139 return base;
140 }
141 }
142 return 0;
143}
144unsigned long __init
145txboard_request_phys_region_range(unsigned long begin, unsigned long end,
146 unsigned long size)
147{
148 unsigned long base;
149 base = txboard_find_free_phys_region(begin, end, size);
150 if (base)
151 txboard_add_phys_region(base, size);
152 return base;
153}
154unsigned long __init
155txboard_request_phys_region(unsigned long size)
156{
157 unsigned long base;
158 unsigned long begin = 0, end = 0x20000000; /* search low 512MB */
159 base = txboard_find_free_phys_region(begin, end, size);
160 if (base)
161 txboard_add_phys_region(base, size);
162 return base;
163}
164unsigned long __init
165txboard_request_phys_region_shrink(unsigned long *size)
166{
167 unsigned long base;
168 unsigned long begin = 0, end = 0x20000000; /* search low 512MB */
169 base = txboard_find_free_phys_region_shrink(begin, end, size);
170 if (base)
171 txboard_add_phys_region(base, *size);
172 return base;
173}
174
175#ifdef CONFIG_PCI
176void __init
177tx4938_pcic_setup(struct tx4938_pcic_reg *pcicptr,
178 struct pci_controller *channel,
179 unsigned long pci_io_base,
180 int extarb)
181{
182 int i;
183
184 /* Disable All Initiator Space */
185 pcicptr->pciccfg &= ~(TX4938_PCIC_PCICCFG_G2PMEN(0)|
186 TX4938_PCIC_PCICCFG_G2PMEN(1)|
187 TX4938_PCIC_PCICCFG_G2PMEN(2)|
188 TX4938_PCIC_PCICCFG_G2PIOEN);
189
190 /* GB->PCI mappings */
191 pcicptr->g2piomask = (channel->io_resource->end - channel->io_resource->start) >> 4;
192 pcicptr->g2piogbase = pci_io_base |
193#ifdef __BIG_ENDIAN
194 TX4938_PCIC_G2PIOGBASE_ECHG
195#else
196 TX4938_PCIC_G2PIOGBASE_BSDIS
197#endif
198 ;
199 pcicptr->g2piopbase = 0;
200 for (i = 0; i < 3; i++) {
201 pcicptr->g2pmmask[i] = 0;
202 pcicptr->g2pmgbase[i] = 0;
203 pcicptr->g2pmpbase[i] = 0;
204 }
205 if (channel->mem_resource->end) {
206 pcicptr->g2pmmask[0] = (channel->mem_resource->end - channel->mem_resource->start) >> 4;
207 pcicptr->g2pmgbase[0] = channel->mem_resource->start |
208#ifdef __BIG_ENDIAN
209 TX4938_PCIC_G2PMnGBASE_ECHG
210#else
211 TX4938_PCIC_G2PMnGBASE_BSDIS
212#endif
213 ;
214 pcicptr->g2pmpbase[0] = channel->mem_resource->start;
215 }
216 /* PCI->GB mappings (I/O 256B) */
217 pcicptr->p2giopbase = 0; /* 256B */
218 pcicptr->p2giogbase = 0;
219 /* PCI->GB mappings (MEM 512MB (64MB on R1.x)) */
220 pcicptr->p2gm0plbase = 0;
221 pcicptr->p2gm0pubase = 0;
222 pcicptr->p2gmgbase[0] = 0 |
223 TX4938_PCIC_P2GMnGBASE_TMEMEN |
224#ifdef __BIG_ENDIAN
225 TX4938_PCIC_P2GMnGBASE_TECHG
226#else
227 TX4938_PCIC_P2GMnGBASE_TBSDIS
228#endif
229 ;
230 /* PCI->GB mappings (MEM 16MB) */
231 pcicptr->p2gm1plbase = 0xffffffff;
232 pcicptr->p2gm1pubase = 0xffffffff;
233 pcicptr->p2gmgbase[1] = 0;
234 /* PCI->GB mappings (MEM 1MB) */
235 pcicptr->p2gm2pbase = 0xffffffff; /* 1MB */
236 pcicptr->p2gmgbase[2] = 0;
237
238 pcicptr->pciccfg &= TX4938_PCIC_PCICCFG_GBWC_MASK;
239 /* Enable Initiator Memory Space */
240 if (channel->mem_resource->end)
241 pcicptr->pciccfg |= TX4938_PCIC_PCICCFG_G2PMEN(0);
242 /* Enable Initiator I/O Space */
243 if (channel->io_resource->end)
244 pcicptr->pciccfg |= TX4938_PCIC_PCICCFG_G2PIOEN;
245 /* Enable Initiator Config */
246 pcicptr->pciccfg |=
247 TX4938_PCIC_PCICCFG_ICAEN |
248 TX4938_PCIC_PCICCFG_TCAR;
249
250 /* Do not use MEMMUL, MEMINF: YMFPCI card causes M_ABORT. */
251 pcicptr->pcicfg1 = 0;
252
253 pcicptr->g2ptocnt &= ~0xffff;
254
255 if (tx4938_pcic_trdyto >= 0) {
256 pcicptr->g2ptocnt &= ~0xff;
257 pcicptr->g2ptocnt |= (tx4938_pcic_trdyto & 0xff);
258 }
259
260 if (tx4938_pcic_retryto >= 0) {
261 pcicptr->g2ptocnt &= ~0xff00;
262 pcicptr->g2ptocnt |= ((tx4938_pcic_retryto<<8) & 0xff00);
263 }
264
265 /* Clear All Local Bus Status */
266 pcicptr->pcicstatus = TX4938_PCIC_PCICSTATUS_ALL;
267 /* Enable All Local Bus Interrupts */
268 pcicptr->pcicmask = TX4938_PCIC_PCICSTATUS_ALL;
269 /* Clear All Initiator Status */
270 pcicptr->g2pstatus = TX4938_PCIC_G2PSTATUS_ALL;
271 /* Enable All Initiator Interrupts */
272 pcicptr->g2pmask = TX4938_PCIC_G2PSTATUS_ALL;
273 /* Clear All PCI Status Error */
274 pcicptr->pcistatus =
275 (pcicptr->pcistatus & 0x0000ffff) |
276 (TX4938_PCIC_PCISTATUS_ALL << 16);
277 /* Enable All PCI Status Error Interrupts */
278 pcicptr->pcimask = TX4938_PCIC_PCISTATUS_ALL;
279
280 if (!extarb) {
281 /* Reset Bus Arbiter */
282 pcicptr->pbacfg = TX4938_PCIC_PBACFG_RPBA;
283 pcicptr->pbabm = 0;
284 /* Enable Bus Arbiter */
285 pcicptr->pbacfg = TX4938_PCIC_PBACFG_PBAEN;
286 }
287
288 /* PCIC Int => IRC IRQ16 */
289 pcicptr->pcicfg2 =
290 (pcicptr->pcicfg2 & 0xffffff00) | TX4938_IR_PCIC;
291
292 pcicptr->pcistatus = PCI_COMMAND_MASTER |
293 PCI_COMMAND_MEMORY |
294 PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
295}
296
297int __init
298tx4938_report_pciclk(void)
299{
300 unsigned long pcode = TX4938_REV_PCODE();
301 int pciclk = 0;
302 printk("TX%lx PCIC --%s PCICLK:",
303 pcode,
304 (tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI66) ? " PCI66" : "");
305 if (tx4938_ccfgptr->pcfg & TX4938_PCFG_PCICLKEN_ALL) {
306
307 switch ((unsigned long)tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIDIVMODE_MASK) {
308 case TX4938_CCFG_PCIDIVMODE_4:
309 pciclk = txx9_cpu_clock / 4; break;
310 case TX4938_CCFG_PCIDIVMODE_4_5:
311 pciclk = txx9_cpu_clock * 2 / 9; break;
312 case TX4938_CCFG_PCIDIVMODE_5:
313 pciclk = txx9_cpu_clock / 5; break;
314 case TX4938_CCFG_PCIDIVMODE_5_5:
315 pciclk = txx9_cpu_clock * 2 / 11; break;
316 case TX4938_CCFG_PCIDIVMODE_8:
317 pciclk = txx9_cpu_clock / 8; break;
318 case TX4938_CCFG_PCIDIVMODE_9:
319 pciclk = txx9_cpu_clock / 9; break;
320 case TX4938_CCFG_PCIDIVMODE_10:
321 pciclk = txx9_cpu_clock / 10; break;
322 case TX4938_CCFG_PCIDIVMODE_11:
323 pciclk = txx9_cpu_clock / 11; break;
324 }
325 printk("Internal(%dMHz)", pciclk / 1000000);
326 } else {
327 printk("External");
328 pciclk = -1;
329 }
330 printk("\n");
331 return pciclk;
332}
333
334void __init set_tx4938_pcicptr(int ch, struct tx4938_pcic_reg *pcicptr)
335{
336 pcicptrs[ch] = pcicptr;
337}
338
339struct tx4938_pcic_reg *get_tx4938_pcicptr(int ch)
340{
341 return pcicptrs[ch];
342}
343
344static struct pci_dev *fake_pci_dev(struct pci_controller *hose,
345 int top_bus, int busnr, int devfn)
346{
347 static struct pci_dev dev;
348 static struct pci_bus bus;
349
350 dev.sysdata = bus.sysdata = hose;
351 dev.devfn = devfn;
352 bus.number = busnr;
353 bus.ops = hose->pci_ops;
354 bus.parent = NULL;
355 dev.bus = &bus;
356
357 return &dev;
358}
359
360#define EARLY_PCI_OP(rw, size, type) \
361static int early_##rw##_config_##size(struct pci_controller *hose, \
362 int top_bus, int bus, int devfn, int offset, type value) \
363{ \
364 return pci_##rw##_config_##size( \
365 fake_pci_dev(hose, top_bus, bus, devfn), \
366 offset, value); \
367}
368
369EARLY_PCI_OP(read, word, u16 *)
370
371int txboard_pci66_check(struct pci_controller *hose, int top_bus, int current_bus)
372{
373 u32 pci_devfn;
374 unsigned short vid;
375 int devfn_start = 0;
376 int devfn_stop = 0xff;
377 int cap66 = -1;
378 u16 stat;
379
380 printk("PCI: Checking 66MHz capabilities...\n");
381
382 for (pci_devfn=devfn_start; pci_devfn<devfn_stop; pci_devfn++) {
383 if (early_read_config_word(hose, top_bus, current_bus,
384 pci_devfn, PCI_VENDOR_ID,
385 &vid) != PCIBIOS_SUCCESSFUL)
386 continue;
387
388 if (vid == 0xffff) continue;
389
390 /* check 66MHz capability */
391 if (cap66 < 0)
392 cap66 = 1;
393 if (cap66) {
394 early_read_config_word(hose, top_bus, current_bus, pci_devfn,
395 PCI_STATUS, &stat);
396 if (!(stat & PCI_STATUS_66MHZ)) {
397 printk(KERN_DEBUG "PCI: %02x:%02x not 66MHz capable.\n",
398 current_bus, pci_devfn);
399 cap66 = 0;
400 break;
401 }
402 }
403 }
404 return cap66 > 0;
405}
406
407int __init
408tx4938_pciclk66_setup(void)
409{
410 int pciclk;
411
412 /* Assert M66EN */
413 tx4938_ccfgptr->ccfg |= TX4938_CCFG_PCI66;
414 /* Double PCICLK (if possible) */
415 if (tx4938_ccfgptr->pcfg & TX4938_PCFG_PCICLKEN_ALL) {
416 unsigned int pcidivmode =
417 tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIDIVMODE_MASK;
418 switch (pcidivmode) {
419 case TX4938_CCFG_PCIDIVMODE_8:
420 case TX4938_CCFG_PCIDIVMODE_4:
421 pcidivmode = TX4938_CCFG_PCIDIVMODE_4;
422 pciclk = txx9_cpu_clock / 4;
423 break;
424 case TX4938_CCFG_PCIDIVMODE_9:
425 case TX4938_CCFG_PCIDIVMODE_4_5:
426 pcidivmode = TX4938_CCFG_PCIDIVMODE_4_5;
427 pciclk = txx9_cpu_clock * 2 / 9;
428 break;
429 case TX4938_CCFG_PCIDIVMODE_10:
430 case TX4938_CCFG_PCIDIVMODE_5:
431 pcidivmode = TX4938_CCFG_PCIDIVMODE_5;
432 pciclk = txx9_cpu_clock / 5;
433 break;
434 case TX4938_CCFG_PCIDIVMODE_11:
435 case TX4938_CCFG_PCIDIVMODE_5_5:
436 default:
437 pcidivmode = TX4938_CCFG_PCIDIVMODE_5_5;
438 pciclk = txx9_cpu_clock * 2 / 11;
439 break;
440 }
441 tx4938_ccfgptr->ccfg =
442 (tx4938_ccfgptr->ccfg & ~TX4938_CCFG_PCIDIVMODE_MASK)
443 | pcidivmode;
444 printk(KERN_DEBUG "PCICLK: ccfg:%08lx\n",
445 (unsigned long)tx4938_ccfgptr->ccfg);
446 } else {
447 pciclk = -1;
448 }
449 return pciclk;
450}
451
452extern struct pci_controller tx4938_pci_controller[];
453static int __init tx4938_pcibios_init(void)
454{
455 unsigned long mem_base[2];
456 unsigned long mem_size[2] = {TX4938_PCIMEM_SIZE_0, TX4938_PCIMEM_SIZE_1}; /* MAX 128M,64K */
457 unsigned long io_base[2];
458 unsigned long io_size[2] = {TX4938_PCIIO_SIZE_0, TX4938_PCIIO_SIZE_1}; /* MAX 16M,64K */
459 /* TX4938 PCIC1: 64K MEM/IO is enough for ETH0,ETH1 */
460 int extarb = !(tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIXARB);
461
462 PCIBIOS_MIN_IO = 0x00001000UL;
463
464 mem_base[0] = txboard_request_phys_region_shrink(&mem_size[0]);
465 io_base[0] = txboard_request_phys_region_shrink(&io_size[0]);
466
467 printk("TX4938 PCIC -- DID:%04x VID:%04x RID:%02x Arbiter:%s\n",
468 (unsigned short)(tx4938_pcicptr->pciid >> 16),
469 (unsigned short)(tx4938_pcicptr->pciid & 0xffff),
470 (unsigned short)(tx4938_pcicptr->pciccrev & 0xff),
471 extarb ? "External" : "Internal");
472
473 /* setup PCI area */
474 tx4938_pci_controller[0].io_resource->start = io_base[0];
475 tx4938_pci_controller[0].io_resource->end = (io_base[0] + io_size[0]) - 1;
476 tx4938_pci_controller[0].mem_resource->start = mem_base[0];
477 tx4938_pci_controller[0].mem_resource->end = mem_base[0] + mem_size[0] - 1;
478
479 set_tx4938_pcicptr(0, tx4938_pcicptr);
480
481 register_pci_controller(&tx4938_pci_controller[0]);
482
483 if (tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI66) {
484 printk("TX4938_CCFG_PCI66 already configured\n");
485 txboard_pci66_mode = -1; /* already configured */
486 }
487
488 /* Reset PCI Bus */
489 writeb(0, rbtx4938_pcireset_addr);
490 /* Reset PCIC */
491 tx4938_ccfgptr->clkctr |= TX4938_CLKCTR_PCIRST;
492 if (txboard_pci66_mode > 0)
493 tx4938_pciclk66_setup();
494 mdelay(10);
495 /* clear PCIC reset */
496 tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIRST;
497 writeb(1, rbtx4938_pcireset_addr);
498 mmiowb();
499 tx4938_report_pcic_status1(tx4938_pcicptr);
500
501 tx4938_report_pciclk();
502 tx4938_pcic_setup(tx4938_pcicptr, &tx4938_pci_controller[0], io_base[0], extarb);
503 if (txboard_pci66_mode == 0 &&
504 txboard_pci66_check(&tx4938_pci_controller[0], 0, 0)) {
505 /* Reset PCI Bus */
506 writeb(0, rbtx4938_pcireset_addr);
507 /* Reset PCIC */
508 tx4938_ccfgptr->clkctr |= TX4938_CLKCTR_PCIRST;
509 tx4938_pciclk66_setup();
510 mdelay(10);
511 /* clear PCIC reset */
512 tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIRST;
513 writeb(1, rbtx4938_pcireset_addr);
514 mmiowb();
515 /* Reinitialize PCIC */
516 tx4938_report_pciclk();
517 tx4938_pcic_setup(tx4938_pcicptr, &tx4938_pci_controller[0], io_base[0], extarb);
518 }
519
520 mem_base[1] = txboard_request_phys_region_shrink(&mem_size[1]);
521 io_base[1] = txboard_request_phys_region_shrink(&io_size[1]);
522 /* Reset PCIC1 */
523 tx4938_ccfgptr->clkctr |= TX4938_CLKCTR_PCIC1RST;
524 /* PCI1DMD==0 => PCI1CLK==GBUSCLK/2 => PCI66 */
525 if (!(tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI1DMD))
526 tx4938_ccfgptr->ccfg |= TX4938_CCFG_PCI1_66;
527 else
528 tx4938_ccfgptr->ccfg &= ~TX4938_CCFG_PCI1_66;
529 mdelay(10);
530 /* clear PCIC1 reset */
531 tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIC1RST;
532 tx4938_report_pcic_status1(tx4938_pcic1ptr);
533
534 printk("TX4938 PCIC1 -- DID:%04x VID:%04x RID:%02x",
535 (unsigned short)(tx4938_pcic1ptr->pciid >> 16),
536 (unsigned short)(tx4938_pcic1ptr->pciid & 0xffff),
537 (unsigned short)(tx4938_pcic1ptr->pciccrev & 0xff));
538 printk("%s PCICLK:%dMHz\n",
539 (tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI1_66) ? " PCI66" : "",
540 txx9_gbus_clock /
541 ((tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI1DMD) ? 4 : 2) /
542 1000000);
543
544 /* assumption: CPHYSADDR(mips_io_port_base) == io_base[0] */
545 tx4938_pci_controller[1].io_resource->start =
546 io_base[1] - io_base[0];
547 tx4938_pci_controller[1].io_resource->end =
548 io_base[1] - io_base[0] + io_size[1] - 1;
549 tx4938_pci_controller[1].mem_resource->start = mem_base[1];
550 tx4938_pci_controller[1].mem_resource->end =
551 mem_base[1] + mem_size[1] - 1;
552 set_tx4938_pcicptr(1, tx4938_pcic1ptr);
553
554 register_pci_controller(&tx4938_pci_controller[1]);
555
556 tx4938_pcic_setup(tx4938_pcic1ptr, &tx4938_pci_controller[1], io_base[1], extarb);
557
558 /* map ioport 0 to PCI I/O space address 0 */
559 set_io_port_base(KSEG1 + io_base[0]);
560
561 return 0;
562}
563
564arch_initcall(tx4938_pcibios_init);
565
566#endif /* CONFIG_PCI */
567
568/* SPI support */
569
570/* chip select for SPI devices */
571#define SEEPROM1_CS 7 /* PIO7 */
572#define SEEPROM2_CS 0 /* IOC */
573#define SEEPROM3_CS 1 /* IOC */
574#define SRTC_CS 2 /* IOC */
575
576#ifdef CONFIG_PCI
577static int __init rbtx4938_ethaddr_init(void)
578{
579 unsigned char dat[17];
580 unsigned char sum;
581 int i;
582
583 /* 0-3: "MAC\0", 4-9:eth0, 10-15:eth1, 16:sum */
584 if (spi_eeprom_read(SEEPROM1_CS, 0, dat, sizeof(dat))) {
585 printk(KERN_ERR "seeprom: read error.\n");
586 return -ENODEV;
587 } else {
588 if (strcmp(dat, "MAC") != 0)
589 printk(KERN_WARNING "seeprom: bad signature.\n");
590 for (i = 0, sum = 0; i < sizeof(dat); i++)
591 sum += dat[i];
592 if (sum)
593 printk(KERN_WARNING "seeprom: bad checksum.\n");
594 }
595 for (i = 0; i < 2; i++) {
596 unsigned int id =
597 TXX9_IRQ_BASE + (i ? TX4938_IR_ETH1 : TX4938_IR_ETH0);
598 struct platform_device *pdev;
599 if (!(tx4938_ccfgptr->pcfg &
600 (i ? TX4938_PCFG_ETH1_SEL : TX4938_PCFG_ETH0_SEL)))
601 continue;
602 pdev = platform_device_alloc("tc35815-mac", id);
603 if (!pdev ||
604 platform_device_add_data(pdev, &dat[4 + 6 * i], 6) ||
605 platform_device_add(pdev))
606 platform_device_put(pdev);
607 }
608 return 0;
609}
610device_initcall(rbtx4938_ethaddr_init);
611#endif /* CONFIG_PCI */
612
613static void __init rbtx4938_spi_setup(void)
614{
615 /* set SPI_SEL */
616 tx4938_ccfgptr->pcfg |= TX4938_PCFG_SPI_SEL;
617}
618
619static struct resource rbtx4938_fpga_resource;
620
621static char pcode_str[8];
622static struct resource tx4938_reg_resource = {
623 .start = TX4938_REG_BASE,
624 .end = TX4938_REG_BASE + TX4938_REG_SIZE,
625 .name = pcode_str,
626 .flags = IORESOURCE_MEM
627};
628
629void __init tx4938_board_setup(void)
630{
631 int i;
632 unsigned long divmode;
633 int cpuclk = 0;
634 unsigned long pcode = TX4938_REV_PCODE();
635
636 ioport_resource.start = 0x1000;
637 ioport_resource.end = 0xffffffff;
638 iomem_resource.start = 0x1000;
639 iomem_resource.end = 0xffffffff; /* expand to 4GB */
640
641 sprintf(pcode_str, "TX%lx", pcode);
642 /* SDRAMC,EBUSC are configured by PROM */
643 for (i = 0; i < 8; i++) {
644 if (!(tx4938_ebuscptr->cr[i] & 0x8))
645 continue; /* disabled */
646 rbtx4938_ce_base[i] = (unsigned long)TX4938_EBUSC_BA(i);
647 txboard_add_phys_region(rbtx4938_ce_base[i], TX4938_EBUSC_SIZE(i));
648 }
649
650 /* clocks */
651 if (txx9_master_clock) {
652 /* calculate gbus_clock and cpu_clock_freq from master_clock */
653 divmode = (unsigned long)tx4938_ccfgptr->ccfg & TX4938_CCFG_DIVMODE_MASK;
654 switch (divmode) {
655 case TX4938_CCFG_DIVMODE_8:
656 case TX4938_CCFG_DIVMODE_10:
657 case TX4938_CCFG_DIVMODE_12:
658 case TX4938_CCFG_DIVMODE_16:
659 case TX4938_CCFG_DIVMODE_18:
660 txx9_gbus_clock = txx9_master_clock * 4; break;
661 default:
662 txx9_gbus_clock = txx9_master_clock;
663 }
664 switch (divmode) {
665 case TX4938_CCFG_DIVMODE_2:
666 case TX4938_CCFG_DIVMODE_8:
667 cpuclk = txx9_gbus_clock * 2; break;
668 case TX4938_CCFG_DIVMODE_2_5:
669 case TX4938_CCFG_DIVMODE_10:
670 cpuclk = txx9_gbus_clock * 5 / 2; break;
671 case TX4938_CCFG_DIVMODE_3:
672 case TX4938_CCFG_DIVMODE_12:
673 cpuclk = txx9_gbus_clock * 3; break;
674 case TX4938_CCFG_DIVMODE_4:
675 case TX4938_CCFG_DIVMODE_16:
676 cpuclk = txx9_gbus_clock * 4; break;
677 case TX4938_CCFG_DIVMODE_4_5:
678 case TX4938_CCFG_DIVMODE_18:
679 cpuclk = txx9_gbus_clock * 9 / 2; break;
680 }
681 txx9_cpu_clock = cpuclk;
682 } else {
683 if (txx9_cpu_clock == 0) {
684 txx9_cpu_clock = 300000000; /* 300MHz */
685 }
686 /* calculate gbus_clock and master_clock from cpu_clock_freq */
687 cpuclk = txx9_cpu_clock;
688 divmode = (unsigned long)tx4938_ccfgptr->ccfg & TX4938_CCFG_DIVMODE_MASK;
689 switch (divmode) {
690 case TX4938_CCFG_DIVMODE_2:
691 case TX4938_CCFG_DIVMODE_8:
692 txx9_gbus_clock = cpuclk / 2; break;
693 case TX4938_CCFG_DIVMODE_2_5:
694 case TX4938_CCFG_DIVMODE_10:
695 txx9_gbus_clock = cpuclk * 2 / 5; break;
696 case TX4938_CCFG_DIVMODE_3:
697 case TX4938_CCFG_DIVMODE_12:
698 txx9_gbus_clock = cpuclk / 3; break;
699 case TX4938_CCFG_DIVMODE_4:
700 case TX4938_CCFG_DIVMODE_16:
701 txx9_gbus_clock = cpuclk / 4; break;
702 case TX4938_CCFG_DIVMODE_4_5:
703 case TX4938_CCFG_DIVMODE_18:
704 txx9_gbus_clock = cpuclk * 2 / 9; break;
705 }
706 switch (divmode) {
707 case TX4938_CCFG_DIVMODE_8:
708 case TX4938_CCFG_DIVMODE_10:
709 case TX4938_CCFG_DIVMODE_12:
710 case TX4938_CCFG_DIVMODE_16:
711 case TX4938_CCFG_DIVMODE_18:
712 txx9_master_clock = txx9_gbus_clock / 4; break;
713 default:
714 txx9_master_clock = txx9_gbus_clock;
715 }
716 }
717 /* change default value to udelay/mdelay take reasonable time */
718 loops_per_jiffy = txx9_cpu_clock / HZ / 2;
719
720 /* CCFG */
721 /* clear WatchDogReset,BusErrorOnWrite flag (W1C) */
722 tx4938_ccfgptr->ccfg |= TX4938_CCFG_WDRST | TX4938_CCFG_BEOW;
723 /* do reset on watchdog */
724 tx4938_ccfgptr->ccfg |= TX4938_CCFG_WR;
725 /* clear PCIC1 reset */
726 if (tx4938_ccfgptr->clkctr & TX4938_CLKCTR_PCIC1RST)
727 tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIC1RST;
728
729 /* enable Timeout BusError */
730 if (tx4938_ccfg_toeon)
731 tx4938_ccfgptr->ccfg |= TX4938_CCFG_TOE;
732
733 /* DMA selection */
734 tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_DMASEL_ALL;
735
736 /* Use external clock for external arbiter */
737 if (!(tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIXARB))
738 tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_PCICLKEN_ALL;
739
740 printk("%s -- %dMHz(M%dMHz) CRIR:%08lx CCFG:%Lx PCFG:%Lx\n",
741 pcode_str,
742 cpuclk / 1000000, txx9_master_clock / 1000000,
743 (unsigned long)tx4938_ccfgptr->crir,
744 tx4938_ccfgptr->ccfg,
745 tx4938_ccfgptr->pcfg);
746
747 printk("%s SDRAMC --", pcode_str);
748 for (i = 0; i < 4; i++) {
749 unsigned long long cr = tx4938_sdramcptr->cr[i];
750 unsigned long ram_base, ram_size;
751 if (!((unsigned long)cr & 0x00000400))
752 continue; /* disabled */
753 ram_base = (unsigned long)(cr >> 49) << 21;
754 ram_size = ((unsigned long)(cr >> 33) + 1) << 21;
755 if (ram_base >= 0x20000000)
756 continue; /* high memory (ignore) */
757 printk(" CR%d:%016Lx", i, cr);
758 txboard_add_phys_region(ram_base, ram_size);
759 }
760 printk(" TR:%09Lx\n", tx4938_sdramcptr->tr);
761
762 /* SRAM */
763 if (pcode == 0x4938 && tx4938_sramcptr->cr & 1) {
764 unsigned int size = 0x800;
765 unsigned long base =
766 (tx4938_sramcptr->cr >> (39-11)) & ~(size - 1);
767 txboard_add_phys_region(base, size);
768 }
769
770 /* TMR */
771 for (i = 0; i < TX4938_NR_TMR; i++)
772 txx9_tmr_init(TX4938_TMR_REG(i) & 0xfffffffffULL);
773
774 /* enable DMA */
775 for (i = 0; i < 2; i++)
776 ____raw_writeq(TX4938_DMA_MCR_MSTEN,
777 (void __iomem *)(TX4938_DMA_REG(i) + 0x50));
778
779 /* PIO */
780 __raw_writel(0, &tx4938_pioptr->maskcpu);
781 __raw_writel(0, &tx4938_pioptr->maskext);
782
783 /* TX4938 internal registers */
784 if (request_resource(&iomem_resource, &tx4938_reg_resource))
785 printk("request resource for internal registers failed\n");
786}
787
788#ifdef CONFIG_PCI
789static inline void tx4938_report_pcic_status1(struct tx4938_pcic_reg *pcicptr)
790{
791 unsigned short pcistatus = (unsigned short)(pcicptr->pcistatus >> 16);
792 unsigned long g2pstatus = pcicptr->g2pstatus;
793 unsigned long pcicstatus = pcicptr->pcicstatus;
794 static struct {
795 unsigned long flag;
796 const char *str;
797 } pcistat_tbl[] = {
798 { PCI_STATUS_DETECTED_PARITY, "DetectedParityError" },
799 { PCI_STATUS_SIG_SYSTEM_ERROR, "SignaledSystemError" },
800 { PCI_STATUS_REC_MASTER_ABORT, "ReceivedMasterAbort" },
801 { PCI_STATUS_REC_TARGET_ABORT, "ReceivedTargetAbort" },
802 { PCI_STATUS_SIG_TARGET_ABORT, "SignaledTargetAbort" },
803 { PCI_STATUS_PARITY, "MasterParityError" },
804 }, g2pstat_tbl[] = {
805 { TX4938_PCIC_G2PSTATUS_TTOE, "TIOE" },
806 { TX4938_PCIC_G2PSTATUS_RTOE, "RTOE" },
807 }, pcicstat_tbl[] = {
808 { TX4938_PCIC_PCICSTATUS_PME, "PME" },
809 { TX4938_PCIC_PCICSTATUS_TLB, "TLB" },
810 { TX4938_PCIC_PCICSTATUS_NIB, "NIB" },
811 { TX4938_PCIC_PCICSTATUS_ZIB, "ZIB" },
812 { TX4938_PCIC_PCICSTATUS_PERR, "PERR" },
813 { TX4938_PCIC_PCICSTATUS_SERR, "SERR" },
814 { TX4938_PCIC_PCICSTATUS_GBE, "GBE" },
815 { TX4938_PCIC_PCICSTATUS_IWB, "IWB" },
816 };
817 int i;
818
819 printk("pcistat:%04x(", pcistatus);
820 for (i = 0; i < ARRAY_SIZE(pcistat_tbl); i++)
821 if (pcistatus & pcistat_tbl[i].flag)
822 printk("%s ", pcistat_tbl[i].str);
823 printk("), g2pstatus:%08lx(", g2pstatus);
824 for (i = 0; i < ARRAY_SIZE(g2pstat_tbl); i++)
825 if (g2pstatus & g2pstat_tbl[i].flag)
826 printk("%s ", g2pstat_tbl[i].str);
827 printk("), pcicstatus:%08lx(", pcicstatus);
828 for (i = 0; i < ARRAY_SIZE(pcicstat_tbl); i++)
829 if (pcicstatus & pcicstat_tbl[i].flag)
830 printk("%s ", pcicstat_tbl[i].str);
831 printk(")\n");
832}
833
834void tx4938_report_pcic_status(void)
835{
836 int i;
837 struct tx4938_pcic_reg *pcicptr;
838 for (i = 0; (pcicptr = get_tx4938_pcicptr(i)) != NULL; i++)
839 tx4938_report_pcic_status1(pcicptr);
840}
841
842#endif /* CONFIG_PCI */
843
844void __init plat_time_init(void)
845{
846 mips_hpt_frequency = txx9_cpu_clock / 2;
847 if (tx4938_ccfgptr->ccfg & TX4938_CCFG_TINTDIS)
848 txx9_clockevent_init(TX4938_TMR_REG(0) & 0xfffffffffULL,
849 TXX9_IRQ_BASE + TX4938_IR_TMR(0),
850 txx9_gbus_clock / 2);
851}
852
853void __init plat_mem_setup(void)
854{
855 unsigned long long pcfg;
856 char *argptr;
857
858 iomem_resource.end = 0xffffffff; /* 4GB */
859
860 if (txx9_master_clock == 0)
861 txx9_master_clock = 25000000; /* 25MHz */
862 tx4938_board_setup();
863#ifndef CONFIG_PCI
864 set_io_port_base(RBTX4938_ETHER_BASE);
865#endif
866
867#ifdef CONFIG_SERIAL_TXX9
868 {
869 extern int early_serial_txx9_setup(struct uart_port *port);
870 int i;
871 struct uart_port req;
872 for(i = 0; i < 2; i++) {
873 memset(&req, 0, sizeof(req));
874 req.line = i;
875 req.iotype = UPIO_MEM;
876 req.membase = (char *)(0xff1ff300 + i * 0x100);
877 req.mapbase = 0xff1ff300 + i * 0x100;
878 req.irq = RBTX4938_IRQ_IRC_SIO(i);
879 req.flags |= UPF_BUGGY_UART /*HAVE_CTS_LINE*/;
880 req.uartclk = 50000000;
881 early_serial_txx9_setup(&req);
882 }
883 }
884#ifdef CONFIG_SERIAL_TXX9_CONSOLE
885 argptr = prom_getcmdline();
886 if (strstr(argptr, "console=") == NULL) {
887 strcat(argptr, " console=ttyS0,38400");
888 }
889#endif
890#endif
891
892#ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_PIO58_61
893 printk("PIOSEL: disabling both ata and nand selection\n");
894 local_irq_disable();
895 tx4938_ccfgptr->pcfg &= ~(TX4938_PCFG_NDF_SEL | TX4938_PCFG_ATA_SEL);
896#endif
897
898#ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_NAND
899 printk("PIOSEL: enabling nand selection\n");
900 tx4938_ccfgptr->pcfg |= TX4938_PCFG_NDF_SEL;
901 tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_ATA_SEL;
902#endif
903
904#ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_ATA
905 printk("PIOSEL: enabling ata selection\n");
906 tx4938_ccfgptr->pcfg |= TX4938_PCFG_ATA_SEL;
907 tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_NDF_SEL;
908#endif
909
910#ifdef CONFIG_IP_PNP
911 argptr = prom_getcmdline();
912 if (strstr(argptr, "ip=") == NULL) {
913 strcat(argptr, " ip=any");
914 }
915#endif
916
917
918#ifdef CONFIG_FB
919 {
920 conswitchp = &dummy_con;
921 }
922#endif
923
924 rbtx4938_spi_setup();
925 pcfg = tx4938_ccfgptr->pcfg; /* updated */
926 /* fixup piosel */
927 if ((pcfg & (TX4938_PCFG_ATA_SEL | TX4938_PCFG_NDF_SEL)) ==
928 TX4938_PCFG_ATA_SEL)
929 writeb((readb(rbtx4938_piosel_addr) & 0x03) | 0x04,
930 rbtx4938_piosel_addr);
931 else if ((pcfg & (TX4938_PCFG_ATA_SEL | TX4938_PCFG_NDF_SEL)) ==
932 TX4938_PCFG_NDF_SEL)
933 writeb((readb(rbtx4938_piosel_addr) & 0x03) | 0x08,
934 rbtx4938_piosel_addr);
935 else
936 writeb(readb(rbtx4938_piosel_addr) & ~(0x08 | 0x04),
937 rbtx4938_piosel_addr);
938
939 rbtx4938_fpga_resource.name = "FPGA Registers";
940 rbtx4938_fpga_resource.start = CPHYSADDR(RBTX4938_FPGA_REG_ADDR);
941 rbtx4938_fpga_resource.end = CPHYSADDR(RBTX4938_FPGA_REG_ADDR) + 0xffff;
942 rbtx4938_fpga_resource.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
943 if (request_resource(&iomem_resource, &rbtx4938_fpga_resource))
944 printk("request resource for fpga failed\n");
945
946 _machine_restart = rbtx4938_machine_restart;
947 _machine_halt = rbtx4938_machine_halt;
948 pm_power_off = rbtx4938_machine_power_off;
949
950 writeb(0xff, rbtx4938_led_addr);
951 printk(KERN_INFO "RBTX4938 --- FPGA(Rev %02x) DIPSW:%02x,%02x\n",
952 readb(rbtx4938_fpga_rev_addr),
953 readb(rbtx4938_dipsw_addr), readb(rbtx4938_bdipsw_addr));
954}
955
956static int __init rbtx4938_ne_init(void)
957{
958 struct resource res[] = {
959 {
960 .start = RBTX4938_RTL_8019_BASE,
961 .end = RBTX4938_RTL_8019_BASE + 0x20 - 1,
962 .flags = IORESOURCE_IO,
963 }, {
964 .start = RBTX4938_RTL_8019_IRQ,
965 .flags = IORESOURCE_IRQ,
966 }
967 };
968 struct platform_device *dev =
969 platform_device_register_simple("ne", -1,
970 res, ARRAY_SIZE(res));
971 return IS_ERR(dev) ? PTR_ERR(dev) : 0;
972}
973device_initcall(rbtx4938_ne_init);
974
975/* GPIO support */
976
977int gpio_to_irq(unsigned gpio)
978{
979 return -EINVAL;
980}
981
982int irq_to_gpio(unsigned irq)
983{
984 return -EINVAL;
985}
986
987static DEFINE_SPINLOCK(rbtx4938_spi_gpio_lock);
988
989static void rbtx4938_spi_gpio_set(struct gpio_chip *chip, unsigned int offset,
990 int value)
991{
992 u8 val;
993 unsigned long flags;
994 spin_lock_irqsave(&rbtx4938_spi_gpio_lock, flags);
995 val = readb(rbtx4938_spics_addr);
996 if (value)
997 val |= 1 << offset;
998 else
999 val &= ~(1 << offset);
1000 writeb(val, rbtx4938_spics_addr);
1001 mmiowb();
1002 spin_unlock_irqrestore(&rbtx4938_spi_gpio_lock, flags);
1003}
1004
1005static int rbtx4938_spi_gpio_dir_out(struct gpio_chip *chip,
1006 unsigned int offset, int value)
1007{
1008 rbtx4938_spi_gpio_set(chip, offset, value);
1009 return 0;
1010}
1011
1012static struct gpio_chip rbtx4938_spi_gpio_chip = {
1013 .set = rbtx4938_spi_gpio_set,
1014 .direction_output = rbtx4938_spi_gpio_dir_out,
1015 .label = "RBTX4938-SPICS",
1016 .base = 16,
1017 .ngpio = 3,
1018};
1019
1020/* SPI support */
1021
1022static void __init txx9_spi_init(unsigned long base, int irq)
1023{
1024 struct resource res[] = {
1025 {
1026 .start = base,
1027 .end = base + 0x20 - 1,
1028 .flags = IORESOURCE_MEM,
1029 }, {
1030 .start = irq,
1031 .flags = IORESOURCE_IRQ,
1032 },
1033 };
1034 platform_device_register_simple("spi_txx9", 0,
1035 res, ARRAY_SIZE(res));
1036}
1037
1038static int __init rbtx4938_spi_init(void)
1039{
1040 struct spi_board_info srtc_info = {
1041 .modalias = "rtc-rs5c348",
1042 .max_speed_hz = 1000000, /* 1.0Mbps @ Vdd 2.0V */
1043 .bus_num = 0,
1044 .chip_select = 16 + SRTC_CS,
1045 /* Mode 1 (High-Active, Shift-Then-Sample), High Avtive CS */
1046 .mode = SPI_MODE_1 | SPI_CS_HIGH,
1047 };
1048 spi_register_board_info(&srtc_info, 1);
1049 spi_eeprom_register(SEEPROM1_CS);
1050 spi_eeprom_register(16 + SEEPROM2_CS);
1051 spi_eeprom_register(16 + SEEPROM3_CS);
1052 gpio_request(16 + SRTC_CS, "rtc-rs5c348");
1053 gpio_direction_output(16 + SRTC_CS, 0);
1054 gpio_request(SEEPROM1_CS, "seeprom1");
1055 gpio_direction_output(SEEPROM1_CS, 1);
1056 gpio_request(16 + SEEPROM2_CS, "seeprom2");
1057 gpio_direction_output(16 + SEEPROM2_CS, 1);
1058 gpio_request(16 + SEEPROM3_CS, "seeprom3");
1059 gpio_direction_output(16 + SEEPROM3_CS, 1);
1060 txx9_spi_init(TX4938_SPI_REG & 0xfffffffffULL, RBTX4938_IRQ_IRC_SPI);
1061 return 0;
1062}
1063
1064static int __init rbtx4938_arch_init(void)
1065{
1066 txx9_gpio_init(TX4938_PIO_REG & 0xfffffffffULL, 0, 16);
1067 gpiochip_add(&rbtx4938_spi_gpio_chip);
1068 return rbtx4938_spi_init();
1069}
1070arch_initcall(rbtx4938_arch_init);
1071
1072/* Watchdog support */
1073
1074static int __init txx9_wdt_init(unsigned long base)
1075{
1076 struct resource res = {
1077 .start = base,
1078 .end = base + 0x100 - 1,
1079 .flags = IORESOURCE_MEM,
1080 };
1081 struct platform_device *dev =
1082 platform_device_register_simple("txx9wdt", -1, &res, 1);
1083 return IS_ERR(dev) ? PTR_ERR(dev) : 0;
1084}
1085
1086static int __init rbtx4938_wdt_init(void)
1087{
1088 return txx9_wdt_init(TX4938_TMR_REG(2) & 0xfffffffffULL);
1089}
1090device_initcall(rbtx4938_wdt_init);
1091
1092/* Minimum CLK support */
1093
1094struct clk *clk_get(struct device *dev, const char *id)
1095{
1096 if (!strcmp(id, "spi-baseclk"))
1097 return (struct clk *)(txx9_gbus_clock / 2 / 4);
1098 if (!strcmp(id, "imbus_clk"))
1099 return (struct clk *)(txx9_gbus_clock / 2);
1100 return ERR_PTR(-ENOENT);
1101}
1102EXPORT_SYMBOL(clk_get);
1103
1104int clk_enable(struct clk *clk)
1105{
1106 return 0;
1107}
1108EXPORT_SYMBOL(clk_enable);
1109
1110void clk_disable(struct clk *clk)
1111{
1112}
1113EXPORT_SYMBOL(clk_disable);
1114
1115unsigned long clk_get_rate(struct clk *clk)
1116{
1117 return (unsigned long)clk;
1118}
1119EXPORT_SYMBOL(clk_get_rate);
1120
1121void clk_put(struct clk *clk)
1122{
1123}
1124EXPORT_SYMBOL(clk_put);
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/spi_eeprom.c b/arch/mips/tx4938/toshiba_rbtx4938/spi_eeprom.c
deleted file mode 100644
index 4d6b4ade5e8c..000000000000
--- a/arch/mips/tx4938/toshiba_rbtx4938/spi_eeprom.c
+++ /dev/null
@@ -1,99 +0,0 @@
1/*
2 * linux/arch/mips/tx4938/toshiba_rbtx4938/spi_eeprom.c
3 * Copyright (C) 2000-2001 Toshiba Corporation
4 *
5 * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
6 * terms of the GNU General Public License version 2. This program is
7 * licensed "as is" without any warranty of any kind, whether express
8 * or implied.
9 *
10 * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
11 */
12#include <linux/init.h>
13#include <linux/device.h>
14#include <linux/spi/spi.h>
15#include <linux/spi/eeprom.h>
16#include <asm/tx4938/spi.h>
17
18#define AT250X0_PAGE_SIZE 8
19
20/* register board information for at25 driver */
21int __init spi_eeprom_register(int chipid)
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 = {
30 .modalias = "at25",
31 .max_speed_hz = 1500000, /* 1.5Mbps */
32 .bus_num = 0,
33 .chip_select = chipid,
34 .platform_data = &eeprom,
35 /* Mode 0: High-Active, Sample-Then-Shift */
36 };
37
38 return spi_register_board_info(&info, 1);
39}
40
41/* simple temporary spi driver to provide early access to seeprom. */
42
43static struct read_param {
44 int chipid;
45 int address;
46 unsigned char *buf;
47 int len;
48} *read_param;
49
50static int __init early_seeprom_probe(struct spi_device *spi)
51{
52 int stat = 0;
53 u8 cmd[2];
54 int len = read_param->len;
55 char *buf = read_param->buf;
56 int address = read_param->address;
57
58 dev_info(&spi->dev, "spiclk %u KHz.\n",
59 (spi->max_speed_hz + 500) / 1000);
60 if (read_param->chipid != spi->chip_select)
61 return -ENODEV;
62 while (len > 0) {
63 /* spi_write_then_read can only work with small chunk */
64 int c = len < AT250X0_PAGE_SIZE ? len : AT250X0_PAGE_SIZE;
65 cmd[0] = 0x03; /* AT25_READ */
66 cmd[1] = address;
67 stat = spi_write_then_read(spi, cmd, sizeof(cmd), buf, c);
68 buf += c;
69 len -= c;
70 address += c;
71 }
72 return stat;
73}
74
75static struct spi_driver early_seeprom_driver __initdata = {
76 .driver = {
77 .name = "at25",
78 .owner = THIS_MODULE,
79 },
80 .probe = early_seeprom_probe,
81};
82
83int __init spi_eeprom_read(int chipid, int address,
84 unsigned char *buf, int len)
85{
86 int ret;
87 struct read_param param = {
88 .chipid = chipid,
89 .address = address,
90 .buf = buf,
91 .len = len
92 };
93
94 read_param = &param;
95 ret = spi_register_driver(&early_seeprom_driver);
96 if (!ret)
97 spi_unregister_driver(&early_seeprom_driver);
98 return ret;
99}