kernel: update bcma and ssb to version master-2011-12-16 from wireless-testing
[15.05/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
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,33 @@
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 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_resume(struct bcma_bus *bus);
70 +#endif
71  
72  /* scan.c */
73  int bcma_bus_scan(struct bcma_bus *bus);
74 +int __init bcma_bus_scan_early(struct bcma_bus *bus,
75 +                              struct bcma_device_id *match,
76 +                              struct bcma_device *core);
77 +void bcma_init_bus(struct bcma_bus *bus);
78 +
79 +/* sprom.c */
80 +int bcma_sprom_get(struct bcma_bus *bus);
81 +
82 +/* driver_chipcommon.c */
83 +#ifdef CONFIG_BCMA_DRIVER_MIPS
84 +void bcma_chipco_serial_init(struct bcma_drv_cc *cc);
85 +#endif /* CONFIG_BCMA_DRIVER_MIPS */
86 +
87 +/* driver_chipcommon_pmu.c */
88 +u32 bcma_pmu_alp_clock(struct bcma_drv_cc *cc);
89 +u32 bcma_pmu_get_clockcpu(struct bcma_drv_cc *cc);
90  
91  #ifdef CONFIG_BCMA_HOST_PCI
92  /* host_pci.c */
93 @@ -25,4 +47,8 @@ extern int __init bcma_host_pci_init(voi
94  extern void __exit bcma_host_pci_exit(void);
95  #endif /* CONFIG_BCMA_HOST_PCI */
96  
97 +#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
98 +void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc);
99 +#endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */
100 +
101  #endif
102 --- a/drivers/bcma/core.c
103 +++ b/drivers/bcma/core.c
104 @@ -19,7 +19,7 @@ bool bcma_core_is_enabled(struct bcma_de
105  }
106  EXPORT_SYMBOL_GPL(bcma_core_is_enabled);
107  
108 -static void bcma_core_disable(struct bcma_device *core, u32 flags)
109 +void bcma_core_disable(struct bcma_device *core, u32 flags)
110  {
111         if (bcma_aread32(core, BCMA_RESET_CTL) & BCMA_RESET_CTL_RESET)
112                 return;
113 @@ -31,6 +31,7 @@ static void bcma_core_disable(struct bcm
114         bcma_awrite32(core, BCMA_RESET_CTL, BCMA_RESET_CTL_RESET);
115         udelay(1);
116  }
117 +EXPORT_SYMBOL_GPL(bcma_core_disable);
118  
119  int bcma_core_enable(struct bcma_device *core, u32 flags)
120  {
121 @@ -49,3 +50,77 @@ int bcma_core_enable(struct bcma_device
122         return 0;
123  }
124  EXPORT_SYMBOL_GPL(bcma_core_enable);
125 +
126 +void bcma_core_set_clockmode(struct bcma_device *core,
127 +                            enum bcma_clkmode clkmode)
128 +{
129 +       u16 i;
130 +
131 +       WARN_ON(core->id.id != BCMA_CORE_CHIPCOMMON &&
132 +               core->id.id != BCMA_CORE_PCIE &&
133 +               core->id.id != BCMA_CORE_80211);
134 +
135 +       switch (clkmode) {
136 +       case BCMA_CLKMODE_FAST:
137 +               bcma_set32(core, BCMA_CLKCTLST, BCMA_CLKCTLST_FORCEHT);
138 +               udelay(64);
139 +               for (i = 0; i < 1500; i++) {
140 +                       if (bcma_read32(core, BCMA_CLKCTLST) &
141 +                           BCMA_CLKCTLST_HAVEHT) {
142 +                               i = 0;
143 +                               break;
144 +                       }
145 +                       udelay(10);
146 +               }
147 +               if (i)
148 +                       pr_err("HT force timeout\n");
149 +               break;
150 +       case BCMA_CLKMODE_DYNAMIC:
151 +               pr_warn("Dynamic clockmode not supported yet!\n");
152 +               break;
153 +       }
154 +}
155 +EXPORT_SYMBOL_GPL(bcma_core_set_clockmode);
156 +
157 +void bcma_core_pll_ctl(struct bcma_device *core, u32 req, u32 status, bool on)
158 +{
159 +       u16 i;
160 +
161 +       WARN_ON(req & ~BCMA_CLKCTLST_EXTRESREQ);
162 +       WARN_ON(status & ~BCMA_CLKCTLST_EXTRESST);
163 +
164 +       if (on) {
165 +               bcma_set32(core, BCMA_CLKCTLST, req);
166 +               for (i = 0; i < 10000; i++) {
167 +                       if ((bcma_read32(core, BCMA_CLKCTLST) & status) ==
168 +                           status) {
169 +                               i = 0;
170 +                               break;
171 +                       }
172 +                       udelay(10);
173 +               }
174 +               if (i)
175 +                       pr_err("PLL enable timeout\n");
176 +       } else {
177 +               pr_warn("Disabling PLL not supported yet!\n");
178 +       }
179 +}
180 +EXPORT_SYMBOL_GPL(bcma_core_pll_ctl);
181 +
182 +u32 bcma_core_dma_translation(struct bcma_device *core)
183 +{
184 +       switch (core->bus->hosttype) {
185 +       case BCMA_HOSTTYPE_SOC:
186 +               return 0;
187 +       case BCMA_HOSTTYPE_PCI:
188 +               if (bcma_aread32(core, BCMA_IOST) & BCMA_IOST_DMA64)
189 +                       return BCMA_DMA_TRANSLATION_DMA64_CMT;
190 +               else
191 +                       return BCMA_DMA_TRANSLATION_DMA32_CMT;
192 +       default:
193 +               pr_err("DMA translation unknown for host %d\n",
194 +                      core->bus->hosttype);
195 +       }
196 +       return BCMA_DMA_TRANSLATION_NONE;
197 +}
198 +EXPORT_SYMBOL(bcma_core_dma_translation);
199 --- a/drivers/bcma/driver_chipcommon.c
200 +++ b/drivers/bcma/driver_chipcommon.c
201 @@ -3,7 +3,7 @@
202   * ChipCommon core driver
203   *
204   * Copyright 2005, Broadcom Corporation
205 - * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
206 + * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
207   *
208   * Licensed under the GNU/GPL. See COPYING for details.
209   */
210 @@ -23,6 +23,12 @@ static inline u32 bcma_cc_write32_masked
211  
212  void bcma_core_chipcommon_init(struct bcma_drv_cc *cc)
213  {
214 +       u32 leddc_on = 10;
215 +       u32 leddc_off = 90;
216 +
217 +       if (cc->setup_done)
218 +               return;
219 +
220         if (cc->core->id.rev >= 11)
221                 cc->status = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
222         cc->capabilities = bcma_cc_read32(cc, BCMA_CC_CAP);
223 @@ -38,6 +44,19 @@ void bcma_core_chipcommon_init(struct bc
224                 bcma_pmu_init(cc);
225         if (cc->capabilities & BCMA_CC_CAP_PCTL)
226                 pr_err("Power control not implemented!\n");
227 +
228 +       if (cc->core->id.rev >= 16) {
229 +               if (cc->core->bus->sprom.leddc_on_time &&
230 +                   cc->core->bus->sprom.leddc_off_time) {
231 +                       leddc_on = cc->core->bus->sprom.leddc_on_time;
232 +                       leddc_off = cc->core->bus->sprom.leddc_off_time;
233 +               }
234 +               bcma_cc_write32(cc, BCMA_CC_GPIOTIMER,
235 +                       ((leddc_on << BCMA_CC_GPIOTIMER_ONTIME_SHIFT) |
236 +                        (leddc_off << BCMA_CC_GPIOTIMER_OFFTIME_SHIFT)));
237 +       }
238 +
239 +       cc->setup_done = true;
240  }
241  
242  /* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */
243 @@ -87,3 +106,51 @@ u32 bcma_chipco_gpio_polarity(struct bcm
244  {
245         return bcma_cc_write32_masked(cc, BCMA_CC_GPIOPOL, mask, value);
246  }
247 +
248 +#ifdef CONFIG_BCMA_DRIVER_MIPS
249 +void bcma_chipco_serial_init(struct bcma_drv_cc *cc)
250 +{
251 +       unsigned int irq;
252 +       u32 baud_base;
253 +       u32 i;
254 +       unsigned int ccrev = cc->core->id.rev;
255 +       struct bcma_serial_port *ports = cc->serial_ports;
256 +
257 +       if (ccrev >= 11 && ccrev != 15) {
258 +               /* Fixed ALP clock */
259 +               baud_base = bcma_pmu_alp_clock(cc);
260 +               if (ccrev >= 21) {
261 +                       /* Turn off UART clock before switching clocksource. */
262 +                       bcma_cc_write32(cc, BCMA_CC_CORECTL,
263 +                                      bcma_cc_read32(cc, BCMA_CC_CORECTL)
264 +                                      & ~BCMA_CC_CORECTL_UARTCLKEN);
265 +               }
266 +               /* Set the override bit so we don't divide it */
267 +               bcma_cc_write32(cc, BCMA_CC_CORECTL,
268 +                              bcma_cc_read32(cc, BCMA_CC_CORECTL)
269 +                              | BCMA_CC_CORECTL_UARTCLK0);
270 +               if (ccrev >= 21) {
271 +                       /* Re-enable the UART clock. */
272 +                       bcma_cc_write32(cc, BCMA_CC_CORECTL,
273 +                                      bcma_cc_read32(cc, BCMA_CC_CORECTL)
274 +                                      | BCMA_CC_CORECTL_UARTCLKEN);
275 +               }
276 +       } else {
277 +               pr_err("serial not supported on this device ccrev: 0x%x\n",
278 +                      ccrev);
279 +               return;
280 +       }
281 +
282 +       irq = bcma_core_mips_irq(cc->core);
283 +
284 +       /* Determine the registers of the UARTs */
285 +       cc->nr_serial_ports = (cc->capabilities & BCMA_CC_CAP_NRUART);
286 +       for (i = 0; i < cc->nr_serial_ports; i++) {
287 +               ports[i].regs = cc->core->io_addr + BCMA_CC_UART0_DATA +
288 +                               (i * 256);
289 +               ports[i].irq = irq;
290 +               ports[i].baud_base = baud_base;
291 +               ports[i].reg_shift = 0;
292 +       }
293 +}
294 +#endif /* CONFIG_BCMA_DRIVER_MIPS */
295 --- a/drivers/bcma/driver_chipcommon_pmu.c
296 +++ b/drivers/bcma/driver_chipcommon_pmu.c
297 @@ -2,7 +2,7 @@
298   * Broadcom specific AMBA
299   * ChipCommon Power Management Unit driver
300   *
301 - * Copyright 2009, Michael Buesch <mb@bu3sch.de>
302 + * Copyright 2009, Michael Buesch <m@bues.ch>
303   * Copyright 2007, Broadcom Corporation
304   *
305   * Licensed under the GNU/GPL. See COPYING for details.
306 @@ -11,20 +11,47 @@
307  #include "bcma_private.h"
308  #include <linux/bcma/bcma.h>
309  
310 -static void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc,
311 -                                       u32 offset, u32 mask, u32 set)
312 +static u32 bcma_chipco_pll_read(struct bcma_drv_cc *cc, u32 offset)
313  {
314 -       u32 value;
315 +       bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
316 +       bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
317 +       return bcma_cc_read32(cc, BCMA_CC_PLLCTL_DATA);
318 +}
319  
320 -       bcma_cc_read32(cc, BCMA_CC_CHIPCTL_ADDR);
321 +void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset, u32 value)
322 +{
323 +       bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
324 +       bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
325 +       bcma_cc_write32(cc, BCMA_CC_PLLCTL_DATA, value);
326 +}
327 +EXPORT_SYMBOL_GPL(bcma_chipco_pll_write);
328 +
329 +void bcma_chipco_pll_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask,
330 +                            u32 set)
331 +{
332 +       bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
333 +       bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
334 +       bcma_cc_maskset32(cc, BCMA_CC_PLLCTL_DATA, mask, set);
335 +}
336 +EXPORT_SYMBOL_GPL(bcma_chipco_pll_maskset);
337 +
338 +void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc,
339 +                                u32 offset, u32 mask, u32 set)
340 +{
341         bcma_cc_write32(cc, BCMA_CC_CHIPCTL_ADDR, offset);
342         bcma_cc_read32(cc, BCMA_CC_CHIPCTL_ADDR);
343 -       value = bcma_cc_read32(cc, BCMA_CC_CHIPCTL_DATA);
344 -       value &= mask;
345 -       value |= set;
346 -       bcma_cc_write32(cc, BCMA_CC_CHIPCTL_DATA, value);
347 -       bcma_cc_read32(cc, BCMA_CC_CHIPCTL_DATA);
348 +       bcma_cc_maskset32(cc, BCMA_CC_CHIPCTL_DATA, mask, set);
349 +}
350 +EXPORT_SYMBOL_GPL(bcma_chipco_chipctl_maskset);
351 +
352 +void bcma_chipco_regctl_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask,
353 +                               u32 set)
354 +{
355 +       bcma_cc_write32(cc, BCMA_CC_REGCTL_ADDR, offset);
356 +       bcma_cc_read32(cc, BCMA_CC_REGCTL_ADDR);
357 +       bcma_cc_maskset32(cc, BCMA_CC_REGCTL_DATA, mask, set);
358  }
359 +EXPORT_SYMBOL_GPL(bcma_chipco_regctl_maskset);
360  
361  static void bcma_pmu_pll_init(struct bcma_drv_cc *cc)
362  {
363 @@ -53,6 +80,7 @@ static void bcma_pmu_resources_init(stru
364                 max_msk = 0xFFFF;
365                 break;
366         case 43224:
367 +       case 43225:
368                 break;
369         default:
370                 pr_err("PMU resource config unknown for device 0x%04X\n",
371 @@ -74,6 +102,7 @@ void bcma_pmu_swreg_init(struct bcma_drv
372         case 0x4313:
373         case 0x4331:
374         case 43224:
375 +       case 43225:
376                 break;
377         default:
378                 pr_err("PMU switch/regulators init unknown for device "
379 @@ -81,6 +110,24 @@ void bcma_pmu_swreg_init(struct bcma_drv
380         }
381  }
382  
383 +/* Disable to allow reading SPROM. Don't know the adventages of enabling it. */
384 +void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable)
385 +{
386 +       struct bcma_bus *bus = cc->core->bus;
387 +       u32 val;
388 +
389 +       val = bcma_cc_read32(cc, BCMA_CC_CHIPCTL);
390 +       if (enable) {
391 +               val |= BCMA_CHIPCTL_4331_EXTPA_EN;
392 +               if (bus->chipinfo.pkg == 9 || bus->chipinfo.pkg == 11)
393 +                       val |= BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5;
394 +       } else {
395 +               val &= ~BCMA_CHIPCTL_4331_EXTPA_EN;
396 +               val &= ~BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5;
397 +       }
398 +       bcma_cc_write32(cc, BCMA_CC_CHIPCTL, val);
399 +}
400 +
401  void bcma_pmu_workarounds(struct bcma_drv_cc *cc)
402  {
403         struct bcma_bus *bus = cc->core->bus;
404 @@ -90,17 +137,19 @@ void bcma_pmu_workarounds(struct bcma_dr
405                 bcma_chipco_chipctl_maskset(cc, 0, ~0, 0x7);
406                 break;
407         case 0x4331:
408 -               pr_err("Enabling Ext PA lines not implemented\n");
409 +               /* BCM4331 workaround is SPROM-related, we put it in sprom.c */
410                 break;
411         case 43224:
412                 if (bus->chipinfo.rev == 0) {
413                         pr_err("Workarounds for 43224 rev 0 not fully "
414                                 "implemented\n");
415 -                       bcma_chipco_chipctl_maskset(cc, 0, ~0, 0xF0);
416 +                       bcma_chipco_chipctl_maskset(cc, 0, ~0, 0x00F000F0);
417                 } else {
418                         bcma_chipco_chipctl_maskset(cc, 0, ~0, 0xF0);
419                 }
420                 break;
421 +       case 43225:
422 +               break;
423         default:
424                 pr_err("Workarounds unknown for device 0x%04X\n",
425                         bus->chipinfo.id);
426 @@ -132,3 +181,129 @@ void bcma_pmu_init(struct bcma_drv_cc *c
427         bcma_pmu_swreg_init(cc);
428         bcma_pmu_workarounds(cc);
429  }
430 +
431 +u32 bcma_pmu_alp_clock(struct bcma_drv_cc *cc)
432 +{
433 +       struct bcma_bus *bus = cc->core->bus;
434 +
435 +       switch (bus->chipinfo.id) {
436 +       case 0x4716:
437 +       case 0x4748:
438 +       case 47162:
439 +       case 0x4313:
440 +       case 0x5357:
441 +       case 0x4749:
442 +       case 53572:
443 +               /* always 20Mhz */
444 +               return 20000 * 1000;
445 +       case 0x5356:
446 +       case 0x5300:
447 +               /* always 25Mhz */
448 +               return 25000 * 1000;
449 +       default:
450 +               pr_warn("No ALP clock specified for %04X device, "
451 +                       "pmu rev. %d, using default %d Hz\n",
452 +                       bus->chipinfo.id, cc->pmu.rev, BCMA_CC_PMU_ALP_CLOCK);
453 +       }
454 +       return BCMA_CC_PMU_ALP_CLOCK;
455 +}
456 +
457 +/* Find the output of the "m" pll divider given pll controls that start with
458 + * pllreg "pll0" i.e. 12 for main 6 for phy, 0 for misc.
459 + */
460 +static u32 bcma_pmu_clock(struct bcma_drv_cc *cc, u32 pll0, u32 m)
461 +{
462 +       u32 tmp, div, ndiv, p1, p2, fc;
463 +       struct bcma_bus *bus = cc->core->bus;
464 +
465 +       BUG_ON((pll0 & 3) || (pll0 > BCMA_CC_PMU4716_MAINPLL_PLL0));
466 +
467 +       BUG_ON(!m || m > 4);
468 +
469 +       if (bus->chipinfo.id == 0x5357 || bus->chipinfo.id == 0x4749) {
470 +               /* Detect failure in clock setting */
471 +               tmp = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
472 +               if (tmp & 0x40000)
473 +                       return 133 * 1000000;
474 +       }
475 +
476 +       tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_P1P2_OFF);
477 +       p1 = (tmp & BCMA_CC_PPL_P1_MASK) >> BCMA_CC_PPL_P1_SHIFT;
478 +       p2 = (tmp & BCMA_CC_PPL_P2_MASK) >> BCMA_CC_PPL_P2_SHIFT;
479 +
480 +       tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_M14_OFF);
481 +       div = (tmp >> ((m - 1) * BCMA_CC_PPL_MDIV_WIDTH)) &
482 +               BCMA_CC_PPL_MDIV_MASK;
483 +
484 +       tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_NM5_OFF);
485 +       ndiv = (tmp & BCMA_CC_PPL_NDIV_MASK) >> BCMA_CC_PPL_NDIV_SHIFT;
486 +
487 +       /* Do calculation in Mhz */
488 +       fc = bcma_pmu_alp_clock(cc) / 1000000;
489 +       fc = (p1 * ndiv * fc) / p2;
490 +
491 +       /* Return clock in Hertz */
492 +       return (fc / div) * 1000000;
493 +}
494 +
495 +/* query bus clock frequency for PMU-enabled chipcommon */
496 +u32 bcma_pmu_get_clockcontrol(struct bcma_drv_cc *cc)
497 +{
498 +       struct bcma_bus *bus = cc->core->bus;
499 +
500 +       switch (bus->chipinfo.id) {
501 +       case 0x4716:
502 +       case 0x4748:
503 +       case 47162:
504 +               return bcma_pmu_clock(cc, BCMA_CC_PMU4716_MAINPLL_PLL0,
505 +                                     BCMA_CC_PMU5_MAINPLL_SSB);
506 +       case 0x5356:
507 +               return bcma_pmu_clock(cc, BCMA_CC_PMU5356_MAINPLL_PLL0,
508 +                                     BCMA_CC_PMU5_MAINPLL_SSB);
509 +       case 0x5357:
510 +       case 0x4749:
511 +               return bcma_pmu_clock(cc, BCMA_CC_PMU5357_MAINPLL_PLL0,
512 +                                     BCMA_CC_PMU5_MAINPLL_SSB);
513 +       case 0x5300:
514 +               return bcma_pmu_clock(cc, BCMA_CC_PMU4706_MAINPLL_PLL0,
515 +                                     BCMA_CC_PMU5_MAINPLL_SSB);
516 +       case 53572:
517 +               return 75000000;
518 +       default:
519 +               pr_warn("No backplane clock specified for %04X device, "
520 +                       "pmu rev. %d, using default %d Hz\n",
521 +                       bus->chipinfo.id, cc->pmu.rev, BCMA_CC_PMU_HT_CLOCK);
522 +       }
523 +       return BCMA_CC_PMU_HT_CLOCK;
524 +}
525 +
526 +/* query cpu clock frequency for PMU-enabled chipcommon */
527 +u32 bcma_pmu_get_clockcpu(struct bcma_drv_cc *cc)
528 +{
529 +       struct bcma_bus *bus = cc->core->bus;
530 +
531 +       if (bus->chipinfo.id == 53572)
532 +               return 300000000;
533 +
534 +       if (cc->pmu.rev >= 5) {
535 +               u32 pll;
536 +               switch (bus->chipinfo.id) {
537 +               case 0x5356:
538 +                       pll = BCMA_CC_PMU5356_MAINPLL_PLL0;
539 +                       break;
540 +               case 0x5357:
541 +               case 0x4749:
542 +                       pll = BCMA_CC_PMU5357_MAINPLL_PLL0;
543 +                       break;
544 +               default:
545 +                       pll = BCMA_CC_PMU4716_MAINPLL_PLL0;
546 +                       break;
547 +               }
548 +
549 +               /* TODO: if (bus->chipinfo.id == 0x5300)
550 +                 return si_4706_pmu_clock(sih, osh, cc, PMU4706_MAINPLL_PLL0, PMU5_MAINPLL_CPU); */
551 +               return bcma_pmu_clock(cc, pll, BCMA_CC_PMU5_MAINPLL_CPU);
552 +       }
553 +
554 +       return bcma_pmu_get_clockcontrol(cc);
555 +}
556 --- /dev/null
557 +++ b/drivers/bcma/driver_mips.c
558 @@ -0,0 +1,256 @@
559 +/*
560 + * Broadcom specific AMBA
561 + * Broadcom MIPS32 74K core driver
562 + *
563 + * Copyright 2009, Broadcom Corporation
564 + * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
565 + * Copyright 2010, Bernhard Loos <bernhardloos@googlemail.com>
566 + * Copyright 2011, Hauke Mehrtens <hauke@hauke-m.de>
567 + *
568 + * Licensed under the GNU/GPL. See COPYING for details.
569 + */
570 +
571 +#include "bcma_private.h"
572 +
573 +#include <linux/bcma/bcma.h>
574 +
575 +#include <linux/serial.h>
576 +#include <linux/serial_core.h>
577 +#include <linux/serial_reg.h>
578 +#include <linux/time.h>
579 +
580 +/* The 47162a0 hangs when reading MIPS DMP registers registers */
581 +static inline bool bcma_core_mips_bcm47162a0_quirk(struct bcma_device *dev)
582 +{
583 +       return dev->bus->chipinfo.id == 47162 && dev->bus->chipinfo.rev == 0 &&
584 +              dev->id.id == BCMA_CORE_MIPS_74K;
585 +}
586 +
587 +/* The 5357b0 hangs when reading USB20H DMP registers */
588 +static inline bool bcma_core_mips_bcm5357b0_quirk(struct bcma_device *dev)
589 +{
590 +       return (dev->bus->chipinfo.id == 0x5357 ||
591 +               dev->bus->chipinfo.id == 0x4749) &&
592 +              dev->bus->chipinfo.pkg == 11 &&
593 +              dev->id.id == BCMA_CORE_USB20_HOST;
594 +}
595 +
596 +static inline u32 mips_read32(struct bcma_drv_mips *mcore,
597 +                             u16 offset)
598 +{
599 +       return bcma_read32(mcore->core, offset);
600 +}
601 +
602 +static inline void mips_write32(struct bcma_drv_mips *mcore,
603 +                               u16 offset,
604 +                               u32 value)
605 +{
606 +       bcma_write32(mcore->core, offset, value);
607 +}
608 +
609 +static const u32 ipsflag_irq_mask[] = {
610 +       0,
611 +       BCMA_MIPS_IPSFLAG_IRQ1,
612 +       BCMA_MIPS_IPSFLAG_IRQ2,
613 +       BCMA_MIPS_IPSFLAG_IRQ3,
614 +       BCMA_MIPS_IPSFLAG_IRQ4,
615 +};
616 +
617 +static const u32 ipsflag_irq_shift[] = {
618 +       0,
619 +       BCMA_MIPS_IPSFLAG_IRQ1_SHIFT,
620 +       BCMA_MIPS_IPSFLAG_IRQ2_SHIFT,
621 +       BCMA_MIPS_IPSFLAG_IRQ3_SHIFT,
622 +       BCMA_MIPS_IPSFLAG_IRQ4_SHIFT,
623 +};
624 +
625 +static u32 bcma_core_mips_irqflag(struct bcma_device *dev)
626 +{
627 +       u32 flag;
628 +
629 +       if (bcma_core_mips_bcm47162a0_quirk(dev))
630 +               return dev->core_index;
631 +       if (bcma_core_mips_bcm5357b0_quirk(dev))
632 +               return dev->core_index;
633 +       flag = bcma_aread32(dev, BCMA_MIPS_OOBSELOUTA30);
634 +
635 +       return flag & 0x1F;
636 +}
637 +
638 +/* Get the MIPS IRQ assignment for a specified device.
639 + * If unassigned, 0 is returned.
640 + */
641 +unsigned int bcma_core_mips_irq(struct bcma_device *dev)
642 +{
643 +       struct bcma_device *mdev = dev->bus->drv_mips.core;
644 +       u32 irqflag;
645 +       unsigned int irq;
646 +
647 +       irqflag = bcma_core_mips_irqflag(dev);
648 +
649 +       for (irq = 1; irq <= 4; irq++)
650 +               if (bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq)) &
651 +                   (1 << irqflag))
652 +                       return irq;
653 +
654 +       return 0;
655 +}
656 +EXPORT_SYMBOL(bcma_core_mips_irq);
657 +
658 +static void bcma_core_mips_set_irq(struct bcma_device *dev, unsigned int irq)
659 +{
660 +       unsigned int oldirq = bcma_core_mips_irq(dev);
661 +       struct bcma_bus *bus = dev->bus;
662 +       struct bcma_device *mdev = bus->drv_mips.core;
663 +       u32 irqflag;
664 +
665 +       irqflag = bcma_core_mips_irqflag(dev);
666 +       BUG_ON(oldirq == 6);
667 +
668 +       dev->irq = irq + 2;
669 +
670 +       /* clear the old irq */
671 +       if (oldirq == 0)
672 +               bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0),
673 +                           bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) &
674 +                           ~(1 << irqflag));
675 +       else
676 +               bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq), 0);
677 +
678 +       /* assign the new one */
679 +       if (irq == 0) {
680 +               bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0),
681 +                           bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) |
682 +                           (1 << irqflag));
683 +       } else {
684 +               u32 oldirqflag = bcma_read32(mdev,
685 +                                            BCMA_MIPS_MIPS74K_INTMASK(irq));
686 +               if (oldirqflag) {
687 +                       struct bcma_device *core;
688 +
689 +                       /* backplane irq line is in use, find out who uses
690 +                        * it and set user to irq 0
691 +                        */
692 +                       list_for_each_entry_reverse(core, &bus->cores, list) {
693 +                               if ((1 << bcma_core_mips_irqflag(core)) ==
694 +                                   oldirqflag) {
695 +                                       bcma_core_mips_set_irq(core, 0);
696 +                                       break;
697 +                               }
698 +                       }
699 +               }
700 +               bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq),
701 +                            1 << irqflag);
702 +       }
703 +
704 +       pr_info("set_irq: core 0x%04x, irq %d => %d\n",
705 +               dev->id.id, oldirq + 2, irq + 2);
706 +}
707 +
708 +static void bcma_core_mips_print_irq(struct bcma_device *dev, unsigned int irq)
709 +{
710 +       int i;
711 +       static const char *irq_name[] = {"2(S)", "3", "4", "5", "6", "D", "I"};
712 +       printk(KERN_INFO KBUILD_MODNAME ": core 0x%04x, irq :", dev->id.id);
713 +       for (i = 0; i <= 6; i++)
714 +               printk(" %s%s", irq_name[i], i == irq ? "*" : " ");
715 +       printk("\n");
716 +}
717 +
718 +static void bcma_core_mips_dump_irq(struct bcma_bus *bus)
719 +{
720 +       struct bcma_device *core;
721 +
722 +       list_for_each_entry_reverse(core, &bus->cores, list) {
723 +               bcma_core_mips_print_irq(core, bcma_core_mips_irq(core));
724 +       }
725 +}
726 +
727 +u32 bcma_cpu_clock(struct bcma_drv_mips *mcore)
728 +{
729 +       struct bcma_bus *bus = mcore->core->bus;
730 +
731 +       if (bus->drv_cc.capabilities & BCMA_CC_CAP_PMU)
732 +               return bcma_pmu_get_clockcpu(&bus->drv_cc);
733 +
734 +       pr_err("No PMU available, need this to get the cpu clock\n");
735 +       return 0;
736 +}
737 +EXPORT_SYMBOL(bcma_cpu_clock);
738 +
739 +static void bcma_core_mips_flash_detect(struct bcma_drv_mips *mcore)
740 +{
741 +       struct bcma_bus *bus = mcore->core->bus;
742 +
743 +       switch (bus->drv_cc.capabilities & BCMA_CC_CAP_FLASHT) {
744 +       case BCMA_CC_FLASHT_STSER:
745 +       case BCMA_CC_FLASHT_ATSER:
746 +               pr_err("Serial flash not supported.\n");
747 +               break;
748 +       case BCMA_CC_FLASHT_PARA:
749 +               pr_info("found parallel flash.\n");
750 +               bus->drv_cc.pflash.window = 0x1c000000;
751 +               bus->drv_cc.pflash.window_size = 0x02000000;
752 +
753 +               if ((bcma_read32(bus->drv_cc.core, BCMA_CC_FLASH_CFG) &
754 +                    BCMA_CC_FLASH_CFG_DS) == 0)
755 +                       bus->drv_cc.pflash.buswidth = 1;
756 +               else
757 +                       bus->drv_cc.pflash.buswidth = 2;
758 +               break;
759 +       default:
760 +               pr_err("flash not supported.\n");
761 +       }
762 +}
763 +
764 +void bcma_core_mips_init(struct bcma_drv_mips *mcore)
765 +{
766 +       struct bcma_bus *bus;
767 +       struct bcma_device *core;
768 +       bus = mcore->core->bus;
769 +
770 +       pr_info("Initializing MIPS core...\n");
771 +
772 +       if (!mcore->setup_done)
773 +               mcore->assigned_irqs = 1;
774 +
775 +       /* Assign IRQs to all cores on the bus */
776 +       list_for_each_entry_reverse(core, &bus->cores, list) {
777 +               int mips_irq;
778 +               if (core->irq)
779 +                       continue;
780 +
781 +               mips_irq = bcma_core_mips_irq(core);
782 +               if (mips_irq > 4)
783 +                       core->irq = 0;
784 +               else
785 +                       core->irq = mips_irq + 2;
786 +               if (core->irq > 5)
787 +                       continue;
788 +               switch (core->id.id) {
789 +               case BCMA_CORE_PCI:
790 +               case BCMA_CORE_PCIE:
791 +               case BCMA_CORE_ETHERNET:
792 +               case BCMA_CORE_ETHERNET_GBIT:
793 +               case BCMA_CORE_MAC_GBIT:
794 +               case BCMA_CORE_80211:
795 +               case BCMA_CORE_USB20_HOST:
796 +                       /* These devices get their own IRQ line if available,
797 +                        * the rest goes on IRQ0
798 +                        */
799 +                       if (mcore->assigned_irqs <= 4)
800 +                               bcma_core_mips_set_irq(core,
801 +                                                      mcore->assigned_irqs++);
802 +                       break;
803 +               }
804 +       }
805 +       pr_info("IRQ reconfiguration done\n");
806 +       bcma_core_mips_dump_irq(bus);
807 +
808 +       if (mcore->setup_done)
809 +               return;
810 +
811 +       bcma_chipco_serial_init(&bus->drv_cc);
812 +       bcma_core_mips_flash_detect(mcore);
813 +       mcore->setup_done = true;
814 +}
815 --- a/drivers/bcma/driver_pci.c
816 +++ b/drivers/bcma/driver_pci.c
817 @@ -3,7 +3,7 @@
818   * PCI Core
819   *
820   * Copyright 2005, Broadcom Corporation
821 - * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
822 + * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
823   *
824   * Licensed under the GNU/GPL. See COPYING for details.
825   */
826 @@ -157,7 +157,81 @@ static void bcma_pcicore_serdes_workarou
827   * Init.
828   **************************************************/
829  
830 -void bcma_core_pci_init(struct bcma_drv_pci *pc)
831 +static void bcma_core_pci_clientmode_init(struct bcma_drv_pci *pc)
832  {
833         bcma_pcicore_serdes_workaround(pc);
834  }
835 +
836 +static bool bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc)
837 +{
838 +       struct bcma_bus *bus = pc->core->bus;
839 +       u16 chipid_top;
840 +
841 +       chipid_top = (bus->chipinfo.id & 0xFF00);
842 +       if (chipid_top != 0x4700 &&
843 +           chipid_top != 0x5300)
844 +               return false;
845 +
846 +#ifdef CONFIG_SSB_DRIVER_PCICORE
847 +       if (bus->sprom.boardflags_lo & SSB_BFL_NOPCI)
848 +               return false;
849 +#endif /* CONFIG_SSB_DRIVER_PCICORE */
850 +
851 +#if 0
852 +       /* TODO: on BCMA we use address from EROM instead of magic formula */
853 +       u32 tmp;
854 +       return !mips_busprobe32(tmp, (bus->mmio +
855 +               (pc->core->core_index * BCMA_CORE_SIZE)));
856 +#endif
857 +
858 +       return true;
859 +}
860 +
861 +void bcma_core_pci_init(struct bcma_drv_pci *pc)
862 +{
863 +       if (pc->setup_done)
864 +               return;
865 +
866 +       if (bcma_core_pci_is_in_hostmode(pc)) {
867 +#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
868 +               bcma_core_pci_hostmode_init(pc);
869 +#else
870 +               pr_err("Driver compiled without support for hostmode PCI\n");
871 +#endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */
872 +       } else {
873 +               bcma_core_pci_clientmode_init(pc);
874 +       }
875 +
876 +       pc->setup_done = true;
877 +}
878 +
879 +int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core,
880 +                         bool enable)
881 +{
882 +       struct pci_dev *pdev = pc->core->bus->host_pci;
883 +       u32 coremask, tmp;
884 +       int err = 0;
885 +
886 +       if (core->bus->hosttype != BCMA_HOSTTYPE_PCI) {
887 +               /* This bcma device is not on a PCI host-bus. So the IRQs are
888 +                * not routed through the PCI core.
889 +                * So we must not enable routing through the PCI core. */
890 +               goto out;
891 +       }
892 +
893 +       err = pci_read_config_dword(pdev, BCMA_PCI_IRQMASK, &tmp);
894 +       if (err)
895 +               goto out;
896 +
897 +       coremask = BIT(core->core_index) << 8;
898 +       if (enable)
899 +               tmp |= coremask;
900 +       else
901 +               tmp &= ~coremask;
902 +
903 +       err = pci_write_config_dword(pdev, BCMA_PCI_IRQMASK, tmp);
904 +
905 +out:
906 +       return err;
907 +}
908 +EXPORT_SYMBOL_GPL(bcma_core_pci_irq_ctl);
909 --- /dev/null
910 +++ b/drivers/bcma/driver_pci_host.c
911 @@ -0,0 +1,14 @@
912 +/*
913 + * Broadcom specific AMBA
914 + * PCI Core in hostmode
915 + *
916 + * Licensed under the GNU/GPL. See COPYING for details.
917 + */
918 +
919 +#include "bcma_private.h"
920 +#include <linux/bcma/bcma.h>
921 +
922 +void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc)
923 +{
924 +       pr_err("No support for PCI core in hostmode yet\n");
925 +}
926 --- a/drivers/bcma/host_pci.c
927 +++ b/drivers/bcma/host_pci.c
928 @@ -9,6 +9,7 @@
929  #include <linux/slab.h>
930  #include <linux/bcma/bcma.h>
931  #include <linux/pci.h>
932 +#include <linux/module.h>
933  
934  static void bcma_host_pci_switch_core(struct bcma_device *core)
935  {
936 @@ -20,50 +21,108 @@ static void bcma_host_pci_switch_core(st
937         pr_debug("Switched to core: 0x%X\n", core->id.id);
938  }
939  
940 -static u8 bcma_host_pci_read8(struct bcma_device *core, u16 offset)
941 -{
942 +/* Provides access to the requested core. Returns base offset that has to be
943 + * used. It makes use of fixed windows when possible. */
944 +static u16 bcma_host_pci_provide_access_to_core(struct bcma_device *core)
945 +{
946 +       switch (core->id.id) {
947 +       case BCMA_CORE_CHIPCOMMON:
948 +               return 3 * BCMA_CORE_SIZE;
949 +       case BCMA_CORE_PCIE:
950 +               return 2 * BCMA_CORE_SIZE;
951 +       }
952 +
953         if (core->bus->mapped_core != core)
954                 bcma_host_pci_switch_core(core);
955 +       return 0;
956 +}
957 +
958 +static u8 bcma_host_pci_read8(struct bcma_device *core, u16 offset)
959 +{
960 +       offset += bcma_host_pci_provide_access_to_core(core);
961         return ioread8(core->bus->mmio + offset);
962  }
963  
964  static u16 bcma_host_pci_read16(struct bcma_device *core, u16 offset)
965  {
966 -       if (core->bus->mapped_core != core)
967 -               bcma_host_pci_switch_core(core);
968 +       offset += bcma_host_pci_provide_access_to_core(core);
969         return ioread16(core->bus->mmio + offset);
970  }
971  
972  static u32 bcma_host_pci_read32(struct bcma_device *core, u16 offset)
973  {
974 -       if (core->bus->mapped_core != core)
975 -               bcma_host_pci_switch_core(core);
976 +       offset += bcma_host_pci_provide_access_to_core(core);
977         return ioread32(core->bus->mmio + offset);
978  }
979  
980  static void bcma_host_pci_write8(struct bcma_device *core, u16 offset,
981                                  u8 value)
982  {
983 -       if (core->bus->mapped_core != core)
984 -               bcma_host_pci_switch_core(core);
985 +       offset += bcma_host_pci_provide_access_to_core(core);
986         iowrite8(value, core->bus->mmio + offset);
987  }
988  
989  static void bcma_host_pci_write16(struct bcma_device *core, u16 offset,
990                                  u16 value)
991  {
992 -       if (core->bus->mapped_core != core)
993 -               bcma_host_pci_switch_core(core);
994 +       offset += bcma_host_pci_provide_access_to_core(core);
995         iowrite16(value, core->bus->mmio + offset);
996  }
997  
998  static void bcma_host_pci_write32(struct bcma_device *core, u16 offset,
999                                  u32 value)
1000  {
1001 +       offset += bcma_host_pci_provide_access_to_core(core);
1002 +       iowrite32(value, core->bus->mmio + offset);
1003 +}
1004 +
1005 +#ifdef CONFIG_BCMA_BLOCKIO
1006 +void bcma_host_pci_block_read(struct bcma_device *core, void *buffer,
1007 +                             size_t count, u16 offset, u8 reg_width)
1008 +{
1009 +       void __iomem *addr = core->bus->mmio + offset;
1010         if (core->bus->mapped_core != core)
1011                 bcma_host_pci_switch_core(core);
1012 -       iowrite32(value, core->bus->mmio + offset);
1013 +       switch (reg_width) {
1014 +       case sizeof(u8):
1015 +               ioread8_rep(addr, buffer, count);
1016 +               break;
1017 +       case sizeof(u16):
1018 +               WARN_ON(count & 1);
1019 +               ioread16_rep(addr, buffer, count >> 1);
1020 +               break;
1021 +       case sizeof(u32):
1022 +               WARN_ON(count & 3);
1023 +               ioread32_rep(addr, buffer, count >> 2);
1024 +               break;
1025 +       default:
1026 +               WARN_ON(1);
1027 +       }
1028 +}
1029 +
1030 +void bcma_host_pci_block_write(struct bcma_device *core, const void *buffer,
1031 +                              size_t count, u16 offset, u8 reg_width)
1032 +{
1033 +       void __iomem *addr = core->bus->mmio + offset;
1034 +       if (core->bus->mapped_core != core)
1035 +               bcma_host_pci_switch_core(core);
1036 +       switch (reg_width) {
1037 +       case sizeof(u8):
1038 +               iowrite8_rep(addr, buffer, count);
1039 +               break;
1040 +       case sizeof(u16):
1041 +               WARN_ON(count & 1);
1042 +               iowrite16_rep(addr, buffer, count >> 1);
1043 +               break;
1044 +       case sizeof(u32):
1045 +               WARN_ON(count & 3);
1046 +               iowrite32_rep(addr, buffer, count >> 2);
1047 +               break;
1048 +       default:
1049 +               WARN_ON(1);
1050 +       }
1051  }
1052 +#endif
1053  
1054  static u32 bcma_host_pci_aread32(struct bcma_device *core, u16 offset)
1055  {
1056 @@ -87,6 +146,10 @@ const struct bcma_host_ops bcma_host_pci
1057         .write8         = bcma_host_pci_write8,
1058         .write16        = bcma_host_pci_write16,
1059         .write32        = bcma_host_pci_write32,
1060 +#ifdef CONFIG_BCMA_BLOCKIO
1061 +       .block_read     = bcma_host_pci_block_read,
1062 +       .block_write    = bcma_host_pci_block_write,
1063 +#endif
1064         .aread32        = bcma_host_pci_aread32,
1065         .awrite32       = bcma_host_pci_awrite32,
1066  };
1067 @@ -171,10 +234,46 @@ static void bcma_host_pci_remove(struct
1068         pci_set_drvdata(dev, NULL);
1069  }
1070  
1071 +#ifdef CONFIG_PM
1072 +static int bcma_host_pci_suspend(struct pci_dev *dev, pm_message_t state)
1073 +{
1074 +       /* Host specific */
1075 +       pci_save_state(dev);
1076 +       pci_disable_device(dev);
1077 +       pci_set_power_state(dev, pci_choose_state(dev, state));
1078 +
1079 +       return 0;
1080 +}
1081 +
1082 +static int bcma_host_pci_resume(struct pci_dev *dev)
1083 +{
1084 +       struct bcma_bus *bus = pci_get_drvdata(dev);
1085 +       int err;
1086 +
1087 +       /* Host specific */
1088 +       pci_set_power_state(dev, 0);
1089 +       err = pci_enable_device(dev);
1090 +       if (err)
1091 +               return err;
1092 +       pci_restore_state(dev);
1093 +
1094 +       /* Bus specific */
1095 +       err = bcma_bus_resume(bus);
1096 +       if (err)
1097 +               return err;
1098 +
1099 +       return 0;
1100 +}
1101 +#else /* CONFIG_PM */
1102 +# define bcma_host_pci_suspend NULL
1103 +# define bcma_host_pci_resume  NULL
1104 +#endif /* CONFIG_PM */
1105 +
1106  static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = {
1107         { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) },
1108         { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) },
1109         { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4353) },
1110 +       { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4357) },
1111         { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) },
1112         { 0, },
1113  };
1114 @@ -185,6 +284,8 @@ static struct pci_driver bcma_pci_bridge
1115         .id_table = bcma_pci_bridge_tbl,
1116         .probe = bcma_host_pci_probe,
1117         .remove = bcma_host_pci_remove,
1118 +       .suspend = bcma_host_pci_suspend,
1119 +       .resume = bcma_host_pci_resume,
1120  };
1121  
1122  int __init bcma_host_pci_init(void)
1123 --- /dev/null
1124 +++ b/drivers/bcma/host_soc.c
1125 @@ -0,0 +1,183 @@
1126 +/*
1127 + * Broadcom specific AMBA
1128 + * System on Chip (SoC) Host
1129 + *
1130 + * Licensed under the GNU/GPL. See COPYING for details.
1131 + */
1132 +
1133 +#include "bcma_private.h"
1134 +#include "scan.h"
1135 +#include <linux/bcma/bcma.h>
1136 +#include <linux/bcma/bcma_soc.h>
1137 +
1138 +static u8 bcma_host_soc_read8(struct bcma_device *core, u16 offset)
1139 +{
1140 +       return readb(core->io_addr + offset);
1141 +}
1142 +
1143 +static u16 bcma_host_soc_read16(struct bcma_device *core, u16 offset)
1144 +{
1145 +       return readw(core->io_addr + offset);
1146 +}
1147 +
1148 +static u32 bcma_host_soc_read32(struct bcma_device *core, u16 offset)
1149 +{
1150 +       return readl(core->io_addr + offset);
1151 +}
1152 +
1153 +static void bcma_host_soc_write8(struct bcma_device *core, u16 offset,
1154 +                                u8 value)
1155 +{
1156 +       writeb(value, core->io_addr + offset);
1157 +}
1158 +
1159 +static void bcma_host_soc_write16(struct bcma_device *core, u16 offset,
1160 +                                u16 value)
1161 +{
1162 +       writew(value, core->io_addr + offset);
1163 +}
1164 +
1165 +static void bcma_host_soc_write32(struct bcma_device *core, u16 offset,
1166 +                                u32 value)
1167 +{
1168 +       writel(value, core->io_addr + offset);
1169 +}
1170 +
1171 +#ifdef CONFIG_BCMA_BLOCKIO
1172 +static void bcma_host_soc_block_read(struct bcma_device *core, void *buffer,
1173 +                                    size_t count, u16 offset, u8 reg_width)
1174 +{
1175 +       void __iomem *addr = core->io_addr + offset;
1176 +
1177 +       switch (reg_width) {
1178 +       case sizeof(u8): {
1179 +               u8 *buf = buffer;
1180 +
1181 +               while (count) {
1182 +                       *buf = __raw_readb(addr);
1183 +                       buf++;
1184 +                       count--;
1185 +               }
1186 +               break;
1187 +       }
1188 +       case sizeof(u16): {
1189 +               __le16 *buf = buffer;
1190 +
1191 +               WARN_ON(count & 1);
1192 +               while (count) {
1193 +                       *buf = (__force __le16)__raw_readw(addr);
1194 +                       buf++;
1195 +                       count -= 2;
1196 +               }
1197 +               break;
1198 +       }
1199 +       case sizeof(u32): {
1200 +               __le32 *buf = buffer;
1201 +
1202 +               WARN_ON(count & 3);
1203 +               while (count) {
1204 +                       *buf = (__force __le32)__raw_readl(addr);
1205 +                       buf++;
1206 +                       count -= 4;
1207 +               }
1208 +               break;
1209 +       }
1210 +       default:
1211 +               WARN_ON(1);
1212 +       }
1213 +}
1214 +
1215 +static void bcma_host_soc_block_write(struct bcma_device *core,
1216 +                                     const void *buffer,
1217 +                                     size_t count, u16 offset, u8 reg_width)
1218 +{
1219 +       void __iomem *addr = core->io_addr + offset;
1220 +
1221 +       switch (reg_width) {
1222 +       case sizeof(u8): {
1223 +               const u8 *buf = buffer;
1224 +
1225 +               while (count) {
1226 +                       __raw_writeb(*buf, addr);
1227 +                       buf++;
1228 +                       count--;
1229 +               }
1230 +               break;
1231 +       }
1232 +       case sizeof(u16): {
1233 +               const __le16 *buf = buffer;
1234 +
1235 +               WARN_ON(count & 1);
1236 +               while (count) {
1237 +                       __raw_writew((__force u16)(*buf), addr);
1238 +                       buf++;
1239 +                       count -= 2;
1240 +               }
1241 +               break;
1242 +       }
1243 +       case sizeof(u32): {
1244 +               const __le32 *buf = buffer;
1245 +
1246 +               WARN_ON(count & 3);
1247 +               while (count) {
1248 +                       __raw_writel((__force u32)(*buf), addr);
1249 +                       buf++;
1250 +                       count -= 4;
1251 +               }
1252 +               break;
1253 +       }
1254 +       default:
1255 +               WARN_ON(1);
1256 +       }
1257 +}
1258 +#endif /* CONFIG_BCMA_BLOCKIO */
1259 +
1260 +static u32 bcma_host_soc_aread32(struct bcma_device *core, u16 offset)
1261 +{
1262 +       return readl(core->io_wrap + offset);
1263 +}
1264 +
1265 +static void bcma_host_soc_awrite32(struct bcma_device *core, u16 offset,
1266 +                                 u32 value)
1267 +{
1268 +       writel(value, core->io_wrap + offset);
1269 +}
1270 +
1271 +const struct bcma_host_ops bcma_host_soc_ops = {
1272 +       .read8          = bcma_host_soc_read8,
1273 +       .read16         = bcma_host_soc_read16,
1274 +       .read32         = bcma_host_soc_read32,
1275 +       .write8         = bcma_host_soc_write8,
1276 +       .write16        = bcma_host_soc_write16,
1277 +       .write32        = bcma_host_soc_write32,
1278 +#ifdef CONFIG_BCMA_BLOCKIO
1279 +       .block_read     = bcma_host_soc_block_read,
1280 +       .block_write    = bcma_host_soc_block_write,
1281 +#endif
1282 +       .aread32        = bcma_host_soc_aread32,
1283 +       .awrite32       = bcma_host_soc_awrite32,
1284 +};
1285 +
1286 +int __init bcma_host_soc_register(struct bcma_soc *soc)
1287 +{
1288 +       struct bcma_bus *bus = &soc->bus;
1289 +       int err;
1290 +
1291 +       /* iomap only first core. We have to read some register on this core
1292 +        * to scan the bus.
1293 +        */
1294 +       bus->mmio = ioremap_nocache(BCMA_ADDR_BASE, BCMA_CORE_SIZE * 1);
1295 +       if (!bus->mmio)
1296 +               return -ENOMEM;
1297 +
1298 +       /* Host specific */
1299 +       bus->hosttype = BCMA_HOSTTYPE_SOC;
1300 +       bus->ops = &bcma_host_soc_ops;
1301 +
1302 +       /* Register */
1303 +       err = bcma_bus_early_register(bus, &soc->core_cc, &soc->core_mips);
1304 +       if (err)
1305 +               iounmap(bus->mmio);
1306 +
1307 +       return err;
1308 +}
1309 --- a/drivers/bcma/main.c
1310 +++ b/drivers/bcma/main.c
1311 @@ -6,7 +6,9 @@
1312   */
1313  
1314  #include "bcma_private.h"
1315 +#include <linux/module.h>
1316  #include <linux/bcma/bcma.h>
1317 +#include <linux/slab.h>
1318  
1319  MODULE_DESCRIPTION("Broadcom's specific AMBA driver");
1320  MODULE_LICENSE("GPL");
1321 @@ -14,6 +16,7 @@ MODULE_LICENSE("GPL");
1322  static int bcma_bus_match(struct device *dev, struct device_driver *drv);
1323  static int bcma_device_probe(struct device *dev);
1324  static int bcma_device_remove(struct device *dev);
1325 +static int bcma_device_uevent(struct device *dev, struct kobj_uevent_env *env);
1326  
1327  static ssize_t manuf_show(struct device *dev, struct device_attribute *attr, char *buf)
1328  {
1329 @@ -48,6 +51,7 @@ static struct bus_type bcma_bus_type = {
1330         .match          = bcma_bus_match,
1331         .probe          = bcma_device_probe,
1332         .remove         = bcma_device_remove,
1333 +       .uevent         = bcma_device_uevent,
1334         .dev_attrs      = bcma_device_attrs,
1335  };
1336  
1337 @@ -65,6 +69,10 @@ static struct bcma_device *bcma_find_cor
1338  static void bcma_release_core_dev(struct device *dev)
1339  {
1340         struct bcma_device *core = container_of(dev, struct bcma_device, dev);
1341 +       if (core->io_addr)
1342 +               iounmap(core->io_addr);
1343 +       if (core->io_wrap)
1344 +               iounmap(core->io_wrap);
1345         kfree(core);
1346  }
1347  
1348 @@ -79,6 +87,7 @@ static int bcma_register_cores(struct bc
1349                 case BCMA_CORE_CHIPCOMMON:
1350                 case BCMA_CORE_PCI:
1351                 case BCMA_CORE_PCIE:
1352 +               case BCMA_CORE_MIPS_74K:
1353                         continue;
1354                 }
1355  
1356 @@ -89,8 +98,13 @@ static int bcma_register_cores(struct bc
1357                 switch (bus->hosttype) {
1358                 case BCMA_HOSTTYPE_PCI:
1359                         core->dev.parent = &bus->host_pci->dev;
1360 +                       core->dma_dev = &bus->host_pci->dev;
1361 +                       core->irq = bus->host_pci->irq;
1362 +                       break;
1363 +               case BCMA_HOSTTYPE_SOC:
1364 +                       core->dev.dma_mask = &core->dev.coherent_dma_mask;
1365 +                       core->dma_dev = &core->dev;
1366                         break;
1367 -               case BCMA_HOSTTYPE_NONE:
1368                 case BCMA_HOSTTYPE_SDIO:
1369                         break;
1370                 }
1371 @@ -137,6 +151,13 @@ int bcma_bus_register(struct bcma_bus *b
1372                 bcma_core_chipcommon_init(&bus->drv_cc);
1373         }
1374  
1375 +       /* Init MIPS core */
1376 +       core = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
1377 +       if (core) {
1378 +               bus->drv_mips.core = core;
1379 +               bcma_core_mips_init(&bus->drv_mips);
1380 +       }
1381 +
1382         /* Init PCIE core */
1383         core = bcma_find_core(bus, BCMA_CORE_PCIE);
1384         if (core) {
1385 @@ -144,6 +165,15 @@ int bcma_bus_register(struct bcma_bus *b
1386                 bcma_core_pci_init(&bus->drv_pci);
1387         }
1388  
1389 +       /* Try to get SPROM */
1390 +       err = bcma_sprom_get(bus);
1391 +       if (err == -ENOENT) {
1392 +               pr_err("No SPROM available\n");
1393 +       } else if (err) {
1394 +               pr_err("Failed to get SPROM: %d\n", err);
1395 +               return -ENOENT;
1396 +       }
1397 +
1398         /* Register found cores */
1399         bcma_register_cores(bus);
1400  
1401 @@ -151,13 +181,80 @@ int bcma_bus_register(struct bcma_bus *b
1402  
1403         return 0;
1404  }
1405 -EXPORT_SYMBOL_GPL(bcma_bus_register);
1406  
1407  void bcma_bus_unregister(struct bcma_bus *bus)
1408  {
1409         bcma_unregister_cores(bus);
1410  }
1411 -EXPORT_SYMBOL_GPL(bcma_bus_unregister);
1412 +
1413 +int __init bcma_bus_early_register(struct bcma_bus *bus,
1414 +                                  struct bcma_device *core_cc,
1415 +                                  struct bcma_device *core_mips)
1416 +{
1417 +       int err;
1418 +       struct bcma_device *core;
1419 +       struct bcma_device_id match;
1420 +
1421 +       bcma_init_bus(bus);
1422 +
1423 +       match.manuf = BCMA_MANUF_BCM;
1424 +       match.id = BCMA_CORE_CHIPCOMMON;
1425 +       match.class = BCMA_CL_SIM;
1426 +       match.rev = BCMA_ANY_REV;
1427 +
1428 +       /* Scan for chip common core */
1429 +       err = bcma_bus_scan_early(bus, &match, core_cc);
1430 +       if (err) {
1431 +               pr_err("Failed to scan for common core: %d\n", err);
1432 +               return -1;
1433 +       }
1434 +
1435 +       match.manuf = BCMA_MANUF_MIPS;
1436 +       match.id = BCMA_CORE_MIPS_74K;
1437 +       match.class = BCMA_CL_SIM;
1438 +       match.rev = BCMA_ANY_REV;
1439 +
1440 +       /* Scan for mips core */
1441 +       err = bcma_bus_scan_early(bus, &match, core_mips);
1442 +       if (err) {
1443 +               pr_err("Failed to scan for mips core: %d\n", err);
1444 +               return -1;
1445 +       }
1446 +
1447 +       /* Init CC core */
1448 +       core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON);
1449 +       if (core) {
1450 +               bus->drv_cc.core = core;
1451 +               bcma_core_chipcommon_init(&bus->drv_cc);
1452 +       }
1453 +
1454 +       /* Init MIPS core */
1455 +       core = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
1456 +       if (core) {
1457 +               bus->drv_mips.core = core;
1458 +               bcma_core_mips_init(&bus->drv_mips);
1459 +       }
1460 +
1461 +       pr_info("Early bus registered\n");
1462 +
1463 +       return 0;
1464 +}
1465 +
1466 +#ifdef CONFIG_PM
1467 +int bcma_bus_resume(struct bcma_bus *bus)
1468 +{
1469 +       struct bcma_device *core;
1470 +
1471 +       /* Init CC core */
1472 +       core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON);
1473 +       if (core) {
1474 +               bus->drv_cc.setup_done = false;
1475 +               bcma_core_chipcommon_init(&bus->drv_cc);
1476 +       }
1477 +
1478 +       return 0;
1479 +}
1480 +#endif
1481  
1482  int __bcma_driver_register(struct bcma_driver *drv, struct module *owner)
1483  {
1484 @@ -217,6 +314,16 @@ static int bcma_device_remove(struct dev
1485         return 0;
1486  }
1487  
1488 +static int bcma_device_uevent(struct device *dev, struct kobj_uevent_env *env)
1489 +{
1490 +       struct bcma_device *core = container_of(dev, struct bcma_device, dev);
1491 +
1492 +       return add_uevent_var(env,
1493 +                             "MODALIAS=bcma:m%04Xid%04Xrev%02Xcl%02X",
1494 +                             core->id.manuf, core->id.id,
1495 +                             core->id.rev, core->id.class);
1496 +}
1497 +
1498  static int __init bcma_modinit(void)
1499  {
1500         int err;
1501 --- a/drivers/bcma/scan.c
1502 +++ b/drivers/bcma/scan.c
1503 @@ -200,18 +200,162 @@ static s32 bcma_erom_get_addr_desc(struc
1504         return addrl;
1505  }
1506  
1507 -int bcma_bus_scan(struct bcma_bus *bus)
1508 +static struct bcma_device *bcma_find_core_by_index(struct bcma_bus *bus,
1509 +                                                  u16 index)
1510  {
1511 -       u32 erombase;
1512 -       u32 __iomem *eromptr, *eromend;
1513 +       struct bcma_device *core;
1514  
1515 +       list_for_each_entry(core, &bus->cores, list) {
1516 +               if (core->core_index == index)
1517 +                       return core;
1518 +       }
1519 +       return NULL;
1520 +}
1521 +
1522 +static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
1523 +                             struct bcma_device_id *match, int core_num,
1524 +                             struct bcma_device *core)
1525 +{
1526 +       s32 tmp;
1527 +       u8 i, j;
1528         s32 cia, cib;
1529         u8 ports[2], wrappers[2];
1530  
1531 +       /* get CIs */
1532 +       cia = bcma_erom_get_ci(bus, eromptr);
1533 +       if (cia < 0) {
1534 +               bcma_erom_push_ent(eromptr);
1535 +               if (bcma_erom_is_end(bus, eromptr))
1536 +                       return -ESPIPE;
1537 +               return -EILSEQ;
1538 +       }
1539 +       cib = bcma_erom_get_ci(bus, eromptr);
1540 +       if (cib < 0)
1541 +               return -EILSEQ;
1542 +
1543 +       /* parse CIs */
1544 +       core->id.class = (cia & SCAN_CIA_CLASS) >> SCAN_CIA_CLASS_SHIFT;
1545 +       core->id.id = (cia & SCAN_CIA_ID) >> SCAN_CIA_ID_SHIFT;
1546 +       core->id.manuf = (cia & SCAN_CIA_MANUF) >> SCAN_CIA_MANUF_SHIFT;
1547 +       ports[0] = (cib & SCAN_CIB_NMP) >> SCAN_CIB_NMP_SHIFT;
1548 +       ports[1] = (cib & SCAN_CIB_NSP) >> SCAN_CIB_NSP_SHIFT;
1549 +       wrappers[0] = (cib & SCAN_CIB_NMW) >> SCAN_CIB_NMW_SHIFT;
1550 +       wrappers[1] = (cib & SCAN_CIB_NSW) >> SCAN_CIB_NSW_SHIFT;
1551 +       core->id.rev = (cib & SCAN_CIB_REV) >> SCAN_CIB_REV_SHIFT;
1552 +
1553 +       if (((core->id.manuf == BCMA_MANUF_ARM) &&
1554 +            (core->id.id == 0xFFF)) ||
1555 +           (ports[1] == 0)) {
1556 +               bcma_erom_skip_component(bus, eromptr);
1557 +               return -ENXIO;
1558 +       }
1559 +
1560 +       /* check if component is a core at all */
1561 +       if (wrappers[0] + wrappers[1] == 0) {
1562 +               /* we could save addrl of the router
1563 +               if (cid == BCMA_CORE_OOB_ROUTER)
1564 +                */
1565 +               bcma_erom_skip_component(bus, eromptr);
1566 +               return -ENXIO;
1567 +       }
1568 +
1569 +       if (bcma_erom_is_bridge(bus, eromptr)) {
1570 +               bcma_erom_skip_component(bus, eromptr);
1571 +               return -ENXIO;
1572 +       }
1573 +
1574 +       if (bcma_find_core_by_index(bus, core_num)) {
1575 +               bcma_erom_skip_component(bus, eromptr);
1576 +               return -ENODEV;
1577 +       }
1578 +
1579 +       if (match && ((match->manuf != BCMA_ANY_MANUF &&
1580 +             match->manuf != core->id.manuf) ||
1581 +            (match->id != BCMA_ANY_ID && match->id != core->id.id) ||
1582 +            (match->rev != BCMA_ANY_REV && match->rev != core->id.rev) ||
1583 +            (match->class != BCMA_ANY_CLASS && match->class != core->id.class)
1584 +           )) {
1585 +               bcma_erom_skip_component(bus, eromptr);
1586 +               return -ENODEV;
1587 +       }
1588 +
1589 +       /* get & parse master ports */
1590 +       for (i = 0; i < ports[0]; i++) {
1591 +               s32 mst_port_d = bcma_erom_get_mst_port(bus, eromptr);
1592 +               if (mst_port_d < 0)
1593 +                       return -EILSEQ;
1594 +       }
1595 +
1596 +       /* get & parse slave ports */
1597 +       for (i = 0; i < ports[1]; i++) {
1598 +               for (j = 0; ; j++) {
1599 +                       tmp = bcma_erom_get_addr_desc(bus, eromptr,
1600 +                               SCAN_ADDR_TYPE_SLAVE, i);
1601 +                       if (tmp < 0) {
1602 +                               /* no more entries for port _i_ */
1603 +                               /* pr_debug("erom: slave port %d "
1604 +                                * "has %d descriptors\n", i, j); */
1605 +                               break;
1606 +                       } else {
1607 +                               if (i == 0 && j == 0)
1608 +                                       core->addr = tmp;
1609 +                       }
1610 +               }
1611 +       }
1612 +
1613 +       /* get & parse master wrappers */
1614 +       for (i = 0; i < wrappers[0]; i++) {
1615 +               for (j = 0; ; j++) {
1616 +                       tmp = bcma_erom_get_addr_desc(bus, eromptr,
1617 +                               SCAN_ADDR_TYPE_MWRAP, i);
1618 +                       if (tmp < 0) {
1619 +                               /* no more entries for port _i_ */
1620 +                               /* pr_debug("erom: master wrapper %d "
1621 +                                * "has %d descriptors\n", i, j); */
1622 +                               break;
1623 +                       } else {
1624 +                               if (i == 0 && j == 0)
1625 +                                       core->wrap = tmp;
1626 +                       }
1627 +               }
1628 +       }
1629 +
1630 +       /* get & parse slave wrappers */
1631 +       for (i = 0; i < wrappers[1]; i++) {
1632 +               u8 hack = (ports[1] == 1) ? 0 : 1;
1633 +               for (j = 0; ; j++) {
1634 +                       tmp = bcma_erom_get_addr_desc(bus, eromptr,
1635 +                               SCAN_ADDR_TYPE_SWRAP, i + hack);
1636 +                       if (tmp < 0) {
1637 +                               /* no more entries for port _i_ */
1638 +                               /* pr_debug("erom: master wrapper %d "
1639 +                                * has %d descriptors\n", i, j); */
1640 +                               break;
1641 +                       } else {
1642 +                               if (wrappers[0] == 0 && !i && !j)
1643 +                                       core->wrap = tmp;
1644 +                       }
1645 +               }
1646 +       }
1647 +       if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
1648 +               core->io_addr = ioremap_nocache(core->addr, BCMA_CORE_SIZE);
1649 +               if (!core->io_addr)
1650 +                       return -ENOMEM;
1651 +               core->io_wrap = ioremap_nocache(core->wrap, BCMA_CORE_SIZE);
1652 +               if (!core->io_wrap) {
1653 +                       iounmap(core->io_addr);
1654 +                       return -ENOMEM;
1655 +               }
1656 +       }
1657 +       return 0;
1658 +}
1659 +
1660 +void bcma_init_bus(struct bcma_bus *bus)
1661 +{
1662         s32 tmp;
1663 -       u8 i, j;
1664  
1665 -       int err;
1666 +       if (bus->init_done)
1667 +               return;
1668  
1669         INIT_LIST_HEAD(&bus->cores);
1670         bus->nr_cores = 0;
1671 @@ -222,9 +366,27 @@ int bcma_bus_scan(struct bcma_bus *bus)
1672         bus->chipinfo.id = (tmp & BCMA_CC_ID_ID) >> BCMA_CC_ID_ID_SHIFT;
1673         bus->chipinfo.rev = (tmp & BCMA_CC_ID_REV) >> BCMA_CC_ID_REV_SHIFT;
1674         bus->chipinfo.pkg = (tmp & BCMA_CC_ID_PKG) >> BCMA_CC_ID_PKG_SHIFT;
1675 +       bus->init_done = true;
1676 +}
1677 +
1678 +int bcma_bus_scan(struct bcma_bus *bus)
1679 +{
1680 +       u32 erombase;
1681 +       u32 __iomem *eromptr, *eromend;
1682 +
1683 +       int err, core_num = 0;
1684 +
1685 +       bcma_init_bus(bus);
1686  
1687         erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM);
1688 -       eromptr = bus->mmio;
1689 +       if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
1690 +               eromptr = ioremap_nocache(erombase, BCMA_CORE_SIZE);
1691 +               if (!eromptr)
1692 +                       return -ENOMEM;
1693 +       } else {
1694 +               eromptr = bus->mmio;
1695 +       }
1696 +
1697         eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32);
1698  
1699         bcma_scan_switch_core(bus, erombase);
1700 @@ -236,125 +398,89 @@ int bcma_bus_scan(struct bcma_bus *bus)
1701                 INIT_LIST_HEAD(&core->list);
1702                 core->bus = bus;
1703  
1704 -               /* get CIs */
1705 -               cia = bcma_erom_get_ci(bus, &eromptr);
1706 -               if (cia < 0) {
1707 -                       bcma_erom_push_ent(&eromptr);
1708 -                       if (bcma_erom_is_end(bus, &eromptr))
1709 -                               break;
1710 -                       err= -EILSEQ;
1711 -                       goto out;
1712 -               }
1713 -               cib = bcma_erom_get_ci(bus, &eromptr);
1714 -               if (cib < 0) {
1715 -                       err= -EILSEQ;
1716 -                       goto out;
1717 -               }
1718 -
1719 -               /* parse CIs */
1720 -               core->id.class = (cia & SCAN_CIA_CLASS) >> SCAN_CIA_CLASS_SHIFT;
1721 -               core->id.id = (cia & SCAN_CIA_ID) >> SCAN_CIA_ID_SHIFT;
1722 -               core->id.manuf = (cia & SCAN_CIA_MANUF) >> SCAN_CIA_MANUF_SHIFT;
1723 -               ports[0] = (cib & SCAN_CIB_NMP) >> SCAN_CIB_NMP_SHIFT;
1724 -               ports[1] = (cib & SCAN_CIB_NSP) >> SCAN_CIB_NSP_SHIFT;
1725 -               wrappers[0] = (cib & SCAN_CIB_NMW) >> SCAN_CIB_NMW_SHIFT;
1726 -               wrappers[1] = (cib & SCAN_CIB_NSW) >> SCAN_CIB_NSW_SHIFT;
1727 -               core->id.rev = (cib & SCAN_CIB_REV) >> SCAN_CIB_REV_SHIFT;
1728 -
1729 -               if (((core->id.manuf == BCMA_MANUF_ARM) &&
1730 -                    (core->id.id == 0xFFF)) ||
1731 -                   (ports[1] == 0)) {
1732 -                       bcma_erom_skip_component(bus, &eromptr);
1733 +               err = bcma_get_next_core(bus, &eromptr, NULL, core_num, core);
1734 +               if (err == -ENODEV) {
1735 +                       core_num++;
1736                         continue;
1737 -               }
1738 -
1739 -               /* check if component is a core at all */
1740 -               if (wrappers[0] + wrappers[1] == 0) {
1741 -                       /* we could save addrl of the router
1742 -                       if (cid == BCMA_CORE_OOB_ROUTER)
1743 -                        */
1744 -                       bcma_erom_skip_component(bus, &eromptr);
1745 +               } else if (err == -ENXIO)
1746                         continue;
1747 -               }
1748 +               else if (err == -ESPIPE)
1749 +                       break;
1750 +               else if (err < 0)
1751 +                       return err;
1752  
1753 -               if (bcma_erom_is_bridge(bus, &eromptr)) {
1754 -                       bcma_erom_skip_component(bus, &eromptr);
1755 -                       continue;
1756 -               }
1757 +               core->core_index = core_num++;
1758 +               bus->nr_cores++;
1759  
1760 -               /* get & parse master ports */
1761 -               for (i = 0; i < ports[0]; i++) {
1762 -                       u32 mst_port_d = bcma_erom_get_mst_port(bus, &eromptr);
1763 -                       if (mst_port_d < 0) {
1764 -                               err= -EILSEQ;
1765 -                               goto out;
1766 -                       }
1767 -               }
1768 +               pr_info("Core %d found: %s "
1769 +                       "(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
1770 +                       core->core_index, bcma_device_name(&core->id),
1771 +                       core->id.manuf, core->id.id, core->id.rev,
1772 +                       core->id.class);
1773  
1774 -               /* get & parse slave ports */
1775 -               for (i = 0; i < ports[1]; i++) {
1776 -                       for (j = 0; ; j++) {
1777 -                               tmp = bcma_erom_get_addr_desc(bus, &eromptr,
1778 -                                       SCAN_ADDR_TYPE_SLAVE, i);
1779 -                               if (tmp < 0) {
1780 -                                       /* no more entries for port _i_ */
1781 -                                       /* pr_debug("erom: slave port %d "
1782 -                                        * "has %d descriptors\n", i, j); */
1783 -                                       break;
1784 -                               } else {
1785 -                                       if (i == 0 && j == 0)
1786 -                                               core->addr = tmp;
1787 -                               }
1788 -                       }
1789 -               }
1790 +               list_add(&core->list, &bus->cores);
1791 +       }
1792  
1793 -               /* get & parse master wrappers */
1794 -               for (i = 0; i < wrappers[0]; i++) {
1795 -                       for (j = 0; ; j++) {
1796 -                               tmp = bcma_erom_get_addr_desc(bus, &eromptr,
1797 -                                       SCAN_ADDR_TYPE_MWRAP, i);
1798 -                               if (tmp < 0) {
1799 -                                       /* no more entries for port _i_ */
1800 -                                       /* pr_debug("erom: master wrapper %d "
1801 -                                        * "has %d descriptors\n", i, j); */
1802 -                                       break;
1803 -                               } else {
1804 -                                       if (i == 0 && j == 0)
1805 -                                               core->wrap = tmp;
1806 -                               }
1807 -                       }
1808 -               }
1809 +       if (bus->hosttype == BCMA_HOSTTYPE_SOC)
1810 +               iounmap(eromptr);
1811  
1812 -               /* get & parse slave wrappers */
1813 -               for (i = 0; i < wrappers[1]; i++) {
1814 -                       u8 hack = (ports[1] == 1) ? 0 : 1;
1815 -                       for (j = 0; ; j++) {
1816 -                               tmp = bcma_erom_get_addr_desc(bus, &eromptr,
1817 -                                       SCAN_ADDR_TYPE_SWRAP, i + hack);
1818 -                               if (tmp < 0) {
1819 -                                       /* no more entries for port _i_ */
1820 -                                       /* pr_debug("erom: master wrapper %d "
1821 -                                        * has %d descriptors\n", i, j); */
1822 -                                       break;
1823 -                               } else {
1824 -                                       if (wrappers[0] == 0 && !i && !j)
1825 -                                               core->wrap = tmp;
1826 -                               }
1827 -                       }
1828 -               }
1829 +       return 0;
1830 +}
1831 +
1832 +int __init bcma_bus_scan_early(struct bcma_bus *bus,
1833 +                              struct bcma_device_id *match,
1834 +                              struct bcma_device *core)
1835 +{
1836 +       u32 erombase;
1837 +       u32 __iomem *eromptr, *eromend;
1838  
1839 +       int err = -ENODEV;
1840 +       int core_num = 0;
1841 +
1842 +       erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM);
1843 +       if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
1844 +               eromptr = ioremap_nocache(erombase, BCMA_CORE_SIZE);
1845 +               if (!eromptr)
1846 +                       return -ENOMEM;
1847 +       } else {
1848 +               eromptr = bus->mmio;
1849 +       }
1850 +
1851 +       eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32);
1852 +
1853 +       bcma_scan_switch_core(bus, erombase);
1854 +
1855 +       while (eromptr < eromend) {
1856 +               memset(core, 0, sizeof(*core));
1857 +               INIT_LIST_HEAD(&core->list);
1858 +               core->bus = bus;
1859 +
1860 +               err = bcma_get_next_core(bus, &eromptr, match, core_num, core);
1861 +               if (err == -ENODEV) {
1862 +                       core_num++;
1863 +                       continue;
1864 +               } else if (err == -ENXIO)
1865 +                       continue;
1866 +               else if (err == -ESPIPE)
1867 +                       break;
1868 +               else if (err < 0)
1869 +                       return err;
1870 +
1871 +               core->core_index = core_num++;
1872 +               bus->nr_cores++;
1873                 pr_info("Core %d found: %s "
1874                         "(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
1875 -                       bus->nr_cores, bcma_device_name(&core->id),
1876 +                       core->core_index, bcma_device_name(&core->id),
1877                         core->id.manuf, core->id.id, core->id.rev,
1878                         core->id.class);
1879  
1880 -               core->core_index = bus->nr_cores++;
1881                 list_add(&core->list, &bus->cores);
1882 -               continue;
1883 -out:
1884 -               return err;
1885 +               err = 0;
1886 +               break;
1887         }
1888  
1889 -       return 0;
1890 +       if (bus->hosttype == BCMA_HOSTTYPE_SOC)
1891 +               iounmap(eromptr);
1892 +
1893 +       return err;
1894  }
1895 --- /dev/null
1896 +++ b/drivers/bcma/sprom.c
1897 @@ -0,0 +1,247 @@
1898 +/*
1899 + * Broadcom specific AMBA
1900 + * SPROM reading
1901 + *
1902 + * Licensed under the GNU/GPL. See COPYING for details.
1903 + */
1904 +
1905 +#include "bcma_private.h"
1906 +
1907 +#include <linux/bcma/bcma.h>
1908 +#include <linux/bcma/bcma_regs.h>
1909 +#include <linux/pci.h>
1910 +#include <linux/io.h>
1911 +#include <linux/dma-mapping.h>
1912 +#include <linux/slab.h>
1913 +
1914 +#define SPOFF(offset)  ((offset) / sizeof(u16))
1915 +
1916 +/**************************************************
1917 + * R/W ops.
1918 + **************************************************/
1919 +
1920 +static void bcma_sprom_read(struct bcma_bus *bus, u16 offset, u16 *sprom)
1921 +{
1922 +       int i;
1923 +       for (i = 0; i < SSB_SPROMSIZE_WORDS_R4; i++)
1924 +               sprom[i] = bcma_read16(bus->drv_cc.core,
1925 +                                      offset + (i * 2));
1926 +}
1927 +
1928 +/**************************************************
1929 + * Validation.
1930 + **************************************************/
1931 +
1932 +static inline u8 bcma_crc8(u8 crc, u8 data)
1933 +{
1934 +       /* Polynomial:   x^8 + x^7 + x^6 + x^4 + x^2 + 1   */
1935 +       static const u8 t[] = {
1936 +               0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B,
1937 +               0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21,
1938 +               0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF,
1939 +               0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5,
1940 +               0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14,
1941 +               0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E,
1942 +               0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80,
1943 +               0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA,
1944 +               0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95,
1945 +               0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF,
1946 +               0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01,
1947 +               0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B,
1948 +               0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA,
1949 +               0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0,
1950 +               0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E,
1951 +               0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34,
1952 +               0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0,
1953 +               0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A,
1954 +               0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54,
1955 +               0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E,
1956 +               0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF,
1957 +               0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5,
1958 +               0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B,
1959 +               0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61,
1960 +               0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E,
1961 +               0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74,
1962 +               0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA,
1963 +               0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0,
1964 +               0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41,
1965 +               0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B,
1966 +               0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5,
1967 +               0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F,
1968 +       };
1969 +       return t[crc ^ data];
1970 +}
1971 +
1972 +static u8 bcma_sprom_crc(const u16 *sprom)
1973 +{
1974 +       int word;
1975 +       u8 crc = 0xFF;
1976 +
1977 +       for (word = 0; word < SSB_SPROMSIZE_WORDS_R4 - 1; word++) {
1978 +               crc = bcma_crc8(crc, sprom[word] & 0x00FF);
1979 +               crc = bcma_crc8(crc, (sprom[word] & 0xFF00) >> 8);
1980 +       }
1981 +       crc = bcma_crc8(crc, sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & 0x00FF);
1982 +       crc ^= 0xFF;
1983 +
1984 +       return crc;
1985 +}
1986 +
1987 +static int bcma_sprom_check_crc(const u16 *sprom)
1988 +{
1989 +       u8 crc;
1990 +       u8 expected_crc;
1991 +       u16 tmp;
1992 +
1993 +       crc = bcma_sprom_crc(sprom);
1994 +       tmp = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & SSB_SPROM_REVISION_CRC;
1995 +       expected_crc = tmp >> SSB_SPROM_REVISION_CRC_SHIFT;
1996 +       if (crc != expected_crc)
1997 +               return -EPROTO;
1998 +
1999 +       return 0;
2000 +}
2001 +
2002 +static int bcma_sprom_valid(const u16 *sprom)
2003 +{
2004 +       u16 revision;
2005 +       int err;
2006 +
2007 +       err = bcma_sprom_check_crc(sprom);
2008 +       if (err)
2009 +               return err;
2010 +
2011 +       revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & SSB_SPROM_REVISION_REV;
2012 +       if (revision != 8 && revision != 9) {
2013 +               pr_err("Unsupported SPROM revision: %d\n", revision);
2014 +               return -ENOENT;
2015 +       }
2016 +
2017 +       return 0;
2018 +}
2019 +
2020 +/**************************************************
2021 + * SPROM extraction.
2022 + **************************************************/
2023 +
2024 +static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
2025 +{
2026 +       u16 v;
2027 +       int i;
2028 +
2029 +       bus->sprom.revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] &
2030 +               SSB_SPROM_REVISION_REV;
2031 +
2032 +       for (i = 0; i < 3; i++) {
2033 +               v = sprom[SPOFF(SSB_SPROM8_IL0MAC) + i];
2034 +               *(((__be16 *)bus->sprom.il0mac) + i) = cpu_to_be16(v);
2035 +       }
2036 +
2037 +       bus->sprom.board_rev = sprom[SPOFF(SSB_SPROM8_BOARDREV)];
2038 +
2039 +       bus->sprom.txpid2g[0] = (sprom[SPOFF(SSB_SPROM4_TXPID2G01)] &
2040 +            SSB_SPROM4_TXPID2G0) >> SSB_SPROM4_TXPID2G0_SHIFT;
2041 +       bus->sprom.txpid2g[1] = (sprom[SPOFF(SSB_SPROM4_TXPID2G01)] &
2042 +            SSB_SPROM4_TXPID2G1) >> SSB_SPROM4_TXPID2G1_SHIFT;
2043 +       bus->sprom.txpid2g[2] = (sprom[SPOFF(SSB_SPROM4_TXPID2G23)] &
2044 +            SSB_SPROM4_TXPID2G2) >> SSB_SPROM4_TXPID2G2_SHIFT;
2045 +       bus->sprom.txpid2g[3] = (sprom[SPOFF(SSB_SPROM4_TXPID2G23)] &
2046 +            SSB_SPROM4_TXPID2G3) >> SSB_SPROM4_TXPID2G3_SHIFT;
2047 +
2048 +       bus->sprom.txpid5gl[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL01)] &
2049 +            SSB_SPROM4_TXPID5GL0) >> SSB_SPROM4_TXPID5GL0_SHIFT;
2050 +       bus->sprom.txpid5gl[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL01)] &
2051 +            SSB_SPROM4_TXPID5GL1) >> SSB_SPROM4_TXPID5GL1_SHIFT;
2052 +       bus->sprom.txpid5gl[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL23)] &
2053 +            SSB_SPROM4_TXPID5GL2) >> SSB_SPROM4_TXPID5GL2_SHIFT;
2054 +       bus->sprom.txpid5gl[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL23)] &
2055 +            SSB_SPROM4_TXPID5GL3) >> SSB_SPROM4_TXPID5GL3_SHIFT;
2056 +
2057 +       bus->sprom.txpid5g[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5G01)] &
2058 +            SSB_SPROM4_TXPID5G0) >> SSB_SPROM4_TXPID5G0_SHIFT;
2059 +       bus->sprom.txpid5g[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5G01)] &
2060 +            SSB_SPROM4_TXPID5G1) >> SSB_SPROM4_TXPID5G1_SHIFT;
2061 +       bus->sprom.txpid5g[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5G23)] &
2062 +            SSB_SPROM4_TXPID5G2) >> SSB_SPROM4_TXPID5G2_SHIFT;
2063 +       bus->sprom.txpid5g[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5G23)] &
2064 +            SSB_SPROM4_TXPID5G3) >> SSB_SPROM4_TXPID5G3_SHIFT;
2065 +
2066 +       bus->sprom.txpid5gh[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH01)] &
2067 +            SSB_SPROM4_TXPID5GH0) >> SSB_SPROM4_TXPID5GH0_SHIFT;
2068 +       bus->sprom.txpid5gh[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH01)] &
2069 +            SSB_SPROM4_TXPID5GH1) >> SSB_SPROM4_TXPID5GH1_SHIFT;
2070 +       bus->sprom.txpid5gh[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH23)] &
2071 +            SSB_SPROM4_TXPID5GH2) >> SSB_SPROM4_TXPID5GH2_SHIFT;
2072 +       bus->sprom.txpid5gh[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH23)] &
2073 +            SSB_SPROM4_TXPID5GH3) >> SSB_SPROM4_TXPID5GH3_SHIFT;
2074 +
2075 +       bus->sprom.boardflags_lo = sprom[SPOFF(SSB_SPROM8_BFLLO)];
2076 +       bus->sprom.boardflags_hi = sprom[SPOFF(SSB_SPROM8_BFLHI)];
2077 +       bus->sprom.boardflags2_lo = sprom[SPOFF(SSB_SPROM8_BFL2LO)];
2078 +       bus->sprom.boardflags2_hi = sprom[SPOFF(SSB_SPROM8_BFL2HI)];
2079 +
2080 +       bus->sprom.country_code = sprom[SPOFF(SSB_SPROM8_CCODE)];
2081 +
2082 +       bus->sprom.fem.ghz2.tssipos = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
2083 +               SSB_SROM8_FEM_TSSIPOS) >> SSB_SROM8_FEM_TSSIPOS_SHIFT;
2084 +       bus->sprom.fem.ghz2.extpa_gain = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
2085 +               SSB_SROM8_FEM_EXTPA_GAIN) >> SSB_SROM8_FEM_EXTPA_GAIN_SHIFT;
2086 +       bus->sprom.fem.ghz2.pdet_range = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
2087 +               SSB_SROM8_FEM_PDET_RANGE) >> SSB_SROM8_FEM_PDET_RANGE_SHIFT;
2088 +       bus->sprom.fem.ghz2.tr_iso = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
2089 +               SSB_SROM8_FEM_TR_ISO) >> SSB_SROM8_FEM_TR_ISO_SHIFT;
2090 +       bus->sprom.fem.ghz2.antswlut = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
2091 +               SSB_SROM8_FEM_ANTSWLUT) >> SSB_SROM8_FEM_ANTSWLUT_SHIFT;
2092 +
2093 +       bus->sprom.fem.ghz5.tssipos = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
2094 +               SSB_SROM8_FEM_TSSIPOS) >> SSB_SROM8_FEM_TSSIPOS_SHIFT;
2095 +       bus->sprom.fem.ghz5.extpa_gain = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
2096 +               SSB_SROM8_FEM_EXTPA_GAIN) >> SSB_SROM8_FEM_EXTPA_GAIN_SHIFT;
2097 +       bus->sprom.fem.ghz5.pdet_range = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
2098 +               SSB_SROM8_FEM_PDET_RANGE) >> SSB_SROM8_FEM_PDET_RANGE_SHIFT;
2099 +       bus->sprom.fem.ghz5.tr_iso = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
2100 +               SSB_SROM8_FEM_TR_ISO) >> SSB_SROM8_FEM_TR_ISO_SHIFT;
2101 +       bus->sprom.fem.ghz5.antswlut = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
2102 +               SSB_SROM8_FEM_ANTSWLUT) >> SSB_SROM8_FEM_ANTSWLUT_SHIFT;
2103 +}
2104 +
2105 +int bcma_sprom_get(struct bcma_bus *bus)
2106 +{
2107 +       u16 offset;
2108 +       u16 *sprom;
2109 +       int err = 0;
2110 +
2111 +       if (!bus->drv_cc.core)
2112 +               return -EOPNOTSUPP;
2113 +
2114 +       if (!(bus->drv_cc.capabilities & BCMA_CC_CAP_SPROM))
2115 +               return -ENOENT;
2116 +
2117 +       sprom = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16),
2118 +                       GFP_KERNEL);
2119 +       if (!sprom)
2120 +               return -ENOMEM;
2121 +
2122 +       if (bus->chipinfo.id == 0x4331)
2123 +               bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, false);
2124 +
2125 +       /* Most cards have SPROM moved by additional offset 0x30 (48 dwords).
2126 +        * According to brcm80211 this applies to cards with PCIe rev >= 6
2127 +        * TODO: understand this condition and use it */
2128 +       offset = (bus->chipinfo.id == 0x4331) ? BCMA_CC_SPROM :
2129 +               BCMA_CC_SPROM_PCIE6;
2130 +       bcma_sprom_read(bus, offset, sprom);
2131 +
2132 +       if (bus->chipinfo.id == 0x4331)
2133 +               bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, true);
2134 +
2135 +       err = bcma_sprom_valid(sprom);
2136 +       if (err)
2137 +               goto out;
2138 +
2139 +       bcma_sprom_extract_r8(bus, sprom);
2140 +
2141 +out:
2142 +       kfree(sprom);
2143 +       return err;
2144 +}
2145 --- a/include/linux/bcma/bcma.h
2146 +++ b/include/linux/bcma/bcma.h
2147 @@ -6,6 +6,8 @@
2148  
2149  #include <linux/bcma/bcma_driver_chipcommon.h>
2150  #include <linux/bcma/bcma_driver_pci.h>
2151 +#include <linux/bcma/bcma_driver_mips.h>
2152 +#include <linux/ssb/ssb.h> /* SPROM sharing */
2153  
2154  #include "bcma_regs.h"
2155  
2156 @@ -13,9 +15,9 @@ struct bcma_device;
2157  struct bcma_bus;
2158  
2159  enum bcma_hosttype {
2160 -       BCMA_HOSTTYPE_NONE,
2161         BCMA_HOSTTYPE_PCI,
2162         BCMA_HOSTTYPE_SDIO,
2163 +       BCMA_HOSTTYPE_SOC,
2164  };
2165  
2166  struct bcma_chipinfo {
2167 @@ -24,6 +26,11 @@ struct bcma_chipinfo {
2168         u8 pkg;
2169  };
2170  
2171 +enum bcma_clkmode {
2172 +       BCMA_CLKMODE_FAST,
2173 +       BCMA_CLKMODE_DYNAMIC,
2174 +};
2175 +
2176  struct bcma_host_ops {
2177         u8 (*read8)(struct bcma_device *core, u16 offset);
2178         u16 (*read16)(struct bcma_device *core, u16 offset);
2179 @@ -31,6 +38,12 @@ struct bcma_host_ops {
2180         void (*write8)(struct bcma_device *core, u16 offset, u8 value);
2181         void (*write16)(struct bcma_device *core, u16 offset, u16 value);
2182         void (*write32)(struct bcma_device *core, u16 offset, u32 value);
2183 +#ifdef CONFIG_BCMA_BLOCKIO
2184 +       void (*block_read)(struct bcma_device *core, void *buffer,
2185 +                          size_t count, u16 offset, u8 reg_width);
2186 +       void (*block_write)(struct bcma_device *core, const void *buffer,
2187 +                           size_t count, u16 offset, u8 reg_width);
2188 +#endif
2189         /* Agent ops */
2190         u32 (*aread32)(struct bcma_device *core, u16 offset);
2191         void (*awrite32)(struct bcma_device *core, u16 offset, u32 value);
2192 @@ -117,6 +130,9 @@ struct bcma_device {
2193         struct bcma_device_id id;
2194  
2195         struct device dev;
2196 +       struct device *dma_dev;
2197 +
2198 +       unsigned int irq;
2199         bool dev_registered;
2200  
2201         u8 core_index;
2202 @@ -124,6 +140,9 @@ struct bcma_device {
2203         u32 addr;
2204         u32 wrap;
2205  
2206 +       void __iomem *io_addr;
2207 +       void __iomem *io_wrap;
2208 +
2209         void *drvdata;
2210         struct list_head list;
2211  };
2212 @@ -151,10 +170,9 @@ struct bcma_driver {
2213  };
2214  extern
2215  int __bcma_driver_register(struct bcma_driver *drv, struct module *owner);
2216 -static inline int bcma_driver_register(struct bcma_driver *drv)
2217 -{
2218 -       return __bcma_driver_register(drv, THIS_MODULE);
2219 -}
2220 +#define bcma_driver_register(drv) \
2221 +       __bcma_driver_register(drv, THIS_MODULE)
2222 +
2223  extern void bcma_driver_unregister(struct bcma_driver *drv);
2224  
2225  struct bcma_bus {
2226 @@ -176,49 +194,105 @@ struct bcma_bus {
2227         struct bcma_device *mapped_core;
2228         struct list_head cores;
2229         u8 nr_cores;
2230 +       u8 init_done:1;
2231  
2232         struct bcma_drv_cc drv_cc;
2233         struct bcma_drv_pci drv_pci;
2234 +       struct bcma_drv_mips drv_mips;
2235 +
2236 +       /* We decided to share SPROM struct with SSB as long as we do not need
2237 +        * any hacks for BCMA. This simplifies drivers code. */
2238 +       struct ssb_sprom sprom;
2239  };
2240  
2241 -extern inline u32 bcma_read8(struct bcma_device *core, u16 offset)
2242 +static inline u32 bcma_read8(struct bcma_device *core, u16 offset)
2243  {
2244         return core->bus->ops->read8(core, offset);
2245  }
2246 -extern inline u32 bcma_read16(struct bcma_device *core, u16 offset)
2247 +static inline u32 bcma_read16(struct bcma_device *core, u16 offset)
2248  {
2249         return core->bus->ops->read16(core, offset);
2250  }
2251 -extern inline u32 bcma_read32(struct bcma_device *core, u16 offset)
2252 +static inline u32 bcma_read32(struct bcma_device *core, u16 offset)
2253  {
2254         return core->bus->ops->read32(core, offset);
2255  }
2256 -extern inline
2257 +static inline
2258  void bcma_write8(struct bcma_device *core, u16 offset, u32 value)
2259  {
2260         core->bus->ops->write8(core, offset, value);
2261  }
2262 -extern inline
2263 +static inline
2264  void bcma_write16(struct bcma_device *core, u16 offset, u32 value)
2265  {
2266         core->bus->ops->write16(core, offset, value);
2267  }
2268 -extern inline
2269 +static inline
2270  void bcma_write32(struct bcma_device *core, u16 offset, u32 value)
2271  {
2272         core->bus->ops->write32(core, offset, value);
2273  }
2274 -extern inline u32 bcma_aread32(struct bcma_device *core, u16 offset)
2275 +#ifdef CONFIG_BCMA_BLOCKIO
2276 +static inline void bcma_block_read(struct bcma_device *core, void *buffer,
2277 +                                  size_t count, u16 offset, u8 reg_width)
2278 +{
2279 +       core->bus->ops->block_read(core, buffer, count, offset, reg_width);
2280 +}
2281 +static inline void bcma_block_write(struct bcma_device *core,
2282 +                                   const void *buffer, size_t count,
2283 +                                   u16 offset, u8 reg_width)
2284 +{
2285 +       core->bus->ops->block_write(core, buffer, count, offset, reg_width);
2286 +}
2287 +#endif
2288 +static inline u32 bcma_aread32(struct bcma_device *core, u16 offset)
2289  {
2290         return core->bus->ops->aread32(core, offset);
2291  }
2292 -extern inline
2293 +static inline
2294  void bcma_awrite32(struct bcma_device *core, u16 offset, u32 value)
2295  {
2296         core->bus->ops->awrite32(core, offset, value);
2297  }
2298  
2299 +static inline void bcma_mask32(struct bcma_device *cc, u16 offset, u32 mask)
2300 +{
2301 +       bcma_write32(cc, offset, bcma_read32(cc, offset) & mask);
2302 +}
2303 +static inline void bcma_set32(struct bcma_device *cc, u16 offset, u32 set)
2304 +{
2305 +       bcma_write32(cc, offset, bcma_read32(cc, offset) | set);
2306 +}
2307 +static inline void bcma_maskset32(struct bcma_device *cc,
2308 +                                 u16 offset, u32 mask, u32 set)
2309 +{
2310 +       bcma_write32(cc, offset, (bcma_read32(cc, offset) & mask) | set);
2311 +}
2312 +static inline void bcma_mask16(struct bcma_device *cc, u16 offset, u16 mask)
2313 +{
2314 +       bcma_write16(cc, offset, bcma_read16(cc, offset) & mask);
2315 +}
2316 +static inline void bcma_set16(struct bcma_device *cc, u16 offset, u16 set)
2317 +{
2318 +       bcma_write16(cc, offset, bcma_read16(cc, offset) | set);
2319 +}
2320 +static inline void bcma_maskset16(struct bcma_device *cc,
2321 +                                 u16 offset, u16 mask, u16 set)
2322 +{
2323 +       bcma_write16(cc, offset, (bcma_read16(cc, offset) & mask) | set);
2324 +}
2325 +
2326  extern bool bcma_core_is_enabled(struct bcma_device *core);
2327 +extern void bcma_core_disable(struct bcma_device *core, u32 flags);
2328  extern int bcma_core_enable(struct bcma_device *core, u32 flags);
2329 +extern void bcma_core_set_clockmode(struct bcma_device *core,
2330 +                                   enum bcma_clkmode clkmode);
2331 +extern void bcma_core_pll_ctl(struct bcma_device *core, u32 req, u32 status,
2332 +                             bool on);
2333 +#define BCMA_DMA_TRANSLATION_MASK      0xC0000000
2334 +#define  BCMA_DMA_TRANSLATION_NONE     0x00000000
2335 +#define  BCMA_DMA_TRANSLATION_DMA32_CMT        0x40000000 /* Client Mode Translation for 32-bit DMA */
2336 +#define  BCMA_DMA_TRANSLATION_DMA64_CMT        0x80000000 /* Client Mode Translation for 64-bit DMA */
2337 +extern u32 bcma_core_dma_translation(struct bcma_device *core);
2338  
2339  #endif /* LINUX_BCMA_H_ */
2340 --- a/include/linux/bcma/bcma_driver_chipcommon.h
2341 +++ b/include/linux/bcma/bcma_driver_chipcommon.h
2342 @@ -24,6 +24,7 @@
2343  #define   BCMA_CC_FLASHT_NONE          0x00000000      /* No flash */
2344  #define   BCMA_CC_FLASHT_STSER         0x00000100      /* ST serial flash */
2345  #define   BCMA_CC_FLASHT_ATSER         0x00000200      /* Atmel serial flash */
2346 +#define   BCMA_CC_FLASHT_NFLASH                0x00000200
2347  #define          BCMA_CC_FLASHT_PARA           0x00000700      /* Parallel flash */
2348  #define  BCMA_CC_CAP_PLLT              0x00038000      /* PLL Type */
2349  #define   BCMA_PLLTYPE_NONE            0x00000000
2350 @@ -178,16 +179,9 @@
2351  #define BCMA_CC_PROG_CFG               0x0120
2352  #define BCMA_CC_PROG_WAITCNT           0x0124
2353  #define BCMA_CC_FLASH_CFG              0x0128
2354 +#define  BCMA_CC_FLASH_CFG_DS          0x0010  /* Data size, 0=8bit, 1=16bit */
2355  #define BCMA_CC_FLASH_WAITCNT          0x012C
2356 -#define BCMA_CC_CLKCTLST               0x01E0 /* Clock control and status (rev >= 20) */
2357 -#define  BCMA_CC_CLKCTLST_FORCEALP     0x00000001 /* Force ALP request */
2358 -#define  BCMA_CC_CLKCTLST_FORCEHT      0x00000002 /* Force HT request */
2359 -#define  BCMA_CC_CLKCTLST_FORCEILP     0x00000004 /* Force ILP request */
2360 -#define  BCMA_CC_CLKCTLST_HAVEALPREQ   0x00000008 /* ALP available request */
2361 -#define  BCMA_CC_CLKCTLST_HAVEHTREQ    0x00000010 /* HT available request */
2362 -#define  BCMA_CC_CLKCTLST_HWCROFF      0x00000020 /* Force HW clock request off */
2363 -#define  BCMA_CC_CLKCTLST_HAVEHT       0x00010000 /* HT available */
2364 -#define  BCMA_CC_CLKCTLST_HAVEALP      0x00020000 /* APL available */
2365 +/* 0x1E0 is defined as shared BCMA_CLKCTLST */
2366  #define BCMA_CC_HW_WORKAROUND          0x01E4 /* Hardware workaround (rev >= 20) */
2367  #define BCMA_CC_UART0_DATA             0x0300
2368  #define BCMA_CC_UART0_IMR              0x0304
2369 @@ -209,6 +203,7 @@
2370  #define BCMA_CC_PMU_CTL                        0x0600 /* PMU control */
2371  #define  BCMA_CC_PMU_CTL_ILP_DIV       0xFFFF0000 /* ILP div mask */
2372  #define  BCMA_CC_PMU_CTL_ILP_DIV_SHIFT 16
2373 +#define  BCMA_CC_PMU_CTL_PLL_UPD       0x00000400
2374  #define  BCMA_CC_PMU_CTL_NOILPONW      0x00000200 /* No ILP on wait */
2375  #define  BCMA_CC_PMU_CTL_HTREQEN       0x00000100 /* HT req enable */
2376  #define  BCMA_CC_PMU_CTL_ALPREQEN      0x00000080 /* ALP req enable */
2377 @@ -244,6 +239,66 @@
2378  #define BCMA_CC_REGCTL_DATA            0x065C
2379  #define BCMA_CC_PLLCTL_ADDR            0x0660
2380  #define BCMA_CC_PLLCTL_DATA            0x0664
2381 +#define BCMA_CC_SPROM                  0x0800 /* SPROM beginning */
2382 +#define BCMA_CC_SPROM_PCIE6            0x0830 /* SPROM beginning on PCIe rev >= 6 */
2383 +
2384 +/* Divider allocation in 4716/47162/5356 */
2385 +#define BCMA_CC_PMU5_MAINPLL_CPU       1
2386 +#define BCMA_CC_PMU5_MAINPLL_MEM       2
2387 +#define BCMA_CC_PMU5_MAINPLL_SSB       3
2388 +
2389 +/* PLL usage in 4716/47162 */
2390 +#define BCMA_CC_PMU4716_MAINPLL_PLL0   12
2391 +
2392 +/* PLL usage in 5356/5357 */
2393 +#define BCMA_CC_PMU5356_MAINPLL_PLL0   0
2394 +#define BCMA_CC_PMU5357_MAINPLL_PLL0   0
2395 +
2396 +/* 4706 PMU */
2397 +#define BCMA_CC_PMU4706_MAINPLL_PLL0   0
2398 +
2399 +/* ALP clock on pre-PMU chips */
2400 +#define BCMA_CC_PMU_ALP_CLOCK          20000000
2401 +/* HT clock for systems with PMU-enabled chipcommon */
2402 +#define BCMA_CC_PMU_HT_CLOCK           80000000
2403 +
2404 +/* PMU rev 5 (& 6) */
2405 +#define BCMA_CC_PPL_P1P2_OFF           0
2406 +#define BCMA_CC_PPL_P1_MASK            0x0f000000
2407 +#define BCMA_CC_PPL_P1_SHIFT           24
2408 +#define BCMA_CC_PPL_P2_MASK            0x00f00000
2409 +#define BCMA_CC_PPL_P2_SHIFT           20
2410 +#define BCMA_CC_PPL_M14_OFF            1
2411 +#define BCMA_CC_PPL_MDIV_MASK          0x000000ff
2412 +#define BCMA_CC_PPL_MDIV_WIDTH         8
2413 +#define BCMA_CC_PPL_NM5_OFF            2
2414 +#define BCMA_CC_PPL_NDIV_MASK          0xfff00000
2415 +#define BCMA_CC_PPL_NDIV_SHIFT         20
2416 +#define BCMA_CC_PPL_FMAB_OFF           3
2417 +#define BCMA_CC_PPL_MRAT_MASK          0xf0000000
2418 +#define BCMA_CC_PPL_MRAT_SHIFT         28
2419 +#define BCMA_CC_PPL_ABRAT_MASK         0x08000000
2420 +#define BCMA_CC_PPL_ABRAT_SHIFT                27
2421 +#define BCMA_CC_PPL_FDIV_MASK          0x07ffffff
2422 +#define BCMA_CC_PPL_PLLCTL_OFF         4
2423 +#define BCMA_CC_PPL_PCHI_OFF           5
2424 +#define BCMA_CC_PPL_PCHI_MASK          0x0000003f
2425 +
2426 +/* BCM4331 ChipControl numbers. */
2427 +#define BCMA_CHIPCTL_4331_BT_COEXIST           BIT(0)  /* 0 disable */
2428 +#define BCMA_CHIPCTL_4331_SECI                 BIT(1)  /* 0 SECI is disabled (JATG functional) */
2429 +#define BCMA_CHIPCTL_4331_EXT_LNA              BIT(2)  /* 0 disable */
2430 +#define BCMA_CHIPCTL_4331_SPROM_GPIO13_15      BIT(3)  /* sprom/gpio13-15 mux */
2431 +#define BCMA_CHIPCTL_4331_EXTPA_EN             BIT(4)  /* 0 ext pa disable, 1 ext pa enabled */
2432 +#define BCMA_CHIPCTL_4331_GPIOCLK_ON_SPROMCS   BIT(5)  /* set drive out GPIO_CLK on sprom_cs pin */
2433 +#define BCMA_CHIPCTL_4331_PCIE_MDIO_ON_SPROMCS BIT(6)  /* use sprom_cs pin as PCIE mdio interface */
2434 +#define BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5     BIT(7)  /* aband extpa will be at gpio2/5 and sprom_dout */
2435 +#define BCMA_CHIPCTL_4331_OVR_PIPEAUXCLKEN     BIT(8)  /* override core control on pipe_AuxClkEnable */
2436 +#define BCMA_CHIPCTL_4331_OVR_PIPEAUXPWRDOWN   BIT(9)  /* override core control on pipe_AuxPowerDown */
2437 +#define BCMA_CHIPCTL_4331_PCIE_AUXCLKEN                BIT(10) /* pcie_auxclkenable */
2438 +#define BCMA_CHIPCTL_4331_PCIE_PIPE_PLLDOWN    BIT(11) /* pcie_pipe_pllpowerdown */
2439 +#define BCMA_CHIPCTL_4331_BT_SHD0_ON_GPIO4     BIT(16) /* enable bt_shd0 at gpio4 */
2440 +#define BCMA_CHIPCTL_4331_BT_SHD1_ON_GPIO5     BIT(17) /* enable bt_shd1 at gpio5 */
2441  
2442  /* Data for the PMU, if available.
2443   * Check availability with ((struct bcma_chipcommon)->capabilities & BCMA_CC_CAP_PMU)
2444 @@ -253,14 +308,37 @@ struct bcma_chipcommon_pmu {
2445         u32 crystalfreq;        /* The active crystal frequency (in kHz) */
2446  };
2447  
2448 +#ifdef CONFIG_BCMA_DRIVER_MIPS
2449 +struct bcma_pflash {
2450 +       u8 buswidth;
2451 +       u32 window;
2452 +       u32 window_size;
2453 +};
2454 +
2455 +struct bcma_serial_port {
2456 +       void *regs;
2457 +       unsigned long clockspeed;
2458 +       unsigned int irq;
2459 +       unsigned int baud_base;
2460 +       unsigned int reg_shift;
2461 +};
2462 +#endif /* CONFIG_BCMA_DRIVER_MIPS */
2463 +
2464  struct bcma_drv_cc {
2465         struct bcma_device *core;
2466         u32 status;
2467         u32 capabilities;
2468         u32 capabilities_ext;
2469 +       u8 setup_done:1;
2470         /* Fast Powerup Delay constant */
2471         u16 fast_pwrup_delay;
2472         struct bcma_chipcommon_pmu pmu;
2473 +#ifdef CONFIG_BCMA_DRIVER_MIPS
2474 +       struct bcma_pflash pflash;
2475 +
2476 +       int nr_serial_ports;
2477 +       struct bcma_serial_port serial_ports[4];
2478 +#endif /* CONFIG_BCMA_DRIVER_MIPS */
2479  };
2480  
2481  /* Register access */
2482 @@ -281,6 +359,8 @@ extern void bcma_core_chipcommon_init(st
2483  extern void bcma_chipco_suspend(struct bcma_drv_cc *cc);
2484  extern void bcma_chipco_resume(struct bcma_drv_cc *cc);
2485  
2486 +void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable);
2487 +
2488  extern void bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc,
2489                                           u32 ticks);
2490  
2491 @@ -299,4 +379,13 @@ u32 bcma_chipco_gpio_polarity(struct bcm
2492  /* PMU support */
2493  extern void bcma_pmu_init(struct bcma_drv_cc *cc);
2494  
2495 +extern void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset,
2496 +                                 u32 value);
2497 +extern void bcma_chipco_pll_maskset(struct bcma_drv_cc *cc, u32 offset,
2498 +                                   u32 mask, u32 set);
2499 +extern void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc,
2500 +                                       u32 offset, u32 mask, u32 set);
2501 +extern void bcma_chipco_regctl_maskset(struct bcma_drv_cc *cc,
2502 +                                      u32 offset, u32 mask, u32 set);
2503 +
2504  #endif /* LINUX_BCMA_DRIVER_CC_H_ */
2505 --- /dev/null
2506 +++ b/include/linux/bcma/bcma_driver_mips.h
2507 @@ -0,0 +1,51 @@
2508 +#ifndef LINUX_BCMA_DRIVER_MIPS_H_
2509 +#define LINUX_BCMA_DRIVER_MIPS_H_
2510 +
2511 +#define BCMA_MIPS_IPSFLAG              0x0F08
2512 +/* which sbflags get routed to mips interrupt 1 */
2513 +#define  BCMA_MIPS_IPSFLAG_IRQ1                0x0000003F
2514 +#define  BCMA_MIPS_IPSFLAG_IRQ1_SHIFT  0
2515 +/* which sbflags get routed to mips interrupt 2 */
2516 +#define  BCMA_MIPS_IPSFLAG_IRQ2                0x00003F00
2517 +#define  BCMA_MIPS_IPSFLAG_IRQ2_SHIFT  8
2518 +/* which sbflags get routed to mips interrupt 3 */
2519 +#define  BCMA_MIPS_IPSFLAG_IRQ3                0x003F0000
2520 +#define  BCMA_MIPS_IPSFLAG_IRQ3_SHIFT  16
2521 +/* which sbflags get routed to mips interrupt 4 */
2522 +#define  BCMA_MIPS_IPSFLAG_IRQ4                0x3F000000
2523 +#define  BCMA_MIPS_IPSFLAG_IRQ4_SHIFT  24
2524 +
2525 +/* MIPS 74K core registers */
2526 +#define BCMA_MIPS_MIPS74K_CORECTL      0x0000
2527 +#define BCMA_MIPS_MIPS74K_EXCEPTBASE   0x0004
2528 +#define BCMA_MIPS_MIPS74K_BIST         0x000C
2529 +#define BCMA_MIPS_MIPS74K_INTMASK_INT0 0x0014
2530 +#define BCMA_MIPS_MIPS74K_INTMASK(int) \
2531 +       ((int) * 4 + BCMA_MIPS_MIPS74K_INTMASK_INT0)
2532 +#define BCMA_MIPS_MIPS74K_NMIMASK      0x002C
2533 +#define BCMA_MIPS_MIPS74K_GPIOSEL      0x0040
2534 +#define BCMA_MIPS_MIPS74K_GPIOOUT      0x0044
2535 +#define BCMA_MIPS_MIPS74K_GPIOEN       0x0048
2536 +#define BCMA_MIPS_MIPS74K_CLKCTLST     0x01E0
2537 +
2538 +#define BCMA_MIPS_OOBSELOUTA30         0x100
2539 +
2540 +struct bcma_device;
2541 +
2542 +struct bcma_drv_mips {
2543 +       struct bcma_device *core;
2544 +       u8 setup_done:1;
2545 +       unsigned int assigned_irqs;
2546 +};
2547 +
2548 +#ifdef CONFIG_BCMA_DRIVER_MIPS
2549 +extern void bcma_core_mips_init(struct bcma_drv_mips *mcore);
2550 +#else
2551 +static inline void bcma_core_mips_init(struct bcma_drv_mips *mcore) { }
2552 +#endif
2553 +
2554 +extern u32 bcma_cpu_clock(struct bcma_drv_mips *mcore);
2555 +
2556 +extern unsigned int bcma_core_mips_irq(struct bcma_device *dev);
2557 +
2558 +#endif /* LINUX_BCMA_DRIVER_MIPS_H_ */
2559 --- a/include/linux/bcma/bcma_driver_pci.h
2560 +++ b/include/linux/bcma/bcma_driver_pci.h
2561 @@ -85,5 +85,7 @@ struct bcma_drv_pci {
2562  #define pcicore_write32(pc, offset, val)       bcma_write32((pc)->core, offset, val)
2563  
2564  extern void bcma_core_pci_init(struct bcma_drv_pci *pc);
2565 +extern int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc,
2566 +                                struct bcma_device *core, bool enable);
2567  
2568  #endif /* LINUX_BCMA_DRIVER_PCI_H_ */
2569 --- a/include/linux/bcma/bcma_regs.h
2570 +++ b/include/linux/bcma/bcma_regs.h
2571 @@ -1,13 +1,38 @@
2572  #ifndef LINUX_BCMA_REGS_H_
2573  #define LINUX_BCMA_REGS_H_
2574  
2575 +/* Some single registers are shared between many cores */
2576 +/* BCMA_CLKCTLST: ChipCommon (rev >= 20), PCIe, 80211 */
2577 +#define BCMA_CLKCTLST                  0x01E0 /* Clock control and status */
2578 +#define  BCMA_CLKCTLST_FORCEALP                0x00000001 /* Force ALP request */
2579 +#define  BCMA_CLKCTLST_FORCEHT         0x00000002 /* Force HT request */
2580 +#define  BCMA_CLKCTLST_FORCEILP                0x00000004 /* Force ILP request */
2581 +#define  BCMA_CLKCTLST_HAVEALPREQ      0x00000008 /* ALP available request */
2582 +#define  BCMA_CLKCTLST_HAVEHTREQ       0x00000010 /* HT available request */
2583 +#define  BCMA_CLKCTLST_HWCROFF         0x00000020 /* Force HW clock request off */
2584 +#define  BCMA_CLKCTLST_EXTRESREQ       0x00000700 /* Mask of external resource requests */
2585 +#define  BCMA_CLKCTLST_HAVEALP         0x00010000 /* ALP available */
2586 +#define  BCMA_CLKCTLST_HAVEHT          0x00020000 /* HT available */
2587 +#define  BCMA_CLKCTLST_BP_ON_ALP       0x00040000 /* RO: running on ALP clock */
2588 +#define  BCMA_CLKCTLST_BP_ON_HT                0x00080000 /* RO: running on HT clock */
2589 +#define  BCMA_CLKCTLST_EXTRESST                0x07000000 /* Mask of external resource status */
2590 +/* Is there any BCM4328 on BCMA bus? */
2591 +#define  BCMA_CLKCTLST_4328A0_HAVEHT   0x00010000 /* 4328a0 has reversed bits */
2592 +#define  BCMA_CLKCTLST_4328A0_HAVEALP  0x00020000 /* 4328a0 has reversed bits */
2593 +
2594  /* Agent registers (common for every core) */
2595 -#define BCMA_IOCTL                     0x0408
2596 +#define BCMA_IOCTL                     0x0408 /* IO control */
2597  #define  BCMA_IOCTL_CLK                        0x0001
2598  #define  BCMA_IOCTL_FGC                        0x0002
2599  #define  BCMA_IOCTL_CORE_BITS          0x3FFC
2600  #define  BCMA_IOCTL_PME_EN             0x4000
2601  #define  BCMA_IOCTL_BIST_EN            0x8000
2602 +#define BCMA_IOST                      0x0500 /* IO status */
2603 +#define  BCMA_IOST_CORE_BITS           0x0FFF
2604 +#define  BCMA_IOST_DMA64               0x1000
2605 +#define  BCMA_IOST_GATED_CLK           0x2000
2606 +#define  BCMA_IOST_BIST_ERROR          0x4000
2607 +#define  BCMA_IOST_BIST_DONE           0x8000
2608  #define BCMA_RESET_CTL                 0x0800
2609  #define  BCMA_RESET_CTL_RESET          0x0001
2610  
2611 --- /dev/null
2612 +++ b/include/linux/bcma/bcma_soc.h
2613 @@ -0,0 +1,16 @@
2614 +#ifndef LINUX_BCMA_SOC_H_
2615 +#define LINUX_BCMA_SOC_H_
2616 +
2617 +#include <linux/bcma/bcma.h>
2618 +
2619 +struct bcma_soc {
2620 +       struct bcma_bus bus;
2621 +       struct bcma_device core_cc;
2622 +       struct bcma_device core_mips;
2623 +};
2624 +
2625 +int __init bcma_host_soc_register(struct bcma_soc *soc);
2626 +
2627 +int bcma_bus_register(struct bcma_bus *bus);
2628 +
2629 +#endif /* LINUX_BCMA_SOC_H_ */