linux/3.3: merge recent ubifs patches from 3.2
[oweals/openwrt.git] / target / linux / generic / patches-3.1 / 025-bcma_backport.patch
1 --- a/drivers/bcma/Kconfig
2 +++ b/drivers/bcma/Kconfig
3 @@ -33,6 +33,19 @@ config BCMA_DRIVER_PCI_HOSTMODE
4         help
5           PCI core hostmode operation (external PCI bus).
6  
7 +config BCMA_HOST_SOC
8 +       bool
9 +       depends on BCMA_DRIVER_MIPS
10 +
11 +config BCMA_DRIVER_MIPS
12 +       bool "BCMA Broadcom MIPS core driver"
13 +       depends on BCMA && MIPS
14 +       help
15 +         Driver for the Broadcom MIPS core attached to Broadcom specific
16 +         Advanced Microcontroller Bus.
17 +
18 +         If unsure, say N
19 +
20  config BCMA_DEBUG
21         bool "BCMA debugging"
22         depends on BCMA
23 --- a/drivers/bcma/Makefile
24 +++ b/drivers/bcma/Makefile
25 @@ -2,7 +2,9 @@ bcma-y                                  += main.o scan.o core.o sprom
26  bcma-y                                 += driver_chipcommon.o driver_chipcommon_pmu.o
27  bcma-y                                 += driver_pci.o
28  bcma-$(CONFIG_BCMA_DRIVER_PCI_HOSTMODE)        += driver_pci_host.o
29 +bcma-$(CONFIG_BCMA_DRIVER_MIPS)                += driver_mips.o
30  bcma-$(CONFIG_BCMA_HOST_PCI)           += host_pci.o
31 +bcma-$(CONFIG_BCMA_HOST_SOC)           += host_soc.o
32  obj-$(CONFIG_BCMA)                     += bcma.o
33  
34  ccflags-$(CONFIG_BCMA_DEBUG)           := -DDEBUG
35 --- a/drivers/bcma/bcma_private.h
36 +++ b/drivers/bcma/bcma_private.h
37 @@ -15,13 +15,32 @@ struct bcma_bus;
38  /* main.c */
39  int bcma_bus_register(struct bcma_bus *bus);
40  void bcma_bus_unregister(struct bcma_bus *bus);
41 +int __init bcma_bus_early_register(struct bcma_bus *bus,
42 +                                  struct bcma_device *core_cc,
43 +                                  struct bcma_device *core_mips);
44 +#ifdef CONFIG_PM
45 +int bcma_bus_resume(struct bcma_bus *bus);
46 +#endif
47  
48  /* scan.c */
49  int bcma_bus_scan(struct bcma_bus *bus);
50 +int __init bcma_bus_scan_early(struct bcma_bus *bus,
51 +                              struct bcma_device_id *match,
52 +                              struct bcma_device *core);
53 +void bcma_init_bus(struct bcma_bus *bus);
54  
55  /* sprom.c */
56  int bcma_sprom_get(struct bcma_bus *bus);
57  
58 +/* driver_chipcommon.c */
59 +#ifdef CONFIG_BCMA_DRIVER_MIPS
60 +void bcma_chipco_serial_init(struct bcma_drv_cc *cc);
61 +#endif /* CONFIG_BCMA_DRIVER_MIPS */
62 +
63 +/* driver_chipcommon_pmu.c */
64 +u32 bcma_pmu_alp_clock(struct bcma_drv_cc *cc);
65 +u32 bcma_pmu_get_clockcpu(struct bcma_drv_cc *cc);
66 +
67  #ifdef CONFIG_BCMA_HOST_PCI
68  /* host_pci.c */
69  extern int __init bcma_host_pci_init(void);
70 --- a/drivers/bcma/core.c
71 +++ b/drivers/bcma/core.c
72 @@ -110,6 +110,8 @@ EXPORT_SYMBOL_GPL(bcma_core_pll_ctl);
73  u32 bcma_core_dma_translation(struct bcma_device *core)
74  {
75         switch (core->bus->hosttype) {
76 +       case BCMA_HOSTTYPE_SOC:
77 +               return 0;
78         case BCMA_HOSTTYPE_PCI:
79                 if (bcma_aread32(core, BCMA_IOST) & BCMA_IOST_DMA64)
80                         return BCMA_DMA_TRANSLATION_DMA64_CMT;
81 --- a/drivers/bcma/driver_chipcommon.c
82 +++ b/drivers/bcma/driver_chipcommon.c
83 @@ -26,6 +26,9 @@ void bcma_core_chipcommon_init(struct bc
84         u32 leddc_on = 10;
85         u32 leddc_off = 90;
86  
87 +       if (cc->setup_done)
88 +               return;
89 +
90         if (cc->core->id.rev >= 11)
91                 cc->status = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
92         cc->capabilities = bcma_cc_read32(cc, BCMA_CC_CAP);
93 @@ -52,6 +55,8 @@ void bcma_core_chipcommon_init(struct bc
94                         ((leddc_on << BCMA_CC_GPIOTIMER_ONTIME_SHIFT) |
95                          (leddc_off << BCMA_CC_GPIOTIMER_OFFTIME_SHIFT)));
96         }
97 +
98 +       cc->setup_done = true;
99  }
100  
101  /* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */
102 @@ -101,3 +106,51 @@ u32 bcma_chipco_gpio_polarity(struct bcm
103  {
104         return bcma_cc_write32_masked(cc, BCMA_CC_GPIOPOL, mask, value);
105  }
106 +
107 +#ifdef CONFIG_BCMA_DRIVER_MIPS
108 +void bcma_chipco_serial_init(struct bcma_drv_cc *cc)
109 +{
110 +       unsigned int irq;
111 +       u32 baud_base;
112 +       u32 i;
113 +       unsigned int ccrev = cc->core->id.rev;
114 +       struct bcma_serial_port *ports = cc->serial_ports;
115 +
116 +       if (ccrev >= 11 && ccrev != 15) {
117 +               /* Fixed ALP clock */
118 +               baud_base = bcma_pmu_alp_clock(cc);
119 +               if (ccrev >= 21) {
120 +                       /* Turn off UART clock before switching clocksource. */
121 +                       bcma_cc_write32(cc, BCMA_CC_CORECTL,
122 +                                      bcma_cc_read32(cc, BCMA_CC_CORECTL)
123 +                                      & ~BCMA_CC_CORECTL_UARTCLKEN);
124 +               }
125 +               /* Set the override bit so we don't divide it */
126 +               bcma_cc_write32(cc, BCMA_CC_CORECTL,
127 +                              bcma_cc_read32(cc, BCMA_CC_CORECTL)
128 +                              | BCMA_CC_CORECTL_UARTCLK0);
129 +               if (ccrev >= 21) {
130 +                       /* Re-enable the UART clock. */
131 +                       bcma_cc_write32(cc, BCMA_CC_CORECTL,
132 +                                      bcma_cc_read32(cc, BCMA_CC_CORECTL)
133 +                                      | BCMA_CC_CORECTL_UARTCLKEN);
134 +               }
135 +       } else {
136 +               pr_err("serial not supported on this device ccrev: 0x%x\n",
137 +                      ccrev);
138 +               return;
139 +       }
140 +
141 +       irq = bcma_core_mips_irq(cc->core);
142 +
143 +       /* Determine the registers of the UARTs */
144 +       cc->nr_serial_ports = (cc->capabilities & BCMA_CC_CAP_NRUART);
145 +       for (i = 0; i < cc->nr_serial_ports; i++) {
146 +               ports[i].regs = cc->core->io_addr + BCMA_CC_UART0_DATA +
147 +                               (i * 256);
148 +               ports[i].irq = irq;
149 +               ports[i].baud_base = baud_base;
150 +               ports[i].reg_shift = 0;
151 +       }
152 +}
153 +#endif /* CONFIG_BCMA_DRIVER_MIPS */
154 --- a/drivers/bcma/driver_chipcommon_pmu.c
155 +++ b/drivers/bcma/driver_chipcommon_pmu.c
156 @@ -11,20 +11,47 @@
157  #include "bcma_private.h"
158  #include <linux/bcma/bcma.h>
159  
160 -static void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc,
161 -                                       u32 offset, u32 mask, u32 set)
162 +static u32 bcma_chipco_pll_read(struct bcma_drv_cc *cc, u32 offset)
163  {
164 -       u32 value;
165 +       bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
166 +       bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
167 +       return bcma_cc_read32(cc, BCMA_CC_PLLCTL_DATA);
168 +}
169  
170 -       bcma_cc_read32(cc, BCMA_CC_CHIPCTL_ADDR);
171 +void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset, u32 value)
172 +{
173 +       bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
174 +       bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
175 +       bcma_cc_write32(cc, BCMA_CC_PLLCTL_DATA, value);
176 +}
177 +EXPORT_SYMBOL_GPL(bcma_chipco_pll_write);
178 +
179 +void bcma_chipco_pll_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask,
180 +                            u32 set)
181 +{
182 +       bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
183 +       bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
184 +       bcma_cc_maskset32(cc, BCMA_CC_PLLCTL_DATA, mask, set);
185 +}
186 +EXPORT_SYMBOL_GPL(bcma_chipco_pll_maskset);
187 +
188 +void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc,
189 +                                u32 offset, u32 mask, u32 set)
190 +{
191         bcma_cc_write32(cc, BCMA_CC_CHIPCTL_ADDR, offset);
192         bcma_cc_read32(cc, BCMA_CC_CHIPCTL_ADDR);
193 -       value = bcma_cc_read32(cc, BCMA_CC_CHIPCTL_DATA);
194 -       value &= mask;
195 -       value |= set;
196 -       bcma_cc_write32(cc, BCMA_CC_CHIPCTL_DATA, value);
197 -       bcma_cc_read32(cc, BCMA_CC_CHIPCTL_DATA);
198 +       bcma_cc_maskset32(cc, BCMA_CC_CHIPCTL_DATA, mask, set);
199  }
200 +EXPORT_SYMBOL_GPL(bcma_chipco_chipctl_maskset);
201 +
202 +void bcma_chipco_regctl_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask,
203 +                               u32 set)
204 +{
205 +       bcma_cc_write32(cc, BCMA_CC_REGCTL_ADDR, offset);
206 +       bcma_cc_read32(cc, BCMA_CC_REGCTL_ADDR);
207 +       bcma_cc_maskset32(cc, BCMA_CC_REGCTL_DATA, mask, set);
208 +}
209 +EXPORT_SYMBOL_GPL(bcma_chipco_regctl_maskset);
210  
211  static void bcma_pmu_pll_init(struct bcma_drv_cc *cc)
212  {
213 @@ -83,6 +110,24 @@ void bcma_pmu_swreg_init(struct bcma_drv
214         }
215  }
216  
217 +/* Disable to allow reading SPROM. Don't know the adventages of enabling it. */
218 +void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable)
219 +{
220 +       struct bcma_bus *bus = cc->core->bus;
221 +       u32 val;
222 +
223 +       val = bcma_cc_read32(cc, BCMA_CC_CHIPCTL);
224 +       if (enable) {
225 +               val |= BCMA_CHIPCTL_4331_EXTPA_EN;
226 +               if (bus->chipinfo.pkg == 9 || bus->chipinfo.pkg == 11)
227 +                       val |= BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5;
228 +       } else {
229 +               val &= ~BCMA_CHIPCTL_4331_EXTPA_EN;
230 +               val &= ~BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5;
231 +       }
232 +       bcma_cc_write32(cc, BCMA_CC_CHIPCTL, val);
233 +}
234 +
235  void bcma_pmu_workarounds(struct bcma_drv_cc *cc)
236  {
237         struct bcma_bus *bus = cc->core->bus;
238 @@ -92,7 +137,7 @@ void bcma_pmu_workarounds(struct bcma_dr
239                 bcma_chipco_chipctl_maskset(cc, 0, ~0, 0x7);
240                 break;
241         case 0x4331:
242 -               pr_err("Enabling Ext PA lines not implemented\n");
243 +               /* BCM4331 workaround is SPROM-related, we put it in sprom.c */
244                 break;
245         case 43224:
246                 if (bus->chipinfo.rev == 0) {
247 @@ -136,3 +181,129 @@ void bcma_pmu_init(struct bcma_drv_cc *c
248         bcma_pmu_swreg_init(cc);
249         bcma_pmu_workarounds(cc);
250  }
251 +
252 +u32 bcma_pmu_alp_clock(struct bcma_drv_cc *cc)
253 +{
254 +       struct bcma_bus *bus = cc->core->bus;
255 +
256 +       switch (bus->chipinfo.id) {
257 +       case 0x4716:
258 +       case 0x4748:
259 +       case 47162:
260 +       case 0x4313:
261 +       case 0x5357:
262 +       case 0x4749:
263 +       case 53572:
264 +               /* always 20Mhz */
265 +               return 20000 * 1000;
266 +       case 0x5356:
267 +       case 0x5300:
268 +               /* always 25Mhz */
269 +               return 25000 * 1000;
270 +       default:
271 +               pr_warn("No ALP clock specified for %04X device, "
272 +                       "pmu rev. %d, using default %d Hz\n",
273 +                       bus->chipinfo.id, cc->pmu.rev, BCMA_CC_PMU_ALP_CLOCK);
274 +       }
275 +       return BCMA_CC_PMU_ALP_CLOCK;
276 +}
277 +
278 +/* Find the output of the "m" pll divider given pll controls that start with
279 + * pllreg "pll0" i.e. 12 for main 6 for phy, 0 for misc.
280 + */
281 +static u32 bcma_pmu_clock(struct bcma_drv_cc *cc, u32 pll0, u32 m)
282 +{
283 +       u32 tmp, div, ndiv, p1, p2, fc;
284 +       struct bcma_bus *bus = cc->core->bus;
285 +
286 +       BUG_ON((pll0 & 3) || (pll0 > BCMA_CC_PMU4716_MAINPLL_PLL0));
287 +
288 +       BUG_ON(!m || m > 4);
289 +
290 +       if (bus->chipinfo.id == 0x5357 || bus->chipinfo.id == 0x4749) {
291 +               /* Detect failure in clock setting */
292 +               tmp = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
293 +               if (tmp & 0x40000)
294 +                       return 133 * 1000000;
295 +       }
296 +
297 +       tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_P1P2_OFF);
298 +       p1 = (tmp & BCMA_CC_PPL_P1_MASK) >> BCMA_CC_PPL_P1_SHIFT;
299 +       p2 = (tmp & BCMA_CC_PPL_P2_MASK) >> BCMA_CC_PPL_P2_SHIFT;
300 +
301 +       tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_M14_OFF);
302 +       div = (tmp >> ((m - 1) * BCMA_CC_PPL_MDIV_WIDTH)) &
303 +               BCMA_CC_PPL_MDIV_MASK;
304 +
305 +       tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_NM5_OFF);
306 +       ndiv = (tmp & BCMA_CC_PPL_NDIV_MASK) >> BCMA_CC_PPL_NDIV_SHIFT;
307 +
308 +       /* Do calculation in Mhz */
309 +       fc = bcma_pmu_alp_clock(cc) / 1000000;
310 +       fc = (p1 * ndiv * fc) / p2;
311 +
312 +       /* Return clock in Hertz */
313 +       return (fc / div) * 1000000;
314 +}
315 +
316 +/* query bus clock frequency for PMU-enabled chipcommon */
317 +u32 bcma_pmu_get_clockcontrol(struct bcma_drv_cc *cc)
318 +{
319 +       struct bcma_bus *bus = cc->core->bus;
320 +
321 +       switch (bus->chipinfo.id) {
322 +       case 0x4716:
323 +       case 0x4748:
324 +       case 47162:
325 +               return bcma_pmu_clock(cc, BCMA_CC_PMU4716_MAINPLL_PLL0,
326 +                                     BCMA_CC_PMU5_MAINPLL_SSB);
327 +       case 0x5356:
328 +               return bcma_pmu_clock(cc, BCMA_CC_PMU5356_MAINPLL_PLL0,
329 +                                     BCMA_CC_PMU5_MAINPLL_SSB);
330 +       case 0x5357:
331 +       case 0x4749:
332 +               return bcma_pmu_clock(cc, BCMA_CC_PMU5357_MAINPLL_PLL0,
333 +                                     BCMA_CC_PMU5_MAINPLL_SSB);
334 +       case 0x5300:
335 +               return bcma_pmu_clock(cc, BCMA_CC_PMU4706_MAINPLL_PLL0,
336 +                                     BCMA_CC_PMU5_MAINPLL_SSB);
337 +       case 53572:
338 +               return 75000000;
339 +       default:
340 +               pr_warn("No backplane clock specified for %04X device, "
341 +                       "pmu rev. %d, using default %d Hz\n",
342 +                       bus->chipinfo.id, cc->pmu.rev, BCMA_CC_PMU_HT_CLOCK);
343 +       }
344 +       return BCMA_CC_PMU_HT_CLOCK;
345 +}
346 +
347 +/* query cpu clock frequency for PMU-enabled chipcommon */
348 +u32 bcma_pmu_get_clockcpu(struct bcma_drv_cc *cc)
349 +{
350 +       struct bcma_bus *bus = cc->core->bus;
351 +
352 +       if (bus->chipinfo.id == 53572)
353 +               return 300000000;
354 +
355 +       if (cc->pmu.rev >= 5) {
356 +               u32 pll;
357 +               switch (bus->chipinfo.id) {
358 +               case 0x5356:
359 +                       pll = BCMA_CC_PMU5356_MAINPLL_PLL0;
360 +                       break;
361 +               case 0x5357:
362 +               case 0x4749:
363 +                       pll = BCMA_CC_PMU5357_MAINPLL_PLL0;
364 +                       break;
365 +               default:
366 +                       pll = BCMA_CC_PMU4716_MAINPLL_PLL0;
367 +                       break;
368 +               }
369 +
370 +               /* TODO: if (bus->chipinfo.id == 0x5300)
371 +                 return si_4706_pmu_clock(sih, osh, cc, PMU4706_MAINPLL_PLL0, PMU5_MAINPLL_CPU); */
372 +               return bcma_pmu_clock(cc, pll, BCMA_CC_PMU5_MAINPLL_CPU);
373 +       }
374 +
375 +       return bcma_pmu_get_clockcontrol(cc);
376 +}
377 --- /dev/null
378 +++ b/drivers/bcma/driver_mips.c
379 @@ -0,0 +1,256 @@
380 +/*
381 + * Broadcom specific AMBA
382 + * Broadcom MIPS32 74K core driver
383 + *
384 + * Copyright 2009, Broadcom Corporation
385 + * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
386 + * Copyright 2010, Bernhard Loos <bernhardloos@googlemail.com>
387 + * Copyright 2011, Hauke Mehrtens <hauke@hauke-m.de>
388 + *
389 + * Licensed under the GNU/GPL. See COPYING for details.
390 + */
391 +
392 +#include "bcma_private.h"
393 +
394 +#include <linux/bcma/bcma.h>
395 +
396 +#include <linux/serial.h>
397 +#include <linux/serial_core.h>
398 +#include <linux/serial_reg.h>
399 +#include <linux/time.h>
400 +
401 +/* The 47162a0 hangs when reading MIPS DMP registers registers */
402 +static inline bool bcma_core_mips_bcm47162a0_quirk(struct bcma_device *dev)
403 +{
404 +       return dev->bus->chipinfo.id == 47162 && dev->bus->chipinfo.rev == 0 &&
405 +              dev->id.id == BCMA_CORE_MIPS_74K;
406 +}
407 +
408 +/* The 5357b0 hangs when reading USB20H DMP registers */
409 +static inline bool bcma_core_mips_bcm5357b0_quirk(struct bcma_device *dev)
410 +{
411 +       return (dev->bus->chipinfo.id == 0x5357 ||
412 +               dev->bus->chipinfo.id == 0x4749) &&
413 +              dev->bus->chipinfo.pkg == 11 &&
414 +              dev->id.id == BCMA_CORE_USB20_HOST;
415 +}
416 +
417 +static inline u32 mips_read32(struct bcma_drv_mips *mcore,
418 +                             u16 offset)
419 +{
420 +       return bcma_read32(mcore->core, offset);
421 +}
422 +
423 +static inline void mips_write32(struct bcma_drv_mips *mcore,
424 +                               u16 offset,
425 +                               u32 value)
426 +{
427 +       bcma_write32(mcore->core, offset, value);
428 +}
429 +
430 +static const u32 ipsflag_irq_mask[] = {
431 +       0,
432 +       BCMA_MIPS_IPSFLAG_IRQ1,
433 +       BCMA_MIPS_IPSFLAG_IRQ2,
434 +       BCMA_MIPS_IPSFLAG_IRQ3,
435 +       BCMA_MIPS_IPSFLAG_IRQ4,
436 +};
437 +
438 +static const u32 ipsflag_irq_shift[] = {
439 +       0,
440 +       BCMA_MIPS_IPSFLAG_IRQ1_SHIFT,
441 +       BCMA_MIPS_IPSFLAG_IRQ2_SHIFT,
442 +       BCMA_MIPS_IPSFLAG_IRQ3_SHIFT,
443 +       BCMA_MIPS_IPSFLAG_IRQ4_SHIFT,
444 +};
445 +
446 +static u32 bcma_core_mips_irqflag(struct bcma_device *dev)
447 +{
448 +       u32 flag;
449 +
450 +       if (bcma_core_mips_bcm47162a0_quirk(dev))
451 +               return dev->core_index;
452 +       if (bcma_core_mips_bcm5357b0_quirk(dev))
453 +               return dev->core_index;
454 +       flag = bcma_aread32(dev, BCMA_MIPS_OOBSELOUTA30);
455 +
456 +       return flag & 0x1F;
457 +}
458 +
459 +/* Get the MIPS IRQ assignment for a specified device.
460 + * If unassigned, 0 is returned.
461 + */
462 +unsigned int bcma_core_mips_irq(struct bcma_device *dev)
463 +{
464 +       struct bcma_device *mdev = dev->bus->drv_mips.core;
465 +       u32 irqflag;
466 +       unsigned int irq;
467 +
468 +       irqflag = bcma_core_mips_irqflag(dev);
469 +
470 +       for (irq = 1; irq <= 4; irq++)
471 +               if (bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq)) &
472 +                   (1 << irqflag))
473 +                       return irq;
474 +
475 +       return 0;
476 +}
477 +EXPORT_SYMBOL(bcma_core_mips_irq);
478 +
479 +static void bcma_core_mips_set_irq(struct bcma_device *dev, unsigned int irq)
480 +{
481 +       unsigned int oldirq = bcma_core_mips_irq(dev);
482 +       struct bcma_bus *bus = dev->bus;
483 +       struct bcma_device *mdev = bus->drv_mips.core;
484 +       u32 irqflag;
485 +
486 +       irqflag = bcma_core_mips_irqflag(dev);
487 +       BUG_ON(oldirq == 6);
488 +
489 +       dev->irq = irq + 2;
490 +
491 +       /* clear the old irq */
492 +       if (oldirq == 0)
493 +               bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0),
494 +                           bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) &
495 +                           ~(1 << irqflag));
496 +       else
497 +               bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq), 0);
498 +
499 +       /* assign the new one */
500 +       if (irq == 0) {
501 +               bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0),
502 +                           bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) |
503 +                           (1 << irqflag));
504 +       } else {
505 +               u32 oldirqflag = bcma_read32(mdev,
506 +                                            BCMA_MIPS_MIPS74K_INTMASK(irq));
507 +               if (oldirqflag) {
508 +                       struct bcma_device *core;
509 +
510 +                       /* backplane irq line is in use, find out who uses
511 +                        * it and set user to irq 0
512 +                        */
513 +                       list_for_each_entry_reverse(core, &bus->cores, list) {
514 +                               if ((1 << bcma_core_mips_irqflag(core)) ==
515 +                                   oldirqflag) {
516 +                                       bcma_core_mips_set_irq(core, 0);
517 +                                       break;
518 +                               }
519 +                       }
520 +               }
521 +               bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq),
522 +                            1 << irqflag);
523 +       }
524 +
525 +       pr_info("set_irq: core 0x%04x, irq %d => %d\n",
526 +               dev->id.id, oldirq + 2, irq + 2);
527 +}
528 +
529 +static void bcma_core_mips_print_irq(struct bcma_device *dev, unsigned int irq)
530 +{
531 +       int i;
532 +       static const char *irq_name[] = {"2(S)", "3", "4", "5", "6", "D", "I"};
533 +       printk(KERN_INFO KBUILD_MODNAME ": core 0x%04x, irq :", dev->id.id);
534 +       for (i = 0; i <= 6; i++)
535 +               printk(" %s%s", irq_name[i], i == irq ? "*" : " ");
536 +       printk("\n");
537 +}
538 +
539 +static void bcma_core_mips_dump_irq(struct bcma_bus *bus)
540 +{
541 +       struct bcma_device *core;
542 +
543 +       list_for_each_entry_reverse(core, &bus->cores, list) {
544 +               bcma_core_mips_print_irq(core, bcma_core_mips_irq(core));
545 +       }
546 +}
547 +
548 +u32 bcma_cpu_clock(struct bcma_drv_mips *mcore)
549 +{
550 +       struct bcma_bus *bus = mcore->core->bus;
551 +
552 +       if (bus->drv_cc.capabilities & BCMA_CC_CAP_PMU)
553 +               return bcma_pmu_get_clockcpu(&bus->drv_cc);
554 +
555 +       pr_err("No PMU available, need this to get the cpu clock\n");
556 +       return 0;
557 +}
558 +EXPORT_SYMBOL(bcma_cpu_clock);
559 +
560 +static void bcma_core_mips_flash_detect(struct bcma_drv_mips *mcore)
561 +{
562 +       struct bcma_bus *bus = mcore->core->bus;
563 +
564 +       switch (bus->drv_cc.capabilities & BCMA_CC_CAP_FLASHT) {
565 +       case BCMA_CC_FLASHT_STSER:
566 +       case BCMA_CC_FLASHT_ATSER:
567 +               pr_err("Serial flash not supported.\n");
568 +               break;
569 +       case BCMA_CC_FLASHT_PARA:
570 +               pr_info("found parallel flash.\n");
571 +               bus->drv_cc.pflash.window = 0x1c000000;
572 +               bus->drv_cc.pflash.window_size = 0x02000000;
573 +
574 +               if ((bcma_read32(bus->drv_cc.core, BCMA_CC_FLASH_CFG) &
575 +                    BCMA_CC_FLASH_CFG_DS) == 0)
576 +                       bus->drv_cc.pflash.buswidth = 1;
577 +               else
578 +                       bus->drv_cc.pflash.buswidth = 2;
579 +               break;
580 +       default:
581 +               pr_err("flash not supported.\n");
582 +       }
583 +}
584 +
585 +void bcma_core_mips_init(struct bcma_drv_mips *mcore)
586 +{
587 +       struct bcma_bus *bus;
588 +       struct bcma_device *core;
589 +       bus = mcore->core->bus;
590 +
591 +       pr_info("Initializing MIPS core...\n");
592 +
593 +       if (!mcore->setup_done)
594 +               mcore->assigned_irqs = 1;
595 +
596 +       /* Assign IRQs to all cores on the bus */
597 +       list_for_each_entry_reverse(core, &bus->cores, list) {
598 +               int mips_irq;
599 +               if (core->irq)
600 +                       continue;
601 +
602 +               mips_irq = bcma_core_mips_irq(core);
603 +               if (mips_irq > 4)
604 +                       core->irq = 0;
605 +               else
606 +                       core->irq = mips_irq + 2;
607 +               if (core->irq > 5)
608 +                       continue;
609 +               switch (core->id.id) {
610 +               case BCMA_CORE_PCI:
611 +               case BCMA_CORE_PCIE:
612 +               case BCMA_CORE_ETHERNET:
613 +               case BCMA_CORE_ETHERNET_GBIT:
614 +               case BCMA_CORE_MAC_GBIT:
615 +               case BCMA_CORE_80211:
616 +               case BCMA_CORE_USB20_HOST:
617 +                       /* These devices get their own IRQ line if available,
618 +                        * the rest goes on IRQ0
619 +                        */
620 +                       if (mcore->assigned_irqs <= 4)
621 +                               bcma_core_mips_set_irq(core,
622 +                                                      mcore->assigned_irqs++);
623 +                       break;
624 +               }
625 +       }
626 +       pr_info("IRQ reconfiguration done\n");
627 +       bcma_core_mips_dump_irq(bus);
628 +
629 +       if (mcore->setup_done)
630 +               return;
631 +
632 +       bcma_chipco_serial_init(&bus->drv_cc);
633 +       bcma_core_mips_flash_detect(mcore);
634 +       mcore->setup_done = true;
635 +}
636 --- a/drivers/bcma/driver_pci.c
637 +++ b/drivers/bcma/driver_pci.c
638 @@ -173,7 +173,7 @@ static bool bcma_core_pci_is_in_hostmode
639                 return false;
640  
641  #ifdef CONFIG_SSB_DRIVER_PCICORE
642 -       if (bus->sprom.boardflags_lo & SSB_PCICORE_BFL_NOPCI)
643 +       if (bus->sprom.boardflags_lo & SSB_BFL_NOPCI)
644                 return false;
645  #endif /* CONFIG_SSB_DRIVER_PCICORE */
646  
647 @@ -189,6 +189,9 @@ static bool bcma_core_pci_is_in_hostmode
648  
649  void bcma_core_pci_init(struct bcma_drv_pci *pc)
650  {
651 +       if (pc->setup_done)
652 +               return;
653 +
654         if (bcma_core_pci_is_in_hostmode(pc)) {
655  #ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
656                 bcma_core_pci_hostmode_init(pc);
657 @@ -198,6 +201,8 @@ void bcma_core_pci_init(struct bcma_drv_
658         } else {
659                 bcma_core_pci_clientmode_init(pc);
660         }
661 +
662 +       pc->setup_done = true;
663  }
664  
665  int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core,
666 @@ -205,7 +210,14 @@ int bcma_core_pci_irq_ctl(struct bcma_dr
667  {
668         struct pci_dev *pdev = pc->core->bus->host_pci;
669         u32 coremask, tmp;
670 -       int err;
671 +       int err = 0;
672 +
673 +       if (core->bus->hosttype != BCMA_HOSTTYPE_PCI) {
674 +               /* This bcma device is not on a PCI host-bus. So the IRQs are
675 +                * not routed through the PCI core.
676 +                * So we must not enable routing through the PCI core. */
677 +               goto out;
678 +       }
679  
680         err = pci_read_config_dword(pdev, BCMA_PCI_IRQMASK, &tmp);
681         if (err)
682 --- a/drivers/bcma/host_pci.c
683 +++ b/drivers/bcma/host_pci.c
684 @@ -9,6 +9,7 @@
685  #include <linux/slab.h>
686  #include <linux/bcma/bcma.h>
687  #include <linux/pci.h>
688 +#include <linux/module.h>
689  
690  static void bcma_host_pci_switch_core(struct bcma_device *core)
691  {
692 @@ -20,48 +21,58 @@ static void bcma_host_pci_switch_core(st
693         pr_debug("Switched to core: 0x%X\n", core->id.id);
694  }
695  
696 -static u8 bcma_host_pci_read8(struct bcma_device *core, u16 offset)
697 -{
698 +/* Provides access to the requested core. Returns base offset that has to be
699 + * used. It makes use of fixed windows when possible. */
700 +static u16 bcma_host_pci_provide_access_to_core(struct bcma_device *core)
701 +{
702 +       switch (core->id.id) {
703 +       case BCMA_CORE_CHIPCOMMON:
704 +               return 3 * BCMA_CORE_SIZE;
705 +       case BCMA_CORE_PCIE:
706 +               return 2 * BCMA_CORE_SIZE;
707 +       }
708 +
709         if (core->bus->mapped_core != core)
710                 bcma_host_pci_switch_core(core);
711 +       return 0;
712 +}
713 +
714 +static u8 bcma_host_pci_read8(struct bcma_device *core, u16 offset)
715 +{
716 +       offset += bcma_host_pci_provide_access_to_core(core);
717         return ioread8(core->bus->mmio + offset);
718  }
719  
720  static u16 bcma_host_pci_read16(struct bcma_device *core, u16 offset)
721  {
722 -       if (core->bus->mapped_core != core)
723 -               bcma_host_pci_switch_core(core);
724 +       offset += bcma_host_pci_provide_access_to_core(core);
725         return ioread16(core->bus->mmio + offset);
726  }
727  
728  static u32 bcma_host_pci_read32(struct bcma_device *core, u16 offset)
729  {
730 -       if (core->bus->mapped_core != core)
731 -               bcma_host_pci_switch_core(core);
732 +       offset += bcma_host_pci_provide_access_to_core(core);
733         return ioread32(core->bus->mmio + offset);
734  }
735  
736  static void bcma_host_pci_write8(struct bcma_device *core, u16 offset,
737                                  u8 value)
738  {
739 -       if (core->bus->mapped_core != core)
740 -               bcma_host_pci_switch_core(core);
741 +       offset += bcma_host_pci_provide_access_to_core(core);
742         iowrite8(value, core->bus->mmio + offset);
743  }
744  
745  static void bcma_host_pci_write16(struct bcma_device *core, u16 offset,
746                                  u16 value)
747  {
748 -       if (core->bus->mapped_core != core)
749 -               bcma_host_pci_switch_core(core);
750 +       offset += bcma_host_pci_provide_access_to_core(core);
751         iowrite16(value, core->bus->mmio + offset);
752  }
753  
754  static void bcma_host_pci_write32(struct bcma_device *core, u16 offset,
755                                  u32 value)
756  {
757 -       if (core->bus->mapped_core != core)
758 -               bcma_host_pci_switch_core(core);
759 +       offset += bcma_host_pci_provide_access_to_core(core);
760         iowrite32(value, core->bus->mmio + offset);
761  }
762  
763 @@ -223,6 +234,41 @@ static void bcma_host_pci_remove(struct
764         pci_set_drvdata(dev, NULL);
765  }
766  
767 +#ifdef CONFIG_PM
768 +static int bcma_host_pci_suspend(struct pci_dev *dev, pm_message_t state)
769 +{
770 +       /* Host specific */
771 +       pci_save_state(dev);
772 +       pci_disable_device(dev);
773 +       pci_set_power_state(dev, pci_choose_state(dev, state));
774 +
775 +       return 0;
776 +}
777 +
778 +static int bcma_host_pci_resume(struct pci_dev *dev)
779 +{
780 +       struct bcma_bus *bus = pci_get_drvdata(dev);
781 +       int err;
782 +
783 +       /* Host specific */
784 +       pci_set_power_state(dev, 0);
785 +       err = pci_enable_device(dev);
786 +       if (err)
787 +               return err;
788 +       pci_restore_state(dev);
789 +
790 +       /* Bus specific */
791 +       err = bcma_bus_resume(bus);
792 +       if (err)
793 +               return err;
794 +
795 +       return 0;
796 +}
797 +#else /* CONFIG_PM */
798 +# define bcma_host_pci_suspend NULL
799 +# define bcma_host_pci_resume  NULL
800 +#endif /* CONFIG_PM */
801 +
802  static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = {
803         { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) },
804         { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) },
805 @@ -238,6 +284,8 @@ static struct pci_driver bcma_pci_bridge
806         .id_table = bcma_pci_bridge_tbl,
807         .probe = bcma_host_pci_probe,
808         .remove = bcma_host_pci_remove,
809 +       .suspend = bcma_host_pci_suspend,
810 +       .resume = bcma_host_pci_resume,
811  };
812  
813  int __init bcma_host_pci_init(void)
814 --- /dev/null
815 +++ b/drivers/bcma/host_soc.c
816 @@ -0,0 +1,183 @@
817 +/*
818 + * Broadcom specific AMBA
819 + * System on Chip (SoC) Host
820 + *
821 + * Licensed under the GNU/GPL. See COPYING for details.
822 + */
823 +
824 +#include "bcma_private.h"
825 +#include "scan.h"
826 +#include <linux/bcma/bcma.h>
827 +#include <linux/bcma/bcma_soc.h>
828 +
829 +static u8 bcma_host_soc_read8(struct bcma_device *core, u16 offset)
830 +{
831 +       return readb(core->io_addr + offset);
832 +}
833 +
834 +static u16 bcma_host_soc_read16(struct bcma_device *core, u16 offset)
835 +{
836 +       return readw(core->io_addr + offset);
837 +}
838 +
839 +static u32 bcma_host_soc_read32(struct bcma_device *core, u16 offset)
840 +{
841 +       return readl(core->io_addr + offset);
842 +}
843 +
844 +static void bcma_host_soc_write8(struct bcma_device *core, u16 offset,
845 +                                u8 value)
846 +{
847 +       writeb(value, core->io_addr + offset);
848 +}
849 +
850 +static void bcma_host_soc_write16(struct bcma_device *core, u16 offset,
851 +                                u16 value)
852 +{
853 +       writew(value, core->io_addr + offset);
854 +}
855 +
856 +static void bcma_host_soc_write32(struct bcma_device *core, u16 offset,
857 +                                u32 value)
858 +{
859 +       writel(value, core->io_addr + offset);
860 +}
861 +
862 +#ifdef CONFIG_BCMA_BLOCKIO
863 +static void bcma_host_soc_block_read(struct bcma_device *core, void *buffer,
864 +                                    size_t count, u16 offset, u8 reg_width)
865 +{
866 +       void __iomem *addr = core->io_addr + offset;
867 +
868 +       switch (reg_width) {
869 +       case sizeof(u8): {
870 +               u8 *buf = buffer;
871 +
872 +               while (count) {
873 +                       *buf = __raw_readb(addr);
874 +                       buf++;
875 +                       count--;
876 +               }
877 +               break;
878 +       }
879 +       case sizeof(u16): {
880 +               __le16 *buf = buffer;
881 +
882 +               WARN_ON(count & 1);
883 +               while (count) {
884 +                       *buf = (__force __le16)__raw_readw(addr);
885 +                       buf++;
886 +                       count -= 2;
887 +               }
888 +               break;
889 +       }
890 +       case sizeof(u32): {
891 +               __le32 *buf = buffer;
892 +
893 +               WARN_ON(count & 3);
894 +               while (count) {
895 +                       *buf = (__force __le32)__raw_readl(addr);
896 +                       buf++;
897 +                       count -= 4;
898 +               }
899 +               break;
900 +       }
901 +       default:
902 +               WARN_ON(1);
903 +       }
904 +}
905 +
906 +static void bcma_host_soc_block_write(struct bcma_device *core,
907 +                                     const void *buffer,
908 +                                     size_t count, u16 offset, u8 reg_width)
909 +{
910 +       void __iomem *addr = core->io_addr + offset;
911 +
912 +       switch (reg_width) {
913 +       case sizeof(u8): {
914 +               const u8 *buf = buffer;
915 +
916 +               while (count) {
917 +                       __raw_writeb(*buf, addr);
918 +                       buf++;
919 +                       count--;
920 +               }
921 +               break;
922 +       }
923 +       case sizeof(u16): {
924 +               const __le16 *buf = buffer;
925 +
926 +               WARN_ON(count & 1);
927 +               while (count) {
928 +                       __raw_writew((__force u16)(*buf), addr);
929 +                       buf++;
930 +                       count -= 2;
931 +               }
932 +               break;
933 +       }
934 +       case sizeof(u32): {
935 +               const __le32 *buf = buffer;
936 +
937 +               WARN_ON(count & 3);
938 +               while (count) {
939 +                       __raw_writel((__force u32)(*buf), addr);
940 +                       buf++;
941 +                       count -= 4;
942 +               }
943 +               break;
944 +       }
945 +       default:
946 +               WARN_ON(1);
947 +       }
948 +}
949 +#endif /* CONFIG_BCMA_BLOCKIO */
950 +
951 +static u32 bcma_host_soc_aread32(struct bcma_device *core, u16 offset)
952 +{
953 +       return readl(core->io_wrap + offset);
954 +}
955 +
956 +static void bcma_host_soc_awrite32(struct bcma_device *core, u16 offset,
957 +                                 u32 value)
958 +{
959 +       writel(value, core->io_wrap + offset);
960 +}
961 +
962 +const struct bcma_host_ops bcma_host_soc_ops = {
963 +       .read8          = bcma_host_soc_read8,
964 +       .read16         = bcma_host_soc_read16,
965 +       .read32         = bcma_host_soc_read32,
966 +       .write8         = bcma_host_soc_write8,
967 +       .write16        = bcma_host_soc_write16,
968 +       .write32        = bcma_host_soc_write32,
969 +#ifdef CONFIG_BCMA_BLOCKIO
970 +       .block_read     = bcma_host_soc_block_read,
971 +       .block_write    = bcma_host_soc_block_write,
972 +#endif
973 +       .aread32        = bcma_host_soc_aread32,
974 +       .awrite32       = bcma_host_soc_awrite32,
975 +};
976 +
977 +int __init bcma_host_soc_register(struct bcma_soc *soc)
978 +{
979 +       struct bcma_bus *bus = &soc->bus;
980 +       int err;
981 +
982 +       /* iomap only first core. We have to read some register on this core
983 +        * to scan the bus.
984 +        */
985 +       bus->mmio = ioremap_nocache(BCMA_ADDR_BASE, BCMA_CORE_SIZE * 1);
986 +       if (!bus->mmio)
987 +               return -ENOMEM;
988 +
989 +       /* Host specific */
990 +       bus->hosttype = BCMA_HOSTTYPE_SOC;
991 +       bus->ops = &bcma_host_soc_ops;
992 +
993 +       /* Register */
994 +       err = bcma_bus_early_register(bus, &soc->core_cc, &soc->core_mips);
995 +       if (err)
996 +               iounmap(bus->mmio);
997 +
998 +       return err;
999 +}
1000 --- a/drivers/bcma/main.c
1001 +++ b/drivers/bcma/main.c
1002 @@ -6,6 +6,7 @@
1003   */
1004  
1005  #include "bcma_private.h"
1006 +#include <linux/module.h>
1007  #include <linux/bcma/bcma.h>
1008  #include <linux/slab.h>
1009  
1010 @@ -68,6 +69,10 @@ static struct bcma_device *bcma_find_cor
1011  static void bcma_release_core_dev(struct device *dev)
1012  {
1013         struct bcma_device *core = container_of(dev, struct bcma_device, dev);
1014 +       if (core->io_addr)
1015 +               iounmap(core->io_addr);
1016 +       if (core->io_wrap)
1017 +               iounmap(core->io_wrap);
1018         kfree(core);
1019  }
1020  
1021 @@ -82,6 +87,7 @@ static int bcma_register_cores(struct bc
1022                 case BCMA_CORE_CHIPCOMMON:
1023                 case BCMA_CORE_PCI:
1024                 case BCMA_CORE_PCIE:
1025 +               case BCMA_CORE_MIPS_74K:
1026                         continue;
1027                 }
1028  
1029 @@ -95,7 +101,10 @@ static int bcma_register_cores(struct bc
1030                         core->dma_dev = &bus->host_pci->dev;
1031                         core->irq = bus->host_pci->irq;
1032                         break;
1033 -               case BCMA_HOSTTYPE_NONE:
1034 +               case BCMA_HOSTTYPE_SOC:
1035 +                       core->dev.dma_mask = &core->dev.coherent_dma_mask;
1036 +                       core->dma_dev = &core->dev;
1037 +                       break;
1038                 case BCMA_HOSTTYPE_SDIO:
1039                         break;
1040                 }
1041 @@ -142,6 +151,13 @@ int bcma_bus_register(struct bcma_bus *b
1042                 bcma_core_chipcommon_init(&bus->drv_cc);
1043         }
1044  
1045 +       /* Init MIPS core */
1046 +       core = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
1047 +       if (core) {
1048 +               bus->drv_mips.core = core;
1049 +               bcma_core_mips_init(&bus->drv_mips);
1050 +       }
1051 +
1052         /* Init PCIE core */
1053         core = bcma_find_core(bus, BCMA_CORE_PCIE);
1054         if (core) {
1055 @@ -171,6 +187,75 @@ void bcma_bus_unregister(struct bcma_bus
1056         bcma_unregister_cores(bus);
1057  }
1058  
1059 +int __init bcma_bus_early_register(struct bcma_bus *bus,
1060 +                                  struct bcma_device *core_cc,
1061 +                                  struct bcma_device *core_mips)
1062 +{
1063 +       int err;
1064 +       struct bcma_device *core;
1065 +       struct bcma_device_id match;
1066 +
1067 +       bcma_init_bus(bus);
1068 +
1069 +       match.manuf = BCMA_MANUF_BCM;
1070 +       match.id = BCMA_CORE_CHIPCOMMON;
1071 +       match.class = BCMA_CL_SIM;
1072 +       match.rev = BCMA_ANY_REV;
1073 +
1074 +       /* Scan for chip common core */
1075 +       err = bcma_bus_scan_early(bus, &match, core_cc);
1076 +       if (err) {
1077 +               pr_err("Failed to scan for common core: %d\n", err);
1078 +               return -1;
1079 +       }
1080 +
1081 +       match.manuf = BCMA_MANUF_MIPS;
1082 +       match.id = BCMA_CORE_MIPS_74K;
1083 +       match.class = BCMA_CL_SIM;
1084 +       match.rev = BCMA_ANY_REV;
1085 +
1086 +       /* Scan for mips core */
1087 +       err = bcma_bus_scan_early(bus, &match, core_mips);
1088 +       if (err) {
1089 +               pr_err("Failed to scan for mips core: %d\n", err);
1090 +               return -1;
1091 +       }
1092 +
1093 +       /* Init CC core */
1094 +       core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON);
1095 +       if (core) {
1096 +               bus->drv_cc.core = core;
1097 +               bcma_core_chipcommon_init(&bus->drv_cc);
1098 +       }
1099 +
1100 +       /* Init MIPS core */
1101 +       core = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
1102 +       if (core) {
1103 +               bus->drv_mips.core = core;
1104 +               bcma_core_mips_init(&bus->drv_mips);
1105 +       }
1106 +
1107 +       pr_info("Early bus registered\n");
1108 +
1109 +       return 0;
1110 +}
1111 +
1112 +#ifdef CONFIG_PM
1113 +int bcma_bus_resume(struct bcma_bus *bus)
1114 +{
1115 +       struct bcma_device *core;
1116 +
1117 +       /* Init CC core */
1118 +       core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON);
1119 +       if (core) {
1120 +               bus->drv_cc.setup_done = false;
1121 +               bcma_core_chipcommon_init(&bus->drv_cc);
1122 +       }
1123 +
1124 +       return 0;
1125 +}
1126 +#endif
1127 +
1128  int __bcma_driver_register(struct bcma_driver *drv, struct module *owner)
1129  {
1130         drv->drv.name = drv->name;
1131 --- a/drivers/bcma/scan.c
1132 +++ b/drivers/bcma/scan.c
1133 @@ -200,18 +200,162 @@ static s32 bcma_erom_get_addr_desc(struc
1134         return addrl;
1135  }
1136  
1137 -int bcma_bus_scan(struct bcma_bus *bus)
1138 +static struct bcma_device *bcma_find_core_by_index(struct bcma_bus *bus,
1139 +                                                  u16 index)
1140  {
1141 -       u32 erombase;
1142 -       u32 __iomem *eromptr, *eromend;
1143 +       struct bcma_device *core;
1144  
1145 +       list_for_each_entry(core, &bus->cores, list) {
1146 +               if (core->core_index == index)
1147 +                       return core;
1148 +       }
1149 +       return NULL;
1150 +}
1151 +
1152 +static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
1153 +                             struct bcma_device_id *match, int core_num,
1154 +                             struct bcma_device *core)
1155 +{
1156 +       s32 tmp;
1157 +       u8 i, j;
1158         s32 cia, cib;
1159         u8 ports[2], wrappers[2];
1160  
1161 +       /* get CIs */
1162 +       cia = bcma_erom_get_ci(bus, eromptr);
1163 +       if (cia < 0) {
1164 +               bcma_erom_push_ent(eromptr);
1165 +               if (bcma_erom_is_end(bus, eromptr))
1166 +                       return -ESPIPE;
1167 +               return -EILSEQ;
1168 +       }
1169 +       cib = bcma_erom_get_ci(bus, eromptr);
1170 +       if (cib < 0)
1171 +               return -EILSEQ;
1172 +
1173 +       /* parse CIs */
1174 +       core->id.class = (cia & SCAN_CIA_CLASS) >> SCAN_CIA_CLASS_SHIFT;
1175 +       core->id.id = (cia & SCAN_CIA_ID) >> SCAN_CIA_ID_SHIFT;
1176 +       core->id.manuf = (cia & SCAN_CIA_MANUF) >> SCAN_CIA_MANUF_SHIFT;
1177 +       ports[0] = (cib & SCAN_CIB_NMP) >> SCAN_CIB_NMP_SHIFT;
1178 +       ports[1] = (cib & SCAN_CIB_NSP) >> SCAN_CIB_NSP_SHIFT;
1179 +       wrappers[0] = (cib & SCAN_CIB_NMW) >> SCAN_CIB_NMW_SHIFT;
1180 +       wrappers[1] = (cib & SCAN_CIB_NSW) >> SCAN_CIB_NSW_SHIFT;
1181 +       core->id.rev = (cib & SCAN_CIB_REV) >> SCAN_CIB_REV_SHIFT;
1182 +
1183 +       if (((core->id.manuf == BCMA_MANUF_ARM) &&
1184 +            (core->id.id == 0xFFF)) ||
1185 +           (ports[1] == 0)) {
1186 +               bcma_erom_skip_component(bus, eromptr);
1187 +               return -ENXIO;
1188 +       }
1189 +
1190 +       /* check if component is a core at all */
1191 +       if (wrappers[0] + wrappers[1] == 0) {
1192 +               /* we could save addrl of the router
1193 +               if (cid == BCMA_CORE_OOB_ROUTER)
1194 +                */
1195 +               bcma_erom_skip_component(bus, eromptr);
1196 +               return -ENXIO;
1197 +       }
1198 +
1199 +       if (bcma_erom_is_bridge(bus, eromptr)) {
1200 +               bcma_erom_skip_component(bus, eromptr);
1201 +               return -ENXIO;
1202 +       }
1203 +
1204 +       if (bcma_find_core_by_index(bus, core_num)) {
1205 +               bcma_erom_skip_component(bus, eromptr);
1206 +               return -ENODEV;
1207 +       }
1208 +
1209 +       if (match && ((match->manuf != BCMA_ANY_MANUF &&
1210 +             match->manuf != core->id.manuf) ||
1211 +            (match->id != BCMA_ANY_ID && match->id != core->id.id) ||
1212 +            (match->rev != BCMA_ANY_REV && match->rev != core->id.rev) ||
1213 +            (match->class != BCMA_ANY_CLASS && match->class != core->id.class)
1214 +           )) {
1215 +               bcma_erom_skip_component(bus, eromptr);
1216 +               return -ENODEV;
1217 +       }
1218 +
1219 +       /* get & parse master ports */
1220 +       for (i = 0; i < ports[0]; i++) {
1221 +               s32 mst_port_d = bcma_erom_get_mst_port(bus, eromptr);
1222 +               if (mst_port_d < 0)
1223 +                       return -EILSEQ;
1224 +       }
1225 +
1226 +       /* get & parse slave ports */
1227 +       for (i = 0; i < ports[1]; i++) {
1228 +               for (j = 0; ; j++) {
1229 +                       tmp = bcma_erom_get_addr_desc(bus, eromptr,
1230 +                               SCAN_ADDR_TYPE_SLAVE, i);
1231 +                       if (tmp < 0) {
1232 +                               /* no more entries for port _i_ */
1233 +                               /* pr_debug("erom: slave port %d "
1234 +                                * "has %d descriptors\n", i, j); */
1235 +                               break;
1236 +                       } else {
1237 +                               if (i == 0 && j == 0)
1238 +                                       core->addr = tmp;
1239 +                       }
1240 +               }
1241 +       }
1242 +
1243 +       /* get & parse master wrappers */
1244 +       for (i = 0; i < wrappers[0]; i++) {
1245 +               for (j = 0; ; j++) {
1246 +                       tmp = bcma_erom_get_addr_desc(bus, eromptr,
1247 +                               SCAN_ADDR_TYPE_MWRAP, i);
1248 +                       if (tmp < 0) {
1249 +                               /* no more entries for port _i_ */
1250 +                               /* pr_debug("erom: master wrapper %d "
1251 +                                * "has %d descriptors\n", i, j); */
1252 +                               break;
1253 +                       } else {
1254 +                               if (i == 0 && j == 0)
1255 +                                       core->wrap = tmp;
1256 +                       }
1257 +               }
1258 +       }
1259 +
1260 +       /* get & parse slave wrappers */
1261 +       for (i = 0; i < wrappers[1]; i++) {
1262 +               u8 hack = (ports[1] == 1) ? 0 : 1;
1263 +               for (j = 0; ; j++) {
1264 +                       tmp = bcma_erom_get_addr_desc(bus, eromptr,
1265 +                               SCAN_ADDR_TYPE_SWRAP, i + hack);
1266 +                       if (tmp < 0) {
1267 +                               /* no more entries for port _i_ */
1268 +                               /* pr_debug("erom: master wrapper %d "
1269 +                                * has %d descriptors\n", i, j); */
1270 +                               break;
1271 +                       } else {
1272 +                               if (wrappers[0] == 0 && !i && !j)
1273 +                                       core->wrap = tmp;
1274 +                       }
1275 +               }
1276 +       }
1277 +       if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
1278 +               core->io_addr = ioremap_nocache(core->addr, BCMA_CORE_SIZE);
1279 +               if (!core->io_addr)
1280 +                       return -ENOMEM;
1281 +               core->io_wrap = ioremap_nocache(core->wrap, BCMA_CORE_SIZE);
1282 +               if (!core->io_wrap) {
1283 +                       iounmap(core->io_addr);
1284 +                       return -ENOMEM;
1285 +               }
1286 +       }
1287 +       return 0;
1288 +}
1289 +
1290 +void bcma_init_bus(struct bcma_bus *bus)
1291 +{
1292         s32 tmp;
1293 -       u8 i, j;
1294  
1295 -       int err;
1296 +       if (bus->init_done)
1297 +               return;
1298  
1299         INIT_LIST_HEAD(&bus->cores);
1300         bus->nr_cores = 0;
1301 @@ -222,9 +366,27 @@ int bcma_bus_scan(struct bcma_bus *bus)
1302         bus->chipinfo.id = (tmp & BCMA_CC_ID_ID) >> BCMA_CC_ID_ID_SHIFT;
1303         bus->chipinfo.rev = (tmp & BCMA_CC_ID_REV) >> BCMA_CC_ID_REV_SHIFT;
1304         bus->chipinfo.pkg = (tmp & BCMA_CC_ID_PKG) >> BCMA_CC_ID_PKG_SHIFT;
1305 +       bus->init_done = true;
1306 +}
1307 +
1308 +int bcma_bus_scan(struct bcma_bus *bus)
1309 +{
1310 +       u32 erombase;
1311 +       u32 __iomem *eromptr, *eromend;
1312 +
1313 +       int err, core_num = 0;
1314 +
1315 +       bcma_init_bus(bus);
1316  
1317         erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM);
1318 -       eromptr = bus->mmio;
1319 +       if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
1320 +               eromptr = ioremap_nocache(erombase, BCMA_CORE_SIZE);
1321 +               if (!eromptr)
1322 +                       return -ENOMEM;
1323 +       } else {
1324 +               eromptr = bus->mmio;
1325 +       }
1326 +
1327         eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32);
1328  
1329         bcma_scan_switch_core(bus, erombase);
1330 @@ -236,125 +398,89 @@ int bcma_bus_scan(struct bcma_bus *bus)
1331                 INIT_LIST_HEAD(&core->list);
1332                 core->bus = bus;
1333  
1334 -               /* get CIs */
1335 -               cia = bcma_erom_get_ci(bus, &eromptr);
1336 -               if (cia < 0) {
1337 -                       bcma_erom_push_ent(&eromptr);
1338 -                       if (bcma_erom_is_end(bus, &eromptr))
1339 -                               break;
1340 -                       err= -EILSEQ;
1341 -                       goto out;
1342 -               }
1343 -               cib = bcma_erom_get_ci(bus, &eromptr);
1344 -               if (cib < 0) {
1345 -                       err= -EILSEQ;
1346 -                       goto out;
1347 -               }
1348 -
1349 -               /* parse CIs */
1350 -               core->id.class = (cia & SCAN_CIA_CLASS) >> SCAN_CIA_CLASS_SHIFT;
1351 -               core->id.id = (cia & SCAN_CIA_ID) >> SCAN_CIA_ID_SHIFT;
1352 -               core->id.manuf = (cia & SCAN_CIA_MANUF) >> SCAN_CIA_MANUF_SHIFT;
1353 -               ports[0] = (cib & SCAN_CIB_NMP) >> SCAN_CIB_NMP_SHIFT;
1354 -               ports[1] = (cib & SCAN_CIB_NSP) >> SCAN_CIB_NSP_SHIFT;
1355 -               wrappers[0] = (cib & SCAN_CIB_NMW) >> SCAN_CIB_NMW_SHIFT;
1356 -               wrappers[1] = (cib & SCAN_CIB_NSW) >> SCAN_CIB_NSW_SHIFT;
1357 -               core->id.rev = (cib & SCAN_CIB_REV) >> SCAN_CIB_REV_SHIFT;
1358 -
1359 -               if (((core->id.manuf == BCMA_MANUF_ARM) &&
1360 -                    (core->id.id == 0xFFF)) ||
1361 -                   (ports[1] == 0)) {
1362 -                       bcma_erom_skip_component(bus, &eromptr);
1363 +               err = bcma_get_next_core(bus, &eromptr, NULL, core_num, core);
1364 +               if (err == -ENODEV) {
1365 +                       core_num++;
1366                         continue;
1367 -               }
1368 -
1369 -               /* check if component is a core at all */
1370 -               if (wrappers[0] + wrappers[1] == 0) {
1371 -                       /* we could save addrl of the router
1372 -                       if (cid == BCMA_CORE_OOB_ROUTER)
1373 -                        */
1374 -                       bcma_erom_skip_component(bus, &eromptr);
1375 +               } else if (err == -ENXIO)
1376                         continue;
1377 -               }
1378 +               else if (err == -ESPIPE)
1379 +                       break;
1380 +               else if (err < 0)
1381 +                       return err;
1382  
1383 -               if (bcma_erom_is_bridge(bus, &eromptr)) {
1384 -                       bcma_erom_skip_component(bus, &eromptr);
1385 -                       continue;
1386 -               }
1387 +               core->core_index = core_num++;
1388 +               bus->nr_cores++;
1389  
1390 -               /* get & parse master ports */
1391 -               for (i = 0; i < ports[0]; i++) {
1392 -                       u32 mst_port_d = bcma_erom_get_mst_port(bus, &eromptr);
1393 -                       if (mst_port_d < 0) {
1394 -                               err= -EILSEQ;
1395 -                               goto out;
1396 -                       }
1397 -               }
1398 +               pr_info("Core %d found: %s "
1399 +                       "(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
1400 +                       core->core_index, bcma_device_name(&core->id),
1401 +                       core->id.manuf, core->id.id, core->id.rev,
1402 +                       core->id.class);
1403  
1404 -               /* get & parse slave ports */
1405 -               for (i = 0; i < ports[1]; i++) {
1406 -                       for (j = 0; ; j++) {
1407 -                               tmp = bcma_erom_get_addr_desc(bus, &eromptr,
1408 -                                       SCAN_ADDR_TYPE_SLAVE, i);
1409 -                               if (tmp < 0) {
1410 -                                       /* no more entries for port _i_ */
1411 -                                       /* pr_debug("erom: slave port %d "
1412 -                                        * "has %d descriptors\n", i, j); */
1413 -                                       break;
1414 -                               } else {
1415 -                                       if (i == 0 && j == 0)
1416 -                                               core->addr = tmp;
1417 -                               }
1418 -                       }
1419 -               }
1420 +               list_add(&core->list, &bus->cores);
1421 +       }
1422  
1423 -               /* get & parse master wrappers */
1424 -               for (i = 0; i < wrappers[0]; i++) {
1425 -                       for (j = 0; ; j++) {
1426 -                               tmp = bcma_erom_get_addr_desc(bus, &eromptr,
1427 -                                       SCAN_ADDR_TYPE_MWRAP, i);
1428 -                               if (tmp < 0) {
1429 -                                       /* no more entries for port _i_ */
1430 -                                       /* pr_debug("erom: master wrapper %d "
1431 -                                        * "has %d descriptors\n", i, j); */
1432 -                                       break;
1433 -                               } else {
1434 -                                       if (i == 0 && j == 0)
1435 -                                               core->wrap = tmp;
1436 -                               }
1437 -                       }
1438 -               }
1439 +       if (bus->hosttype == BCMA_HOSTTYPE_SOC)
1440 +               iounmap(eromptr);
1441  
1442 -               /* get & parse slave wrappers */
1443 -               for (i = 0; i < wrappers[1]; i++) {
1444 -                       u8 hack = (ports[1] == 1) ? 0 : 1;
1445 -                       for (j = 0; ; j++) {
1446 -                               tmp = bcma_erom_get_addr_desc(bus, &eromptr,
1447 -                                       SCAN_ADDR_TYPE_SWRAP, i + hack);
1448 -                               if (tmp < 0) {
1449 -                                       /* no more entries for port _i_ */
1450 -                                       /* pr_debug("erom: master wrapper %d "
1451 -                                        * has %d descriptors\n", i, j); */
1452 -                                       break;
1453 -                               } else {
1454 -                                       if (wrappers[0] == 0 && !i && !j)
1455 -                                               core->wrap = tmp;
1456 -                               }
1457 -                       }
1458 -               }
1459 +       return 0;
1460 +}
1461 +
1462 +int __init bcma_bus_scan_early(struct bcma_bus *bus,
1463 +                              struct bcma_device_id *match,
1464 +                              struct bcma_device *core)
1465 +{
1466 +       u32 erombase;
1467 +       u32 __iomem *eromptr, *eromend;
1468  
1469 +       int err = -ENODEV;
1470 +       int core_num = 0;
1471 +
1472 +       erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM);
1473 +       if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
1474 +               eromptr = ioremap_nocache(erombase, BCMA_CORE_SIZE);
1475 +               if (!eromptr)
1476 +                       return -ENOMEM;
1477 +       } else {
1478 +               eromptr = bus->mmio;
1479 +       }
1480 +
1481 +       eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32);
1482 +
1483 +       bcma_scan_switch_core(bus, erombase);
1484 +
1485 +       while (eromptr < eromend) {
1486 +               memset(core, 0, sizeof(*core));
1487 +               INIT_LIST_HEAD(&core->list);
1488 +               core->bus = bus;
1489 +
1490 +               err = bcma_get_next_core(bus, &eromptr, match, core_num, core);
1491 +               if (err == -ENODEV) {
1492 +                       core_num++;
1493 +                       continue;
1494 +               } else if (err == -ENXIO)
1495 +                       continue;
1496 +               else if (err == -ESPIPE)
1497 +                       break;
1498 +               else if (err < 0)
1499 +                       return err;
1500 +
1501 +               core->core_index = core_num++;
1502 +               bus->nr_cores++;
1503                 pr_info("Core %d found: %s "
1504                         "(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
1505 -                       bus->nr_cores, bcma_device_name(&core->id),
1506 +                       core->core_index, bcma_device_name(&core->id),
1507                         core->id.manuf, core->id.id, core->id.rev,
1508                         core->id.class);
1509  
1510 -               core->core_index = bus->nr_cores++;
1511                 list_add(&core->list, &bus->cores);
1512 -               continue;
1513 -out:
1514 -               return err;
1515 +               err = 0;
1516 +               break;
1517         }
1518  
1519 -       return 0;
1520 +       if (bus->hosttype == BCMA_HOSTTYPE_SOC)
1521 +               iounmap(eromptr);
1522 +
1523 +       return err;
1524  }
1525 --- a/drivers/bcma/sprom.c
1526 +++ b/drivers/bcma/sprom.c
1527 @@ -129,10 +129,80 @@ static void bcma_sprom_extract_r8(struct
1528         u16 v;
1529         int i;
1530  
1531 +       bus->sprom.revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] &
1532 +               SSB_SPROM_REVISION_REV;
1533 +
1534         for (i = 0; i < 3; i++) {
1535                 v = sprom[SPOFF(SSB_SPROM8_IL0MAC) + i];
1536                 *(((__be16 *)bus->sprom.il0mac) + i) = cpu_to_be16(v);
1537         }
1538 +
1539 +       bus->sprom.board_rev = sprom[SPOFF(SSB_SPROM8_BOARDREV)];
1540 +
1541 +       bus->sprom.txpid2g[0] = (sprom[SPOFF(SSB_SPROM4_TXPID2G01)] &
1542 +            SSB_SPROM4_TXPID2G0) >> SSB_SPROM4_TXPID2G0_SHIFT;
1543 +       bus->sprom.txpid2g[1] = (sprom[SPOFF(SSB_SPROM4_TXPID2G01)] &
1544 +            SSB_SPROM4_TXPID2G1) >> SSB_SPROM4_TXPID2G1_SHIFT;
1545 +       bus->sprom.txpid2g[2] = (sprom[SPOFF(SSB_SPROM4_TXPID2G23)] &
1546 +            SSB_SPROM4_TXPID2G2) >> SSB_SPROM4_TXPID2G2_SHIFT;
1547 +       bus->sprom.txpid2g[3] = (sprom[SPOFF(SSB_SPROM4_TXPID2G23)] &
1548 +            SSB_SPROM4_TXPID2G3) >> SSB_SPROM4_TXPID2G3_SHIFT;
1549 +
1550 +       bus->sprom.txpid5gl[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL01)] &
1551 +            SSB_SPROM4_TXPID5GL0) >> SSB_SPROM4_TXPID5GL0_SHIFT;
1552 +       bus->sprom.txpid5gl[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL01)] &
1553 +            SSB_SPROM4_TXPID5GL1) >> SSB_SPROM4_TXPID5GL1_SHIFT;
1554 +       bus->sprom.txpid5gl[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL23)] &
1555 +            SSB_SPROM4_TXPID5GL2) >> SSB_SPROM4_TXPID5GL2_SHIFT;
1556 +       bus->sprom.txpid5gl[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL23)] &
1557 +            SSB_SPROM4_TXPID5GL3) >> SSB_SPROM4_TXPID5GL3_SHIFT;
1558 +
1559 +       bus->sprom.txpid5g[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5G01)] &
1560 +            SSB_SPROM4_TXPID5G0) >> SSB_SPROM4_TXPID5G0_SHIFT;
1561 +       bus->sprom.txpid5g[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5G01)] &
1562 +            SSB_SPROM4_TXPID5G1) >> SSB_SPROM4_TXPID5G1_SHIFT;
1563 +       bus->sprom.txpid5g[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5G23)] &
1564 +            SSB_SPROM4_TXPID5G2) >> SSB_SPROM4_TXPID5G2_SHIFT;
1565 +       bus->sprom.txpid5g[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5G23)] &
1566 +            SSB_SPROM4_TXPID5G3) >> SSB_SPROM4_TXPID5G3_SHIFT;
1567 +
1568 +       bus->sprom.txpid5gh[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH01)] &
1569 +            SSB_SPROM4_TXPID5GH0) >> SSB_SPROM4_TXPID5GH0_SHIFT;
1570 +       bus->sprom.txpid5gh[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH01)] &
1571 +            SSB_SPROM4_TXPID5GH1) >> SSB_SPROM4_TXPID5GH1_SHIFT;
1572 +       bus->sprom.txpid5gh[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH23)] &
1573 +            SSB_SPROM4_TXPID5GH2) >> SSB_SPROM4_TXPID5GH2_SHIFT;
1574 +       bus->sprom.txpid5gh[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH23)] &
1575 +            SSB_SPROM4_TXPID5GH3) >> SSB_SPROM4_TXPID5GH3_SHIFT;
1576 +
1577 +       bus->sprom.boardflags_lo = sprom[SPOFF(SSB_SPROM8_BFLLO)];
1578 +       bus->sprom.boardflags_hi = sprom[SPOFF(SSB_SPROM8_BFLHI)];
1579 +       bus->sprom.boardflags2_lo = sprom[SPOFF(SSB_SPROM8_BFL2LO)];
1580 +       bus->sprom.boardflags2_hi = sprom[SPOFF(SSB_SPROM8_BFL2HI)];
1581 +
1582 +       bus->sprom.country_code = sprom[SPOFF(SSB_SPROM8_CCODE)];
1583 +
1584 +       bus->sprom.fem.ghz2.tssipos = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
1585 +               SSB_SROM8_FEM_TSSIPOS) >> SSB_SROM8_FEM_TSSIPOS_SHIFT;
1586 +       bus->sprom.fem.ghz2.extpa_gain = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
1587 +               SSB_SROM8_FEM_EXTPA_GAIN) >> SSB_SROM8_FEM_EXTPA_GAIN_SHIFT;
1588 +       bus->sprom.fem.ghz2.pdet_range = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
1589 +               SSB_SROM8_FEM_PDET_RANGE) >> SSB_SROM8_FEM_PDET_RANGE_SHIFT;
1590 +       bus->sprom.fem.ghz2.tr_iso = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
1591 +               SSB_SROM8_FEM_TR_ISO) >> SSB_SROM8_FEM_TR_ISO_SHIFT;
1592 +       bus->sprom.fem.ghz2.antswlut = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
1593 +               SSB_SROM8_FEM_ANTSWLUT) >> SSB_SROM8_FEM_ANTSWLUT_SHIFT;
1594 +
1595 +       bus->sprom.fem.ghz5.tssipos = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
1596 +               SSB_SROM8_FEM_TSSIPOS) >> SSB_SROM8_FEM_TSSIPOS_SHIFT;
1597 +       bus->sprom.fem.ghz5.extpa_gain = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
1598 +               SSB_SROM8_FEM_EXTPA_GAIN) >> SSB_SROM8_FEM_EXTPA_GAIN_SHIFT;
1599 +       bus->sprom.fem.ghz5.pdet_range = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
1600 +               SSB_SROM8_FEM_PDET_RANGE) >> SSB_SROM8_FEM_PDET_RANGE_SHIFT;
1601 +       bus->sprom.fem.ghz5.tr_iso = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
1602 +               SSB_SROM8_FEM_TR_ISO) >> SSB_SROM8_FEM_TR_ISO_SHIFT;
1603 +       bus->sprom.fem.ghz5.antswlut = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
1604 +               SSB_SROM8_FEM_ANTSWLUT) >> SSB_SROM8_FEM_ANTSWLUT_SHIFT;
1605  }
1606  
1607  int bcma_sprom_get(struct bcma_bus *bus)
1608 @@ -152,6 +222,9 @@ int bcma_sprom_get(struct bcma_bus *bus)
1609         if (!sprom)
1610                 return -ENOMEM;
1611  
1612 +       if (bus->chipinfo.id == 0x4331)
1613 +               bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, false);
1614 +
1615         /* Most cards have SPROM moved by additional offset 0x30 (48 dwords).
1616          * According to brcm80211 this applies to cards with PCIe rev >= 6
1617          * TODO: understand this condition and use it */
1618 @@ -159,6 +232,9 @@ int bcma_sprom_get(struct bcma_bus *bus)
1619                 BCMA_CC_SPROM_PCIE6;
1620         bcma_sprom_read(bus, offset, sprom);
1621  
1622 +       if (bus->chipinfo.id == 0x4331)
1623 +               bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, true);
1624 +
1625         err = bcma_sprom_valid(sprom);
1626         if (err)
1627                 goto out;
1628 --- a/include/linux/bcma/bcma.h
1629 +++ b/include/linux/bcma/bcma.h
1630 @@ -6,6 +6,7 @@
1631  
1632  #include <linux/bcma/bcma_driver_chipcommon.h>
1633  #include <linux/bcma/bcma_driver_pci.h>
1634 +#include <linux/bcma/bcma_driver_mips.h>
1635  #include <linux/ssb/ssb.h> /* SPROM sharing */
1636  
1637  #include "bcma_regs.h"
1638 @@ -14,9 +15,9 @@ struct bcma_device;
1639  struct bcma_bus;
1640  
1641  enum bcma_hosttype {
1642 -       BCMA_HOSTTYPE_NONE,
1643         BCMA_HOSTTYPE_PCI,
1644         BCMA_HOSTTYPE_SDIO,
1645 +       BCMA_HOSTTYPE_SOC,
1646  };
1647  
1648  struct bcma_chipinfo {
1649 @@ -130,6 +131,7 @@ struct bcma_device {
1650  
1651         struct device dev;
1652         struct device *dma_dev;
1653 +
1654         unsigned int irq;
1655         bool dev_registered;
1656  
1657 @@ -138,6 +140,9 @@ struct bcma_device {
1658         u32 addr;
1659         u32 wrap;
1660  
1661 +       void __iomem *io_addr;
1662 +       void __iomem *io_wrap;
1663 +
1664         void *drvdata;
1665         struct list_head list;
1666  };
1667 @@ -165,10 +170,9 @@ struct bcma_driver {
1668  };
1669  extern
1670  int __bcma_driver_register(struct bcma_driver *drv, struct module *owner);
1671 -static inline int bcma_driver_register(struct bcma_driver *drv)
1672 -{
1673 -       return __bcma_driver_register(drv, THIS_MODULE);
1674 -}
1675 +#define bcma_driver_register(drv) \
1676 +       __bcma_driver_register(drv, THIS_MODULE)
1677 +
1678  extern void bcma_driver_unregister(struct bcma_driver *drv);
1679  
1680  struct bcma_bus {
1681 @@ -190,70 +194,93 @@ struct bcma_bus {
1682         struct bcma_device *mapped_core;
1683         struct list_head cores;
1684         u8 nr_cores;
1685 +       u8 init_done:1;
1686  
1687         struct bcma_drv_cc drv_cc;
1688         struct bcma_drv_pci drv_pci;
1689 +       struct bcma_drv_mips drv_mips;
1690  
1691         /* We decided to share SPROM struct with SSB as long as we do not need
1692          * any hacks for BCMA. This simplifies drivers code. */
1693         struct ssb_sprom sprom;
1694  };
1695  
1696 -extern inline u32 bcma_read8(struct bcma_device *core, u16 offset)
1697 +static inline u32 bcma_read8(struct bcma_device *core, u16 offset)
1698  {
1699         return core->bus->ops->read8(core, offset);
1700  }
1701 -extern inline u32 bcma_read16(struct bcma_device *core, u16 offset)
1702 +static inline u32 bcma_read16(struct bcma_device *core, u16 offset)
1703  {
1704         return core->bus->ops->read16(core, offset);
1705  }
1706 -extern inline u32 bcma_read32(struct bcma_device *core, u16 offset)
1707 +static inline u32 bcma_read32(struct bcma_device *core, u16 offset)
1708  {
1709         return core->bus->ops->read32(core, offset);
1710  }
1711 -extern inline
1712 +static inline
1713  void bcma_write8(struct bcma_device *core, u16 offset, u32 value)
1714  {
1715         core->bus->ops->write8(core, offset, value);
1716  }
1717 -extern inline
1718 +static inline
1719  void bcma_write16(struct bcma_device *core, u16 offset, u32 value)
1720  {
1721         core->bus->ops->write16(core, offset, value);
1722  }
1723 -extern inline
1724 +static inline
1725  void bcma_write32(struct bcma_device *core, u16 offset, u32 value)
1726  {
1727         core->bus->ops->write32(core, offset, value);
1728  }
1729  #ifdef CONFIG_BCMA_BLOCKIO
1730 -extern inline void bcma_block_read(struct bcma_device *core, void *buffer,
1731 +static inline void bcma_block_read(struct bcma_device *core, void *buffer,
1732                                    size_t count, u16 offset, u8 reg_width)
1733  {
1734         core->bus->ops->block_read(core, buffer, count, offset, reg_width);
1735  }
1736 -extern inline void bcma_block_write(struct bcma_device *core, const void *buffer,
1737 -                                   size_t count, u16 offset, u8 reg_width)
1738 +static inline void bcma_block_write(struct bcma_device *core,
1739 +                                   const void *buffer, size_t count,
1740 +                                   u16 offset, u8 reg_width)
1741  {
1742         core->bus->ops->block_write(core, buffer, count, offset, reg_width);
1743  }
1744  #endif
1745 -extern inline u32 bcma_aread32(struct bcma_device *core, u16 offset)
1746 +static inline u32 bcma_aread32(struct bcma_device *core, u16 offset)
1747  {
1748         return core->bus->ops->aread32(core, offset);
1749  }
1750 -extern inline
1751 +static inline
1752  void bcma_awrite32(struct bcma_device *core, u16 offset, u32 value)
1753  {
1754         core->bus->ops->awrite32(core, offset, value);
1755  }
1756  
1757 -#define bcma_mask32(cc, offset, mask) \
1758 -       bcma_write32(cc, offset, bcma_read32(cc, offset) & (mask))
1759 -#define bcma_set32(cc, offset, set) \
1760 -       bcma_write32(cc, offset, bcma_read32(cc, offset) | (set))
1761 -#define bcma_maskset32(cc, offset, mask, set) \
1762 -       bcma_write32(cc, offset, (bcma_read32(cc, offset) & (mask)) | (set))
1763 +static inline void bcma_mask32(struct bcma_device *cc, u16 offset, u32 mask)
1764 +{
1765 +       bcma_write32(cc, offset, bcma_read32(cc, offset) & mask);
1766 +}
1767 +static inline void bcma_set32(struct bcma_device *cc, u16 offset, u32 set)
1768 +{
1769 +       bcma_write32(cc, offset, bcma_read32(cc, offset) | set);
1770 +}
1771 +static inline void bcma_maskset32(struct bcma_device *cc,
1772 +                                 u16 offset, u32 mask, u32 set)
1773 +{
1774 +       bcma_write32(cc, offset, (bcma_read32(cc, offset) & mask) | set);
1775 +}
1776 +static inline void bcma_mask16(struct bcma_device *cc, u16 offset, u16 mask)
1777 +{
1778 +       bcma_write16(cc, offset, bcma_read16(cc, offset) & mask);
1779 +}
1780 +static inline void bcma_set16(struct bcma_device *cc, u16 offset, u16 set)
1781 +{
1782 +       bcma_write16(cc, offset, bcma_read16(cc, offset) | set);
1783 +}
1784 +static inline void bcma_maskset16(struct bcma_device *cc,
1785 +                                 u16 offset, u16 mask, u16 set)
1786 +{
1787 +       bcma_write16(cc, offset, (bcma_read16(cc, offset) & mask) | set);
1788 +}
1789  
1790  extern bool bcma_core_is_enabled(struct bcma_device *core);
1791  extern void bcma_core_disable(struct bcma_device *core, u32 flags);
1792 --- a/include/linux/bcma/bcma_driver_chipcommon.h
1793 +++ b/include/linux/bcma/bcma_driver_chipcommon.h
1794 @@ -24,6 +24,7 @@
1795  #define   BCMA_CC_FLASHT_NONE          0x00000000      /* No flash */
1796  #define   BCMA_CC_FLASHT_STSER         0x00000100      /* ST serial flash */
1797  #define   BCMA_CC_FLASHT_ATSER         0x00000200      /* Atmel serial flash */
1798 +#define   BCMA_CC_FLASHT_NFLASH                0x00000200
1799  #define          BCMA_CC_FLASHT_PARA           0x00000700      /* Parallel flash */
1800  #define  BCMA_CC_CAP_PLLT              0x00038000      /* PLL Type */
1801  #define   BCMA_PLLTYPE_NONE            0x00000000
1802 @@ -178,6 +179,7 @@
1803  #define BCMA_CC_PROG_CFG               0x0120
1804  #define BCMA_CC_PROG_WAITCNT           0x0124
1805  #define BCMA_CC_FLASH_CFG              0x0128
1806 +#define  BCMA_CC_FLASH_CFG_DS          0x0010  /* Data size, 0=8bit, 1=16bit */
1807  #define BCMA_CC_FLASH_WAITCNT          0x012C
1808  /* 0x1E0 is defined as shared BCMA_CLKCTLST */
1809  #define BCMA_CC_HW_WORKAROUND          0x01E4 /* Hardware workaround (rev >= 20) */
1810 @@ -201,6 +203,7 @@
1811  #define BCMA_CC_PMU_CTL                        0x0600 /* PMU control */
1812  #define  BCMA_CC_PMU_CTL_ILP_DIV       0xFFFF0000 /* ILP div mask */
1813  #define  BCMA_CC_PMU_CTL_ILP_DIV_SHIFT 16
1814 +#define  BCMA_CC_PMU_CTL_PLL_UPD       0x00000400
1815  #define  BCMA_CC_PMU_CTL_NOILPONW      0x00000200 /* No ILP on wait */
1816  #define  BCMA_CC_PMU_CTL_HTREQEN       0x00000100 /* HT req enable */
1817  #define  BCMA_CC_PMU_CTL_ALPREQEN      0x00000080 /* ALP req enable */
1818 @@ -239,6 +242,64 @@
1819  #define BCMA_CC_SPROM                  0x0800 /* SPROM beginning */
1820  #define BCMA_CC_SPROM_PCIE6            0x0830 /* SPROM beginning on PCIe rev >= 6 */
1821  
1822 +/* Divider allocation in 4716/47162/5356 */
1823 +#define BCMA_CC_PMU5_MAINPLL_CPU       1
1824 +#define BCMA_CC_PMU5_MAINPLL_MEM       2
1825 +#define BCMA_CC_PMU5_MAINPLL_SSB       3
1826 +
1827 +/* PLL usage in 4716/47162 */
1828 +#define BCMA_CC_PMU4716_MAINPLL_PLL0   12
1829 +
1830 +/* PLL usage in 5356/5357 */
1831 +#define BCMA_CC_PMU5356_MAINPLL_PLL0   0
1832 +#define BCMA_CC_PMU5357_MAINPLL_PLL0   0
1833 +
1834 +/* 4706 PMU */
1835 +#define BCMA_CC_PMU4706_MAINPLL_PLL0   0
1836 +
1837 +/* ALP clock on pre-PMU chips */
1838 +#define BCMA_CC_PMU_ALP_CLOCK          20000000
1839 +/* HT clock for systems with PMU-enabled chipcommon */
1840 +#define BCMA_CC_PMU_HT_CLOCK           80000000
1841 +
1842 +/* PMU rev 5 (& 6) */
1843 +#define BCMA_CC_PPL_P1P2_OFF           0
1844 +#define BCMA_CC_PPL_P1_MASK            0x0f000000
1845 +#define BCMA_CC_PPL_P1_SHIFT           24
1846 +#define BCMA_CC_PPL_P2_MASK            0x00f00000
1847 +#define BCMA_CC_PPL_P2_SHIFT           20
1848 +#define BCMA_CC_PPL_M14_OFF            1
1849 +#define BCMA_CC_PPL_MDIV_MASK          0x000000ff
1850 +#define BCMA_CC_PPL_MDIV_WIDTH         8
1851 +#define BCMA_CC_PPL_NM5_OFF            2
1852 +#define BCMA_CC_PPL_NDIV_MASK          0xfff00000
1853 +#define BCMA_CC_PPL_NDIV_SHIFT         20
1854 +#define BCMA_CC_PPL_FMAB_OFF           3
1855 +#define BCMA_CC_PPL_MRAT_MASK          0xf0000000
1856 +#define BCMA_CC_PPL_MRAT_SHIFT         28
1857 +#define BCMA_CC_PPL_ABRAT_MASK         0x08000000
1858 +#define BCMA_CC_PPL_ABRAT_SHIFT                27
1859 +#define BCMA_CC_PPL_FDIV_MASK          0x07ffffff
1860 +#define BCMA_CC_PPL_PLLCTL_OFF         4
1861 +#define BCMA_CC_PPL_PCHI_OFF           5
1862 +#define BCMA_CC_PPL_PCHI_MASK          0x0000003f
1863 +
1864 +/* BCM4331 ChipControl numbers. */
1865 +#define BCMA_CHIPCTL_4331_BT_COEXIST           BIT(0)  /* 0 disable */
1866 +#define BCMA_CHIPCTL_4331_SECI                 BIT(1)  /* 0 SECI is disabled (JATG functional) */
1867 +#define BCMA_CHIPCTL_4331_EXT_LNA              BIT(2)  /* 0 disable */
1868 +#define BCMA_CHIPCTL_4331_SPROM_GPIO13_15      BIT(3)  /* sprom/gpio13-15 mux */
1869 +#define BCMA_CHIPCTL_4331_EXTPA_EN             BIT(4)  /* 0 ext pa disable, 1 ext pa enabled */
1870 +#define BCMA_CHIPCTL_4331_GPIOCLK_ON_SPROMCS   BIT(5)  /* set drive out GPIO_CLK on sprom_cs pin */
1871 +#define BCMA_CHIPCTL_4331_PCIE_MDIO_ON_SPROMCS BIT(6)  /* use sprom_cs pin as PCIE mdio interface */
1872 +#define BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5     BIT(7)  /* aband extpa will be at gpio2/5 and sprom_dout */
1873 +#define BCMA_CHIPCTL_4331_OVR_PIPEAUXCLKEN     BIT(8)  /* override core control on pipe_AuxClkEnable */
1874 +#define BCMA_CHIPCTL_4331_OVR_PIPEAUXPWRDOWN   BIT(9)  /* override core control on pipe_AuxPowerDown */
1875 +#define BCMA_CHIPCTL_4331_PCIE_AUXCLKEN                BIT(10) /* pcie_auxclkenable */
1876 +#define BCMA_CHIPCTL_4331_PCIE_PIPE_PLLDOWN    BIT(11) /* pcie_pipe_pllpowerdown */
1877 +#define BCMA_CHIPCTL_4331_BT_SHD0_ON_GPIO4     BIT(16) /* enable bt_shd0 at gpio4 */
1878 +#define BCMA_CHIPCTL_4331_BT_SHD1_ON_GPIO5     BIT(17) /* enable bt_shd1 at gpio5 */
1879 +
1880  /* Data for the PMU, if available.
1881   * Check availability with ((struct bcma_chipcommon)->capabilities & BCMA_CC_CAP_PMU)
1882   */
1883 @@ -247,14 +308,37 @@ struct bcma_chipcommon_pmu {
1884         u32 crystalfreq;        /* The active crystal frequency (in kHz) */
1885  };
1886  
1887 +#ifdef CONFIG_BCMA_DRIVER_MIPS
1888 +struct bcma_pflash {
1889 +       u8 buswidth;
1890 +       u32 window;
1891 +       u32 window_size;
1892 +};
1893 +
1894 +struct bcma_serial_port {
1895 +       void *regs;
1896 +       unsigned long clockspeed;
1897 +       unsigned int irq;
1898 +       unsigned int baud_base;
1899 +       unsigned int reg_shift;
1900 +};
1901 +#endif /* CONFIG_BCMA_DRIVER_MIPS */
1902 +
1903  struct bcma_drv_cc {
1904         struct bcma_device *core;
1905         u32 status;
1906         u32 capabilities;
1907         u32 capabilities_ext;
1908 +       u8 setup_done:1;
1909         /* Fast Powerup Delay constant */
1910         u16 fast_pwrup_delay;
1911         struct bcma_chipcommon_pmu pmu;
1912 +#ifdef CONFIG_BCMA_DRIVER_MIPS
1913 +       struct bcma_pflash pflash;
1914 +
1915 +       int nr_serial_ports;
1916 +       struct bcma_serial_port serial_ports[4];
1917 +#endif /* CONFIG_BCMA_DRIVER_MIPS */
1918  };
1919  
1920  /* Register access */
1921 @@ -275,6 +359,8 @@ extern void bcma_core_chipcommon_init(st
1922  extern void bcma_chipco_suspend(struct bcma_drv_cc *cc);
1923  extern void bcma_chipco_resume(struct bcma_drv_cc *cc);
1924  
1925 +void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable);
1926 +
1927  extern void bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc,
1928                                           u32 ticks);
1929  
1930 @@ -293,4 +379,13 @@ u32 bcma_chipco_gpio_polarity(struct bcm
1931  /* PMU support */
1932  extern void bcma_pmu_init(struct bcma_drv_cc *cc);
1933  
1934 +extern void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset,
1935 +                                 u32 value);
1936 +extern void bcma_chipco_pll_maskset(struct bcma_drv_cc *cc, u32 offset,
1937 +                                   u32 mask, u32 set);
1938 +extern void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc,
1939 +                                       u32 offset, u32 mask, u32 set);
1940 +extern void bcma_chipco_regctl_maskset(struct bcma_drv_cc *cc,
1941 +                                      u32 offset, u32 mask, u32 set);
1942 +
1943  #endif /* LINUX_BCMA_DRIVER_CC_H_ */
1944 --- /dev/null
1945 +++ b/include/linux/bcma/bcma_driver_mips.h
1946 @@ -0,0 +1,51 @@
1947 +#ifndef LINUX_BCMA_DRIVER_MIPS_H_
1948 +#define LINUX_BCMA_DRIVER_MIPS_H_
1949 +
1950 +#define BCMA_MIPS_IPSFLAG              0x0F08
1951 +/* which sbflags get routed to mips interrupt 1 */
1952 +#define  BCMA_MIPS_IPSFLAG_IRQ1                0x0000003F
1953 +#define  BCMA_MIPS_IPSFLAG_IRQ1_SHIFT  0
1954 +/* which sbflags get routed to mips interrupt 2 */
1955 +#define  BCMA_MIPS_IPSFLAG_IRQ2                0x00003F00
1956 +#define  BCMA_MIPS_IPSFLAG_IRQ2_SHIFT  8
1957 +/* which sbflags get routed to mips interrupt 3 */
1958 +#define  BCMA_MIPS_IPSFLAG_IRQ3                0x003F0000
1959 +#define  BCMA_MIPS_IPSFLAG_IRQ3_SHIFT  16
1960 +/* which sbflags get routed to mips interrupt 4 */
1961 +#define  BCMA_MIPS_IPSFLAG_IRQ4                0x3F000000
1962 +#define  BCMA_MIPS_IPSFLAG_IRQ4_SHIFT  24
1963 +
1964 +/* MIPS 74K core registers */
1965 +#define BCMA_MIPS_MIPS74K_CORECTL      0x0000
1966 +#define BCMA_MIPS_MIPS74K_EXCEPTBASE   0x0004
1967 +#define BCMA_MIPS_MIPS74K_BIST         0x000C
1968 +#define BCMA_MIPS_MIPS74K_INTMASK_INT0 0x0014
1969 +#define BCMA_MIPS_MIPS74K_INTMASK(int) \
1970 +       ((int) * 4 + BCMA_MIPS_MIPS74K_INTMASK_INT0)
1971 +#define BCMA_MIPS_MIPS74K_NMIMASK      0x002C
1972 +#define BCMA_MIPS_MIPS74K_GPIOSEL      0x0040
1973 +#define BCMA_MIPS_MIPS74K_GPIOOUT      0x0044
1974 +#define BCMA_MIPS_MIPS74K_GPIOEN       0x0048
1975 +#define BCMA_MIPS_MIPS74K_CLKCTLST     0x01E0
1976 +
1977 +#define BCMA_MIPS_OOBSELOUTA30         0x100
1978 +
1979 +struct bcma_device;
1980 +
1981 +struct bcma_drv_mips {
1982 +       struct bcma_device *core;
1983 +       u8 setup_done:1;
1984 +       unsigned int assigned_irqs;
1985 +};
1986 +
1987 +#ifdef CONFIG_BCMA_DRIVER_MIPS
1988 +extern void bcma_core_mips_init(struct bcma_drv_mips *mcore);
1989 +#else
1990 +static inline void bcma_core_mips_init(struct bcma_drv_mips *mcore) { }
1991 +#endif
1992 +
1993 +extern u32 bcma_cpu_clock(struct bcma_drv_mips *mcore);
1994 +
1995 +extern unsigned int bcma_core_mips_irq(struct bcma_device *dev);
1996 +
1997 +#endif /* LINUX_BCMA_DRIVER_MIPS_H_ */
1998 --- /dev/null
1999 +++ b/include/linux/bcma/bcma_soc.h
2000 @@ -0,0 +1,16 @@
2001 +#ifndef LINUX_BCMA_SOC_H_
2002 +#define LINUX_BCMA_SOC_H_
2003 +
2004 +#include <linux/bcma/bcma.h>
2005 +
2006 +struct bcma_soc {
2007 +       struct bcma_bus bus;
2008 +       struct bcma_device core_cc;
2009 +       struct bcma_device core_mips;
2010 +};
2011 +
2012 +int __init bcma_host_soc_register(struct bcma_soc *soc);
2013 +
2014 +int bcma_bus_register(struct bcma_bus *bus);
2015 +
2016 +#endif /* LINUX_BCMA_SOC_H_ */