add initial 2.6.28 support for brcm47xx target
[openwrt.git] / target / linux / brcm47xx / patches-2.6.28 / 400-arch-bcm47xx.patch
1 diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
2 --- a/arch/mips/Kconfig
3 +++ b/arch/mips/Kconfig
4 @@ -53,6 +53,7 @@ config BCM47XX
5         select SSB_DRIVER_MIPS
6         select SSB_DRIVER_EXTIF
7         select SSB_EMBEDDED
8 +       select SSB_B43_PCI_BRIDGE
9         select SSB_PCICORE_HOSTMODE if PCI
10         select GENERIC_GPIO
11         select SYS_HAS_EARLY_PRINTK
12 diff --git a/arch/mips/bcm47xx/Makefile b/arch/mips/bcm47xx/Makefile
13 --- a/arch/mips/bcm47xx/Makefile
14 +++ b/arch/mips/bcm47xx/Makefile
15 @@ -3,4 +3,4 @@
16  # under Linux.
17  #
18  
19 -obj-y := gpio.o irq.o prom.o serial.o setup.o time.o wgt634u.o
20 +obj-y := cfe_env.o gpio.o irq.o nvram.o prom.o serial.o setup.o time.o wgt634u.o
21 diff --git a/arch/mips/bcm47xx/irq.c b/arch/mips/bcm47xx/irq.c
22 --- a/arch/mips/bcm47xx/irq.c
23 +++ b/arch/mips/bcm47xx/irq.c
24 @@ -1,5 +1,6 @@
25  /*
26   *  Copyright (C) 2004 Florian Schirmer <jolt@tuxbox.org>
27 + *  Copyright (C) 2008 Michael Buesch <mb@bu3sch.de>
28   *
29   *  This program is free software; you can redistribute  it and/or modify it
30   *  under  the terms of  the GNU General  Public License as published by the
31 @@ -23,10 +24,19 @@
32   */
33  
34  #include <linux/types.h>
35 +#include <linux/errno.h>
36 +#include <linux/init.h>
37  #include <linux/interrupt.h>
38  #include <linux/irq.h>
39 +#include <linux/pci.h>
40 +#include <linux/ssb/ssb.h>
41 +
42  #include <asm/irq_cpu.h>
43  
44 +
45 +extern struct ssb_bus ssb_bcm47xx;
46 +
47 +
48  void plat_irq_dispatch(void)
49  {
50         u32 cause;
51 diff --git a/arch/mips/bcm47xx/nvram.c b/arch/mips/bcm47xx/nvram.c
52 --- a/arch/mips/bcm47xx/nvram.c
53 +++ b/arch/mips/bcm47xx/nvram.c
54 @@ -24,10 +24,10 @@
55  #include <asm/io.h>
56  #include <asm/uaccess.h>
57  
58 -#include <nvram.h>
59 +#include "include/nvram.h"
60  
61  #define MB * 1048576
62 -extern struct ssb_bus ssb;
63 +extern struct ssb_bus ssb_bcm47xx;
64  
65  static char nvram_buf[NVRAM_SPACE];
66  static int cfe_env;
67 @@ -36,7 +36,7 @@ extern char *cfe_env_get(char *nv_buf, const char *name);
68  /* Probe for NVRAM header */
69  static void __init early_nvram_init(void)
70  {
71 -       struct ssb_mipscore *mcore = &ssb.mipscore;
72 +       struct ssb_mipscore *mcore = &ssb_bcm47xx.mipscore;
73         struct nvram_header *header;
74         int i;
75         u32 base, lim, off;
76 diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c
77 --- a/arch/mips/bcm47xx/setup.c
78 +++ b/arch/mips/bcm47xx/setup.c
79 @@ -2,7 +2,7 @@
80   *  Copyright (C) 2004 Florian Schirmer <jolt@tuxbox.org>
81   *  Copyright (C) 2005 Waldemar Brodkorb <wbx@openwrt.org>
82   *  Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
83 - *  Copyright (C) 2006 Michael Buesch <mb@bu3sch.de>
84 + *  Copyright (C) 2006-2008 Michael Buesch <mb@bu3sch.de>
85   *
86   *  This program is free software; you can redistribute  it and/or modify it
87   *  under  the terms of  the GNU General  Public License as published by the
88 @@ -25,18 +25,28 @@
89   *  675 Mass Ave, Cambridge, MA 02139, USA.
90   */
91  
92 +#include <linux/init.h>
93  #include <linux/types.h>
94  #include <linux/ssb/ssb.h>
95  #include <linux/ssb/ssb_embedded.h>
96 +#include <linux/tty.h>
97 +#include <linux/serial.h>
98 +#include <linux/serial_core.h>
99 +#include <linux/serial_reg.h>
100 +#include <linux/serial_8250.h>
101  #include <asm/bootinfo.h>
102  #include <asm/reboot.h>
103  #include <asm/time.h>
104 -#include <bcm47xx.h>
105  #include <asm/fw/cfe/cfe_api.h>
106 +#include <linux/pm.h>
107 +
108 +#include "include/nvram.h"
109  
110  struct ssb_bus ssb_bcm47xx;
111  EXPORT_SYMBOL(ssb_bcm47xx);
112  
113 +extern void bcm47xx_pci_init(void);
114 +
115  static void bcm47xx_machine_restart(char *command)
116  {
117         printk(KERN_ALERT "Please stand by while rebooting the system...\n");
118 @@ -56,7 +66,7 @@ static void bcm47xx_machine_halt(void)
119                 cpu_relax();
120  }
121  
122 -static void str2eaddr(char *str, char *dest)
123 +static void e_aton(char *str, char *dest)
124  {
125         int i = 0;
126  
127 @@ -73,52 +83,141 @@ static void str2eaddr(char *str, char *dest)
128         }
129  }
130  
131 -static int bcm47xx_get_invariants(struct ssb_bus *bus,
132 -                                  struct ssb_init_invariants *iv)
133 +static void bcm47xx_fill_sprom(struct ssb_sprom *sprom)
134 +{
135 +       char *s;
136 +
137 +       memset(sprom, 0xFF, sizeof(struct ssb_sprom));
138 +
139 +       sprom->revision = 1;
140 +       if ((s = nvram_get("il0macaddr")))
141 +               e_aton(s, sprom->il0mac);
142 +       if ((s = nvram_get("et0macaddr")))
143 +               e_aton(s, sprom->et0mac);
144 +       if ((s = nvram_get("et1macaddr")))
145 +               e_aton(s, sprom->et1mac);
146 +       if ((s = nvram_get("et0phyaddr")))
147 +               sprom->et0phyaddr = simple_strtoul(s, NULL, 0);
148 +       if ((s = nvram_get("et1phyaddr")))
149 +               sprom->et1phyaddr = simple_strtoul(s, NULL, 0);
150 +       if ((s = nvram_get("et0mdcport")))
151 +               sprom->et0mdcport = !!simple_strtoul(s, NULL, 10);
152 +       if ((s = nvram_get("et1mdcport")))
153 +               sprom->et1mdcport = !!simple_strtoul(s, NULL, 10);
154 +       if ((s = nvram_get("pa0b0")))
155 +               sprom->pa0b0 = simple_strtoul(s, NULL, 0);
156 +       if ((s = nvram_get("pa0b1")))
157 +               sprom->pa0b1 = simple_strtoul(s, NULL, 0);
158 +       if ((s = nvram_get("pa0b2")))
159 +               sprom->pa0b2 = simple_strtoul(s, NULL, 0);
160 +       if ((s = nvram_get("pa1b0")))
161 +               sprom->pa1b0 = simple_strtoul(s, NULL, 0);
162 +       if ((s = nvram_get("pa1b1")))
163 +               sprom->pa1b1 = simple_strtoul(s, NULL, 0);
164 +       if ((s = nvram_get("pa1b2")))
165 +               sprom->pa1b2 = simple_strtoul(s, NULL, 0);
166 +       if ((s = nvram_get("wl0gpio0")))
167 +               sprom->gpio0 = simple_strtoul(s, NULL, 0);
168 +       if ((s = nvram_get("wl0gpio1")))
169 +               sprom->gpio1 = simple_strtoul(s, NULL, 0);
170 +       if ((s = nvram_get("wl0gpio2")))
171 +               sprom->gpio2 = simple_strtoul(s, NULL, 0);
172 +       if ((s = nvram_get("wl0gpio3")))
173 +               sprom->gpio3 = simple_strtoul(s, NULL, 0);
174 +       if ((s = nvram_get("pa0maxpwr")))
175 +               sprom->maxpwr_bg = simple_strtoul(s, NULL, 0);
176 +       if ((s = nvram_get("pa1maxpwr")))
177 +               sprom->maxpwr_a = simple_strtoul(s, NULL, 0);
178 +       if ((s = nvram_get("pa0itssit")))
179 +               sprom->itssi_bg = simple_strtoul(s, NULL, 0);
180 +       if ((s = nvram_get("pa1itssit")))
181 +               sprom->itssi_a = simple_strtoul(s, NULL, 0);
182 +       sprom->boardflags_lo = 0;
183 +       if ((s = nvram_get("boardflags")))
184 +               sprom->boardflags_lo = simple_strtoul(s, NULL, 0);
185 +       sprom->boardflags_hi = 0;
186 +       if ((s = nvram_get("boardflags2")))
187 +               sprom->boardflags_hi = simple_strtoul(s, NULL, 0);
188 +}
189 +
190 +static int bcm47xx_get_invariants(struct ssb_bus *bus, struct ssb_init_invariants *iv)
191  {
192 -       char buf[100];
193 -
194 -       /* Fill boardinfo structure */
195 -       memset(&(iv->boardinfo), 0 , sizeof(struct ssb_boardinfo));
196 -
197 -       if (cfe_getenv("boardvendor", buf, sizeof(buf)) >= 0)
198 -               iv->boardinfo.type = (u16)simple_strtoul(buf, NULL, 0);
199 -       if (cfe_getenv("boardtype", buf, sizeof(buf)) >= 0)
200 -               iv->boardinfo.type = (u16)simple_strtoul(buf, NULL, 0);
201 -       if (cfe_getenv("boardrev", buf, sizeof(buf)) >= 0)
202 -               iv->boardinfo.rev = (u16)simple_strtoul(buf, NULL, 0);
203 -
204 -       /* Fill sprom structure */
205 -       memset(&(iv->sprom), 0, sizeof(struct ssb_sprom));
206 -       iv->sprom.revision = 3;
207 -
208 -       if (cfe_getenv("et0macaddr", buf, sizeof(buf)) >= 0)
209 -               str2eaddr(buf, iv->sprom.et0mac);
210 -       if (cfe_getenv("et1macaddr", buf, sizeof(buf)) >= 0)
211 -               str2eaddr(buf, iv->sprom.et1mac);
212 -       if (cfe_getenv("et0phyaddr", buf, sizeof(buf)) >= 0)
213 -               iv->sprom.et0phyaddr = simple_strtoul(buf, NULL, 10);
214 -       if (cfe_getenv("et1phyaddr", buf, sizeof(buf)) >= 0)
215 -               iv->sprom.et1phyaddr = simple_strtoul(buf, NULL, 10);
216 -       if (cfe_getenv("et0mdcport", buf, sizeof(buf)) >= 0)
217 -               iv->sprom.et0mdcport = simple_strtoul(buf, NULL, 10);
218 -       if (cfe_getenv("et1mdcport", buf, sizeof(buf)) >= 0)
219 -               iv->sprom.et1mdcport = simple_strtoul(buf, NULL, 10);
220 +       char *s;
221 +
222 +       iv->boardinfo.vendor = SSB_BOARDVENDOR_BCM;
223 +       if ((s = nvram_get("boardtype")))
224 +               iv->boardinfo.type = (u16)simple_strtoul(s, NULL, 0);
225 +       if ((s = nvram_get("boardrev")))
226 +               iv->boardinfo.rev = (u16)simple_strtoul(s, NULL, 0);
227 +
228 +       bcm47xx_fill_sprom(&iv->sprom);
229 +
230 +       if ((s = nvram_get("cardbus")))
231 +               iv->has_cardbus_slot = !!simple_strtoul(s, NULL, 10);
232  
233         return 0;
234  }
235  
236  void __init plat_mem_setup(void)
237  {
238 -       int err;
239 +       int i, err;
240 +       char *s;
241 +       struct ssb_mipscore *mcore;
242 +
243 +       err = ssb_bus_ssbbus_register(&ssb_bcm47xx, SSB_ENUM_BASE, bcm47xx_get_invariants);
244 +       if (err) {
245 +               const char *msg = "Failed to initialize SSB bus (err %d)\n";
246 +               printk(msg, err); /* Make sure the message gets out of the box. */
247 +               panic(msg, err);
248 +       }
249 +       mcore = &ssb_bcm47xx.mipscore;
250 +
251 +       s = nvram_get("kernel_args");
252 +       if (s && !strncmp(s, "console=ttyS1", 13)) {
253 +               struct ssb_serial_port port;
254  
255 -       err = ssb_bus_ssbbus_register(&ssb_bcm47xx, SSB_ENUM_BASE,
256 -                                     bcm47xx_get_invariants);
257 -       if (err)
258 -               panic("Failed to initialize SSB bus (err %d)\n", err);
259 +               printk("Swapping serial ports!\n");
260 +               /* swap serial ports */
261 +               memcpy(&port, &mcore->serial_ports[0], sizeof(port));
262 +               memcpy(&mcore->serial_ports[0], &mcore->serial_ports[1], sizeof(port));
263 +               memcpy(&mcore->serial_ports[1], &port, sizeof(port));
264 +       }
265 +
266 +       for (i = 0; i < mcore->nr_serial_ports; i++) {
267 +               struct ssb_serial_port *port = &(mcore->serial_ports[i]);
268 +               struct uart_port s;
269 +
270 +               memset(&s, 0, sizeof(s));
271 +               s.line = i;
272 +               s.membase = port->regs;
273 +               s.irq = port->irq + 2;
274 +               s.uartclk = port->baud_base;
275 +               s.flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ;
276 +               s.iotype = SERIAL_IO_MEM;
277 +               s.regshift = port->reg_shift;
278 +
279 +               early_serial_setup(&s);
280 +       }
281 +       printk("Serial init done.\n");
282  
283         _machine_restart = bcm47xx_machine_restart;
284         _machine_halt = bcm47xx_machine_halt;
285         pm_power_off = bcm47xx_machine_halt;
286  }
287  
288 +static int __init bcm47xx_register_gpiodev(void)
289 +{
290 +       static struct resource res = {
291 +               .start = 0xFFFFFFFF,
292 +       };
293 +       struct platform_device *pdev;
294 +
295 +       pdev = platform_device_register_simple("GPIODEV", 0, &res, 1);
296 +       if (!pdev) {
297 +               printk(KERN_ERR "bcm47xx: GPIODEV init failed\n");
298 +               return -ENODEV;
299 +       }
300 +
301 +       return 0;
302 +}
303 +device_initcall(bcm47xx_register_gpiodev);
304 diff --git a/arch/mips/bcm47xx/time.c b/arch/mips/bcm47xx/time.c
305 --- a/arch/mips/bcm47xx/time.c
306 +++ b/arch/mips/bcm47xx/time.c
307 @@ -22,11 +22,17 @@
308   *  675 Mass Ave, Cambridge, MA 02139, USA.
309   */
310  
311 -
312  #include <linux/init.h>
313 +#include <linux/kernel.h>
314 +#include <linux/sched.h>
315 +#include <linux/serial_reg.h>
316 +#include <linux/interrupt.h>
317  #include <linux/ssb/ssb.h>
318 +#include <asm/addrspace.h>
319 +#include <asm/io.h>
320  #include <asm/time.h>
321 -#include <bcm47xx.h>
322 +
323 +extern struct ssb_bus ssb_bcm47xx;
324  
325  void __init plat_time_init(void)
326  {