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