linux: move certain disabled symbols to the generic configs
[openwrt.git] / target / linux / generic / patches-3.1 / 025-bcma_backport.patch
1 --- a/drivers/bcma/Kconfig
2 +++ b/drivers/bcma/Kconfig
3 @@ -29,10 +29,23 @@ config BCMA_HOST_PCI
4  
5  config BCMA_DRIVER_PCI_HOSTMODE
6         bool "Driver for PCI core working in hostmode"
7 -       depends on BCMA && MIPS
8 +       depends on BCMA && MIPS && BCMA_HOST_PCI
9         help
10           PCI core hostmode operation (external PCI bus).
11  
12 +config BCMA_HOST_SOC
13 +       bool
14 +       depends on BCMA_DRIVER_MIPS
15 +
16 +config BCMA_DRIVER_MIPS
17 +       bool "BCMA Broadcom MIPS core driver"
18 +       depends on BCMA && MIPS
19 +       help
20 +         Driver for the Broadcom MIPS core attached to Broadcom specific
21 +         Advanced Microcontroller Bus.
22 +
23 +         If unsure, say N
24 +
25  config BCMA_DEBUG
26         bool "BCMA debugging"
27         depends on BCMA
28 --- a/drivers/bcma/Makefile
29 +++ b/drivers/bcma/Makefile
30 @@ -2,7 +2,9 @@ bcma-y                                  += main.o scan.o core.o sprom
31  bcma-y                                 += driver_chipcommon.o driver_chipcommon_pmu.o
32  bcma-y                                 += driver_pci.o
33  bcma-$(CONFIG_BCMA_DRIVER_PCI_HOSTMODE)        += driver_pci_host.o
34 +bcma-$(CONFIG_BCMA_DRIVER_MIPS)                += driver_mips.o
35  bcma-$(CONFIG_BCMA_HOST_PCI)           += host_pci.o
36 +bcma-$(CONFIG_BCMA_HOST_SOC)           += host_soc.o
37  obj-$(CONFIG_BCMA)                     += bcma.o
38  
39  ccflags-$(CONFIG_BCMA_DEBUG)           := -DDEBUG
40 --- a/drivers/bcma/bcma_private.h
41 +++ b/drivers/bcma/bcma_private.h
42 @@ -13,23 +13,47 @@
43  struct bcma_bus;
44  
45  /* main.c */
46 -int bcma_bus_register(struct bcma_bus *bus);
47 +int __devinit bcma_bus_register(struct bcma_bus *bus);
48  void bcma_bus_unregister(struct bcma_bus *bus);
49 +int __init bcma_bus_early_register(struct bcma_bus *bus,
50 +                                  struct bcma_device *core_cc,
51 +                                  struct bcma_device *core_mips);
52 +#ifdef CONFIG_PM
53 +int bcma_bus_suspend(struct bcma_bus *bus);
54 +int bcma_bus_resume(struct bcma_bus *bus);
55 +#endif
56  
57  /* scan.c */
58  int bcma_bus_scan(struct bcma_bus *bus);
59 +int __init bcma_bus_scan_early(struct bcma_bus *bus,
60 +                              struct bcma_device_id *match,
61 +                              struct bcma_device *core);
62 +void bcma_init_bus(struct bcma_bus *bus);
63  
64  /* sprom.c */
65  int bcma_sprom_get(struct bcma_bus *bus);
66  
67 +/* driver_chipcommon.c */
68 +#ifdef CONFIG_BCMA_DRIVER_MIPS
69 +void bcma_chipco_serial_init(struct bcma_drv_cc *cc);
70 +#endif /* CONFIG_BCMA_DRIVER_MIPS */
71 +
72 +/* driver_chipcommon_pmu.c */
73 +u32 bcma_pmu_alp_clock(struct bcma_drv_cc *cc);
74 +u32 bcma_pmu_get_clockcpu(struct bcma_drv_cc *cc);
75 +
76  #ifdef CONFIG_BCMA_HOST_PCI
77  /* host_pci.c */
78  extern int __init bcma_host_pci_init(void);
79  extern void __exit bcma_host_pci_exit(void);
80  #endif /* CONFIG_BCMA_HOST_PCI */
81  
82 +/* driver_pci.c */
83 +u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address);
84 +
85  #ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
86 -void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc);
87 +bool __devinit bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc);
88 +void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc);
89  #endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */
90  
91  #endif
92 --- a/drivers/bcma/core.c
93 +++ b/drivers/bcma/core.c
94 @@ -110,6 +110,8 @@ EXPORT_SYMBOL_GPL(bcma_core_pll_ctl);
95  u32 bcma_core_dma_translation(struct bcma_device *core)
96  {
97         switch (core->bus->hosttype) {
98 +       case BCMA_HOSTTYPE_SOC:
99 +               return 0;
100         case BCMA_HOSTTYPE_PCI:
101                 if (bcma_aread32(core, BCMA_IOST) & BCMA_IOST_DMA64)
102                         return BCMA_DMA_TRANSLATION_DMA64_CMT;
103 --- a/drivers/bcma/driver_chipcommon.c
104 +++ b/drivers/bcma/driver_chipcommon.c
105 @@ -26,6 +26,9 @@ void bcma_core_chipcommon_init(struct bc
106         u32 leddc_on = 10;
107         u32 leddc_off = 90;
108  
109 +       if (cc->setup_done)
110 +               return;
111 +
112         if (cc->core->id.rev >= 11)
113                 cc->status = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
114         cc->capabilities = bcma_cc_read32(cc, BCMA_CC_CAP);
115 @@ -52,6 +55,8 @@ void bcma_core_chipcommon_init(struct bc
116                         ((leddc_on << BCMA_CC_GPIOTIMER_ONTIME_SHIFT) |
117                          (leddc_off << BCMA_CC_GPIOTIMER_OFFTIME_SHIFT)));
118         }
119 +
120 +       cc->setup_done = true;
121  }
122  
123  /* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */
124 @@ -101,3 +106,51 @@ u32 bcma_chipco_gpio_polarity(struct bcm
125  {
126         return bcma_cc_write32_masked(cc, BCMA_CC_GPIOPOL, mask, value);
127  }
128 +
129 +#ifdef CONFIG_BCMA_DRIVER_MIPS
130 +void bcma_chipco_serial_init(struct bcma_drv_cc *cc)
131 +{
132 +       unsigned int irq;
133 +       u32 baud_base;
134 +       u32 i;
135 +       unsigned int ccrev = cc->core->id.rev;
136 +       struct bcma_serial_port *ports = cc->serial_ports;
137 +
138 +       if (ccrev >= 11 && ccrev != 15) {
139 +               /* Fixed ALP clock */
140 +               baud_base = bcma_pmu_alp_clock(cc);
141 +               if (ccrev >= 21) {
142 +                       /* Turn off UART clock before switching clocksource. */
143 +                       bcma_cc_write32(cc, BCMA_CC_CORECTL,
144 +                                      bcma_cc_read32(cc, BCMA_CC_CORECTL)
145 +                                      & ~BCMA_CC_CORECTL_UARTCLKEN);
146 +               }
147 +               /* Set the override bit so we don't divide it */
148 +               bcma_cc_write32(cc, BCMA_CC_CORECTL,
149 +                              bcma_cc_read32(cc, BCMA_CC_CORECTL)
150 +                              | BCMA_CC_CORECTL_UARTCLK0);
151 +               if (ccrev >= 21) {
152 +                       /* Re-enable the UART clock. */
153 +                       bcma_cc_write32(cc, BCMA_CC_CORECTL,
154 +                                      bcma_cc_read32(cc, BCMA_CC_CORECTL)
155 +                                      | BCMA_CC_CORECTL_UARTCLKEN);
156 +               }
157 +       } else {
158 +               pr_err("serial not supported on this device ccrev: 0x%x\n",
159 +                      ccrev);
160 +               return;
161 +       }
162 +
163 +       irq = bcma_core_mips_irq(cc->core);
164 +
165 +       /* Determine the registers of the UARTs */
166 +       cc->nr_serial_ports = (cc->capabilities & BCMA_CC_CAP_NRUART);
167 +       for (i = 0; i < cc->nr_serial_ports; i++) {
168 +               ports[i].regs = cc->core->io_addr + BCMA_CC_UART0_DATA +
169 +                               (i * 256);
170 +               ports[i].irq = irq;
171 +               ports[i].baud_base = baud_base;
172 +               ports[i].reg_shift = 0;
173 +       }
174 +}
175 +#endif /* CONFIG_BCMA_DRIVER_MIPS */
176 --- a/drivers/bcma/driver_chipcommon_pmu.c
177 +++ b/drivers/bcma/driver_chipcommon_pmu.c
178 @@ -11,20 +11,47 @@
179  #include "bcma_private.h"
180  #include <linux/bcma/bcma.h>
181  
182 -static void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc,
183 -                                       u32 offset, u32 mask, u32 set)
184 +static u32 bcma_chipco_pll_read(struct bcma_drv_cc *cc, u32 offset)
185  {
186 -       u32 value;
187 +       bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
188 +       bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
189 +       return bcma_cc_read32(cc, BCMA_CC_PLLCTL_DATA);
190 +}
191  
192 -       bcma_cc_read32(cc, BCMA_CC_CHIPCTL_ADDR);
193 +void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset, u32 value)
194 +{
195 +       bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
196 +       bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
197 +       bcma_cc_write32(cc, BCMA_CC_PLLCTL_DATA, value);
198 +}
199 +EXPORT_SYMBOL_GPL(bcma_chipco_pll_write);
200 +
201 +void bcma_chipco_pll_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask,
202 +                            u32 set)
203 +{
204 +       bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
205 +       bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
206 +       bcma_cc_maskset32(cc, BCMA_CC_PLLCTL_DATA, mask, set);
207 +}
208 +EXPORT_SYMBOL_GPL(bcma_chipco_pll_maskset);
209 +
210 +void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc,
211 +                                u32 offset, u32 mask, u32 set)
212 +{
213         bcma_cc_write32(cc, BCMA_CC_CHIPCTL_ADDR, offset);
214         bcma_cc_read32(cc, BCMA_CC_CHIPCTL_ADDR);
215 -       value = bcma_cc_read32(cc, BCMA_CC_CHIPCTL_DATA);
216 -       value &= mask;
217 -       value |= set;
218 -       bcma_cc_write32(cc, BCMA_CC_CHIPCTL_DATA, value);
219 -       bcma_cc_read32(cc, BCMA_CC_CHIPCTL_DATA);
220 +       bcma_cc_maskset32(cc, BCMA_CC_CHIPCTL_DATA, mask, set);
221  }
222 +EXPORT_SYMBOL_GPL(bcma_chipco_chipctl_maskset);
223 +
224 +void bcma_chipco_regctl_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask,
225 +                               u32 set)
226 +{
227 +       bcma_cc_write32(cc, BCMA_CC_REGCTL_ADDR, offset);
228 +       bcma_cc_read32(cc, BCMA_CC_REGCTL_ADDR);
229 +       bcma_cc_maskset32(cc, BCMA_CC_REGCTL_DATA, mask, set);
230 +}
231 +EXPORT_SYMBOL_GPL(bcma_chipco_regctl_maskset);
232  
233  static void bcma_pmu_pll_init(struct bcma_drv_cc *cc)
234  {
235 @@ -52,6 +79,7 @@ static void bcma_pmu_resources_init(stru
236                 min_msk = 0x200D;
237                 max_msk = 0xFFFF;
238                 break;
239 +       case 0x4331:
240         case 43224:
241         case 43225:
242                 break;
243 @@ -83,6 +111,24 @@ void bcma_pmu_swreg_init(struct bcma_drv
244         }
245  }
246  
247 +/* Disable to allow reading SPROM. Don't know the adventages of enabling it. */
248 +void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable)
249 +{
250 +       struct bcma_bus *bus = cc->core->bus;
251 +       u32 val;
252 +
253 +       val = bcma_cc_read32(cc, BCMA_CC_CHIPCTL);
254 +       if (enable) {
255 +               val |= BCMA_CHIPCTL_4331_EXTPA_EN;
256 +               if (bus->chipinfo.pkg == 9 || bus->chipinfo.pkg == 11)
257 +                       val |= BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5;
258 +       } else {
259 +               val &= ~BCMA_CHIPCTL_4331_EXTPA_EN;
260 +               val &= ~BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5;
261 +       }
262 +       bcma_cc_write32(cc, BCMA_CC_CHIPCTL, val);
263 +}
264 +
265  void bcma_pmu_workarounds(struct bcma_drv_cc *cc)
266  {
267         struct bcma_bus *bus = cc->core->bus;
268 @@ -92,7 +138,7 @@ void bcma_pmu_workarounds(struct bcma_dr
269                 bcma_chipco_chipctl_maskset(cc, 0, ~0, 0x7);
270                 break;
271         case 0x4331:
272 -               pr_err("Enabling Ext PA lines not implemented\n");
273 +               /* BCM4331 workaround is SPROM-related, we put it in sprom.c */
274                 break;
275         case 43224:
276                 if (bus->chipinfo.rev == 0) {
277 @@ -136,3 +182,129 @@ void bcma_pmu_init(struct bcma_drv_cc *c
278         bcma_pmu_swreg_init(cc);
279         bcma_pmu_workarounds(cc);
280  }
281 +
282 +u32 bcma_pmu_alp_clock(struct bcma_drv_cc *cc)
283 +{
284 +       struct bcma_bus *bus = cc->core->bus;
285 +
286 +       switch (bus->chipinfo.id) {
287 +       case 0x4716:
288 +       case 0x4748:
289 +       case 47162:
290 +       case 0x4313:
291 +       case 0x5357:
292 +       case 0x4749:
293 +       case 53572:
294 +               /* always 20Mhz */
295 +               return 20000 * 1000;
296 +       case 0x5356:
297 +       case 0x5300:
298 +               /* always 25Mhz */
299 +               return 25000 * 1000;
300 +       default:
301 +               pr_warn("No ALP clock specified for %04X device, "
302 +                       "pmu rev. %d, using default %d Hz\n",
303 +                       bus->chipinfo.id, cc->pmu.rev, BCMA_CC_PMU_ALP_CLOCK);
304 +       }
305 +       return BCMA_CC_PMU_ALP_CLOCK;
306 +}
307 +
308 +/* Find the output of the "m" pll divider given pll controls that start with
309 + * pllreg "pll0" i.e. 12 for main 6 for phy, 0 for misc.
310 + */
311 +static u32 bcma_pmu_clock(struct bcma_drv_cc *cc, u32 pll0, u32 m)
312 +{
313 +       u32 tmp, div, ndiv, p1, p2, fc;
314 +       struct bcma_bus *bus = cc->core->bus;
315 +
316 +       BUG_ON((pll0 & 3) || (pll0 > BCMA_CC_PMU4716_MAINPLL_PLL0));
317 +
318 +       BUG_ON(!m || m > 4);
319 +
320 +       if (bus->chipinfo.id == 0x5357 || bus->chipinfo.id == 0x4749) {
321 +               /* Detect failure in clock setting */
322 +               tmp = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
323 +               if (tmp & 0x40000)
324 +                       return 133 * 1000000;
325 +       }
326 +
327 +       tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_P1P2_OFF);
328 +       p1 = (tmp & BCMA_CC_PPL_P1_MASK) >> BCMA_CC_PPL_P1_SHIFT;
329 +       p2 = (tmp & BCMA_CC_PPL_P2_MASK) >> BCMA_CC_PPL_P2_SHIFT;
330 +
331 +       tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_M14_OFF);
332 +       div = (tmp >> ((m - 1) * BCMA_CC_PPL_MDIV_WIDTH)) &
333 +               BCMA_CC_PPL_MDIV_MASK;
334 +
335 +       tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_NM5_OFF);
336 +       ndiv = (tmp & BCMA_CC_PPL_NDIV_MASK) >> BCMA_CC_PPL_NDIV_SHIFT;
337 +
338 +       /* Do calculation in Mhz */
339 +       fc = bcma_pmu_alp_clock(cc) / 1000000;
340 +       fc = (p1 * ndiv * fc) / p2;
341 +
342 +       /* Return clock in Hertz */
343 +       return (fc / div) * 1000000;
344 +}
345 +
346 +/* query bus clock frequency for PMU-enabled chipcommon */
347 +u32 bcma_pmu_get_clockcontrol(struct bcma_drv_cc *cc)
348 +{
349 +       struct bcma_bus *bus = cc->core->bus;
350 +
351 +       switch (bus->chipinfo.id) {
352 +       case 0x4716:
353 +       case 0x4748:
354 +       case 47162:
355 +               return bcma_pmu_clock(cc, BCMA_CC_PMU4716_MAINPLL_PLL0,
356 +                                     BCMA_CC_PMU5_MAINPLL_SSB);
357 +       case 0x5356:
358 +               return bcma_pmu_clock(cc, BCMA_CC_PMU5356_MAINPLL_PLL0,
359 +                                     BCMA_CC_PMU5_MAINPLL_SSB);
360 +       case 0x5357:
361 +       case 0x4749:
362 +               return bcma_pmu_clock(cc, BCMA_CC_PMU5357_MAINPLL_PLL0,
363 +                                     BCMA_CC_PMU5_MAINPLL_SSB);
364 +       case 0x5300:
365 +               return bcma_pmu_clock(cc, BCMA_CC_PMU4706_MAINPLL_PLL0,
366 +                                     BCMA_CC_PMU5_MAINPLL_SSB);
367 +       case 53572:
368 +               return 75000000;
369 +       default:
370 +               pr_warn("No backplane clock specified for %04X device, "
371 +                       "pmu rev. %d, using default %d Hz\n",
372 +                       bus->chipinfo.id, cc->pmu.rev, BCMA_CC_PMU_HT_CLOCK);
373 +       }
374 +       return BCMA_CC_PMU_HT_CLOCK;
375 +}
376 +
377 +/* query cpu clock frequency for PMU-enabled chipcommon */
378 +u32 bcma_pmu_get_clockcpu(struct bcma_drv_cc *cc)
379 +{
380 +       struct bcma_bus *bus = cc->core->bus;
381 +
382 +       if (bus->chipinfo.id == 53572)
383 +               return 300000000;
384 +
385 +       if (cc->pmu.rev >= 5) {
386 +               u32 pll;
387 +               switch (bus->chipinfo.id) {
388 +               case 0x5356:
389 +                       pll = BCMA_CC_PMU5356_MAINPLL_PLL0;
390 +                       break;
391 +               case 0x5357:
392 +               case 0x4749:
393 +                       pll = BCMA_CC_PMU5357_MAINPLL_PLL0;
394 +                       break;
395 +               default:
396 +                       pll = BCMA_CC_PMU4716_MAINPLL_PLL0;
397 +                       break;
398 +               }
399 +
400 +               /* TODO: if (bus->chipinfo.id == 0x5300)
401 +                 return si_4706_pmu_clock(sih, osh, cc, PMU4706_MAINPLL_PLL0, PMU5_MAINPLL_CPU); */
402 +               return bcma_pmu_clock(cc, pll, BCMA_CC_PMU5_MAINPLL_CPU);
403 +       }
404 +
405 +       return bcma_pmu_get_clockcontrol(cc);
406 +}
407 --- /dev/null
408 +++ b/drivers/bcma/driver_mips.c
409 @@ -0,0 +1,256 @@
410 +/*
411 + * Broadcom specific AMBA
412 + * Broadcom MIPS32 74K core driver
413 + *
414 + * Copyright 2009, Broadcom Corporation
415 + * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
416 + * Copyright 2010, Bernhard Loos <bernhardloos@googlemail.com>
417 + * Copyright 2011, Hauke Mehrtens <hauke@hauke-m.de>
418 + *
419 + * Licensed under the GNU/GPL. See COPYING for details.
420 + */
421 +
422 +#include "bcma_private.h"
423 +
424 +#include <linux/bcma/bcma.h>
425 +
426 +#include <linux/serial.h>
427 +#include <linux/serial_core.h>
428 +#include <linux/serial_reg.h>
429 +#include <linux/time.h>
430 +
431 +/* The 47162a0 hangs when reading MIPS DMP registers registers */
432 +static inline bool bcma_core_mips_bcm47162a0_quirk(struct bcma_device *dev)
433 +{
434 +       return dev->bus->chipinfo.id == 47162 && dev->bus->chipinfo.rev == 0 &&
435 +              dev->id.id == BCMA_CORE_MIPS_74K;
436 +}
437 +
438 +/* The 5357b0 hangs when reading USB20H DMP registers */
439 +static inline bool bcma_core_mips_bcm5357b0_quirk(struct bcma_device *dev)
440 +{
441 +       return (dev->bus->chipinfo.id == 0x5357 ||
442 +               dev->bus->chipinfo.id == 0x4749) &&
443 +              dev->bus->chipinfo.pkg == 11 &&
444 +              dev->id.id == BCMA_CORE_USB20_HOST;
445 +}
446 +
447 +static inline u32 mips_read32(struct bcma_drv_mips *mcore,
448 +                             u16 offset)
449 +{
450 +       return bcma_read32(mcore->core, offset);
451 +}
452 +
453 +static inline void mips_write32(struct bcma_drv_mips *mcore,
454 +                               u16 offset,
455 +                               u32 value)
456 +{
457 +       bcma_write32(mcore->core, offset, value);
458 +}
459 +
460 +static const u32 ipsflag_irq_mask[] = {
461 +       0,
462 +       BCMA_MIPS_IPSFLAG_IRQ1,
463 +       BCMA_MIPS_IPSFLAG_IRQ2,
464 +       BCMA_MIPS_IPSFLAG_IRQ3,
465 +       BCMA_MIPS_IPSFLAG_IRQ4,
466 +};
467 +
468 +static const u32 ipsflag_irq_shift[] = {
469 +       0,
470 +       BCMA_MIPS_IPSFLAG_IRQ1_SHIFT,
471 +       BCMA_MIPS_IPSFLAG_IRQ2_SHIFT,
472 +       BCMA_MIPS_IPSFLAG_IRQ3_SHIFT,
473 +       BCMA_MIPS_IPSFLAG_IRQ4_SHIFT,
474 +};
475 +
476 +static u32 bcma_core_mips_irqflag(struct bcma_device *dev)
477 +{
478 +       u32 flag;
479 +
480 +       if (bcma_core_mips_bcm47162a0_quirk(dev))
481 +               return dev->core_index;
482 +       if (bcma_core_mips_bcm5357b0_quirk(dev))
483 +               return dev->core_index;
484 +       flag = bcma_aread32(dev, BCMA_MIPS_OOBSELOUTA30);
485 +
486 +       return flag & 0x1F;
487 +}
488 +
489 +/* Get the MIPS IRQ assignment for a specified device.
490 + * If unassigned, 0 is returned.
491 + */
492 +unsigned int bcma_core_mips_irq(struct bcma_device *dev)
493 +{
494 +       struct bcma_device *mdev = dev->bus->drv_mips.core;
495 +       u32 irqflag;
496 +       unsigned int irq;
497 +
498 +       irqflag = bcma_core_mips_irqflag(dev);
499 +
500 +       for (irq = 1; irq <= 4; irq++)
501 +               if (bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq)) &
502 +                   (1 << irqflag))
503 +                       return irq;
504 +
505 +       return 0;
506 +}
507 +EXPORT_SYMBOL(bcma_core_mips_irq);
508 +
509 +static void bcma_core_mips_set_irq(struct bcma_device *dev, unsigned int irq)
510 +{
511 +       unsigned int oldirq = bcma_core_mips_irq(dev);
512 +       struct bcma_bus *bus = dev->bus;
513 +       struct bcma_device *mdev = bus->drv_mips.core;
514 +       u32 irqflag;
515 +
516 +       irqflag = bcma_core_mips_irqflag(dev);
517 +       BUG_ON(oldirq == 6);
518 +
519 +       dev->irq = irq + 2;
520 +
521 +       /* clear the old irq */
522 +       if (oldirq == 0)
523 +               bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0),
524 +                           bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) &
525 +                           ~(1 << irqflag));
526 +       else
527 +               bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq), 0);
528 +
529 +       /* assign the new one */
530 +       if (irq == 0) {
531 +               bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0),
532 +                           bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) |
533 +                           (1 << irqflag));
534 +       } else {
535 +               u32 oldirqflag = bcma_read32(mdev,
536 +                                            BCMA_MIPS_MIPS74K_INTMASK(irq));
537 +               if (oldirqflag) {
538 +                       struct bcma_device *core;
539 +
540 +                       /* backplane irq line is in use, find out who uses
541 +                        * it and set user to irq 0
542 +                        */
543 +                       list_for_each_entry_reverse(core, &bus->cores, list) {
544 +                               if ((1 << bcma_core_mips_irqflag(core)) ==
545 +                                   oldirqflag) {
546 +                                       bcma_core_mips_set_irq(core, 0);
547 +                                       break;
548 +                               }
549 +                       }
550 +               }
551 +               bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq),
552 +                            1 << irqflag);
553 +       }
554 +
555 +       pr_info("set_irq: core 0x%04x, irq %d => %d\n",
556 +               dev->id.id, oldirq + 2, irq + 2);
557 +}
558 +
559 +static void bcma_core_mips_print_irq(struct bcma_device *dev, unsigned int irq)
560 +{
561 +       int i;
562 +       static const char *irq_name[] = {"2(S)", "3", "4", "5", "6", "D", "I"};
563 +       printk(KERN_INFO KBUILD_MODNAME ": core 0x%04x, irq :", dev->id.id);
564 +       for (i = 0; i <= 6; i++)
565 +               printk(" %s%s", irq_name[i], i == irq ? "*" : " ");
566 +       printk("\n");
567 +}
568 +
569 +static void bcma_core_mips_dump_irq(struct bcma_bus *bus)
570 +{
571 +       struct bcma_device *core;
572 +
573 +       list_for_each_entry_reverse(core, &bus->cores, list) {
574 +               bcma_core_mips_print_irq(core, bcma_core_mips_irq(core));
575 +       }
576 +}
577 +
578 +u32 bcma_cpu_clock(struct bcma_drv_mips *mcore)
579 +{
580 +       struct bcma_bus *bus = mcore->core->bus;
581 +
582 +       if (bus->drv_cc.capabilities & BCMA_CC_CAP_PMU)
583 +               return bcma_pmu_get_clockcpu(&bus->drv_cc);
584 +
585 +       pr_err("No PMU available, need this to get the cpu clock\n");
586 +       return 0;
587 +}
588 +EXPORT_SYMBOL(bcma_cpu_clock);
589 +
590 +static void bcma_core_mips_flash_detect(struct bcma_drv_mips *mcore)
591 +{
592 +       struct bcma_bus *bus = mcore->core->bus;
593 +
594 +       switch (bus->drv_cc.capabilities & BCMA_CC_CAP_FLASHT) {
595 +       case BCMA_CC_FLASHT_STSER:
596 +       case BCMA_CC_FLASHT_ATSER:
597 +               pr_err("Serial flash not supported.\n");
598 +               break;
599 +       case BCMA_CC_FLASHT_PARA:
600 +               pr_info("found parallel flash.\n");
601 +               bus->drv_cc.pflash.window = 0x1c000000;
602 +               bus->drv_cc.pflash.window_size = 0x02000000;
603 +
604 +               if ((bcma_read32(bus->drv_cc.core, BCMA_CC_FLASH_CFG) &
605 +                    BCMA_CC_FLASH_CFG_DS) == 0)
606 +                       bus->drv_cc.pflash.buswidth = 1;
607 +               else
608 +                       bus->drv_cc.pflash.buswidth = 2;
609 +               break;
610 +       default:
611 +               pr_err("flash not supported.\n");
612 +       }
613 +}
614 +
615 +void bcma_core_mips_init(struct bcma_drv_mips *mcore)
616 +{
617 +       struct bcma_bus *bus;
618 +       struct bcma_device *core;
619 +       bus = mcore->core->bus;
620 +
621 +       pr_info("Initializing MIPS core...\n");
622 +
623 +       if (!mcore->setup_done)
624 +               mcore->assigned_irqs = 1;
625 +
626 +       /* Assign IRQs to all cores on the bus */
627 +       list_for_each_entry_reverse(core, &bus->cores, list) {
628 +               int mips_irq;
629 +               if (core->irq)
630 +                       continue;
631 +
632 +               mips_irq = bcma_core_mips_irq(core);
633 +               if (mips_irq > 4)
634 +                       core->irq = 0;
635 +               else
636 +                       core->irq = mips_irq + 2;
637 +               if (core->irq > 5)
638 +                       continue;
639 +               switch (core->id.id) {
640 +               case BCMA_CORE_PCI:
641 +               case BCMA_CORE_PCIE:
642 +               case BCMA_CORE_ETHERNET:
643 +               case BCMA_CORE_ETHERNET_GBIT:
644 +               case BCMA_CORE_MAC_GBIT:
645 +               case BCMA_CORE_80211:
646 +               case BCMA_CORE_USB20_HOST:
647 +                       /* These devices get their own IRQ line if available,
648 +                        * the rest goes on IRQ0
649 +                        */
650 +                       if (mcore->assigned_irqs <= 4)
651 +                               bcma_core_mips_set_irq(core,
652 +                                                      mcore->assigned_irqs++);
653 +                       break;
654 +               }
655 +       }
656 +       pr_info("IRQ reconfiguration done\n");
657 +       bcma_core_mips_dump_irq(bus);
658 +
659 +       if (mcore->setup_done)
660 +               return;
661 +
662 +       bcma_chipco_serial_init(&bus->drv_cc);
663 +       bcma_core_mips_flash_detect(mcore);
664 +       mcore->setup_done = true;
665 +}
666 --- a/drivers/bcma/driver_pci.c
667 +++ b/drivers/bcma/driver_pci.c
668 @@ -2,8 +2,9 @@
669   * Broadcom specific AMBA
670   * PCI Core
671   *
672 - * Copyright 2005, Broadcom Corporation
673 + * Copyright 2005, 2011, Broadcom Corporation
674   * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
675 + * Copyright 2011, 2012, Hauke Mehrtens <hauke@hauke-m.de>
676   *
677   * Licensed under the GNU/GPL. See COPYING for details.
678   */
679 @@ -15,40 +16,41 @@
680   * R/W ops.
681   **************************************************/
682  
683 -static u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address)
684 +u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address)
685  {
686 -       pcicore_write32(pc, 0x130, address);
687 -       pcicore_read32(pc, 0x130);
688 -       return pcicore_read32(pc, 0x134);
689 +       pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_ADDR, address);
690 +       pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_ADDR);
691 +       return pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_DATA);
692  }
693  
694  #if 0
695  static void bcma_pcie_write(struct bcma_drv_pci *pc, u32 address, u32 data)
696  {
697 -       pcicore_write32(pc, 0x130, address);
698 -       pcicore_read32(pc, 0x130);
699 -       pcicore_write32(pc, 0x134, data);
700 +       pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_ADDR, address);
701 +       pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_ADDR);
702 +       pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_DATA, data);
703  }
704  #endif
705  
706  static void bcma_pcie_mdio_set_phy(struct bcma_drv_pci *pc, u8 phy)
707  {
708 -       const u16 mdio_control = 0x128;
709 -       const u16 mdio_data = 0x12C;
710         u32 v;
711         int i;
712  
713 -       v = (1 << 30); /* Start of Transaction */
714 -       v |= (1 << 28); /* Write Transaction */
715 -       v |= (1 << 17); /* Turnaround */
716 -       v |= (0x1F << 18);
717 +       v = BCMA_CORE_PCI_MDIODATA_START;
718 +       v |= BCMA_CORE_PCI_MDIODATA_WRITE;
719 +       v |= (BCMA_CORE_PCI_MDIODATA_DEV_ADDR <<
720 +             BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF);
721 +       v |= (BCMA_CORE_PCI_MDIODATA_BLK_ADDR <<
722 +             BCMA_CORE_PCI_MDIODATA_REGADDR_SHF);
723 +       v |= BCMA_CORE_PCI_MDIODATA_TA;
724         v |= (phy << 4);
725 -       pcicore_write32(pc, mdio_data, v);
726 +       pcicore_write32(pc, BCMA_CORE_PCI_MDIO_DATA, v);
727  
728         udelay(10);
729         for (i = 0; i < 200; i++) {
730 -               v = pcicore_read32(pc, mdio_control);
731 -               if (v & 0x100 /* Trans complete */)
732 +               v = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_CONTROL);
733 +               if (v & BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE)
734                         break;
735                 msleep(1);
736         }
737 @@ -56,79 +58,84 @@ static void bcma_pcie_mdio_set_phy(struc
738  
739  static u16 bcma_pcie_mdio_read(struct bcma_drv_pci *pc, u8 device, u8 address)
740  {
741 -       const u16 mdio_control = 0x128;
742 -       const u16 mdio_data = 0x12C;
743         int max_retries = 10;
744         u16 ret = 0;
745         u32 v;
746         int i;
747  
748 -       v = 0x80; /* Enable Preamble Sequence */
749 -       v |= 0x2; /* MDIO Clock Divisor */
750 -       pcicore_write32(pc, mdio_control, v);
751 +       /* enable mdio access to SERDES */
752 +       v = BCMA_CORE_PCI_MDIOCTL_PREAM_EN;
753 +       v |= BCMA_CORE_PCI_MDIOCTL_DIVISOR_VAL;
754 +       pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, v);
755  
756         if (pc->core->id.rev >= 10) {
757                 max_retries = 200;
758                 bcma_pcie_mdio_set_phy(pc, device);
759 +               v = (BCMA_CORE_PCI_MDIODATA_DEV_ADDR <<
760 +                    BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF);
761 +               v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF);
762 +       } else {
763 +               v = (device << BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF_OLD);
764 +               v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF_OLD);
765         }
766  
767 -       v = (1 << 30); /* Start of Transaction */
768 -       v |= (1 << 29); /* Read Transaction */
769 -       v |= (1 << 17); /* Turnaround */
770 -       if (pc->core->id.rev < 10)
771 -               v |= (u32)device << 22;
772 -       v |= (u32)address << 18;
773 -       pcicore_write32(pc, mdio_data, v);
774 +       v = BCMA_CORE_PCI_MDIODATA_START;
775 +       v |= BCMA_CORE_PCI_MDIODATA_READ;
776 +       v |= BCMA_CORE_PCI_MDIODATA_TA;
777 +
778 +       pcicore_write32(pc, BCMA_CORE_PCI_MDIO_DATA, v);
779         /* Wait for the device to complete the transaction */
780         udelay(10);
781         for (i = 0; i < max_retries; i++) {
782 -               v = pcicore_read32(pc, mdio_control);
783 -               if (v & 0x100 /* Trans complete */) {
784 +               v = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_CONTROL);
785 +               if (v & BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE) {
786                         udelay(10);
787 -                       ret = pcicore_read32(pc, mdio_data);
788 +                       ret = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_DATA);
789                         break;
790                 }
791                 msleep(1);
792         }
793 -       pcicore_write32(pc, mdio_control, 0);
794 +       pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, 0);
795         return ret;
796  }
797  
798  static void bcma_pcie_mdio_write(struct bcma_drv_pci *pc, u8 device,
799                                 u8 address, u16 data)
800  {
801 -       const u16 mdio_control = 0x128;
802 -       const u16 mdio_data = 0x12C;
803         int max_retries = 10;
804         u32 v;
805         int i;
806  
807 -       v = 0x80; /* Enable Preamble Sequence */
808 -       v |= 0x2; /* MDIO Clock Divisor */
809 -       pcicore_write32(pc, mdio_control, v);
810 +       /* enable mdio access to SERDES */
811 +       v = BCMA_CORE_PCI_MDIOCTL_PREAM_EN;
812 +       v |= BCMA_CORE_PCI_MDIOCTL_DIVISOR_VAL;
813 +       pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, v);
814  
815         if (pc->core->id.rev >= 10) {
816                 max_retries = 200;
817                 bcma_pcie_mdio_set_phy(pc, device);
818 +               v = (BCMA_CORE_PCI_MDIODATA_DEV_ADDR <<
819 +                    BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF);
820 +               v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF);
821 +       } else {
822 +               v = (device << BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF_OLD);
823 +               v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF_OLD);
824         }
825  
826 -       v = (1 << 30); /* Start of Transaction */
827 -       v |= (1 << 28); /* Write Transaction */
828 -       v |= (1 << 17); /* Turnaround */
829 -       if (pc->core->id.rev < 10)
830 -               v |= (u32)device << 22;
831 -       v |= (u32)address << 18;
832 +       v = BCMA_CORE_PCI_MDIODATA_START;
833 +       v |= BCMA_CORE_PCI_MDIODATA_WRITE;
834 +       v |= BCMA_CORE_PCI_MDIODATA_TA;
835         v |= data;
836 -       pcicore_write32(pc, mdio_data, v);
837 +       pcicore_write32(pc, BCMA_CORE_PCI_MDIO_DATA, v);
838         /* Wait for the device to complete the transaction */
839         udelay(10);
840         for (i = 0; i < max_retries; i++) {
841 -               v = pcicore_read32(pc, mdio_control);
842 -               if (v & 0x100 /* Trans complete */)
843 +               v = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_CONTROL);
844 +               if (v & BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE)
845                         break;
846                 msleep(1);
847         }
848 -       pcicore_write32(pc, mdio_control, 0);
849 +       pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, 0);
850  }
851  
852  /**************************************************
853 @@ -137,67 +144,53 @@ static void bcma_pcie_mdio_write(struct
854  
855  static u8 bcma_pcicore_polarity_workaround(struct bcma_drv_pci *pc)
856  {
857 -       return (bcma_pcie_read(pc, 0x204) & 0x10) ? 0xC0 : 0x80;
858 +       u32 tmp;
859 +
860 +       tmp = bcma_pcie_read(pc, BCMA_CORE_PCI_PLP_STATUSREG);
861 +       if (tmp & BCMA_CORE_PCI_PLP_POLARITYINV_STAT)
862 +               return BCMA_CORE_PCI_SERDES_RX_CTRL_FORCE |
863 +                      BCMA_CORE_PCI_SERDES_RX_CTRL_POLARITY;
864 +       else
865 +               return BCMA_CORE_PCI_SERDES_RX_CTRL_FORCE;
866  }
867  
868  static void bcma_pcicore_serdes_workaround(struct bcma_drv_pci *pc)
869  {
870 -       const u8 serdes_pll_device = 0x1D;
871 -       const u8 serdes_rx_device = 0x1F;
872         u16 tmp;
873  
874 -       bcma_pcie_mdio_write(pc, serdes_rx_device, 1 /* Control */,
875 -                             bcma_pcicore_polarity_workaround(pc));
876 -       tmp = bcma_pcie_mdio_read(pc, serdes_pll_device, 1 /* Control */);
877 -       if (tmp & 0x4000)
878 -               bcma_pcie_mdio_write(pc, serdes_pll_device, 1, tmp & ~0x4000);
879 +       bcma_pcie_mdio_write(pc, BCMA_CORE_PCI_MDIODATA_DEV_RX,
880 +                            BCMA_CORE_PCI_SERDES_RX_CTRL,
881 +                            bcma_pcicore_polarity_workaround(pc));
882 +       tmp = bcma_pcie_mdio_read(pc, BCMA_CORE_PCI_MDIODATA_DEV_PLL,
883 +                                 BCMA_CORE_PCI_SERDES_PLL_CTRL);
884 +       if (tmp & BCMA_CORE_PCI_PLL_CTRL_FREQDET_EN)
885 +               bcma_pcie_mdio_write(pc, BCMA_CORE_PCI_MDIODATA_DEV_PLL,
886 +                                    BCMA_CORE_PCI_SERDES_PLL_CTRL,
887 +                                    tmp & ~BCMA_CORE_PCI_PLL_CTRL_FREQDET_EN);
888  }
889  
890  /**************************************************
891   * Init.
892   **************************************************/
893  
894 -static void bcma_core_pci_clientmode_init(struct bcma_drv_pci *pc)
895 +static void __devinit bcma_core_pci_clientmode_init(struct bcma_drv_pci *pc)
896  {
897         bcma_pcicore_serdes_workaround(pc);
898  }
899  
900 -static bool bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc)
901 +void __devinit bcma_core_pci_init(struct bcma_drv_pci *pc)
902  {
903 -       struct bcma_bus *bus = pc->core->bus;
904 -       u16 chipid_top;
905 -
906 -       chipid_top = (bus->chipinfo.id & 0xFF00);
907 -       if (chipid_top != 0x4700 &&
908 -           chipid_top != 0x5300)
909 -               return false;
910 -
911 -#ifdef CONFIG_SSB_DRIVER_PCICORE
912 -       if (bus->sprom.boardflags_lo & SSB_PCICORE_BFL_NOPCI)
913 -               return false;
914 -#endif /* CONFIG_SSB_DRIVER_PCICORE */
915 -
916 -#if 0
917 -       /* TODO: on BCMA we use address from EROM instead of magic formula */
918 -       u32 tmp;
919 -       return !mips_busprobe32(tmp, (bus->mmio +
920 -               (pc->core->core_index * BCMA_CORE_SIZE)));
921 -#endif
922 -
923 -       return true;
924 -}
925 +       if (pc->setup_done)
926 +               return;
927  
928 -void bcma_core_pci_init(struct bcma_drv_pci *pc)
929 -{
930 -       if (bcma_core_pci_is_in_hostmode(pc)) {
931  #ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
932 +       pc->hostmode = bcma_core_pci_is_in_hostmode(pc);
933 +       if (pc->hostmode)
934                 bcma_core_pci_hostmode_init(pc);
935 -#else
936 -               pr_err("Driver compiled without support for hostmode PCI\n");
937  #endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */
938 -       } else {
939 +
940 +       if (!pc->hostmode)
941                 bcma_core_pci_clientmode_init(pc);
942 -       }
943  }
944  
945  int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core,
946 @@ -205,7 +198,14 @@ int bcma_core_pci_irq_ctl(struct bcma_dr
947  {
948         struct pci_dev *pdev = pc->core->bus->host_pci;
949         u32 coremask, tmp;
950 -       int err;
951 +       int err = 0;
952 +
953 +       if (core->bus->hosttype != BCMA_HOSTTYPE_PCI) {
954 +               /* This bcma device is not on a PCI host-bus. So the IRQs are
955 +                * not routed through the PCI core.
956 +                * So we must not enable routing through the PCI core. */
957 +               goto out;
958 +       }
959  
960         err = pci_read_config_dword(pdev, BCMA_PCI_IRQMASK, &tmp);
961         if (err)
962 --- a/drivers/bcma/driver_pci_host.c
963 +++ b/drivers/bcma/driver_pci_host.c
964 @@ -2,13 +2,587 @@
965   * Broadcom specific AMBA
966   * PCI Core in hostmode
967   *
968 + * Copyright 2005 - 2011, Broadcom Corporation
969 + * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
970 + * Copyright 2011, 2012, Hauke Mehrtens <hauke@hauke-m.de>
971 + *
972   * Licensed under the GNU/GPL. See COPYING for details.
973   */
974  
975  #include "bcma_private.h"
976 +#include <linux/pci.h>
977  #include <linux/bcma/bcma.h>
978 +#include <asm/paccess.h>
979 +
980 +/* Probe a 32bit value on the bus and catch bus exceptions.
981 + * Returns nonzero on a bus exception.
982 + * This is MIPS specific */
983 +#define mips_busprobe32(val, addr)     get_dbe((val), ((u32 *)(addr)))
984 +
985 +/* Assume one-hot slot wiring */
986 +#define BCMA_PCI_SLOT_MAX      16
987 +#define        PCI_CONFIG_SPACE_SIZE   256
988 +
989 +bool __devinit bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc)
990 +{
991 +       struct bcma_bus *bus = pc->core->bus;
992 +       u16 chipid_top;
993 +       u32 tmp;
994 +
995 +       chipid_top = (bus->chipinfo.id & 0xFF00);
996 +       if (chipid_top != 0x4700 &&
997 +           chipid_top != 0x5300)
998 +               return false;
999 +
1000 +       if (bus->sprom.boardflags_lo & BCMA_CORE_PCI_BFL_NOPCI) {
1001 +               pr_info("This PCI core is disabled and not working\n");
1002 +               return false;
1003 +       }
1004 +
1005 +       bcma_core_enable(pc->core, 0);
1006 +
1007 +       return !mips_busprobe32(tmp, pc->core->io_addr);
1008 +}
1009 +
1010 +static u32 bcma_pcie_read_config(struct bcma_drv_pci *pc, u32 address)
1011 +{
1012 +       pcicore_write32(pc, BCMA_CORE_PCI_CONFIG_ADDR, address);
1013 +       pcicore_read32(pc, BCMA_CORE_PCI_CONFIG_ADDR);
1014 +       return pcicore_read32(pc, BCMA_CORE_PCI_CONFIG_DATA);
1015 +}
1016 +
1017 +static void bcma_pcie_write_config(struct bcma_drv_pci *pc, u32 address,
1018 +                                  u32 data)
1019 +{
1020 +       pcicore_write32(pc, BCMA_CORE_PCI_CONFIG_ADDR, address);
1021 +       pcicore_read32(pc, BCMA_CORE_PCI_CONFIG_ADDR);
1022 +       pcicore_write32(pc, BCMA_CORE_PCI_CONFIG_DATA, data);
1023 +}
1024 +
1025 +static u32 bcma_get_cfgspace_addr(struct bcma_drv_pci *pc, unsigned int dev,
1026 +                            unsigned int func, unsigned int off)
1027 +{
1028 +       u32 addr = 0;
1029 +
1030 +       /* Issue config commands only when the data link is up (atleast
1031 +        * one external pcie device is present).
1032 +        */
1033 +       if (dev >= 2 || !(bcma_pcie_read(pc, BCMA_CORE_PCI_DLLP_LSREG)
1034 +                         & BCMA_CORE_PCI_DLLP_LSREG_LINKUP))
1035 +               goto out;
1036 +
1037 +       /* Type 0 transaction */
1038 +       /* Slide the PCI window to the appropriate slot */
1039 +       pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI1, BCMA_CORE_PCI_SBTOPCI_CFG0);
1040 +       /* Calculate the address */
1041 +       addr = pc->host_controller->host_cfg_addr;
1042 +       addr |= (dev << BCMA_CORE_PCI_CFG_SLOT_SHIFT);
1043 +       addr |= (func << BCMA_CORE_PCI_CFG_FUN_SHIFT);
1044 +       addr |= (off & ~3);
1045 +
1046 +out:
1047 +       return addr;
1048 +}
1049  
1050 -void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc)
1051 +static int bcma_extpci_read_config(struct bcma_drv_pci *pc, unsigned int dev,
1052 +                                 unsigned int func, unsigned int off,
1053 +                                 void *buf, int len)
1054  {
1055 -       pr_err("No support for PCI core in hostmode yet\n");
1056 +       int err = -EINVAL;
1057 +       u32 addr, val;
1058 +       void __iomem *mmio = 0;
1059 +
1060 +       WARN_ON(!pc->hostmode);
1061 +       if (unlikely(len != 1 && len != 2 && len != 4))
1062 +               goto out;
1063 +       if (dev == 0) {
1064 +               /* we support only two functions on device 0 */
1065 +               if (func > 1)
1066 +                       return -EINVAL;
1067 +
1068 +               /* accesses to config registers with offsets >= 256
1069 +                * requires indirect access.
1070 +                */
1071 +               if (off >= PCI_CONFIG_SPACE_SIZE) {
1072 +                       addr = (func << 12);
1073 +                       addr |= (off & 0x0FFF);
1074 +                       val = bcma_pcie_read_config(pc, addr);
1075 +               } else {
1076 +                       addr = BCMA_CORE_PCI_PCICFG0;
1077 +                       addr |= (func << 8);
1078 +                       addr |= (off & 0xfc);
1079 +                       val = pcicore_read32(pc, addr);
1080 +               }
1081 +       } else {
1082 +               addr = bcma_get_cfgspace_addr(pc, dev, func, off);
1083 +               if (unlikely(!addr))
1084 +                       goto out;
1085 +               err = -ENOMEM;
1086 +               mmio = ioremap_nocache(addr, len);
1087 +               if (!mmio)
1088 +                       goto out;
1089 +
1090 +               if (mips_busprobe32(val, mmio)) {
1091 +                       val = 0xffffffff;
1092 +                       goto unmap;
1093 +               }
1094 +
1095 +               val = readl(mmio);
1096 +       }
1097 +       val >>= (8 * (off & 3));
1098 +
1099 +       switch (len) {
1100 +       case 1:
1101 +               *((u8 *)buf) = (u8)val;
1102 +               break;
1103 +       case 2:
1104 +               *((u16 *)buf) = (u16)val;
1105 +               break;
1106 +       case 4:
1107 +               *((u32 *)buf) = (u32)val;
1108 +               break;
1109 +       }
1110 +       err = 0;
1111 +unmap:
1112 +       if (mmio)
1113 +               iounmap(mmio);
1114 +out:
1115 +       return err;
1116 +}
1117 +
1118 +static int bcma_extpci_write_config(struct bcma_drv_pci *pc, unsigned int dev,
1119 +                                  unsigned int func, unsigned int off,
1120 +                                  const void *buf, int len)
1121 +{
1122 +       int err = -EINVAL;
1123 +       u32 addr = 0, val = 0;
1124 +       void __iomem *mmio = 0;
1125 +       u16 chipid = pc->core->bus->chipinfo.id;
1126 +
1127 +       WARN_ON(!pc->hostmode);
1128 +       if (unlikely(len != 1 && len != 2 && len != 4))
1129 +               goto out;
1130 +       if (dev == 0) {
1131 +               /* accesses to config registers with offsets >= 256
1132 +                * requires indirect access.
1133 +                */
1134 +               if (off < PCI_CONFIG_SPACE_SIZE) {
1135 +                       addr = pc->core->addr + BCMA_CORE_PCI_PCICFG0;
1136 +                       addr |= (func << 8);
1137 +                       addr |= (off & 0xfc);
1138 +                       mmio = ioremap_nocache(addr, len);
1139 +                       if (!mmio)
1140 +                               goto out;
1141 +               }
1142 +       } else {
1143 +               addr = bcma_get_cfgspace_addr(pc, dev, func, off);
1144 +               if (unlikely(!addr))
1145 +                       goto out;
1146 +               err = -ENOMEM;
1147 +               mmio = ioremap_nocache(addr, len);
1148 +               if (!mmio)
1149 +                       goto out;
1150 +
1151 +               if (mips_busprobe32(val, mmio)) {
1152 +                       val = 0xffffffff;
1153 +                       goto unmap;
1154 +               }
1155 +       }
1156 +
1157 +       switch (len) {
1158 +       case 1:
1159 +               val = readl(mmio);
1160 +               val &= ~(0xFF << (8 * (off & 3)));
1161 +               val |= *((const u8 *)buf) << (8 * (off & 3));
1162 +               break;
1163 +       case 2:
1164 +               val = readl(mmio);
1165 +               val &= ~(0xFFFF << (8 * (off & 3)));
1166 +               val |= *((const u16 *)buf) << (8 * (off & 3));
1167 +               break;
1168 +       case 4:
1169 +               val = *((const u32 *)buf);
1170 +               break;
1171 +       }
1172 +       if (dev == 0 && !addr) {
1173 +               /* accesses to config registers with offsets >= 256
1174 +                * requires indirect access.
1175 +                */
1176 +               addr = (func << 12);
1177 +               addr |= (off & 0x0FFF);
1178 +               bcma_pcie_write_config(pc, addr, val);
1179 +       } else {
1180 +               writel(val, mmio);
1181 +
1182 +               if (chipid == 0x4716 || chipid == 0x4748)
1183 +                       readl(mmio);
1184 +       }
1185 +
1186 +       err = 0;
1187 +unmap:
1188 +       if (mmio)
1189 +               iounmap(mmio);
1190 +out:
1191 +       return err;
1192 +}
1193 +
1194 +static int bcma_core_pci_hostmode_read_config(struct pci_bus *bus,
1195 +                                             unsigned int devfn,
1196 +                                             int reg, int size, u32 *val)
1197 +{
1198 +       unsigned long flags;
1199 +       int err;
1200 +       struct bcma_drv_pci *pc;
1201 +       struct bcma_drv_pci_host *pc_host;
1202 +
1203 +       pc_host = container_of(bus->ops, struct bcma_drv_pci_host, pci_ops);
1204 +       pc = pc_host->pdev;
1205 +
1206 +       spin_lock_irqsave(&pc_host->cfgspace_lock, flags);
1207 +       err = bcma_extpci_read_config(pc, PCI_SLOT(devfn),
1208 +                                    PCI_FUNC(devfn), reg, val, size);
1209 +       spin_unlock_irqrestore(&pc_host->cfgspace_lock, flags);
1210 +
1211 +       return err ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
1212 +}
1213 +
1214 +static int bcma_core_pci_hostmode_write_config(struct pci_bus *bus,
1215 +                                              unsigned int devfn,
1216 +                                              int reg, int size, u32 val)
1217 +{
1218 +       unsigned long flags;
1219 +       int err;
1220 +       struct bcma_drv_pci *pc;
1221 +       struct bcma_drv_pci_host *pc_host;
1222 +
1223 +       pc_host = container_of(bus->ops, struct bcma_drv_pci_host, pci_ops);
1224 +       pc = pc_host->pdev;
1225 +
1226 +       spin_lock_irqsave(&pc_host->cfgspace_lock, flags);
1227 +       err = bcma_extpci_write_config(pc, PCI_SLOT(devfn),
1228 +                                     PCI_FUNC(devfn), reg, &val, size);
1229 +       spin_unlock_irqrestore(&pc_host->cfgspace_lock, flags);
1230 +
1231 +       return err ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
1232 +}
1233 +
1234 +/* return cap_offset if requested capability exists in the PCI config space */
1235 +static u8 __devinit bcma_find_pci_capability(struct bcma_drv_pci *pc,
1236 +                                            unsigned int dev,
1237 +                                            unsigned int func, u8 req_cap_id,
1238 +                                            unsigned char *buf, u32 *buflen)
1239 +{
1240 +       u8 cap_id;
1241 +       u8 cap_ptr = 0;
1242 +       u32 bufsize;
1243 +       u8 byte_val;
1244 +
1245 +       /* check for Header type 0 */
1246 +       bcma_extpci_read_config(pc, dev, func, PCI_HEADER_TYPE, &byte_val,
1247 +                               sizeof(u8));
1248 +       if ((byte_val & 0x7f) != PCI_HEADER_TYPE_NORMAL)
1249 +               return cap_ptr;
1250 +
1251 +       /* check if the capability pointer field exists */
1252 +       bcma_extpci_read_config(pc, dev, func, PCI_STATUS, &byte_val,
1253 +                               sizeof(u8));
1254 +       if (!(byte_val & PCI_STATUS_CAP_LIST))
1255 +               return cap_ptr;
1256 +
1257 +       /* check if the capability pointer is 0x00 */
1258 +       bcma_extpci_read_config(pc, dev, func, PCI_CAPABILITY_LIST, &cap_ptr,
1259 +                               sizeof(u8));
1260 +       if (cap_ptr == 0x00)
1261 +               return cap_ptr;
1262 +
1263 +       /* loop thr'u the capability list and see if the requested capabilty
1264 +        * exists */
1265 +       bcma_extpci_read_config(pc, dev, func, cap_ptr, &cap_id, sizeof(u8));
1266 +       while (cap_id != req_cap_id) {
1267 +               bcma_extpci_read_config(pc, dev, func, cap_ptr + 1, &cap_ptr,
1268 +                                       sizeof(u8));
1269 +               if (cap_ptr == 0x00)
1270 +                       return cap_ptr;
1271 +               bcma_extpci_read_config(pc, dev, func, cap_ptr, &cap_id,
1272 +                                       sizeof(u8));
1273 +       }
1274 +
1275 +       /* found the caller requested capability */
1276 +       if ((buf != NULL) && (buflen != NULL)) {
1277 +               u8 cap_data;
1278 +
1279 +               bufsize = *buflen;
1280 +               if (!bufsize)
1281 +                       return cap_ptr;
1282 +
1283 +               *buflen = 0;
1284 +
1285 +               /* copy the cpability data excluding cap ID and next ptr */
1286 +               cap_data = cap_ptr + 2;
1287 +               if ((bufsize + cap_data)  > PCI_CONFIG_SPACE_SIZE)
1288 +                       bufsize = PCI_CONFIG_SPACE_SIZE - cap_data;
1289 +               *buflen = bufsize;
1290 +               while (bufsize--) {
1291 +                       bcma_extpci_read_config(pc, dev, func, cap_data, buf,
1292 +                                               sizeof(u8));
1293 +                       cap_data++;
1294 +                       buf++;
1295 +               }
1296 +       }
1297 +
1298 +       return cap_ptr;
1299 +}
1300 +
1301 +/* If the root port is capable of returning Config Request
1302 + * Retry Status (CRS) Completion Status to software then
1303 + * enable the feature.
1304 + */
1305 +static void __devinit bcma_core_pci_enable_crs(struct bcma_drv_pci *pc)
1306 +{
1307 +       u8 cap_ptr, root_ctrl, root_cap, dev;
1308 +       u16 val16;
1309 +       int i;
1310 +
1311 +       cap_ptr = bcma_find_pci_capability(pc, 0, 0, PCI_CAP_ID_EXP, NULL,
1312 +                                          NULL);
1313 +       root_cap = cap_ptr + PCI_EXP_RTCAP;
1314 +       bcma_extpci_read_config(pc, 0, 0, root_cap, &val16, sizeof(u16));
1315 +       if (val16 & BCMA_CORE_PCI_RC_CRS_VISIBILITY) {
1316 +               /* Enable CRS software visibility */
1317 +               root_ctrl = cap_ptr + PCI_EXP_RTCTL;
1318 +               val16 = PCI_EXP_RTCTL_CRSSVE;
1319 +               bcma_extpci_read_config(pc, 0, 0, root_ctrl, &val16,
1320 +                                       sizeof(u16));
1321 +
1322 +               /* Initiate a configuration request to read the vendor id
1323 +                * field of the device function's config space header after
1324 +                * 100 ms wait time from the end of Reset. If the device is
1325 +                * not done with its internal initialization, it must at
1326 +                * least return a completion TLP, with a completion status
1327 +                * of "Configuration Request Retry Status (CRS)". The root
1328 +                * complex must complete the request to the host by returning
1329 +                * a read-data value of 0001h for the Vendor ID field and
1330 +                * all 1s for any additional bytes included in the request.
1331 +                * Poll using the config reads for max wait time of 1 sec or
1332 +                * until we receive the successful completion status. Repeat
1333 +                * the procedure for all the devices.
1334 +                */
1335 +               for (dev = 1; dev < BCMA_PCI_SLOT_MAX; dev++) {
1336 +                       for (i = 0; i < 100000; i++) {
1337 +                               bcma_extpci_read_config(pc, dev, 0,
1338 +                                                       PCI_VENDOR_ID, &val16,
1339 +                                                       sizeof(val16));
1340 +                               if (val16 != 0x1)
1341 +                                       break;
1342 +                               udelay(10);
1343 +                       }
1344 +                       if (val16 == 0x1)
1345 +                               pr_err("PCI: Broken device in slot %d\n", dev);
1346 +               }
1347 +       }
1348 +}
1349 +
1350 +void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc)
1351 +{
1352 +       struct bcma_bus *bus = pc->core->bus;
1353 +       struct bcma_drv_pci_host *pc_host;
1354 +       u32 tmp;
1355 +       u32 pci_membase_1G;
1356 +       unsigned long io_map_base;
1357 +
1358 +       pr_info("PCIEcore in host mode found\n");
1359 +
1360 +       pc_host = kzalloc(sizeof(*pc_host), GFP_KERNEL);
1361 +       if (!pc_host)  {
1362 +               pr_err("can not allocate memory");
1363 +               return;
1364 +       }
1365 +
1366 +       pc->host_controller = pc_host;
1367 +       pc_host->pci_controller.io_resource = &pc_host->io_resource;
1368 +       pc_host->pci_controller.mem_resource = &pc_host->mem_resource;
1369 +       pc_host->pci_controller.pci_ops = &pc_host->pci_ops;
1370 +       pc_host->pdev = pc;
1371 +
1372 +       pci_membase_1G = BCMA_SOC_PCI_DMA;
1373 +       pc_host->host_cfg_addr = BCMA_SOC_PCI_CFG;
1374 +
1375 +       pc_host->pci_ops.read = bcma_core_pci_hostmode_read_config;
1376 +       pc_host->pci_ops.write = bcma_core_pci_hostmode_write_config;
1377 +
1378 +       pc_host->mem_resource.name = "BCMA PCIcore external memory",
1379 +       pc_host->mem_resource.start = BCMA_SOC_PCI_DMA;
1380 +       pc_host->mem_resource.end = BCMA_SOC_PCI_DMA + BCMA_SOC_PCI_DMA_SZ - 1;
1381 +       pc_host->mem_resource.flags = IORESOURCE_MEM | IORESOURCE_PCI_FIXED;
1382 +
1383 +       pc_host->io_resource.name = "BCMA PCIcore external I/O",
1384 +       pc_host->io_resource.start = 0x100;
1385 +       pc_host->io_resource.end = 0x7FF;
1386 +       pc_host->io_resource.flags = IORESOURCE_IO | IORESOURCE_PCI_FIXED;
1387 +
1388 +       /* Reset RC */
1389 +       udelay(3000);
1390 +       pcicore_write32(pc, BCMA_CORE_PCI_CTL, BCMA_CORE_PCI_CTL_RST_OE);
1391 +       udelay(1000);
1392 +       pcicore_write32(pc, BCMA_CORE_PCI_CTL, BCMA_CORE_PCI_CTL_RST |
1393 +                       BCMA_CORE_PCI_CTL_RST_OE);
1394 +
1395 +       /* 64 MB I/O access window. On 4716, use
1396 +        * sbtopcie0 to access the device registers. We
1397 +        * can't use address match 2 (1 GB window) region
1398 +        * as mips can't generate 64-bit address on the
1399 +        * backplane.
1400 +        */
1401 +       if (bus->chipinfo.id == 0x4716 || bus->chipinfo.id == 0x4748) {
1402 +               pc_host->mem_resource.start = BCMA_SOC_PCI_MEM;
1403 +               pc_host->mem_resource.end = BCMA_SOC_PCI_MEM +
1404 +                                           BCMA_SOC_PCI_MEM_SZ - 1;
1405 +               pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0,
1406 +                               BCMA_CORE_PCI_SBTOPCI_MEM | BCMA_SOC_PCI_MEM);
1407 +       } else if (bus->chipinfo.id == 0x5300) {
1408 +               tmp = BCMA_CORE_PCI_SBTOPCI_MEM;
1409 +               tmp |= BCMA_CORE_PCI_SBTOPCI_PREF;
1410 +               tmp |= BCMA_CORE_PCI_SBTOPCI_BURST;
1411 +               if (pc->core->core_unit == 0) {
1412 +                       pc_host->mem_resource.start = BCMA_SOC_PCI_MEM;
1413 +                       pc_host->mem_resource.end = BCMA_SOC_PCI_MEM +
1414 +                                                   BCMA_SOC_PCI_MEM_SZ - 1;
1415 +                       pci_membase_1G = BCMA_SOC_PCIE_DMA_H32;
1416 +                       pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0,
1417 +                                       tmp | BCMA_SOC_PCI_MEM);
1418 +               } else if (pc->core->core_unit == 1) {
1419 +                       pc_host->mem_resource.start = BCMA_SOC_PCI1_MEM;
1420 +                       pc_host->mem_resource.end = BCMA_SOC_PCI1_MEM +
1421 +                                                   BCMA_SOC_PCI_MEM_SZ - 1;
1422 +                       pci_membase_1G = BCMA_SOC_PCIE1_DMA_H32;
1423 +                       pc_host->host_cfg_addr = BCMA_SOC_PCI1_CFG;
1424 +                       pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0,
1425 +                                       tmp | BCMA_SOC_PCI1_MEM);
1426 +               }
1427 +       } else
1428 +               pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0,
1429 +                               BCMA_CORE_PCI_SBTOPCI_IO);
1430 +
1431 +       /* 64 MB configuration access window */
1432 +       pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI1, BCMA_CORE_PCI_SBTOPCI_CFG0);
1433 +
1434 +       /* 1 GB memory access window */
1435 +       pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI2,
1436 +                       BCMA_CORE_PCI_SBTOPCI_MEM | pci_membase_1G);
1437 +
1438 +
1439 +       /* As per PCI Express Base Spec 1.1 we need to wait for
1440 +        * at least 100 ms from the end of a reset (cold/warm/hot)
1441 +        * before issuing configuration requests to PCI Express
1442 +        * devices.
1443 +        */
1444 +       udelay(100000);
1445 +
1446 +       bcma_core_pci_enable_crs(pc);
1447 +
1448 +       /* Enable PCI bridge BAR0 memory & master access */
1449 +       tmp = PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
1450 +       bcma_extpci_write_config(pc, 0, 0, PCI_COMMAND, &tmp, sizeof(tmp));
1451 +
1452 +       /* Enable PCI interrupts */
1453 +       pcicore_write32(pc, BCMA_CORE_PCI_IMASK, BCMA_CORE_PCI_IMASK_INTA);
1454 +
1455 +       /* Ok, ready to run, register it to the system.
1456 +        * The following needs change, if we want to port hostmode
1457 +        * to non-MIPS platform. */
1458 +       io_map_base = (unsigned long)ioremap_nocache(BCMA_SOC_PCI_MEM,
1459 +                                                    0x04000000);
1460 +       pc_host->pci_controller.io_map_base = io_map_base;
1461 +       set_io_port_base(pc_host->pci_controller.io_map_base);
1462 +       /* Give some time to the PCI controller to configure itself with the new
1463 +        * values. Not waiting at this point causes crashes of the machine. */
1464 +       mdelay(10);
1465 +       register_pci_controller(&pc_host->pci_controller);
1466 +       return;
1467 +}
1468 +
1469 +/* Early PCI fixup for a device on the PCI-core bridge. */
1470 +static void bcma_core_pci_fixup_pcibridge(struct pci_dev *dev)
1471 +{
1472 +       if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) {
1473 +               /* This is not a device on the PCI-core bridge. */
1474 +               return;
1475 +       }
1476 +       if (PCI_SLOT(dev->devfn) != 0)
1477 +               return;
1478 +
1479 +       pr_info("PCI: Fixing up bridge %s\n", pci_name(dev));
1480 +
1481 +       /* Enable PCI bridge bus mastering and memory space */
1482 +       pci_set_master(dev);
1483 +       if (pcibios_enable_device(dev, ~0) < 0) {
1484 +               pr_err("PCI: BCMA bridge enable failed\n");
1485 +               return;
1486 +       }
1487 +
1488 +       /* Enable PCI bridge BAR1 prefetch and burst */
1489 +       pci_write_config_dword(dev, BCMA_PCI_BAR1_CONTROL, 3);
1490 +}
1491 +DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, bcma_core_pci_fixup_pcibridge);
1492 +
1493 +/* Early PCI fixup for all PCI-cores to set the correct memory address. */
1494 +static void bcma_core_pci_fixup_addresses(struct pci_dev *dev)
1495 +{
1496 +       struct resource *res;
1497 +       int pos;
1498 +
1499 +       if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) {
1500 +               /* This is not a device on the PCI-core bridge. */
1501 +               return;
1502 +       }
1503 +       if (PCI_SLOT(dev->devfn) == 0)
1504 +               return;
1505 +
1506 +       pr_info("PCI: Fixing up addresses %s\n", pci_name(dev));
1507 +
1508 +       for (pos = 0; pos < 6; pos++) {
1509 +               res = &dev->resource[pos];
1510 +               if (res->flags & (IORESOURCE_IO | IORESOURCE_MEM))
1511 +                       pci_assign_resource(dev, pos);
1512 +       }
1513 +}
1514 +DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, bcma_core_pci_fixup_addresses);
1515 +
1516 +/* This function is called when doing a pci_enable_device().
1517 + * We must first check if the device is a device on the PCI-core bridge. */
1518 +int bcma_core_pci_plat_dev_init(struct pci_dev *dev)
1519 +{
1520 +       struct bcma_drv_pci_host *pc_host;
1521 +
1522 +       if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) {
1523 +               /* This is not a device on the PCI-core bridge. */
1524 +               return -ENODEV;
1525 +       }
1526 +       pc_host = container_of(dev->bus->ops, struct bcma_drv_pci_host,
1527 +                              pci_ops);
1528 +
1529 +       pr_info("PCI: Fixing up device %s\n", pci_name(dev));
1530 +
1531 +       /* Fix up interrupt lines */
1532 +       dev->irq = bcma_core_mips_irq(pc_host->pdev->core) + 2;
1533 +       pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
1534 +
1535 +       return 0;
1536 +}
1537 +EXPORT_SYMBOL(bcma_core_pci_plat_dev_init);
1538 +
1539 +/* PCI device IRQ mapping. */
1540 +int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev)
1541 +{
1542 +       struct bcma_drv_pci_host *pc_host;
1543 +
1544 +       if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) {
1545 +               /* This is not a device on the PCI-core bridge. */
1546 +               return -ENODEV;
1547 +       }
1548 +
1549 +       pc_host = container_of(dev->bus->ops, struct bcma_drv_pci_host,
1550 +                              pci_ops);
1551 +       return bcma_core_mips_irq(pc_host->pdev->core) + 2;
1552  }
1553 +EXPORT_SYMBOL(bcma_core_pci_pcibios_map_irq);
1554 --- a/drivers/bcma/host_pci.c
1555 +++ b/drivers/bcma/host_pci.c
1556 @@ -9,6 +9,7 @@
1557  #include <linux/slab.h>
1558  #include <linux/bcma/bcma.h>
1559  #include <linux/pci.h>
1560 +#include <linux/module.h>
1561  
1562  static void bcma_host_pci_switch_core(struct bcma_device *core)
1563  {
1564 @@ -20,48 +21,58 @@ static void bcma_host_pci_switch_core(st
1565         pr_debug("Switched to core: 0x%X\n", core->id.id);
1566  }
1567  
1568 -static u8 bcma_host_pci_read8(struct bcma_device *core, u16 offset)
1569 -{
1570 +/* Provides access to the requested core. Returns base offset that has to be
1571 + * used. It makes use of fixed windows when possible. */
1572 +static u16 bcma_host_pci_provide_access_to_core(struct bcma_device *core)
1573 +{
1574 +       switch (core->id.id) {
1575 +       case BCMA_CORE_CHIPCOMMON:
1576 +               return 3 * BCMA_CORE_SIZE;
1577 +       case BCMA_CORE_PCIE:
1578 +               return 2 * BCMA_CORE_SIZE;
1579 +       }
1580 +
1581         if (core->bus->mapped_core != core)
1582                 bcma_host_pci_switch_core(core);
1583 +       return 0;
1584 +}
1585 +
1586 +static u8 bcma_host_pci_read8(struct bcma_device *core, u16 offset)
1587 +{
1588 +       offset += bcma_host_pci_provide_access_to_core(core);
1589         return ioread8(core->bus->mmio + offset);
1590  }
1591  
1592  static u16 bcma_host_pci_read16(struct bcma_device *core, u16 offset)
1593  {
1594 -       if (core->bus->mapped_core != core)
1595 -               bcma_host_pci_switch_core(core);
1596 +       offset += bcma_host_pci_provide_access_to_core(core);
1597         return ioread16(core->bus->mmio + offset);
1598  }
1599  
1600  static u32 bcma_host_pci_read32(struct bcma_device *core, u16 offset)
1601  {
1602 -       if (core->bus->mapped_core != core)
1603 -               bcma_host_pci_switch_core(core);
1604 +       offset += bcma_host_pci_provide_access_to_core(core);
1605         return ioread32(core->bus->mmio + offset);
1606  }
1607  
1608  static void bcma_host_pci_write8(struct bcma_device *core, u16 offset,
1609                                  u8 value)
1610  {
1611 -       if (core->bus->mapped_core != core)
1612 -               bcma_host_pci_switch_core(core);
1613 +       offset += bcma_host_pci_provide_access_to_core(core);
1614         iowrite8(value, core->bus->mmio + offset);
1615  }
1616  
1617  static void bcma_host_pci_write16(struct bcma_device *core, u16 offset,
1618                                  u16 value)
1619  {
1620 -       if (core->bus->mapped_core != core)
1621 -               bcma_host_pci_switch_core(core);
1622 +       offset += bcma_host_pci_provide_access_to_core(core);
1623         iowrite16(value, core->bus->mmio + offset);
1624  }
1625  
1626  static void bcma_host_pci_write32(struct bcma_device *core, u16 offset,
1627                                  u32 value)
1628  {
1629 -       if (core->bus->mapped_core != core)
1630 -               bcma_host_pci_switch_core(core);
1631 +       offset += bcma_host_pci_provide_access_to_core(core);
1632         iowrite32(value, core->bus->mmio + offset);
1633  }
1634  
1635 @@ -143,8 +154,8 @@ const struct bcma_host_ops bcma_host_pci
1636         .awrite32       = bcma_host_pci_awrite32,
1637  };
1638  
1639 -static int bcma_host_pci_probe(struct pci_dev *dev,
1640 -                            const struct pci_device_id *id)
1641 +static int __devinit bcma_host_pci_probe(struct pci_dev *dev,
1642 +                                        const struct pci_device_id *id)
1643  {
1644         struct bcma_bus *bus;
1645         int err = -ENOMEM;
1646 @@ -223,6 +234,35 @@ static void bcma_host_pci_remove(struct
1647         pci_set_drvdata(dev, NULL);
1648  }
1649  
1650 +#ifdef CONFIG_PM
1651 +static int bcma_host_pci_suspend(struct device *dev)
1652 +{
1653 +       struct pci_dev *pdev = to_pci_dev(dev);
1654 +       struct bcma_bus *bus = pci_get_drvdata(pdev);
1655 +
1656 +       bus->mapped_core = NULL;
1657 +
1658 +       return bcma_bus_suspend(bus);
1659 +}
1660 +
1661 +static int bcma_host_pci_resume(struct device *dev)
1662 +{
1663 +       struct pci_dev *pdev = to_pci_dev(dev);
1664 +       struct bcma_bus *bus = pci_get_drvdata(pdev);
1665 +
1666 +       return bcma_bus_resume(bus);
1667 +}
1668 +
1669 +static SIMPLE_DEV_PM_OPS(bcma_pm_ops, bcma_host_pci_suspend,
1670 +                        bcma_host_pci_resume);
1671 +#define BCMA_PM_OPS    (&bcma_pm_ops)
1672 +
1673 +#else /* CONFIG_PM */
1674 +
1675 +#define BCMA_PM_OPS     NULL
1676 +
1677 +#endif /* CONFIG_PM */
1678 +
1679  static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = {
1680         { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) },
1681         { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) },
1682 @@ -238,6 +278,7 @@ static struct pci_driver bcma_pci_bridge
1683         .id_table = bcma_pci_bridge_tbl,
1684         .probe = bcma_host_pci_probe,
1685         .remove = bcma_host_pci_remove,
1686 +       .driver.pm = BCMA_PM_OPS,
1687  };
1688  
1689  int __init bcma_host_pci_init(void)
1690 --- /dev/null
1691 +++ b/drivers/bcma/host_soc.c
1692 @@ -0,0 +1,183 @@
1693 +/*
1694 + * Broadcom specific AMBA
1695 + * System on Chip (SoC) Host
1696 + *
1697 + * Licensed under the GNU/GPL. See COPYING for details.
1698 + */
1699 +
1700 +#include "bcma_private.h"
1701 +#include "scan.h"
1702 +#include <linux/bcma/bcma.h>
1703 +#include <linux/bcma/bcma_soc.h>
1704 +
1705 +static u8 bcma_host_soc_read8(struct bcma_device *core, u16 offset)
1706 +{
1707 +       return readb(core->io_addr + offset);
1708 +}
1709 +
1710 +static u16 bcma_host_soc_read16(struct bcma_device *core, u16 offset)
1711 +{
1712 +       return readw(core->io_addr + offset);
1713 +}
1714 +
1715 +static u32 bcma_host_soc_read32(struct bcma_device *core, u16 offset)
1716 +{
1717 +       return readl(core->io_addr + offset);
1718 +}
1719 +
1720 +static void bcma_host_soc_write8(struct bcma_device *core, u16 offset,
1721 +                                u8 value)
1722 +{
1723 +       writeb(value, core->io_addr + offset);
1724 +}
1725 +
1726 +static void bcma_host_soc_write16(struct bcma_device *core, u16 offset,
1727 +                                u16 value)
1728 +{
1729 +       writew(value, core->io_addr + offset);
1730 +}
1731 +
1732 +static void bcma_host_soc_write32(struct bcma_device *core, u16 offset,
1733 +                                u32 value)
1734 +{
1735 +       writel(value, core->io_addr + offset);
1736 +}
1737 +
1738 +#ifdef CONFIG_BCMA_BLOCKIO
1739 +static void bcma_host_soc_block_read(struct bcma_device *core, void *buffer,
1740 +                                    size_t count, u16 offset, u8 reg_width)
1741 +{
1742 +       void __iomem *addr = core->io_addr + offset;
1743 +
1744 +       switch (reg_width) {
1745 +       case sizeof(u8): {
1746 +               u8 *buf = buffer;
1747 +
1748 +               while (count) {
1749 +                       *buf = __raw_readb(addr);
1750 +                       buf++;
1751 +                       count--;
1752 +               }
1753 +               break;
1754 +       }
1755 +       case sizeof(u16): {
1756 +               __le16 *buf = buffer;
1757 +
1758 +               WARN_ON(count & 1);
1759 +               while (count) {
1760 +                       *buf = (__force __le16)__raw_readw(addr);
1761 +                       buf++;
1762 +                       count -= 2;
1763 +               }
1764 +               break;
1765 +       }
1766 +       case sizeof(u32): {
1767 +               __le32 *buf = buffer;
1768 +
1769 +               WARN_ON(count & 3);
1770 +               while (count) {
1771 +                       *buf = (__force __le32)__raw_readl(addr);
1772 +                       buf++;
1773 +                       count -= 4;
1774 +               }
1775 +               break;
1776 +       }
1777 +       default:
1778 +               WARN_ON(1);
1779 +       }
1780 +}
1781 +
1782 +static void bcma_host_soc_block_write(struct bcma_device *core,
1783 +                                     const void *buffer,
1784 +                                     size_t count, u16 offset, u8 reg_width)
1785 +{
1786 +       void __iomem *addr = core->io_addr + offset;
1787 +
1788 +       switch (reg_width) {
1789 +       case sizeof(u8): {
1790 +               const u8 *buf = buffer;
1791 +
1792 +               while (count) {
1793 +                       __raw_writeb(*buf, addr);
1794 +                       buf++;
1795 +                       count--;
1796 +               }
1797 +               break;
1798 +       }
1799 +       case sizeof(u16): {
1800 +               const __le16 *buf = buffer;
1801 +
1802 +               WARN_ON(count & 1);
1803 +               while (count) {
1804 +                       __raw_writew((__force u16)(*buf), addr);
1805 +                       buf++;
1806 +                       count -= 2;
1807 +               }
1808 +               break;
1809 +       }
1810 +       case sizeof(u32): {
1811 +               const __le32 *buf = buffer;
1812 +
1813 +               WARN_ON(count & 3);
1814 +               while (count) {
1815 +                       __raw_writel((__force u32)(*buf), addr);
1816 +                       buf++;
1817 +                       count -= 4;
1818 +               }
1819 +               break;
1820 +       }
1821 +       default:
1822 +               WARN_ON(1);
1823 +       }
1824 +}
1825 +#endif /* CONFIG_BCMA_BLOCKIO */
1826 +
1827 +static u32 bcma_host_soc_aread32(struct bcma_device *core, u16 offset)
1828 +{
1829 +       return readl(core->io_wrap + offset);
1830 +}
1831 +
1832 +static void bcma_host_soc_awrite32(struct bcma_device *core, u16 offset,
1833 +                                 u32 value)
1834 +{
1835 +       writel(value, core->io_wrap + offset);
1836 +}
1837 +
1838 +const struct bcma_host_ops bcma_host_soc_ops = {
1839 +       .read8          = bcma_host_soc_read8,
1840 +       .read16         = bcma_host_soc_read16,
1841 +       .read32         = bcma_host_soc_read32,
1842 +       .write8         = bcma_host_soc_write8,
1843 +       .write16        = bcma_host_soc_write16,
1844 +       .write32        = bcma_host_soc_write32,
1845 +#ifdef CONFIG_BCMA_BLOCKIO
1846 +       .block_read     = bcma_host_soc_block_read,
1847 +       .block_write    = bcma_host_soc_block_write,
1848 +#endif
1849 +       .aread32        = bcma_host_soc_aread32,
1850 +       .awrite32       = bcma_host_soc_awrite32,
1851 +};
1852 +
1853 +int __init bcma_host_soc_register(struct bcma_soc *soc)
1854 +{
1855 +       struct bcma_bus *bus = &soc->bus;
1856 +       int err;
1857 +
1858 +       /* iomap only first core. We have to read some register on this core
1859 +        * to scan the bus.
1860 +        */
1861 +       bus->mmio = ioremap_nocache(BCMA_ADDR_BASE, BCMA_CORE_SIZE * 1);
1862 +       if (!bus->mmio)
1863 +               return -ENOMEM;
1864 +
1865 +       /* Host specific */
1866 +       bus->hosttype = BCMA_HOSTTYPE_SOC;
1867 +       bus->ops = &bcma_host_soc_ops;
1868 +
1869 +       /* Register */
1870 +       err = bcma_bus_early_register(bus, &soc->core_cc, &soc->core_mips);
1871 +       if (err)
1872 +               iounmap(bus->mmio);
1873 +
1874 +       return err;
1875 +}
1876 --- a/drivers/bcma/main.c
1877 +++ b/drivers/bcma/main.c
1878 @@ -6,12 +6,19 @@
1879   */
1880  
1881  #include "bcma_private.h"
1882 +#include <linux/module.h>
1883  #include <linux/bcma/bcma.h>
1884  #include <linux/slab.h>
1885  
1886  MODULE_DESCRIPTION("Broadcom's specific AMBA driver");
1887  MODULE_LICENSE("GPL");
1888  
1889 +/* contains the number the next bus should get. */
1890 +static unsigned int bcma_bus_next_num = 0;
1891 +
1892 +/* bcma_buses_mutex locks the bcma_bus_next_num */
1893 +static DEFINE_MUTEX(bcma_buses_mutex);
1894 +
1895  static int bcma_bus_match(struct device *dev, struct device_driver *drv);
1896  static int bcma_device_probe(struct device *dev);
1897  static int bcma_device_remove(struct device *dev);
1898 @@ -54,7 +61,7 @@ static struct bus_type bcma_bus_type = {
1899         .dev_attrs      = bcma_device_attrs,
1900  };
1901  
1902 -static struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid)
1903 +struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid)
1904  {
1905         struct bcma_device *core;
1906  
1907 @@ -64,10 +71,15 @@ static struct bcma_device *bcma_find_cor
1908         }
1909         return NULL;
1910  }
1911 +EXPORT_SYMBOL_GPL(bcma_find_core);
1912  
1913  static void bcma_release_core_dev(struct device *dev)
1914  {
1915         struct bcma_device *core = container_of(dev, struct bcma_device, dev);
1916 +       if (core->io_addr)
1917 +               iounmap(core->io_addr);
1918 +       if (core->io_wrap)
1919 +               iounmap(core->io_wrap);
1920         kfree(core);
1921  }
1922  
1923 @@ -82,12 +94,13 @@ static int bcma_register_cores(struct bc
1924                 case BCMA_CORE_CHIPCOMMON:
1925                 case BCMA_CORE_PCI:
1926                 case BCMA_CORE_PCIE:
1927 +               case BCMA_CORE_MIPS_74K:
1928                         continue;
1929                 }
1930  
1931                 core->dev.release = bcma_release_core_dev;
1932                 core->dev.bus = &bcma_bus_type;
1933 -               dev_set_name(&core->dev, "bcma%d:%d", 0/*bus->num*/, dev_id);
1934 +               dev_set_name(&core->dev, "bcma%d:%d", bus->num, dev_id);
1935  
1936                 switch (bus->hosttype) {
1937                 case BCMA_HOSTTYPE_PCI:
1938 @@ -95,7 +108,10 @@ static int bcma_register_cores(struct bc
1939                         core->dma_dev = &bus->host_pci->dev;
1940                         core->irq = bus->host_pci->irq;
1941                         break;
1942 -               case BCMA_HOSTTYPE_NONE:
1943 +               case BCMA_HOSTTYPE_SOC:
1944 +                       core->dev.dma_mask = &core->dev.coherent_dma_mask;
1945 +                       core->dma_dev = &core->dev;
1946 +                       break;
1947                 case BCMA_HOSTTYPE_SDIO:
1948                         break;
1949                 }
1950 @@ -123,11 +139,15 @@ static void bcma_unregister_cores(struct
1951         }
1952  }
1953  
1954 -int bcma_bus_register(struct bcma_bus *bus)
1955 +int __devinit bcma_bus_register(struct bcma_bus *bus)
1956  {
1957         int err;
1958         struct bcma_device *core;
1959  
1960 +       mutex_lock(&bcma_buses_mutex);
1961 +       bus->num = bcma_bus_next_num++;
1962 +       mutex_unlock(&bcma_buses_mutex);
1963 +
1964         /* Scan for devices (cores) */
1965         err = bcma_bus_scan(bus);
1966         if (err) {
1967 @@ -142,6 +162,13 @@ int bcma_bus_register(struct bcma_bus *b
1968                 bcma_core_chipcommon_init(&bus->drv_cc);
1969         }
1970  
1971 +       /* Init MIPS core */
1972 +       core = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
1973 +       if (core) {
1974 +               bus->drv_mips.core = core;
1975 +               bcma_core_mips_init(&bus->drv_mips);
1976 +       }
1977 +
1978         /* Init PCIE core */
1979         core = bcma_find_core(bus, BCMA_CORE_PCIE);
1980         if (core) {
1981 @@ -153,10 +180,8 @@ int bcma_bus_register(struct bcma_bus *b
1982         err = bcma_sprom_get(bus);
1983         if (err == -ENOENT) {
1984                 pr_err("No SPROM available\n");
1985 -       } else if (err) {
1986 +       } else if (err)
1987                 pr_err("Failed to get SPROM: %d\n", err);
1988 -               return -ENOENT;
1989 -       }
1990  
1991         /* Register found cores */
1992         bcma_register_cores(bus);
1993 @@ -171,6 +196,99 @@ void bcma_bus_unregister(struct bcma_bus
1994         bcma_unregister_cores(bus);
1995  }
1996  
1997 +int __init bcma_bus_early_register(struct bcma_bus *bus,
1998 +                                  struct bcma_device *core_cc,
1999 +                                  struct bcma_device *core_mips)
2000 +{
2001 +       int err;
2002 +       struct bcma_device *core;
2003 +       struct bcma_device_id match;
2004 +
2005 +       bcma_init_bus(bus);
2006 +
2007 +       match.manuf = BCMA_MANUF_BCM;
2008 +       match.id = BCMA_CORE_CHIPCOMMON;
2009 +       match.class = BCMA_CL_SIM;
2010 +       match.rev = BCMA_ANY_REV;
2011 +
2012 +       /* Scan for chip common core */
2013 +       err = bcma_bus_scan_early(bus, &match, core_cc);
2014 +       if (err) {
2015 +               pr_err("Failed to scan for common core: %d\n", err);
2016 +               return -1;
2017 +       }
2018 +
2019 +       match.manuf = BCMA_MANUF_MIPS;
2020 +       match.id = BCMA_CORE_MIPS_74K;
2021 +       match.class = BCMA_CL_SIM;
2022 +       match.rev = BCMA_ANY_REV;
2023 +
2024 +       /* Scan for mips core */
2025 +       err = bcma_bus_scan_early(bus, &match, core_mips);
2026 +       if (err) {
2027 +               pr_err("Failed to scan for mips core: %d\n", err);
2028 +               return -1;
2029 +       }
2030 +
2031 +       /* Init CC core */
2032 +       core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON);
2033 +       if (core) {
2034 +               bus->drv_cc.core = core;
2035 +               bcma_core_chipcommon_init(&bus->drv_cc);
2036 +       }
2037 +
2038 +       /* Init MIPS core */
2039 +       core = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
2040 +       if (core) {
2041 +               bus->drv_mips.core = core;
2042 +               bcma_core_mips_init(&bus->drv_mips);
2043 +       }
2044 +
2045 +       pr_info("Early bus registered\n");
2046 +
2047 +       return 0;
2048 +}
2049 +
2050 +#ifdef CONFIG_PM
2051 +int bcma_bus_suspend(struct bcma_bus *bus)
2052 +{
2053 +       struct bcma_device *core;
2054 +
2055 +       list_for_each_entry(core, &bus->cores, list) {
2056 +               struct device_driver *drv = core->dev.driver;
2057 +               if (drv) {
2058 +                       struct bcma_driver *adrv = container_of(drv, struct bcma_driver, drv);
2059 +                       if (adrv->suspend)
2060 +                               adrv->suspend(core);
2061 +               }
2062 +       }
2063 +       return 0;
2064 +}
2065 +
2066 +int bcma_bus_resume(struct bcma_bus *bus)
2067 +{
2068 +       struct bcma_device *core;
2069 +
2070 +       /* Init CC core */
2071 +       core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON);
2072 +       if (core) {
2073 +               bus->drv_cc.setup_done = false;
2074 +               bcma_core_chipcommon_init(&bus->drv_cc);
2075 +       }
2076 +
2077 +       list_for_each_entry(core, &bus->cores, list) {
2078 +               struct device_driver *drv = core->dev.driver;
2079 +               if (drv) {
2080 +                       struct bcma_driver *adrv = container_of(drv, struct bcma_driver, drv);
2081 +                       if (adrv->resume)
2082 +                               adrv->resume(core);
2083 +               }
2084 +       }
2085 +
2086 +       return 0;
2087 +}
2088 +#endif
2089 +
2090  int __bcma_driver_register(struct bcma_driver *drv, struct module *owner)
2091  {
2092         drv->drv.name = drv->name;
2093 --- a/drivers/bcma/scan.c
2094 +++ b/drivers/bcma/scan.c
2095 @@ -200,18 +200,174 @@ static s32 bcma_erom_get_addr_desc(struc
2096         return addrl;
2097  }
2098  
2099 -int bcma_bus_scan(struct bcma_bus *bus)
2100 +static struct bcma_device *bcma_find_core_by_index(struct bcma_bus *bus,
2101 +                                                  u16 index)
2102  {
2103 -       u32 erombase;
2104 -       u32 __iomem *eromptr, *eromend;
2105 +       struct bcma_device *core;
2106 +
2107 +       list_for_each_entry(core, &bus->cores, list) {
2108 +               if (core->core_index == index)
2109 +                       return core;
2110 +       }
2111 +       return NULL;
2112 +}
2113 +
2114 +static struct bcma_device *bcma_find_core_reverse(struct bcma_bus *bus, u16 coreid)
2115 +{
2116 +       struct bcma_device *core;
2117 +
2118 +       list_for_each_entry_reverse(core, &bus->cores, list) {
2119 +               if (core->id.id == coreid)
2120 +                       return core;
2121 +       }
2122 +       return NULL;
2123 +}
2124  
2125 +static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
2126 +                             struct bcma_device_id *match, int core_num,
2127 +                             struct bcma_device *core)
2128 +{
2129 +       s32 tmp;
2130 +       u8 i, j;
2131         s32 cia, cib;
2132         u8 ports[2], wrappers[2];
2133  
2134 +       /* get CIs */
2135 +       cia = bcma_erom_get_ci(bus, eromptr);
2136 +       if (cia < 0) {
2137 +               bcma_erom_push_ent(eromptr);
2138 +               if (bcma_erom_is_end(bus, eromptr))
2139 +                       return -ESPIPE;
2140 +               return -EILSEQ;
2141 +       }
2142 +       cib = bcma_erom_get_ci(bus, eromptr);
2143 +       if (cib < 0)
2144 +               return -EILSEQ;
2145 +
2146 +       /* parse CIs */
2147 +       core->id.class = (cia & SCAN_CIA_CLASS) >> SCAN_CIA_CLASS_SHIFT;
2148 +       core->id.id = (cia & SCAN_CIA_ID) >> SCAN_CIA_ID_SHIFT;
2149 +       core->id.manuf = (cia & SCAN_CIA_MANUF) >> SCAN_CIA_MANUF_SHIFT;
2150 +       ports[0] = (cib & SCAN_CIB_NMP) >> SCAN_CIB_NMP_SHIFT;
2151 +       ports[1] = (cib & SCAN_CIB_NSP) >> SCAN_CIB_NSP_SHIFT;
2152 +       wrappers[0] = (cib & SCAN_CIB_NMW) >> SCAN_CIB_NMW_SHIFT;
2153 +       wrappers[1] = (cib & SCAN_CIB_NSW) >> SCAN_CIB_NSW_SHIFT;
2154 +       core->id.rev = (cib & SCAN_CIB_REV) >> SCAN_CIB_REV_SHIFT;
2155 +
2156 +       if (((core->id.manuf == BCMA_MANUF_ARM) &&
2157 +            (core->id.id == 0xFFF)) ||
2158 +           (ports[1] == 0)) {
2159 +               bcma_erom_skip_component(bus, eromptr);
2160 +               return -ENXIO;
2161 +       }
2162 +
2163 +       /* check if component is a core at all */
2164 +       if (wrappers[0] + wrappers[1] == 0) {
2165 +               /* we could save addrl of the router
2166 +               if (cid == BCMA_CORE_OOB_ROUTER)
2167 +                */
2168 +               bcma_erom_skip_component(bus, eromptr);
2169 +               return -ENXIO;
2170 +       }
2171 +
2172 +       if (bcma_erom_is_bridge(bus, eromptr)) {
2173 +               bcma_erom_skip_component(bus, eromptr);
2174 +               return -ENXIO;
2175 +       }
2176 +
2177 +       if (bcma_find_core_by_index(bus, core_num)) {
2178 +               bcma_erom_skip_component(bus, eromptr);
2179 +               return -ENODEV;
2180 +       }
2181 +
2182 +       if (match && ((match->manuf != BCMA_ANY_MANUF &&
2183 +             match->manuf != core->id.manuf) ||
2184 +            (match->id != BCMA_ANY_ID && match->id != core->id.id) ||
2185 +            (match->rev != BCMA_ANY_REV && match->rev != core->id.rev) ||
2186 +            (match->class != BCMA_ANY_CLASS && match->class != core->id.class)
2187 +           )) {
2188 +               bcma_erom_skip_component(bus, eromptr);
2189 +               return -ENODEV;
2190 +       }
2191 +
2192 +       /* get & parse master ports */
2193 +       for (i = 0; i < ports[0]; i++) {
2194 +               s32 mst_port_d = bcma_erom_get_mst_port(bus, eromptr);
2195 +               if (mst_port_d < 0)
2196 +                       return -EILSEQ;
2197 +       }
2198 +
2199 +       /* get & parse slave ports */
2200 +       for (i = 0; i < ports[1]; i++) {
2201 +               for (j = 0; ; j++) {
2202 +                       tmp = bcma_erom_get_addr_desc(bus, eromptr,
2203 +                               SCAN_ADDR_TYPE_SLAVE, i);
2204 +                       if (tmp < 0) {
2205 +                               /* no more entries for port _i_ */
2206 +                               /* pr_debug("erom: slave port %d "
2207 +                                * "has %d descriptors\n", i, j); */
2208 +                               break;
2209 +                       } else {
2210 +                               if (i == 0 && j == 0)
2211 +                                       core->addr = tmp;
2212 +                       }
2213 +               }
2214 +       }
2215 +
2216 +       /* get & parse master wrappers */
2217 +       for (i = 0; i < wrappers[0]; i++) {
2218 +               for (j = 0; ; j++) {
2219 +                       tmp = bcma_erom_get_addr_desc(bus, eromptr,
2220 +                               SCAN_ADDR_TYPE_MWRAP, i);
2221 +                       if (tmp < 0) {
2222 +                               /* no more entries for port _i_ */
2223 +                               /* pr_debug("erom: master wrapper %d "
2224 +                                * "has %d descriptors\n", i, j); */
2225 +                               break;
2226 +                       } else {
2227 +                               if (i == 0 && j == 0)
2228 +                                       core->wrap = tmp;
2229 +                       }
2230 +               }
2231 +       }
2232 +
2233 +       /* get & parse slave wrappers */
2234 +       for (i = 0; i < wrappers[1]; i++) {
2235 +               u8 hack = (ports[1] == 1) ? 0 : 1;
2236 +               for (j = 0; ; j++) {
2237 +                       tmp = bcma_erom_get_addr_desc(bus, eromptr,
2238 +                               SCAN_ADDR_TYPE_SWRAP, i + hack);
2239 +                       if (tmp < 0) {
2240 +                               /* no more entries for port _i_ */
2241 +                               /* pr_debug("erom: master wrapper %d "
2242 +                                * has %d descriptors\n", i, j); */
2243 +                               break;
2244 +                       } else {
2245 +                               if (wrappers[0] == 0 && !i && !j)
2246 +                                       core->wrap = tmp;
2247 +                       }
2248 +               }
2249 +       }
2250 +       if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
2251 +               core->io_addr = ioremap_nocache(core->addr, BCMA_CORE_SIZE);
2252 +               if (!core->io_addr)
2253 +                       return -ENOMEM;
2254 +               core->io_wrap = ioremap_nocache(core->wrap, BCMA_CORE_SIZE);
2255 +               if (!core->io_wrap) {
2256 +                       iounmap(core->io_addr);
2257 +                       return -ENOMEM;
2258 +               }
2259 +       }
2260 +       return 0;
2261 +}
2262 +
2263 +void bcma_init_bus(struct bcma_bus *bus)
2264 +{
2265         s32 tmp;
2266 -       u8 i, j;
2267 +       struct bcma_chipinfo *chipinfo = &(bus->chipinfo);
2268  
2269 -       int err;
2270 +       if (bus->init_done)
2271 +               return;
2272  
2273         INIT_LIST_HEAD(&bus->cores);
2274         bus->nr_cores = 0;
2275 @@ -219,142 +375,133 @@ int bcma_bus_scan(struct bcma_bus *bus)
2276         bcma_scan_switch_core(bus, BCMA_ADDR_BASE);
2277  
2278         tmp = bcma_scan_read32(bus, 0, BCMA_CC_ID);
2279 -       bus->chipinfo.id = (tmp & BCMA_CC_ID_ID) >> BCMA_CC_ID_ID_SHIFT;
2280 -       bus->chipinfo.rev = (tmp & BCMA_CC_ID_REV) >> BCMA_CC_ID_REV_SHIFT;
2281 -       bus->chipinfo.pkg = (tmp & BCMA_CC_ID_PKG) >> BCMA_CC_ID_PKG_SHIFT;
2282 +       chipinfo->id = (tmp & BCMA_CC_ID_ID) >> BCMA_CC_ID_ID_SHIFT;
2283 +       chipinfo->rev = (tmp & BCMA_CC_ID_REV) >> BCMA_CC_ID_REV_SHIFT;
2284 +       chipinfo->pkg = (tmp & BCMA_CC_ID_PKG) >> BCMA_CC_ID_PKG_SHIFT;
2285 +       pr_info("Found chip with id 0x%04X, rev 0x%02X and package 0x%02X\n",
2286 +               chipinfo->id, chipinfo->rev, chipinfo->pkg);
2287 +
2288 +       bus->init_done = true;
2289 +}
2290 +
2291 +int bcma_bus_scan(struct bcma_bus *bus)
2292 +{
2293 +       u32 erombase;
2294 +       u32 __iomem *eromptr, *eromend;
2295 +
2296 +       int err, core_num = 0;
2297 +
2298 +       bcma_init_bus(bus);
2299  
2300         erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM);
2301 -       eromptr = bus->mmio;
2302 +       if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
2303 +               eromptr = ioremap_nocache(erombase, BCMA_CORE_SIZE);
2304 +               if (!eromptr)
2305 +                       return -ENOMEM;
2306 +       } else {
2307 +               eromptr = bus->mmio;
2308 +       }
2309 +
2310         eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32);
2311  
2312         bcma_scan_switch_core(bus, erombase);
2313  
2314         while (eromptr < eromend) {
2315 +               struct bcma_device *other_core;
2316                 struct bcma_device *core = kzalloc(sizeof(*core), GFP_KERNEL);
2317                 if (!core)
2318                         return -ENOMEM;
2319                 INIT_LIST_HEAD(&core->list);
2320                 core->bus = bus;
2321  
2322 -               /* get CIs */
2323 -               cia = bcma_erom_get_ci(bus, &eromptr);
2324 -               if (cia < 0) {
2325 -                       bcma_erom_push_ent(&eromptr);
2326 -                       if (bcma_erom_is_end(bus, &eromptr))
2327 +               err = bcma_get_next_core(bus, &eromptr, NULL, core_num, core);
2328 +               if (err < 0) {
2329 +                       kfree(core);
2330 +                       if (err == -ENODEV) {
2331 +                               core_num++;
2332 +                               continue;
2333 +                       } else if (err == -ENXIO) {
2334 +                               continue;
2335 +                       } else if (err == -ESPIPE) {
2336                                 break;
2337 -                       err= -EILSEQ;
2338 -                       goto out;
2339 -               }
2340 -               cib = bcma_erom_get_ci(bus, &eromptr);
2341 -               if (cib < 0) {
2342 -                       err= -EILSEQ;
2343 -                       goto out;
2344 +                       }
2345 +                       return err;
2346                 }
2347  
2348 -               /* parse CIs */
2349 -               core->id.class = (cia & SCAN_CIA_CLASS) >> SCAN_CIA_CLASS_SHIFT;
2350 -               core->id.id = (cia & SCAN_CIA_ID) >> SCAN_CIA_ID_SHIFT;
2351 -               core->id.manuf = (cia & SCAN_CIA_MANUF) >> SCAN_CIA_MANUF_SHIFT;
2352 -               ports[0] = (cib & SCAN_CIB_NMP) >> SCAN_CIB_NMP_SHIFT;
2353 -               ports[1] = (cib & SCAN_CIB_NSP) >> SCAN_CIB_NSP_SHIFT;
2354 -               wrappers[0] = (cib & SCAN_CIB_NMW) >> SCAN_CIB_NMW_SHIFT;
2355 -               wrappers[1] = (cib & SCAN_CIB_NSW) >> SCAN_CIB_NSW_SHIFT;
2356 -               core->id.rev = (cib & SCAN_CIB_REV) >> SCAN_CIB_REV_SHIFT;
2357 -
2358 -               if (((core->id.manuf == BCMA_MANUF_ARM) &&
2359 -                    (core->id.id == 0xFFF)) ||
2360 -                   (ports[1] == 0)) {
2361 -                       bcma_erom_skip_component(bus, &eromptr);
2362 -                       continue;
2363 -               }
2364 +               core->core_index = core_num++;
2365 +               bus->nr_cores++;
2366 +               other_core = bcma_find_core_reverse(bus, core->id.id);
2367 +               core->core_unit = (other_core == NULL) ? 0 : other_core->core_unit + 1;
2368  
2369 -               /* check if component is a core at all */
2370 -               if (wrappers[0] + wrappers[1] == 0) {
2371 -                       /* we could save addrl of the router
2372 -                       if (cid == BCMA_CORE_OOB_ROUTER)
2373 -                        */
2374 -                       bcma_erom_skip_component(bus, &eromptr);
2375 -                       continue;
2376 -               }
2377 +               pr_info("Core %d found: %s "
2378 +                       "(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
2379 +                       core->core_index, bcma_device_name(&core->id),
2380 +                       core->id.manuf, core->id.id, core->id.rev,
2381 +                       core->id.class);
2382  
2383 -               if (bcma_erom_is_bridge(bus, &eromptr)) {
2384 -                       bcma_erom_skip_component(bus, &eromptr);
2385 -                       continue;
2386 -               }
2387 +               list_add(&core->list, &bus->cores);
2388 +       }
2389  
2390 -               /* get & parse master ports */
2391 -               for (i = 0; i < ports[0]; i++) {
2392 -                       u32 mst_port_d = bcma_erom_get_mst_port(bus, &eromptr);
2393 -                       if (mst_port_d < 0) {
2394 -                               err= -EILSEQ;
2395 -                               goto out;
2396 -                       }
2397 -               }
2398 +       if (bus->hosttype == BCMA_HOSTTYPE_SOC)
2399 +               iounmap(eromptr);
2400  
2401 -               /* get & parse slave ports */
2402 -               for (i = 0; i < ports[1]; i++) {
2403 -                       for (j = 0; ; j++) {
2404 -                               tmp = bcma_erom_get_addr_desc(bus, &eromptr,
2405 -                                       SCAN_ADDR_TYPE_SLAVE, i);
2406 -                               if (tmp < 0) {
2407 -                                       /* no more entries for port _i_ */
2408 -                                       /* pr_debug("erom: slave port %d "
2409 -                                        * "has %d descriptors\n", i, j); */
2410 -                                       break;
2411 -                               } else {
2412 -                                       if (i == 0 && j == 0)
2413 -                                               core->addr = tmp;
2414 -                               }
2415 -                       }
2416 -               }
2417 +       return 0;
2418 +}
2419  
2420 -               /* get & parse master wrappers */
2421 -               for (i = 0; i < wrappers[0]; i++) {
2422 -                       for (j = 0; ; j++) {
2423 -                               tmp = bcma_erom_get_addr_desc(bus, &eromptr,
2424 -                                       SCAN_ADDR_TYPE_MWRAP, i);
2425 -                               if (tmp < 0) {
2426 -                                       /* no more entries for port _i_ */
2427 -                                       /* pr_debug("erom: master wrapper %d "
2428 -                                        * "has %d descriptors\n", i, j); */
2429 -                                       break;
2430 -                               } else {
2431 -                                       if (i == 0 && j == 0)
2432 -                                               core->wrap = tmp;
2433 -                               }
2434 -                       }
2435 -               }
2436 +int __init bcma_bus_scan_early(struct bcma_bus *bus,
2437 +                              struct bcma_device_id *match,
2438 +                              struct bcma_device *core)
2439 +{
2440 +       u32 erombase;
2441 +       u32 __iomem *eromptr, *eromend;
2442  
2443 -               /* get & parse slave wrappers */
2444 -               for (i = 0; i < wrappers[1]; i++) {
2445 -                       u8 hack = (ports[1] == 1) ? 0 : 1;
2446 -                       for (j = 0; ; j++) {
2447 -                               tmp = bcma_erom_get_addr_desc(bus, &eromptr,
2448 -                                       SCAN_ADDR_TYPE_SWRAP, i + hack);
2449 -                               if (tmp < 0) {
2450 -                                       /* no more entries for port _i_ */
2451 -                                       /* pr_debug("erom: master wrapper %d "
2452 -                                        * has %d descriptors\n", i, j); */
2453 -                                       break;
2454 -                               } else {
2455 -                                       if (wrappers[0] == 0 && !i && !j)
2456 -                                               core->wrap = tmp;
2457 -                               }
2458 -                       }
2459 -               }
2460 +       int err = -ENODEV;
2461 +       int core_num = 0;
2462 +
2463 +       erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM);
2464 +       if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
2465 +               eromptr = ioremap_nocache(erombase, BCMA_CORE_SIZE);
2466 +               if (!eromptr)
2467 +                       return -ENOMEM;
2468 +       } else {
2469 +               eromptr = bus->mmio;
2470 +       }
2471  
2472 +       eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32);
2473 +
2474 +       bcma_scan_switch_core(bus, erombase);
2475 +
2476 +       while (eromptr < eromend) {
2477 +               memset(core, 0, sizeof(*core));
2478 +               INIT_LIST_HEAD(&core->list);
2479 +               core->bus = bus;
2480 +
2481 +               err = bcma_get_next_core(bus, &eromptr, match, core_num, core);
2482 +               if (err == -ENODEV) {
2483 +                       core_num++;
2484 +                       continue;
2485 +               } else if (err == -ENXIO)
2486 +                       continue;
2487 +               else if (err == -ESPIPE)
2488 +                       break;
2489 +               else if (err < 0)
2490 +                       return err;
2491 +
2492 +               core->core_index = core_num++;
2493 +               bus->nr_cores++;
2494                 pr_info("Core %d found: %s "
2495                         "(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
2496 -                       bus->nr_cores, bcma_device_name(&core->id),
2497 +                       core->core_index, bcma_device_name(&core->id),
2498                         core->id.manuf, core->id.id, core->id.rev,
2499                         core->id.class);
2500  
2501 -               core->core_index = bus->nr_cores++;
2502                 list_add(&core->list, &bus->cores);
2503 -               continue;
2504 -out:
2505 -               return err;
2506 +               err = 0;
2507 +               break;
2508         }
2509  
2510 -       return 0;
2511 +       if (bus->hosttype == BCMA_HOSTTYPE_SOC)
2512 +               iounmap(eromptr);
2513 +
2514 +       return err;
2515  }
2516 --- a/drivers/bcma/sprom.c
2517 +++ b/drivers/bcma/sprom.c
2518 @@ -2,6 +2,8 @@
2519   * Broadcom specific AMBA
2520   * SPROM reading
2521   *
2522 + * Copyright 2011, 2012, Hauke Mehrtens <hauke@hauke-m.de>
2523 + *
2524   * Licensed under the GNU/GPL. See COPYING for details.
2525   */
2526  
2527 @@ -14,7 +16,57 @@
2528  #include <linux/dma-mapping.h>
2529  #include <linux/slab.h>
2530  
2531 -#define SPOFF(offset)  ((offset) / sizeof(u16))
2532 +static int(*get_fallback_sprom)(struct bcma_bus *dev, struct ssb_sprom *out);
2533 +
2534 +/**
2535 + * bcma_arch_register_fallback_sprom - Registers a method providing a
2536 + * fallback SPROM if no SPROM is found.
2537 + *
2538 + * @sprom_callback: The callback function.
2539 + *
2540 + * With this function the architecture implementation may register a
2541 + * callback handler which fills the SPROM data structure. The fallback is
2542 + * used for PCI based BCMA devices, where no valid SPROM can be found
2543 + * in the shadow registers and to provide the SPROM for SoCs where BCMA is
2544 + * to controll the system bus.
2545 + *
2546 + * This function is useful for weird architectures that have a half-assed
2547 + * BCMA device hardwired to their PCI bus.
2548 + *
2549 + * This function is available for architecture code, only. So it is not
2550 + * exported.
2551 + */
2552 +int bcma_arch_register_fallback_sprom(int (*sprom_callback)(struct bcma_bus *bus,
2553 +                                    struct ssb_sprom *out))
2554 +{
2555 +       if (get_fallback_sprom)
2556 +               return -EEXIST;
2557 +       get_fallback_sprom = sprom_callback;
2558 +
2559 +       return 0;
2560 +}
2561 +
2562 +static int bcma_fill_sprom_with_fallback(struct bcma_bus *bus,
2563 +                                        struct ssb_sprom *out)
2564 +{
2565 +       int err;
2566 +
2567 +       if (!get_fallback_sprom) {
2568 +               err = -ENOENT;
2569 +               goto fail;
2570 +       }
2571 +
2572 +       err = get_fallback_sprom(bus, out);
2573 +       if (err)
2574 +               goto fail;
2575 +
2576 +       pr_debug("Using SPROM revision %d provided by"
2577 +                " platform.\n", bus->sprom.revision);
2578 +       return 0;
2579 +fail:
2580 +       pr_warn("Using fallback SPROM failed (err %d)\n", err);
2581 +       return err;
2582 +}
2583  
2584  /**************************************************
2585   * R/W ops.
2586 @@ -124,41 +176,268 @@ static int bcma_sprom_valid(const u16 *s
2587   * SPROM extraction.
2588   **************************************************/
2589  
2590 +#define SPOFF(offset)  ((offset) / sizeof(u16))
2591 +
2592 +#define SPEX(_field, _offset, _mask, _shift)   \
2593 +       bus->sprom._field = ((sprom[SPOFF(_offset)] & (_mask)) >> (_shift))
2594 +
2595  static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
2596  {
2597 -       u16 v;
2598 +       u16 v, o;
2599         int i;
2600 +       u16 pwr_info_offset[] = {
2601 +               SSB_SROM8_PWR_INFO_CORE0, SSB_SROM8_PWR_INFO_CORE1,
2602 +               SSB_SROM8_PWR_INFO_CORE2, SSB_SROM8_PWR_INFO_CORE3
2603 +       };
2604 +       BUILD_BUG_ON(ARRAY_SIZE(pwr_info_offset) !=
2605 +                       ARRAY_SIZE(bus->sprom.core_pwr_info));
2606 +
2607 +       bus->sprom.revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] &
2608 +               SSB_SPROM_REVISION_REV;
2609  
2610         for (i = 0; i < 3; i++) {
2611                 v = sprom[SPOFF(SSB_SPROM8_IL0MAC) + i];
2612                 *(((__be16 *)bus->sprom.il0mac) + i) = cpu_to_be16(v);
2613         }
2614 +
2615 +       SPEX(board_rev, SSB_SPROM8_BOARDREV, ~0, 0);
2616 +
2617 +       SPEX(txpid2g[0], SSB_SPROM4_TXPID2G01, SSB_SPROM4_TXPID2G0,
2618 +            SSB_SPROM4_TXPID2G0_SHIFT);
2619 +       SPEX(txpid2g[1], SSB_SPROM4_TXPID2G01, SSB_SPROM4_TXPID2G1,
2620 +            SSB_SPROM4_TXPID2G1_SHIFT);
2621 +       SPEX(txpid2g[2], SSB_SPROM4_TXPID2G23, SSB_SPROM4_TXPID2G2,
2622 +            SSB_SPROM4_TXPID2G2_SHIFT);
2623 +       SPEX(txpid2g[3], SSB_SPROM4_TXPID2G23, SSB_SPROM4_TXPID2G3,
2624 +            SSB_SPROM4_TXPID2G3_SHIFT);
2625 +
2626 +       SPEX(txpid5gl[0], SSB_SPROM4_TXPID5GL01, SSB_SPROM4_TXPID5GL0,
2627 +            SSB_SPROM4_TXPID5GL0_SHIFT);
2628 +       SPEX(txpid5gl[1], SSB_SPROM4_TXPID5GL01, SSB_SPROM4_TXPID5GL1,
2629 +            SSB_SPROM4_TXPID5GL1_SHIFT);
2630 +       SPEX(txpid5gl[2], SSB_SPROM4_TXPID5GL23, SSB_SPROM4_TXPID5GL2,
2631 +            SSB_SPROM4_TXPID5GL2_SHIFT);
2632 +       SPEX(txpid5gl[3], SSB_SPROM4_TXPID5GL23, SSB_SPROM4_TXPID5GL3,
2633 +            SSB_SPROM4_TXPID5GL3_SHIFT);
2634 +
2635 +       SPEX(txpid5g[0], SSB_SPROM4_TXPID5G01, SSB_SPROM4_TXPID5G0,
2636 +            SSB_SPROM4_TXPID5G0_SHIFT);
2637 +       SPEX(txpid5g[1], SSB_SPROM4_TXPID5G01, SSB_SPROM4_TXPID5G1,
2638 +            SSB_SPROM4_TXPID5G1_SHIFT);
2639 +       SPEX(txpid5g[2], SSB_SPROM4_TXPID5G23, SSB_SPROM4_TXPID5G2,
2640 +            SSB_SPROM4_TXPID5G2_SHIFT);
2641 +       SPEX(txpid5g[3], SSB_SPROM4_TXPID5G23, SSB_SPROM4_TXPID5G3,
2642 +            SSB_SPROM4_TXPID5G3_SHIFT);
2643 +
2644 +       SPEX(txpid5gh[0], SSB_SPROM4_TXPID5GH01, SSB_SPROM4_TXPID5GH0,
2645 +            SSB_SPROM4_TXPID5GH0_SHIFT);
2646 +       SPEX(txpid5gh[1], SSB_SPROM4_TXPID5GH01, SSB_SPROM4_TXPID5GH1,
2647 +            SSB_SPROM4_TXPID5GH1_SHIFT);
2648 +       SPEX(txpid5gh[2], SSB_SPROM4_TXPID5GH23, SSB_SPROM4_TXPID5GH2,
2649 +            SSB_SPROM4_TXPID5GH2_SHIFT);
2650 +       SPEX(txpid5gh[3], SSB_SPROM4_TXPID5GH23, SSB_SPROM4_TXPID5GH3,
2651 +            SSB_SPROM4_TXPID5GH3_SHIFT);
2652 +
2653 +       SPEX(boardflags_lo, SSB_SPROM8_BFLLO, ~0, 0);
2654 +       SPEX(boardflags_hi, SSB_SPROM8_BFLHI, ~0, 0);
2655 +       SPEX(boardflags2_lo, SSB_SPROM8_BFL2LO, ~0, 0);
2656 +       SPEX(boardflags2_hi, SSB_SPROM8_BFL2HI, ~0, 0);
2657 +
2658 +       SPEX(country_code, SSB_SPROM8_CCODE, ~0, 0);
2659 +
2660 +       /* Extract cores power info info */
2661 +       for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) {
2662 +               o = pwr_info_offset[i];
2663 +               SPEX(core_pwr_info[i].itssi_2g, o + SSB_SROM8_2G_MAXP_ITSSI,
2664 +                       SSB_SPROM8_2G_ITSSI, SSB_SPROM8_2G_ITSSI_SHIFT);
2665 +               SPEX(core_pwr_info[i].maxpwr_2g, o + SSB_SROM8_2G_MAXP_ITSSI,
2666 +                       SSB_SPROM8_2G_MAXP, 0);
2667 +
2668 +               SPEX(core_pwr_info[i].pa_2g[0], o + SSB_SROM8_2G_PA_0, ~0, 0);
2669 +               SPEX(core_pwr_info[i].pa_2g[1], o + SSB_SROM8_2G_PA_1, ~0, 0);
2670 +               SPEX(core_pwr_info[i].pa_2g[2], o + SSB_SROM8_2G_PA_2, ~0, 0);
2671 +
2672 +               SPEX(core_pwr_info[i].itssi_5g, o + SSB_SROM8_5G_MAXP_ITSSI,
2673 +                       SSB_SPROM8_5G_ITSSI, SSB_SPROM8_5G_ITSSI_SHIFT);
2674 +               SPEX(core_pwr_info[i].maxpwr_5g, o + SSB_SROM8_5G_MAXP_ITSSI,
2675 +                       SSB_SPROM8_5G_MAXP, 0);
2676 +               SPEX(core_pwr_info[i].maxpwr_5gh, o + SSB_SPROM8_5GHL_MAXP,
2677 +                       SSB_SPROM8_5GH_MAXP, 0);
2678 +               SPEX(core_pwr_info[i].maxpwr_5gl, o + SSB_SPROM8_5GHL_MAXP,
2679 +                       SSB_SPROM8_5GL_MAXP, SSB_SPROM8_5GL_MAXP_SHIFT);
2680 +
2681 +               SPEX(core_pwr_info[i].pa_5gl[0], o + SSB_SROM8_5GL_PA_0, ~0, 0);
2682 +               SPEX(core_pwr_info[i].pa_5gl[1], o + SSB_SROM8_5GL_PA_1, ~0, 0);
2683 +               SPEX(core_pwr_info[i].pa_5gl[2], o + SSB_SROM8_5GL_PA_2, ~0, 0);
2684 +               SPEX(core_pwr_info[i].pa_5g[0], o + SSB_SROM8_5G_PA_0, ~0, 0);
2685 +               SPEX(core_pwr_info[i].pa_5g[1], o + SSB_SROM8_5G_PA_1, ~0, 0);
2686 +               SPEX(core_pwr_info[i].pa_5g[2], o + SSB_SROM8_5G_PA_2, ~0, 0);
2687 +               SPEX(core_pwr_info[i].pa_5gh[0], o + SSB_SROM8_5GH_PA_0, ~0, 0);
2688 +               SPEX(core_pwr_info[i].pa_5gh[1], o + SSB_SROM8_5GH_PA_1, ~0, 0);
2689 +               SPEX(core_pwr_info[i].pa_5gh[2], o + SSB_SROM8_5GH_PA_2, ~0, 0);
2690 +       }
2691 +
2692 +       SPEX(fem.ghz2.tssipos, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_TSSIPOS,
2693 +            SSB_SROM8_FEM_TSSIPOS_SHIFT);
2694 +       SPEX(fem.ghz2.extpa_gain, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_EXTPA_GAIN,
2695 +            SSB_SROM8_FEM_EXTPA_GAIN_SHIFT);
2696 +       SPEX(fem.ghz2.pdet_range, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_PDET_RANGE,
2697 +            SSB_SROM8_FEM_PDET_RANGE_SHIFT);
2698 +       SPEX(fem.ghz2.tr_iso, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_TR_ISO,
2699 +            SSB_SROM8_FEM_TR_ISO_SHIFT);
2700 +       SPEX(fem.ghz2.antswlut, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_ANTSWLUT,
2701 +            SSB_SROM8_FEM_ANTSWLUT_SHIFT);
2702 +
2703 +       SPEX(fem.ghz5.tssipos, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_TSSIPOS,
2704 +            SSB_SROM8_FEM_TSSIPOS_SHIFT);
2705 +       SPEX(fem.ghz5.extpa_gain, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_EXTPA_GAIN,
2706 +            SSB_SROM8_FEM_EXTPA_GAIN_SHIFT);
2707 +       SPEX(fem.ghz5.pdet_range, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_PDET_RANGE,
2708 +            SSB_SROM8_FEM_PDET_RANGE_SHIFT);
2709 +       SPEX(fem.ghz5.tr_iso, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_TR_ISO,
2710 +            SSB_SROM8_FEM_TR_ISO_SHIFT);
2711 +       SPEX(fem.ghz5.antswlut, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_ANTSWLUT,
2712 +            SSB_SROM8_FEM_ANTSWLUT_SHIFT);
2713 +}
2714 +
2715 +/*
2716 + * Indicates the presence of external SPROM.
2717 + */
2718 +static bool bcma_sprom_ext_available(struct bcma_bus *bus)
2719 +{
2720 +       u32 chip_status;
2721 +       u32 srom_control;
2722 +       u32 present_mask;
2723 +
2724 +       if (bus->drv_cc.core->id.rev >= 31) {
2725 +               if (!(bus->drv_cc.capabilities & BCMA_CC_CAP_SPROM))
2726 +                       return false;
2727 +
2728 +               srom_control = bcma_read32(bus->drv_cc.core,
2729 +                                          BCMA_CC_SROM_CONTROL);
2730 +               return srom_control & BCMA_CC_SROM_CONTROL_PRESENT;
2731 +       }
2732 +
2733 +       /* older chipcommon revisions use chip status register */
2734 +       chip_status = bcma_read32(bus->drv_cc.core, BCMA_CC_CHIPSTAT);
2735 +       switch (bus->chipinfo.id) {
2736 +       case 0x4313:
2737 +               present_mask = BCMA_CC_CHIPST_4313_SPROM_PRESENT;
2738 +               break;
2739 +
2740 +       case 0x4331:
2741 +               present_mask = BCMA_CC_CHIPST_4331_SPROM_PRESENT;
2742 +               break;
2743 +
2744 +       default:
2745 +               return true;
2746 +       }
2747 +
2748 +       return chip_status & present_mask;
2749 +}
2750 +
2751 +/*
2752 + * Indicates that on-chip OTP memory is present and enabled.
2753 + */
2754 +static bool bcma_sprom_onchip_available(struct bcma_bus *bus)
2755 +{
2756 +       u32 chip_status;
2757 +       u32 otpsize = 0;
2758 +       bool present;
2759 +
2760 +       chip_status = bcma_read32(bus->drv_cc.core, BCMA_CC_CHIPSTAT);
2761 +       switch (bus->chipinfo.id) {
2762 +       case 0x4313:
2763 +               present = chip_status & BCMA_CC_CHIPST_4313_OTP_PRESENT;
2764 +               break;
2765 +
2766 +       case 0x4331:
2767 +               present = chip_status & BCMA_CC_CHIPST_4331_OTP_PRESENT;
2768 +               break;
2769 +
2770 +       case 43224:
2771 +       case 43225:
2772 +               /* for these chips OTP is always available */
2773 +               present = true;
2774 +               break;
2775 +
2776 +       default:
2777 +               present = false;
2778 +               break;
2779 +       }
2780 +
2781 +       if (present) {
2782 +               otpsize = bus->drv_cc.capabilities & BCMA_CC_CAP_OTPS;
2783 +               otpsize >>= BCMA_CC_CAP_OTPS_SHIFT;
2784 +       }
2785 +
2786 +       return otpsize != 0;
2787 +}
2788 +
2789 +/*
2790 + * Verify OTP is filled and determine the byte
2791 + * offset where SPROM data is located.
2792 + *
2793 + * On error, returns 0; byte offset otherwise.
2794 + */
2795 +static int bcma_sprom_onchip_offset(struct bcma_bus *bus)
2796 +{
2797 +       struct bcma_device *cc = bus->drv_cc.core;
2798 +       u32 offset;
2799 +
2800 +       /* verify OTP status */
2801 +       if ((bcma_read32(cc, BCMA_CC_OTPS) & BCMA_CC_OTPS_GU_PROG_HW) == 0)
2802 +               return 0;
2803 +
2804 +       /* obtain bit offset from otplayout register */
2805 +       offset = (bcma_read32(cc, BCMA_CC_OTPL) & BCMA_CC_OTPL_GURGN_OFFSET);
2806 +       return BCMA_CC_SPROM + (offset >> 3);
2807  }
2808  
2809  int bcma_sprom_get(struct bcma_bus *bus)
2810  {
2811 -       u16 offset;
2812 +       u16 offset = BCMA_CC_SPROM;
2813         u16 *sprom;
2814         int err = 0;
2815  
2816         if (!bus->drv_cc.core)
2817                 return -EOPNOTSUPP;
2818  
2819 -       if (!(bus->drv_cc.capabilities & BCMA_CC_CAP_SPROM))
2820 -               return -ENOENT;
2821 +       if (!bcma_sprom_ext_available(bus)) {
2822 +               /*
2823 +                * External SPROM takes precedence so check
2824 +                * on-chip OTP only when no external SPROM
2825 +                * is present.
2826 +                */
2827 +               if (bcma_sprom_onchip_available(bus)) {
2828 +                       /* determine offset */
2829 +                       offset = bcma_sprom_onchip_offset(bus);
2830 +               }
2831 +               if (!offset) {
2832 +                       /*
2833 +                        * Maybe there is no SPROM on the device?
2834 +                        * Now we ask the arch code if there is some sprom
2835 +                        * available for this device in some other storage.
2836 +                        */
2837 +                       err = bcma_fill_sprom_with_fallback(bus, &bus->sprom);
2838 +                       return err;
2839 +               }
2840 +       }
2841  
2842         sprom = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16),
2843                         GFP_KERNEL);
2844         if (!sprom)
2845                 return -ENOMEM;
2846  
2847 -       /* Most cards have SPROM moved by additional offset 0x30 (48 dwords).
2848 -        * According to brcm80211 this applies to cards with PCIe rev >= 6
2849 -        * TODO: understand this condition and use it */
2850 -       offset = (bus->chipinfo.id == 0x4331) ? BCMA_CC_SPROM :
2851 -               BCMA_CC_SPROM_PCIE6;
2852 +       if (bus->chipinfo.id == 0x4331)
2853 +               bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, false);
2854 +
2855 +       pr_debug("SPROM offset 0x%x\n", offset);
2856         bcma_sprom_read(bus, offset, sprom);
2857  
2858 +       if (bus->chipinfo.id == 0x4331)
2859 +               bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, true);
2860 +
2861         err = bcma_sprom_valid(sprom);
2862         if (err)
2863                 goto out;
2864 --- a/include/linux/bcma/bcma.h
2865 +++ b/include/linux/bcma/bcma.h
2866 @@ -6,6 +6,7 @@
2867  
2868  #include <linux/bcma/bcma_driver_chipcommon.h>
2869  #include <linux/bcma/bcma_driver_pci.h>
2870 +#include <linux/bcma/bcma_driver_mips.h>
2871  #include <linux/ssb/ssb.h> /* SPROM sharing */
2872  
2873  #include "bcma_regs.h"
2874 @@ -14,9 +15,9 @@ struct bcma_device;
2875  struct bcma_bus;
2876  
2877  enum bcma_hosttype {
2878 -       BCMA_HOSTTYPE_NONE,
2879         BCMA_HOSTTYPE_PCI,
2880         BCMA_HOSTTYPE_SDIO,
2881 +       BCMA_HOSTTYPE_SOC,
2882  };
2883  
2884  struct bcma_chipinfo {
2885 @@ -130,14 +131,19 @@ struct bcma_device {
2886  
2887         struct device dev;
2888         struct device *dma_dev;
2889 +
2890         unsigned int irq;
2891         bool dev_registered;
2892  
2893         u8 core_index;
2894 +       u8 core_unit;
2895  
2896         u32 addr;
2897         u32 wrap;
2898  
2899 +       void __iomem *io_addr;
2900 +       void __iomem *io_wrap;
2901 +
2902         void *drvdata;
2903         struct list_head list;
2904  };
2905 @@ -157,7 +163,7 @@ struct bcma_driver {
2906  
2907         int (*probe)(struct bcma_device *dev);
2908         void (*remove)(struct bcma_device *dev);
2909 -       int (*suspend)(struct bcma_device *dev, pm_message_t state);
2910 +       int (*suspend)(struct bcma_device *dev);
2911         int (*resume)(struct bcma_device *dev);
2912         void (*shutdown)(struct bcma_device *dev);
2913  
2914 @@ -165,12 +171,17 @@ struct bcma_driver {
2915  };
2916  extern
2917  int __bcma_driver_register(struct bcma_driver *drv, struct module *owner);
2918 -static inline int bcma_driver_register(struct bcma_driver *drv)
2919 -{
2920 -       return __bcma_driver_register(drv, THIS_MODULE);
2921 -}
2922 +#define bcma_driver_register(drv) \
2923 +       __bcma_driver_register(drv, THIS_MODULE)
2924 +
2925  extern void bcma_driver_unregister(struct bcma_driver *drv);
2926  
2927 +/* Set a fallback SPROM.
2928 + * See kdoc at the function definition for complete documentation. */
2929 +extern int bcma_arch_register_fallback_sprom(
2930 +               int (*sprom_callback)(struct bcma_bus *bus,
2931 +               struct ssb_sprom *out));
2932 +
2933  struct bcma_bus {
2934         /* The MMIO area. */
2935         void __iomem *mmio;
2936 @@ -190,71 +201,96 @@ struct bcma_bus {
2937         struct bcma_device *mapped_core;
2938         struct list_head cores;
2939         u8 nr_cores;
2940 +       u8 init_done:1;
2941 +       u8 num;
2942  
2943         struct bcma_drv_cc drv_cc;
2944         struct bcma_drv_pci drv_pci;
2945 +       struct bcma_drv_mips drv_mips;
2946  
2947         /* We decided to share SPROM struct with SSB as long as we do not need
2948          * any hacks for BCMA. This simplifies drivers code. */
2949         struct ssb_sprom sprom;
2950  };
2951  
2952 -extern inline u32 bcma_read8(struct bcma_device *core, u16 offset)
2953 +static inline u32 bcma_read8(struct bcma_device *core, u16 offset)
2954  {
2955         return core->bus->ops->read8(core, offset);
2956  }
2957 -extern inline u32 bcma_read16(struct bcma_device *core, u16 offset)
2958 +static inline u32 bcma_read16(struct bcma_device *core, u16 offset)
2959  {
2960         return core->bus->ops->read16(core, offset);
2961  }
2962 -extern inline u32 bcma_read32(struct bcma_device *core, u16 offset)
2963 +static inline u32 bcma_read32(struct bcma_device *core, u16 offset)
2964  {
2965         return core->bus->ops->read32(core, offset);
2966  }
2967 -extern inline
2968 +static inline
2969  void bcma_write8(struct bcma_device *core, u16 offset, u32 value)
2970  {
2971         core->bus->ops->write8(core, offset, value);
2972  }
2973 -extern inline
2974 +static inline
2975  void bcma_write16(struct bcma_device *core, u16 offset, u32 value)
2976  {
2977         core->bus->ops->write16(core, offset, value);
2978  }
2979 -extern inline
2980 +static inline
2981  void bcma_write32(struct bcma_device *core, u16 offset, u32 value)
2982  {
2983         core->bus->ops->write32(core, offset, value);
2984  }
2985  #ifdef CONFIG_BCMA_BLOCKIO
2986 -extern inline void bcma_block_read(struct bcma_device *core, void *buffer,
2987 +static inline void bcma_block_read(struct bcma_device *core, void *buffer,
2988                                    size_t count, u16 offset, u8 reg_width)
2989  {
2990         core->bus->ops->block_read(core, buffer, count, offset, reg_width);
2991  }
2992 -extern inline void bcma_block_write(struct bcma_device *core, const void *buffer,
2993 -                                   size_t count, u16 offset, u8 reg_width)
2994 +static inline void bcma_block_write(struct bcma_device *core,
2995 +                                   const void *buffer, size_t count,
2996 +                                   u16 offset, u8 reg_width)
2997  {
2998         core->bus->ops->block_write(core, buffer, count, offset, reg_width);
2999  }
3000  #endif
3001 -extern inline u32 bcma_aread32(struct bcma_device *core, u16 offset)
3002 +static inline u32 bcma_aread32(struct bcma_device *core, u16 offset)
3003  {
3004         return core->bus->ops->aread32(core, offset);
3005  }
3006 -extern inline
3007 +static inline
3008  void bcma_awrite32(struct bcma_device *core, u16 offset, u32 value)
3009  {
3010         core->bus->ops->awrite32(core, offset, value);
3011  }
3012  
3013 -#define bcma_mask32(cc, offset, mask) \
3014 -       bcma_write32(cc, offset, bcma_read32(cc, offset) & (mask))
3015 -#define bcma_set32(cc, offset, set) \
3016 -       bcma_write32(cc, offset, bcma_read32(cc, offset) | (set))
3017 -#define bcma_maskset32(cc, offset, mask, set) \
3018 -       bcma_write32(cc, offset, (bcma_read32(cc, offset) & (mask)) | (set))
3019 +static inline void bcma_mask32(struct bcma_device *cc, u16 offset, u32 mask)
3020 +{
3021 +       bcma_write32(cc, offset, bcma_read32(cc, offset) & mask);
3022 +}
3023 +static inline void bcma_set32(struct bcma_device *cc, u16 offset, u32 set)
3024 +{
3025 +       bcma_write32(cc, offset, bcma_read32(cc, offset) | set);
3026 +}
3027 +static inline void bcma_maskset32(struct bcma_device *cc,
3028 +                                 u16 offset, u32 mask, u32 set)
3029 +{
3030 +       bcma_write32(cc, offset, (bcma_read32(cc, offset) & mask) | set);
3031 +}
3032 +static inline void bcma_mask16(struct bcma_device *cc, u16 offset, u16 mask)
3033 +{
3034 +       bcma_write16(cc, offset, bcma_read16(cc, offset) & mask);
3035 +}
3036 +static inline void bcma_set16(struct bcma_device *cc, u16 offset, u16 set)
3037 +{
3038 +       bcma_write16(cc, offset, bcma_read16(cc, offset) | set);
3039 +}
3040 +static inline void bcma_maskset16(struct bcma_device *cc,
3041 +                                 u16 offset, u16 mask, u16 set)
3042 +{
3043 +       bcma_write16(cc, offset, (bcma_read16(cc, offset) & mask) | set);
3044 +}
3045  
3046 +extern struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid);
3047  extern bool bcma_core_is_enabled(struct bcma_device *core);
3048  extern void bcma_core_disable(struct bcma_device *core, u32 flags);
3049  extern int bcma_core_enable(struct bcma_device *core, u32 flags);
3050 --- a/include/linux/bcma/bcma_driver_chipcommon.h
3051 +++ b/include/linux/bcma/bcma_driver_chipcommon.h
3052 @@ -24,6 +24,7 @@
3053  #define   BCMA_CC_FLASHT_NONE          0x00000000      /* No flash */
3054  #define   BCMA_CC_FLASHT_STSER         0x00000100      /* ST serial flash */
3055  #define   BCMA_CC_FLASHT_ATSER         0x00000200      /* Atmel serial flash */
3056 +#define   BCMA_CC_FLASHT_NFLASH                0x00000200
3057  #define          BCMA_CC_FLASHT_PARA           0x00000700      /* Parallel flash */
3058  #define  BCMA_CC_CAP_PLLT              0x00038000      /* PLL Type */
3059  #define   BCMA_PLLTYPE_NONE            0x00000000
3060 @@ -55,6 +56,9 @@
3061  #define         BCMA_CC_OTPS_HW_PROTECT        0x00000001
3062  #define         BCMA_CC_OTPS_SW_PROTECT        0x00000002
3063  #define         BCMA_CC_OTPS_CID_PROTECT       0x00000004
3064 +#define  BCMA_CC_OTPS_GU_PROG_IND      0x00000F00      /* General Use programmed indication */
3065 +#define  BCMA_CC_OTPS_GU_PROG_IND_SHIFT        8
3066 +#define  BCMA_CC_OTPS_GU_PROG_HW       0x00000100      /* HW region programmed */
3067  #define BCMA_CC_OTPC                   0x0014          /* OTP control */
3068  #define         BCMA_CC_OTPC_RECWAIT           0xFF000000
3069  #define         BCMA_CC_OTPC_PROGWAIT          0x00FFFF00
3070 @@ -71,6 +75,8 @@
3071  #define         BCMA_CC_OTPP_READ              0x40000000
3072  #define         BCMA_CC_OTPP_START             0x80000000
3073  #define         BCMA_CC_OTPP_BUSY              0x80000000
3074 +#define BCMA_CC_OTPL                   0x001C          /* OTP layout */
3075 +#define  BCMA_CC_OTPL_GURGN_OFFSET     0x00000FFF      /* offset of general use region */
3076  #define BCMA_CC_IRQSTAT                        0x0020
3077  #define BCMA_CC_IRQMASK                        0x0024
3078  #define         BCMA_CC_IRQ_GPIO               0x00000001      /* gpio intr */
3079 @@ -78,6 +84,10 @@
3080  #define         BCMA_CC_IRQ_WDRESET            0x80000000      /* watchdog reset occurred */
3081  #define BCMA_CC_CHIPCTL                        0x0028          /* Rev >= 11 only */
3082  #define BCMA_CC_CHIPSTAT               0x002C          /* Rev >= 11 only */
3083 +#define  BCMA_CC_CHIPST_4313_SPROM_PRESENT     1
3084 +#define  BCMA_CC_CHIPST_4313_OTP_PRESENT       2
3085 +#define  BCMA_CC_CHIPST_4331_SPROM_PRESENT     2
3086 +#define  BCMA_CC_CHIPST_4331_OTP_PRESENT       4
3087  #define BCMA_CC_JCMD                   0x0030          /* Rev >= 10 only */
3088  #define  BCMA_CC_JCMD_START            0x80000000
3089  #define  BCMA_CC_JCMD_BUSY             0x80000000
3090 @@ -178,7 +188,24 @@
3091  #define BCMA_CC_PROG_CFG               0x0120
3092  #define BCMA_CC_PROG_WAITCNT           0x0124
3093  #define BCMA_CC_FLASH_CFG              0x0128
3094 +#define  BCMA_CC_FLASH_CFG_DS          0x0010  /* Data size, 0=8bit, 1=16bit */
3095  #define BCMA_CC_FLASH_WAITCNT          0x012C
3096 +#define BCMA_CC_SROM_CONTROL           0x0190
3097 +#define  BCMA_CC_SROM_CONTROL_START    0x80000000
3098 +#define  BCMA_CC_SROM_CONTROL_BUSY     0x80000000
3099 +#define  BCMA_CC_SROM_CONTROL_OPCODE   0x60000000
3100 +#define  BCMA_CC_SROM_CONTROL_OP_READ  0x00000000
3101 +#define  BCMA_CC_SROM_CONTROL_OP_WRITE 0x20000000
3102 +#define  BCMA_CC_SROM_CONTROL_OP_WRDIS 0x40000000
3103 +#define  BCMA_CC_SROM_CONTROL_OP_WREN  0x60000000
3104 +#define  BCMA_CC_SROM_CONTROL_OTPSEL   0x00000010
3105 +#define  BCMA_CC_SROM_CONTROL_LOCK     0x00000008
3106 +#define  BCMA_CC_SROM_CONTROL_SIZE_MASK        0x00000006
3107 +#define  BCMA_CC_SROM_CONTROL_SIZE_1K  0x00000000
3108 +#define  BCMA_CC_SROM_CONTROL_SIZE_4K  0x00000002
3109 +#define  BCMA_CC_SROM_CONTROL_SIZE_16K 0x00000004
3110 +#define  BCMA_CC_SROM_CONTROL_SIZE_SHIFT       1
3111 +#define  BCMA_CC_SROM_CONTROL_PRESENT  0x00000001
3112  /* 0x1E0 is defined as shared BCMA_CLKCTLST */
3113  #define BCMA_CC_HW_WORKAROUND          0x01E4 /* Hardware workaround (rev >= 20) */
3114  #define BCMA_CC_UART0_DATA             0x0300
3115 @@ -201,6 +228,7 @@
3116  #define BCMA_CC_PMU_CTL                        0x0600 /* PMU control */
3117  #define  BCMA_CC_PMU_CTL_ILP_DIV       0xFFFF0000 /* ILP div mask */
3118  #define  BCMA_CC_PMU_CTL_ILP_DIV_SHIFT 16
3119 +#define  BCMA_CC_PMU_CTL_PLL_UPD       0x00000400
3120  #define  BCMA_CC_PMU_CTL_NOILPONW      0x00000200 /* No ILP on wait */
3121  #define  BCMA_CC_PMU_CTL_HTREQEN       0x00000100 /* HT req enable */
3122  #define  BCMA_CC_PMU_CTL_ALPREQEN      0x00000080 /* ALP req enable */
3123 @@ -237,7 +265,64 @@
3124  #define BCMA_CC_PLLCTL_ADDR            0x0660
3125  #define BCMA_CC_PLLCTL_DATA            0x0664
3126  #define BCMA_CC_SPROM                  0x0800 /* SPROM beginning */
3127 -#define BCMA_CC_SPROM_PCIE6            0x0830 /* SPROM beginning on PCIe rev >= 6 */
3128 +
3129 +/* Divider allocation in 4716/47162/5356 */
3130 +#define BCMA_CC_PMU5_MAINPLL_CPU       1
3131 +#define BCMA_CC_PMU5_MAINPLL_MEM       2
3132 +#define BCMA_CC_PMU5_MAINPLL_SSB       3
3133 +
3134 +/* PLL usage in 4716/47162 */
3135 +#define BCMA_CC_PMU4716_MAINPLL_PLL0   12
3136 +
3137 +/* PLL usage in 5356/5357 */
3138 +#define BCMA_CC_PMU5356_MAINPLL_PLL0   0
3139 +#define BCMA_CC_PMU5357_MAINPLL_PLL0   0
3140 +
3141 +/* 4706 PMU */
3142 +#define BCMA_CC_PMU4706_MAINPLL_PLL0   0
3143 +
3144 +/* ALP clock on pre-PMU chips */
3145 +#define BCMA_CC_PMU_ALP_CLOCK          20000000
3146 +/* HT clock for systems with PMU-enabled chipcommon */
3147 +#define BCMA_CC_PMU_HT_CLOCK           80000000
3148 +
3149 +/* PMU rev 5 (& 6) */
3150 +#define BCMA_CC_PPL_P1P2_OFF           0
3151 +#define BCMA_CC_PPL_P1_MASK            0x0f000000
3152 +#define BCMA_CC_PPL_P1_SHIFT           24
3153 +#define BCMA_CC_PPL_P2_MASK            0x00f00000
3154 +#define BCMA_CC_PPL_P2_SHIFT           20
3155 +#define BCMA_CC_PPL_M14_OFF            1
3156 +#define BCMA_CC_PPL_MDIV_MASK          0x000000ff
3157 +#define BCMA_CC_PPL_MDIV_WIDTH         8
3158 +#define BCMA_CC_PPL_NM5_OFF            2
3159 +#define BCMA_CC_PPL_NDIV_MASK          0xfff00000
3160 +#define BCMA_CC_PPL_NDIV_SHIFT         20
3161 +#define BCMA_CC_PPL_FMAB_OFF           3
3162 +#define BCMA_CC_PPL_MRAT_MASK          0xf0000000
3163 +#define BCMA_CC_PPL_MRAT_SHIFT         28
3164 +#define BCMA_CC_PPL_ABRAT_MASK         0x08000000
3165 +#define BCMA_CC_PPL_ABRAT_SHIFT                27
3166 +#define BCMA_CC_PPL_FDIV_MASK          0x07ffffff
3167 +#define BCMA_CC_PPL_PLLCTL_OFF         4
3168 +#define BCMA_CC_PPL_PCHI_OFF           5
3169 +#define BCMA_CC_PPL_PCHI_MASK          0x0000003f
3170 +
3171 +/* BCM4331 ChipControl numbers. */
3172 +#define BCMA_CHIPCTL_4331_BT_COEXIST           BIT(0)  /* 0 disable */
3173 +#define BCMA_CHIPCTL_4331_SECI                 BIT(1)  /* 0 SECI is disabled (JATG functional) */
3174 +#define BCMA_CHIPCTL_4331_EXT_LNA              BIT(2)  /* 0 disable */
3175 +#define BCMA_CHIPCTL_4331_SPROM_GPIO13_15      BIT(3)  /* sprom/gpio13-15 mux */
3176 +#define BCMA_CHIPCTL_4331_EXTPA_EN             BIT(4)  /* 0 ext pa disable, 1 ext pa enabled */
3177 +#define BCMA_CHIPCTL_4331_GPIOCLK_ON_SPROMCS   BIT(5)  /* set drive out GPIO_CLK on sprom_cs pin */
3178 +#define BCMA_CHIPCTL_4331_PCIE_MDIO_ON_SPROMCS BIT(6)  /* use sprom_cs pin as PCIE mdio interface */
3179 +#define BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5     BIT(7)  /* aband extpa will be at gpio2/5 and sprom_dout */
3180 +#define BCMA_CHIPCTL_4331_OVR_PIPEAUXCLKEN     BIT(8)  /* override core control on pipe_AuxClkEnable */
3181 +#define BCMA_CHIPCTL_4331_OVR_PIPEAUXPWRDOWN   BIT(9)  /* override core control on pipe_AuxPowerDown */
3182 +#define BCMA_CHIPCTL_4331_PCIE_AUXCLKEN                BIT(10) /* pcie_auxclkenable */
3183 +#define BCMA_CHIPCTL_4331_PCIE_PIPE_PLLDOWN    BIT(11) /* pcie_pipe_pllpowerdown */
3184 +#define BCMA_CHIPCTL_4331_BT_SHD0_ON_GPIO4     BIT(16) /* enable bt_shd0 at gpio4 */
3185 +#define BCMA_CHIPCTL_4331_BT_SHD1_ON_GPIO5     BIT(17) /* enable bt_shd1 at gpio5 */
3186  
3187  /* Data for the PMU, if available.
3188   * Check availability with ((struct bcma_chipcommon)->capabilities & BCMA_CC_CAP_PMU)
3189 @@ -247,14 +332,37 @@ struct bcma_chipcommon_pmu {
3190         u32 crystalfreq;        /* The active crystal frequency (in kHz) */
3191  };
3192  
3193 +#ifdef CONFIG_BCMA_DRIVER_MIPS
3194 +struct bcma_pflash {
3195 +       u8 buswidth;
3196 +       u32 window;
3197 +       u32 window_size;
3198 +};
3199 +
3200 +struct bcma_serial_port {
3201 +       void *regs;
3202 +       unsigned long clockspeed;
3203 +       unsigned int irq;
3204 +       unsigned int baud_base;
3205 +       unsigned int reg_shift;
3206 +};
3207 +#endif /* CONFIG_BCMA_DRIVER_MIPS */
3208 +
3209  struct bcma_drv_cc {
3210         struct bcma_device *core;
3211         u32 status;
3212         u32 capabilities;
3213         u32 capabilities_ext;
3214 +       u8 setup_done:1;
3215         /* Fast Powerup Delay constant */
3216         u16 fast_pwrup_delay;
3217         struct bcma_chipcommon_pmu pmu;
3218 +#ifdef CONFIG_BCMA_DRIVER_MIPS
3219 +       struct bcma_pflash pflash;
3220 +
3221 +       int nr_serial_ports;
3222 +       struct bcma_serial_port serial_ports[4];
3223 +#endif /* CONFIG_BCMA_DRIVER_MIPS */
3224  };
3225  
3226  /* Register access */
3227 @@ -275,6 +383,8 @@ extern void bcma_core_chipcommon_init(st
3228  extern void bcma_chipco_suspend(struct bcma_drv_cc *cc);
3229  extern void bcma_chipco_resume(struct bcma_drv_cc *cc);
3230  
3231 +void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable);
3232 +
3233  extern void bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc,
3234                                           u32 ticks);
3235  
3236 @@ -293,4 +403,13 @@ u32 bcma_chipco_gpio_polarity(struct bcm
3237  /* PMU support */
3238  extern void bcma_pmu_init(struct bcma_drv_cc *cc);
3239  
3240 +extern void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset,
3241 +                                 u32 value);
3242 +extern void bcma_chipco_pll_maskset(struct bcma_drv_cc *cc, u32 offset,
3243 +                                   u32 mask, u32 set);
3244 +extern void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc,
3245 +                                       u32 offset, u32 mask, u32 set);
3246 +extern void bcma_chipco_regctl_maskset(struct bcma_drv_cc *cc,
3247 +                                      u32 offset, u32 mask, u32 set);
3248 +
3249  #endif /* LINUX_BCMA_DRIVER_CC_H_ */
3250 --- /dev/null
3251 +++ b/include/linux/bcma/bcma_driver_mips.h
3252 @@ -0,0 +1,51 @@
3253 +#ifndef LINUX_BCMA_DRIVER_MIPS_H_
3254 +#define LINUX_BCMA_DRIVER_MIPS_H_
3255 +
3256 +#define BCMA_MIPS_IPSFLAG              0x0F08
3257 +/* which sbflags get routed to mips interrupt 1 */
3258 +#define  BCMA_MIPS_IPSFLAG_IRQ1                0x0000003F
3259 +#define  BCMA_MIPS_IPSFLAG_IRQ1_SHIFT  0
3260 +/* which sbflags get routed to mips interrupt 2 */
3261 +#define  BCMA_MIPS_IPSFLAG_IRQ2                0x00003F00
3262 +#define  BCMA_MIPS_IPSFLAG_IRQ2_SHIFT  8
3263 +/* which sbflags get routed to mips interrupt 3 */
3264 +#define  BCMA_MIPS_IPSFLAG_IRQ3                0x003F0000
3265 +#define  BCMA_MIPS_IPSFLAG_IRQ3_SHIFT  16
3266 +/* which sbflags get routed to mips interrupt 4 */
3267 +#define  BCMA_MIPS_IPSFLAG_IRQ4                0x3F000000
3268 +#define  BCMA_MIPS_IPSFLAG_IRQ4_SHIFT  24
3269 +
3270 +/* MIPS 74K core registers */
3271 +#define BCMA_MIPS_MIPS74K_CORECTL      0x0000
3272 +#define BCMA_MIPS_MIPS74K_EXCEPTBASE   0x0004
3273 +#define BCMA_MIPS_MIPS74K_BIST         0x000C
3274 +#define BCMA_MIPS_MIPS74K_INTMASK_INT0 0x0014
3275 +#define BCMA_MIPS_MIPS74K_INTMASK(int) \
3276 +       ((int) * 4 + BCMA_MIPS_MIPS74K_INTMASK_INT0)
3277 +#define BCMA_MIPS_MIPS74K_NMIMASK      0x002C
3278 +#define BCMA_MIPS_MIPS74K_GPIOSEL      0x0040
3279 +#define BCMA_MIPS_MIPS74K_GPIOOUT      0x0044
3280 +#define BCMA_MIPS_MIPS74K_GPIOEN       0x0048
3281 +#define BCMA_MIPS_MIPS74K_CLKCTLST     0x01E0
3282 +
3283 +#define BCMA_MIPS_OOBSELOUTA30         0x100
3284 +
3285 +struct bcma_device;
3286 +
3287 +struct bcma_drv_mips {
3288 +       struct bcma_device *core;
3289 +       u8 setup_done:1;
3290 +       unsigned int assigned_irqs;
3291 +};
3292 +
3293 +#ifdef CONFIG_BCMA_DRIVER_MIPS
3294 +extern void bcma_core_mips_init(struct bcma_drv_mips *mcore);
3295 +#else
3296 +static inline void bcma_core_mips_init(struct bcma_drv_mips *mcore) { }
3297 +#endif
3298 +
3299 +extern u32 bcma_cpu_clock(struct bcma_drv_mips *mcore);
3300 +
3301 +extern unsigned int bcma_core_mips_irq(struct bcma_device *dev);
3302 +
3303 +#endif /* LINUX_BCMA_DRIVER_MIPS_H_ */
3304 --- a/include/linux/bcma/bcma_driver_pci.h
3305 +++ b/include/linux/bcma/bcma_driver_pci.h
3306 @@ -53,6 +53,35 @@ struct pci_dev;
3307  #define  BCMA_CORE_PCI_SBTOPCI1_MASK           0xFC000000
3308  #define BCMA_CORE_PCI_SBTOPCI2                 0x0108  /* Backplane to PCI translation 2 (sbtopci2) */
3309  #define  BCMA_CORE_PCI_SBTOPCI2_MASK           0xC0000000
3310 +#define BCMA_CORE_PCI_CONFIG_ADDR              0x0120  /* pcie config space access */
3311 +#define BCMA_CORE_PCI_CONFIG_DATA              0x0124  /* pcie config space access */
3312 +#define BCMA_CORE_PCI_MDIO_CONTROL             0x0128  /* controls the mdio access */
3313 +#define  BCMA_CORE_PCI_MDIOCTL_DIVISOR_MASK    0x7f    /* clock to be used on MDIO */
3314 +#define  BCMA_CORE_PCI_MDIOCTL_DIVISOR_VAL     0x2
3315 +#define  BCMA_CORE_PCI_MDIOCTL_PREAM_EN                0x80    /* Enable preamble sequnce */
3316 +#define  BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE     0x100   /* Tranaction complete */
3317 +#define BCMA_CORE_PCI_MDIO_DATA                        0x012c  /* Data to the mdio access */
3318 +#define  BCMA_CORE_PCI_MDIODATA_MASK           0x0000ffff /* data 2 bytes */
3319 +#define  BCMA_CORE_PCI_MDIODATA_TA             0x00020000 /* Turnaround */
3320 +#define  BCMA_CORE_PCI_MDIODATA_REGADDR_SHF_OLD        18      /* Regaddr shift (rev < 10) */
3321 +#define  BCMA_CORE_PCI_MDIODATA_REGADDR_MASK_OLD       0x003c0000 /* Regaddr Mask (rev < 10) */
3322 +#define  BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF_OLD        22      /* Physmedia devaddr shift (rev < 10) */
3323 +#define  BCMA_CORE_PCI_MDIODATA_DEVADDR_MASK_OLD       0x0fc00000 /* Physmedia devaddr Mask (rev < 10) */
3324 +#define  BCMA_CORE_PCI_MDIODATA_REGADDR_SHF    18      /* Regaddr shift */
3325 +#define  BCMA_CORE_PCI_MDIODATA_REGADDR_MASK   0x007c0000 /* Regaddr Mask */
3326 +#define  BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF    23      /* Physmedia devaddr shift */
3327 +#define  BCMA_CORE_PCI_MDIODATA_DEVADDR_MASK   0x0f800000 /* Physmedia devaddr Mask */
3328 +#define  BCMA_CORE_PCI_MDIODATA_WRITE          0x10000000 /* write Transaction */
3329 +#define  BCMA_CORE_PCI_MDIODATA_READ           0x20000000 /* Read Transaction */
3330 +#define  BCMA_CORE_PCI_MDIODATA_START          0x40000000 /* start of Transaction */
3331 +#define  BCMA_CORE_PCI_MDIODATA_DEV_ADDR       0x0     /* dev address for serdes */
3332 +#define  BCMA_CORE_PCI_MDIODATA_BLK_ADDR       0x1F    /* blk address for serdes */
3333 +#define  BCMA_CORE_PCI_MDIODATA_DEV_PLL                0x1d    /* SERDES PLL Dev */
3334 +#define  BCMA_CORE_PCI_MDIODATA_DEV_TX         0x1e    /* SERDES TX Dev */
3335 +#define  BCMA_CORE_PCI_MDIODATA_DEV_RX         0x1f    /* SERDES RX Dev */
3336 +#define BCMA_CORE_PCI_PCIEIND_ADDR             0x0130  /* indirect access to the internal register */
3337 +#define BCMA_CORE_PCI_PCIEIND_DATA             0x0134  /* Data to/from the internal regsiter */
3338 +#define BCMA_CORE_PCI_CLKREQENCTRL             0x0138  /*  >= rev 6, Clkreq rdma control */
3339  #define BCMA_CORE_PCI_PCICFG0                  0x0400  /* PCI config space 0 (rev >= 8) */
3340  #define BCMA_CORE_PCI_PCICFG1                  0x0500  /* PCI config space 1 (rev >= 8) */
3341  #define BCMA_CORE_PCI_PCICFG2                  0x0600  /* PCI config space 2 (rev >= 8) */
3342 @@ -72,20 +101,114 @@ struct pci_dev;
3343  #define  BCMA_CORE_PCI_SBTOPCI_RC_READL                0x00000010 /* Memory read line */
3344  #define  BCMA_CORE_PCI_SBTOPCI_RC_READM                0x00000020 /* Memory read multiple */
3345  
3346 +/* PCIE protocol PHY diagnostic registers */
3347 +#define BCMA_CORE_PCI_PLP_MODEREG              0x200   /* Mode */
3348 +#define BCMA_CORE_PCI_PLP_STATUSREG            0x204   /* Status */
3349 +#define  BCMA_CORE_PCI_PLP_POLARITYINV_STAT    0x10    /* Status reg PCIE_PLP_STATUSREG */
3350 +#define BCMA_CORE_PCI_PLP_LTSSMCTRLREG         0x208   /* LTSSM control */
3351 +#define BCMA_CORE_PCI_PLP_LTLINKNUMREG         0x20c   /* Link Training Link number */
3352 +#define BCMA_CORE_PCI_PLP_LTLANENUMREG         0x210   /* Link Training Lane number */
3353 +#define BCMA_CORE_PCI_PLP_LTNFTSREG            0x214   /* Link Training N_FTS */
3354 +#define BCMA_CORE_PCI_PLP_ATTNREG              0x218   /* Attention */
3355 +#define BCMA_CORE_PCI_PLP_ATTNMASKREG          0x21C   /* Attention Mask */
3356 +#define BCMA_CORE_PCI_PLP_RXERRCTR             0x220   /* Rx Error */
3357 +#define BCMA_CORE_PCI_PLP_RXFRMERRCTR          0x224   /* Rx Framing Error */
3358 +#define BCMA_CORE_PCI_PLP_RXERRTHRESHREG       0x228   /* Rx Error threshold */
3359 +#define BCMA_CORE_PCI_PLP_TESTCTRLREG          0x22C   /* Test Control reg */
3360 +#define BCMA_CORE_PCI_PLP_SERDESCTRLOVRDREG    0x230   /* SERDES Control Override */
3361 +#define BCMA_CORE_PCI_PLP_TIMINGOVRDREG                0x234   /* Timing param override */
3362 +#define BCMA_CORE_PCI_PLP_RXTXSMDIAGREG                0x238   /* RXTX State Machine Diag */
3363 +#define BCMA_CORE_PCI_PLP_LTSSMDIAGREG         0x23C   /* LTSSM State Machine Diag */
3364 +
3365 +/* PCIE protocol DLLP diagnostic registers */
3366 +#define BCMA_CORE_PCI_DLLP_LCREG               0x100   /* Link Control */
3367 +#define BCMA_CORE_PCI_DLLP_LSREG               0x104   /* Link Status */
3368 +#define BCMA_CORE_PCI_DLLP_LAREG               0x108   /* Link Attention */
3369 +#define  BCMA_CORE_PCI_DLLP_LSREG_LINKUP       (1 << 16)
3370 +#define BCMA_CORE_PCI_DLLP_LAMASKREG           0x10C   /* Link Attention Mask */
3371 +#define BCMA_CORE_PCI_DLLP_NEXTTXSEQNUMREG     0x110   /* Next Tx Seq Num */
3372 +#define BCMA_CORE_PCI_DLLP_ACKEDTXSEQNUMREG    0x114   /* Acked Tx Seq Num */
3373 +#define BCMA_CORE_PCI_DLLP_PURGEDTXSEQNUMREG   0x118   /* Purged Tx Seq Num */
3374 +#define BCMA_CORE_PCI_DLLP_RXSEQNUMREG         0x11C   /* Rx Sequence Number */
3375 +#define BCMA_CORE_PCI_DLLP_LRREG               0x120   /* Link Replay */
3376 +#define BCMA_CORE_PCI_DLLP_LACKTOREG           0x124   /* Link Ack Timeout */
3377 +#define BCMA_CORE_PCI_DLLP_PMTHRESHREG         0x128   /* Power Management Threshold */
3378 +#define BCMA_CORE_PCI_DLLP_RTRYWPREG           0x12C   /* Retry buffer write ptr */
3379 +#define BCMA_CORE_PCI_DLLP_RTRYRPREG           0x130   /* Retry buffer Read ptr */
3380 +#define BCMA_CORE_PCI_DLLP_RTRYPPREG           0x134   /* Retry buffer Purged ptr */
3381 +#define BCMA_CORE_PCI_DLLP_RTRRWREG            0x138   /* Retry buffer Read/Write */
3382 +#define BCMA_CORE_PCI_DLLP_ECTHRESHREG         0x13C   /* Error Count Threshold */
3383 +#define BCMA_CORE_PCI_DLLP_TLPERRCTRREG                0x140   /* TLP Error Counter */
3384 +#define BCMA_CORE_PCI_DLLP_ERRCTRREG           0x144   /* Error Counter */
3385 +#define BCMA_CORE_PCI_DLLP_NAKRXCTRREG         0x148   /* NAK Received Counter */
3386 +#define BCMA_CORE_PCI_DLLP_TESTREG             0x14C   /* Test */
3387 +#define BCMA_CORE_PCI_DLLP_PKTBIST             0x150   /* Packet BIST */
3388 +#define BCMA_CORE_PCI_DLLP_PCIE11              0x154   /* DLLP PCIE 1.1 reg */
3389 +
3390 +/* SERDES RX registers */
3391 +#define BCMA_CORE_PCI_SERDES_RX_CTRL           1       /* Rx cntrl */
3392 +#define  BCMA_CORE_PCI_SERDES_RX_CTRL_FORCE    0x80    /* rxpolarity_force */
3393 +#define  BCMA_CORE_PCI_SERDES_RX_CTRL_POLARITY 0x40    /* rxpolarity_value */
3394 +#define BCMA_CORE_PCI_SERDES_RX_TIMER1         2       /* Rx Timer1 */
3395 +#define BCMA_CORE_PCI_SERDES_RX_CDR            6       /* CDR */
3396 +#define BCMA_CORE_PCI_SERDES_RX_CDRBW          7       /* CDR BW */
3397 +
3398 +/* SERDES PLL registers */
3399 +#define BCMA_CORE_PCI_SERDES_PLL_CTRL          1       /* PLL control reg */
3400 +#define BCMA_CORE_PCI_PLL_CTRL_FREQDET_EN      0x4000  /* bit 14 is FREQDET on */
3401 +
3402  /* PCIcore specific boardflags */
3403  #define BCMA_CORE_PCI_BFL_NOPCI                        0x00000400 /* Board leaves PCI floating */
3404  
3405 +/* PCIE Config space accessing MACROS */
3406 +#define BCMA_CORE_PCI_CFG_BUS_SHIFT            24      /* Bus shift */
3407 +#define BCMA_CORE_PCI_CFG_SLOT_SHIFT           19      /* Slot/Device shift */
3408 +#define BCMA_CORE_PCI_CFG_FUN_SHIFT            16      /* Function shift */
3409 +#define BCMA_CORE_PCI_CFG_OFF_SHIFT            0       /* Register shift */
3410 +
3411 +#define BCMA_CORE_PCI_CFG_BUS_MASK             0xff    /* Bus mask */
3412 +#define BCMA_CORE_PCI_CFG_SLOT_MASK            0x1f    /* Slot/Device mask */
3413 +#define BCMA_CORE_PCI_CFG_FUN_MASK             7       /* Function mask */
3414 +#define BCMA_CORE_PCI_CFG_OFF_MASK             0xfff   /* Register mask */
3415 +
3416 +/* PCIE Root Capability Register bits (Host mode only) */
3417 +#define BCMA_CORE_PCI_RC_CRS_VISIBILITY                0x0001
3418 +
3419 +struct bcma_drv_pci;
3420 +
3421 +#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
3422 +struct bcma_drv_pci_host {
3423 +       struct bcma_drv_pci *pdev;
3424 +
3425 +       u32 host_cfg_addr;
3426 +       spinlock_t cfgspace_lock;
3427 +
3428 +       struct pci_controller pci_controller;
3429 +       struct pci_ops pci_ops;
3430 +       struct resource mem_resource;
3431 +       struct resource io_resource;
3432 +};
3433 +#endif
3434 +
3435  struct bcma_drv_pci {
3436         struct bcma_device *core;
3437         u8 setup_done:1;
3438 +       u8 hostmode:1;
3439 +
3440 +#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
3441 +       struct bcma_drv_pci_host *host_controller;
3442 +#endif
3443  };
3444  
3445  /* Register access */
3446  #define pcicore_read32(pc, offset)             bcma_read32((pc)->core, offset)
3447  #define pcicore_write32(pc, offset, val)       bcma_write32((pc)->core, offset, val)
3448  
3449 -extern void bcma_core_pci_init(struct bcma_drv_pci *pc);
3450 +extern void __devinit bcma_core_pci_init(struct bcma_drv_pci *pc);
3451  extern int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc,
3452                                  struct bcma_device *core, bool enable);
3453  
3454 +extern int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev);
3455 +extern int bcma_core_pci_plat_dev_init(struct pci_dev *dev);
3456 +
3457  #endif /* LINUX_BCMA_DRIVER_PCI_H_ */
3458 --- a/include/linux/bcma/bcma_regs.h
3459 +++ b/include/linux/bcma/bcma_regs.h
3460 @@ -56,4 +56,31 @@
3461  #define  BCMA_PCI_GPIO_XTAL            0x40    /* PCI config space GPIO 14 for Xtal powerup */
3462  #define  BCMA_PCI_GPIO_PLL             0x80    /* PCI config space GPIO 15 for PLL powerdown */
3463  
3464 +/* SiliconBackplane Address Map.
3465 + * All regions may not exist on all chips.
3466 + */
3467 +#define BCMA_SOC_SDRAM_BASE            0x00000000U     /* Physical SDRAM */
3468 +#define BCMA_SOC_PCI_MEM               0x08000000U     /* Host Mode sb2pcitranslation0 (64 MB) */
3469 +#define BCMA_SOC_PCI_MEM_SZ            (64 * 1024 * 1024)
3470 +#define BCMA_SOC_PCI_CFG               0x0c000000U     /* Host Mode sb2pcitranslation1 (64 MB) */
3471 +#define BCMA_SOC_SDRAM_SWAPPED         0x10000000U     /* Byteswapped Physical SDRAM */
3472 +#define BCMA_SOC_SDRAM_R2              0x80000000U     /* Region 2 for sdram (512 MB) */
3473 +
3474 +
3475 +#define BCMA_SOC_PCI_DMA               0x40000000U     /* Client Mode sb2pcitranslation2 (1 GB) */
3476 +#define BCMA_SOC_PCI_DMA2              0x80000000U     /* Client Mode sb2pcitranslation2 (1 GB) */
3477 +#define BCMA_SOC_PCI_DMA_SZ            0x40000000U     /* Client Mode sb2pcitranslation2 size in bytes */
3478 +#define BCMA_SOC_PCIE_DMA_L32          0x00000000U     /* PCIE Client Mode sb2pcitranslation2
3479 +                                                        * (2 ZettaBytes), low 32 bits
3480 +                                                        */
3481 +#define BCMA_SOC_PCIE_DMA_H32          0x80000000U     /* PCIE Client Mode sb2pcitranslation2
3482 +                                                        * (2 ZettaBytes), high 32 bits
3483 +                                                        */
3484 +
3485 +#define BCMA_SOC_PCI1_MEM              0x40000000U     /* Host Mode sb2pcitranslation0 (64 MB) */
3486 +#define BCMA_SOC_PCI1_CFG              0x44000000U     /* Host Mode sb2pcitranslation1 (64 MB) */
3487 +#define BCMA_SOC_PCIE1_DMA_H32         0xc0000000U     /* PCIE Client Mode sb2pcitranslation2
3488 +                                                        * (2 ZettaBytes), high 32 bits
3489 +                                                        */
3490 +
3491  #endif /* LINUX_BCMA_REGS_H_ */
3492 --- /dev/null
3493 +++ b/include/linux/bcma/bcma_soc.h
3494 @@ -0,0 +1,16 @@
3495 +#ifndef LINUX_BCMA_SOC_H_
3496 +#define LINUX_BCMA_SOC_H_
3497 +
3498 +#include <linux/bcma/bcma.h>
3499 +
3500 +struct bcma_soc {
3501 +       struct bcma_bus bus;
3502 +       struct bcma_device core_cc;
3503 +       struct bcma_device core_mips;
3504 +};
3505 +
3506 +int __init bcma_host_soc_register(struct bcma_soc *soc);
3507 +
3508 +int bcma_bus_register(struct bcma_bus *bus);
3509 +
3510 +#endif /* LINUX_BCMA_SOC_H_ */