kernel: fix DMA error when BCM4331 is connected to BCM4706
[openwrt.git] / target / linux / generic / patches-3.3 / 025-bcma_backport.patch
1 --- a/arch/mips/bcm47xx/serial.c
2 +++ b/arch/mips/bcm47xx/serial.c
3 @@ -62,7 +62,7 @@ static int __init uart8250_init_bcma(voi
4  
5                 p->mapbase = (unsigned int) bcma_port->regs;
6                 p->membase = (void *) bcma_port->regs;
7 -               p->irq = bcma_port->irq + 2;
8 +               p->irq = bcma_port->irq;
9                 p->uartclk = bcma_port->baud_base;
10                 p->regshift = bcma_port->reg_shift;
11                 p->iotype = UPIO_MEM;
12 --- a/drivers/bcma/Kconfig
13 +++ b/drivers/bcma/Kconfig
14 @@ -26,10 +26,11 @@ config BCMA_HOST_PCI_POSSIBLE
15  config BCMA_HOST_PCI
16         bool "Support for BCMA on PCI-host bus"
17         depends on BCMA_HOST_PCI_POSSIBLE
18 +       default y
19  
20  config BCMA_DRIVER_PCI_HOSTMODE
21         bool "Driver for PCI core working in hostmode"
22 -       depends on BCMA && MIPS
23 +       depends on BCMA && MIPS && BCMA_HOST_PCI
24         help
25           PCI core hostmode operation (external PCI bus).
26  
27 @@ -46,6 +47,33 @@ config BCMA_DRIVER_MIPS
28  
29           If unsure, say N
30  
31 +config BCMA_SFLASH
32 +       bool
33 +       depends on BCMA_DRIVER_MIPS
34 +       default y
35 +
36 +config BCMA_NFLASH
37 +       bool
38 +       depends on BCMA_DRIVER_MIPS
39 +       default y
40 +
41 +config BCMA_DRIVER_GMAC_CMN
42 +       bool "BCMA Broadcom GBIT MAC COMMON core driver"
43 +       depends on BCMA
44 +       help
45 +         Driver for the Broadcom GBIT MAC COMMON core attached to Broadcom
46 +         specific Advanced Microcontroller Bus.
47 +
48 +         If unsure, say N
49 +
50 +config BCMA_DRIVER_GPIO
51 +       bool "BCMA GPIO driver"
52 +       depends on BCMA && GPIOLIB
53 +       help
54 +         Driver to provide access to the GPIO pins of the bcma bus.
55 +
56 +         If unsure, say N
57 +
58  config BCMA_DEBUG
59         bool "BCMA debugging"
60         depends on BCMA
61 --- a/drivers/bcma/Makefile
62 +++ b/drivers/bcma/Makefile
63 @@ -1,8 +1,12 @@
64  bcma-y                                 += main.o scan.o core.o sprom.o
65  bcma-y                                 += driver_chipcommon.o driver_chipcommon_pmu.o
66 +bcma-$(CONFIG_BCMA_SFLASH)             += driver_chipcommon_sflash.o
67 +bcma-$(CONFIG_BCMA_NFLASH)             += driver_chipcommon_nflash.o
68  bcma-y                                 += driver_pci.o
69  bcma-$(CONFIG_BCMA_DRIVER_PCI_HOSTMODE)        += driver_pci_host.o
70  bcma-$(CONFIG_BCMA_DRIVER_MIPS)                += driver_mips.o
71 +bcma-$(CONFIG_BCMA_DRIVER_GMAC_CMN)    += driver_gmac_cmn.o
72 +bcma-$(CONFIG_BCMA_DRIVER_GPIO)                += driver_gpio.o
73  bcma-$(CONFIG_BCMA_HOST_PCI)           += host_pci.o
74  bcma-$(CONFIG_BCMA_HOST_SOC)           += host_soc.o
75  obj-$(CONFIG_BCMA)                     += bcma.o
76 --- a/drivers/bcma/bcma_private.h
77 +++ b/drivers/bcma/bcma_private.h
78 @@ -10,10 +10,21 @@
79  
80  #define BCMA_CORE_SIZE         0x1000
81  
82 +#define bcma_err(bus, fmt, ...) \
83 +       pr_err("bus%d: " fmt, (bus)->num, ##__VA_ARGS__)
84 +#define bcma_warn(bus, fmt, ...) \
85 +       pr_warn("bus%d: " fmt, (bus)->num, ##__VA_ARGS__)
86 +#define bcma_info(bus, fmt, ...) \
87 +       pr_info("bus%d: " fmt, (bus)->num, ##__VA_ARGS__)
88 +#define bcma_debug(bus, fmt, ...) \
89 +       pr_debug("bus%d: " fmt, (bus)->num, ##__VA_ARGS__)
90 +
91  struct bcma_bus;
92  
93  /* main.c */
94 -int bcma_bus_register(struct bcma_bus *bus);
95 +bool bcma_wait_value(struct bcma_device *core, u16 reg, u32 mask, u32 value,
96 +                    int timeout);
97 +int __devinit bcma_bus_register(struct bcma_bus *bus);
98  void bcma_bus_unregister(struct bcma_bus *bus);
99  int __init bcma_bus_early_register(struct bcma_bus *bus,
100                                    struct bcma_device *core_cc,
101 @@ -22,6 +33,8 @@ int __init bcma_bus_early_register(struc
102  int bcma_bus_suspend(struct bcma_bus *bus);
103  int bcma_bus_resume(struct bcma_bus *bus);
104  #endif
105 +struct bcma_device *bcma_find_core_unit(struct bcma_bus *bus, u16 coreid,
106 +                                       u8 unit);
107  
108  /* scan.c */
109  int bcma_bus_scan(struct bcma_bus *bus);
110 @@ -36,11 +49,36 @@ int bcma_sprom_get(struct bcma_bus *bus)
111  /* driver_chipcommon.c */
112  #ifdef CONFIG_BCMA_DRIVER_MIPS
113  void bcma_chipco_serial_init(struct bcma_drv_cc *cc);
114 +extern struct platform_device bcma_pflash_dev;
115  #endif /* CONFIG_BCMA_DRIVER_MIPS */
116  
117  /* driver_chipcommon_pmu.c */
118 -u32 bcma_pmu_alp_clock(struct bcma_drv_cc *cc);
119 -u32 bcma_pmu_get_clockcpu(struct bcma_drv_cc *cc);
120 +u32 bcma_pmu_get_alp_clock(struct bcma_drv_cc *cc);
121 +u32 bcma_pmu_get_cpu_clock(struct bcma_drv_cc *cc);
122 +
123 +#ifdef CONFIG_BCMA_SFLASH
124 +/* driver_chipcommon_sflash.c */
125 +int bcma_sflash_init(struct bcma_drv_cc *cc);
126 +extern struct platform_device bcma_sflash_dev;
127 +#else
128 +static inline int bcma_sflash_init(struct bcma_drv_cc *cc)
129 +{
130 +       bcma_err(cc->core->bus, "Serial flash not supported\n");
131 +       return 0;
132 +}
133 +#endif /* CONFIG_BCMA_SFLASH */
134 +
135 +#ifdef CONFIG_BCMA_NFLASH
136 +/* driver_chipcommon_nflash.c */
137 +int bcma_nflash_init(struct bcma_drv_cc *cc);
138 +extern struct platform_device bcma_nflash_dev;
139 +#else
140 +static inline int bcma_nflash_init(struct bcma_drv_cc *cc)
141 +{
142 +       bcma_err(cc->core->bus, "NAND flash not supported\n");
143 +       return 0;
144 +}
145 +#endif /* CONFIG_BCMA_NFLASH */
146  
147  #ifdef CONFIG_BCMA_HOST_PCI
148  /* host_pci.c */
149 @@ -48,8 +86,29 @@ extern int __init bcma_host_pci_init(voi
150  extern void __exit bcma_host_pci_exit(void);
151  #endif /* CONFIG_BCMA_HOST_PCI */
152  
153 +/* driver_pci.c */
154 +u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address);
155 +
156 +extern int bcma_chipco_watchdog_register(struct bcma_drv_cc *cc);
157 +
158  #ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
159 -void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc);
160 +bool __devinit bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc);
161 +void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc);
162  #endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */
163  
164 +#ifdef CONFIG_BCMA_DRIVER_GPIO
165 +/* driver_gpio.c */
166 +int bcma_gpio_init(struct bcma_drv_cc *cc);
167 +int bcma_gpio_unregister(struct bcma_drv_cc *cc);
168 +#else
169 +static inline int bcma_gpio_init(struct bcma_drv_cc *cc)
170 +{
171 +       return -ENOTSUPP;
172 +}
173 +static inline int bcma_gpio_unregister(struct bcma_drv_cc *cc)
174 +{
175 +       return 0;
176 +}
177 +#endif /* CONFIG_BCMA_DRIVER_GPIO */
178 +
179  #endif
180 --- a/drivers/bcma/core.c
181 +++ b/drivers/bcma/core.c
182 @@ -9,6 +9,25 @@
183  #include <linux/export.h>
184  #include <linux/bcma/bcma.h>
185  
186 +static bool bcma_core_wait_value(struct bcma_device *core, u16 reg, u32 mask,
187 +                                u32 value, int timeout)
188 +{
189 +       unsigned long deadline = jiffies + timeout;
190 +       u32 val;
191 +
192 +       do {
193 +               val = bcma_aread32(core, reg);
194 +               if ((val & mask) == value)
195 +                       return true;
196 +               cpu_relax();
197 +               udelay(10);
198 +       } while (!time_after_eq(jiffies, deadline));
199 +
200 +       bcma_warn(core->bus, "Timeout waiting for register 0x%04X!\n", reg);
201 +
202 +       return false;
203 +}
204 +
205  bool bcma_core_is_enabled(struct bcma_device *core)
206  {
207         if ((bcma_aread32(core, BCMA_IOCTL) & (BCMA_IOCTL_CLK | BCMA_IOCTL_FGC))
208 @@ -25,12 +44,15 @@ void bcma_core_disable(struct bcma_devic
209         if (bcma_aread32(core, BCMA_RESET_CTL) & BCMA_RESET_CTL_RESET)
210                 return;
211  
212 -       bcma_awrite32(core, BCMA_IOCTL, flags);
213 -       bcma_aread32(core, BCMA_IOCTL);
214 -       udelay(10);
215 +       bcma_core_wait_value(core, BCMA_RESET_ST, ~0, 0, 300);
216  
217         bcma_awrite32(core, BCMA_RESET_CTL, BCMA_RESET_CTL_RESET);
218 +       bcma_aread32(core, BCMA_RESET_CTL);
219         udelay(1);
220 +
221 +       bcma_awrite32(core, BCMA_IOCTL, flags);
222 +       bcma_aread32(core, BCMA_IOCTL);
223 +       udelay(10);
224  }
225  EXPORT_SYMBOL_GPL(bcma_core_disable);
226  
227 @@ -42,6 +64,7 @@ int bcma_core_enable(struct bcma_device
228         bcma_aread32(core, BCMA_IOCTL);
229  
230         bcma_awrite32(core, BCMA_RESET_CTL, 0);
231 +       bcma_aread32(core, BCMA_RESET_CTL);
232         udelay(1);
233  
234         bcma_awrite32(core, BCMA_IOCTL, (BCMA_IOCTL_CLK | flags));
235 @@ -64,7 +87,7 @@ void bcma_core_set_clockmode(struct bcma
236         switch (clkmode) {
237         case BCMA_CLKMODE_FAST:
238                 bcma_set32(core, BCMA_CLKCTLST, BCMA_CLKCTLST_FORCEHT);
239 -               udelay(64);
240 +               usleep_range(64, 300);
241                 for (i = 0; i < 1500; i++) {
242                         if (bcma_read32(core, BCMA_CLKCTLST) &
243                             BCMA_CLKCTLST_HAVEHT) {
244 @@ -74,10 +97,10 @@ void bcma_core_set_clockmode(struct bcma
245                         udelay(10);
246                 }
247                 if (i)
248 -                       pr_err("HT force timeout\n");
249 +                       bcma_err(core->bus, "HT force timeout\n");
250                 break;
251         case BCMA_CLKMODE_DYNAMIC:
252 -               pr_warn("Dynamic clockmode not supported yet!\n");
253 +               bcma_set32(core, BCMA_CLKCTLST, ~BCMA_CLKCTLST_FORCEHT);
254                 break;
255         }
256  }
257 @@ -101,9 +124,15 @@ void bcma_core_pll_ctl(struct bcma_devic
258                         udelay(10);
259                 }
260                 if (i)
261 -                       pr_err("PLL enable timeout\n");
262 +                       bcma_err(core->bus, "PLL enable timeout\n");
263         } else {
264 -               pr_warn("Disabling PLL not supported yet!\n");
265 +               /*
266 +                * Mask the PLL but don't wait for it to be disabled. PLL may be
267 +                * shared between cores and will be still up if there is another
268 +                * core using it.
269 +                */
270 +               bcma_mask32(core, BCMA_CLKCTLST, ~req);
271 +               bcma_read32(core, BCMA_CLKCTLST);
272         }
273  }
274  EXPORT_SYMBOL_GPL(bcma_core_pll_ctl);
275 @@ -119,8 +148,8 @@ u32 bcma_core_dma_translation(struct bcm
276                 else
277                         return BCMA_DMA_TRANSLATION_DMA32_CMT;
278         default:
279 -               pr_err("DMA translation unknown for host %d\n",
280 -                      core->bus->hosttype);
281 +               bcma_err(core->bus, "DMA translation unknown for host %d\n",
282 +                        core->bus->hosttype);
283         }
284         return BCMA_DMA_TRANSLATION_NONE;
285  }
286 --- a/drivers/bcma/driver_chipcommon.c
287 +++ b/drivers/bcma/driver_chipcommon.c
288 @@ -4,12 +4,15 @@
289   *
290   * Copyright 2005, Broadcom Corporation
291   * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
292 + * Copyright 2012, Hauke Mehrtens <hauke@hauke-m.de>
293   *
294   * Licensed under the GNU/GPL. See COPYING for details.
295   */
296  
297  #include "bcma_private.h"
298 +#include <linux/bcm47xx_wdt.h>
299  #include <linux/export.h>
300 +#include <linux/platform_device.h>
301  #include <linux/bcma/bcma.h>
302  
303  static inline u32 bcma_cc_write32_masked(struct bcma_drv_cc *cc, u16 offset,
304 @@ -22,29 +25,136 @@ static inline u32 bcma_cc_write32_masked
305         return value;
306  }
307  
308 -void bcma_core_chipcommon_init(struct bcma_drv_cc *cc)
309 +u32 bcma_chipco_get_alp_clock(struct bcma_drv_cc *cc)
310  {
311 -       u32 leddc_on = 10;
312 -       u32 leddc_off = 90;
313 +       if (cc->capabilities & BCMA_CC_CAP_PMU)
314 +               return bcma_pmu_get_alp_clock(cc);
315  
316 -       if (cc->setup_done)
317 +       return 20000000;
318 +}
319 +EXPORT_SYMBOL_GPL(bcma_chipco_get_alp_clock);
320 +
321 +static u32 bcma_chipco_watchdog_get_max_timer(struct bcma_drv_cc *cc)
322 +{
323 +       struct bcma_bus *bus = cc->core->bus;
324 +       u32 nb;
325 +
326 +       if (cc->capabilities & BCMA_CC_CAP_PMU) {
327 +               if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4706)
328 +                       nb = 32;
329 +               else if (cc->core->id.rev < 26)
330 +                       nb = 16;
331 +               else
332 +                       nb = (cc->core->id.rev >= 37) ? 32 : 24;
333 +       } else {
334 +               nb = 28;
335 +       }
336 +       if (nb == 32)
337 +               return 0xffffffff;
338 +       else
339 +               return (1 << nb) - 1;
340 +}
341 +
342 +static u32 bcma_chipco_watchdog_timer_set_wdt(struct bcm47xx_wdt *wdt,
343 +                                             u32 ticks)
344 +{
345 +       struct bcma_drv_cc *cc = bcm47xx_wdt_get_drvdata(wdt);
346 +
347 +       return bcma_chipco_watchdog_timer_set(cc, ticks);
348 +}
349 +
350 +static u32 bcma_chipco_watchdog_timer_set_ms_wdt(struct bcm47xx_wdt *wdt,
351 +                                                u32 ms)
352 +{
353 +       struct bcma_drv_cc *cc = bcm47xx_wdt_get_drvdata(wdt);
354 +       u32 ticks;
355 +
356 +       ticks = bcma_chipco_watchdog_timer_set(cc, cc->ticks_per_ms * ms);
357 +       return ticks / cc->ticks_per_ms;
358 +}
359 +
360 +static int bcma_chipco_watchdog_ticks_per_ms(struct bcma_drv_cc *cc)
361 +{
362 +       struct bcma_bus *bus = cc->core->bus;
363 +
364 +       if (cc->capabilities & BCMA_CC_CAP_PMU) {
365 +               if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4706)
366 +                       /* 4706 CC and PMU watchdogs are clocked at 1/4 of ALP clock */
367 +                       return bcma_chipco_get_alp_clock(cc) / 4000;
368 +               else
369 +                       /* based on 32KHz ILP clock */
370 +                       return 32;
371 +       } else {
372 +               return bcma_chipco_get_alp_clock(cc) / 1000;
373 +       }
374 +}
375 +
376 +int bcma_chipco_watchdog_register(struct bcma_drv_cc *cc)
377 +{
378 +       struct bcm47xx_wdt wdt = {};
379 +       struct platform_device *pdev;
380 +
381 +       wdt.driver_data = cc;
382 +       wdt.timer_set = bcma_chipco_watchdog_timer_set_wdt;
383 +       wdt.timer_set_ms = bcma_chipco_watchdog_timer_set_ms_wdt;
384 +       wdt.max_timer_ms = bcma_chipco_watchdog_get_max_timer(cc) / cc->ticks_per_ms;
385 +
386 +       pdev = platform_device_register_data(NULL, "bcm47xx-wdt",
387 +                                            cc->core->bus->num, &wdt,
388 +                                            sizeof(wdt));
389 +       if (IS_ERR(pdev))
390 +               return PTR_ERR(pdev);
391 +
392 +       cc->watchdog = pdev;
393 +
394 +       return 0;
395 +}
396 +
397 +void bcma_core_chipcommon_early_init(struct bcma_drv_cc *cc)
398 +{
399 +       if (cc->early_setup_done)
400                 return;
401  
402 +       spin_lock_init(&cc->gpio_lock);
403 +
404         if (cc->core->id.rev >= 11)
405                 cc->status = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
406         cc->capabilities = bcma_cc_read32(cc, BCMA_CC_CAP);
407         if (cc->core->id.rev >= 35)
408                 cc->capabilities_ext = bcma_cc_read32(cc, BCMA_CC_CAP_EXT);
409  
410 +       if (cc->capabilities & BCMA_CC_CAP_PMU)
411 +               bcma_pmu_early_init(cc);
412 +
413 +       cc->early_setup_done = true;
414 +}
415 +
416 +void bcma_core_chipcommon_init(struct bcma_drv_cc *cc)
417 +{
418 +       u32 leddc_on = 10;
419 +       u32 leddc_off = 90;
420 +
421 +       if (cc->setup_done)
422 +               return;
423 +
424 +       bcma_core_chipcommon_early_init(cc);
425 +
426         if (cc->core->id.rev >= 20) {
427 -               bcma_cc_write32(cc, BCMA_CC_GPIOPULLUP, 0);
428 -               bcma_cc_write32(cc, BCMA_CC_GPIOPULLDOWN, 0);
429 +               u32 pullup = 0, pulldown = 0;
430 +
431 +               if (cc->core->bus->chipinfo.id == BCMA_CHIP_ID_BCM43142) {
432 +                       pullup = 0x402e0;
433 +                       pulldown = 0x20500;
434 +               }
435 +
436 +               bcma_cc_write32(cc, BCMA_CC_GPIOPULLUP, pullup);
437 +               bcma_cc_write32(cc, BCMA_CC_GPIOPULLDOWN, pulldown);
438         }
439  
440         if (cc->capabilities & BCMA_CC_CAP_PMU)
441                 bcma_pmu_init(cc);
442         if (cc->capabilities & BCMA_CC_CAP_PCTL)
443 -               pr_err("Power control not implemented!\n");
444 +               bcma_err(cc->core->bus, "Power control not implemented!\n");
445  
446         if (cc->core->id.rev >= 16) {
447                 if (cc->core->bus->sprom.leddc_on_time &&
448 @@ -56,15 +166,33 @@ void bcma_core_chipcommon_init(struct bc
449                         ((leddc_on << BCMA_CC_GPIOTIMER_ONTIME_SHIFT) |
450                          (leddc_off << BCMA_CC_GPIOTIMER_OFFTIME_SHIFT)));
451         }
452 +       cc->ticks_per_ms = bcma_chipco_watchdog_ticks_per_ms(cc);
453  
454         cc->setup_done = true;
455  }
456  
457  /* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */
458 -void bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc, u32 ticks)
459 +u32 bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc, u32 ticks)
460  {
461 -       /* instant NMI */
462 -       bcma_cc_write32(cc, BCMA_CC_WATCHDOG, ticks);
463 +       u32 maxt;
464 +       enum bcma_clkmode clkmode;
465 +
466 +       maxt = bcma_chipco_watchdog_get_max_timer(cc);
467 +       if (cc->capabilities & BCMA_CC_CAP_PMU) {
468 +               if (ticks == 1)
469 +                       ticks = 2;
470 +               else if (ticks > maxt)
471 +                       ticks = maxt;
472 +               bcma_cc_write32(cc, BCMA_CC_PMU_WATCHDOG, ticks);
473 +       } else {
474 +               clkmode = ticks ? BCMA_CLKMODE_FAST : BCMA_CLKMODE_DYNAMIC;
475 +               bcma_core_set_clockmode(cc->core, clkmode);
476 +               if (ticks > maxt)
477 +                       ticks = maxt;
478 +               /* instant NMI */
479 +               bcma_cc_write32(cc, BCMA_CC_WATCHDOG, ticks);
480 +       }
481 +       return ticks;
482  }
483  
484  void bcma_chipco_irq_mask(struct bcma_drv_cc *cc, u32 mask, u32 value)
485 @@ -84,28 +212,99 @@ u32 bcma_chipco_gpio_in(struct bcma_drv_
486  
487  u32 bcma_chipco_gpio_out(struct bcma_drv_cc *cc, u32 mask, u32 value)
488  {
489 -       return bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUT, mask, value);
490 +       unsigned long flags;
491 +       u32 res;
492 +
493 +       spin_lock_irqsave(&cc->gpio_lock, flags);
494 +       res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUT, mask, value);
495 +       spin_unlock_irqrestore(&cc->gpio_lock, flags);
496 +
497 +       return res;
498  }
499 +EXPORT_SYMBOL_GPL(bcma_chipco_gpio_out);
500  
501  u32 bcma_chipco_gpio_outen(struct bcma_drv_cc *cc, u32 mask, u32 value)
502  {
503 -       return bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUTEN, mask, value);
504 +       unsigned long flags;
505 +       u32 res;
506 +
507 +       spin_lock_irqsave(&cc->gpio_lock, flags);
508 +       res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUTEN, mask, value);
509 +       spin_unlock_irqrestore(&cc->gpio_lock, flags);
510 +
511 +       return res;
512  }
513 +EXPORT_SYMBOL_GPL(bcma_chipco_gpio_outen);
514  
515 +/*
516 + * If the bit is set to 0, chipcommon controlls this GPIO,
517 + * if the bit is set to 1, it is used by some part of the chip and not our code.
518 + */
519  u32 bcma_chipco_gpio_control(struct bcma_drv_cc *cc, u32 mask, u32 value)
520  {
521 -       return bcma_cc_write32_masked(cc, BCMA_CC_GPIOCTL, mask, value);
522 +       unsigned long flags;
523 +       u32 res;
524 +
525 +       spin_lock_irqsave(&cc->gpio_lock, flags);
526 +       res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOCTL, mask, value);
527 +       spin_unlock_irqrestore(&cc->gpio_lock, flags);
528 +
529 +       return res;
530  }
531  EXPORT_SYMBOL_GPL(bcma_chipco_gpio_control);
532  
533  u32 bcma_chipco_gpio_intmask(struct bcma_drv_cc *cc, u32 mask, u32 value)
534  {
535 -       return bcma_cc_write32_masked(cc, BCMA_CC_GPIOIRQ, mask, value);
536 +       unsigned long flags;
537 +       u32 res;
538 +
539 +       spin_lock_irqsave(&cc->gpio_lock, flags);
540 +       res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOIRQ, mask, value);
541 +       spin_unlock_irqrestore(&cc->gpio_lock, flags);
542 +
543 +       return res;
544  }
545  
546  u32 bcma_chipco_gpio_polarity(struct bcma_drv_cc *cc, u32 mask, u32 value)
547  {
548 -       return bcma_cc_write32_masked(cc, BCMA_CC_GPIOPOL, mask, value);
549 +       unsigned long flags;
550 +       u32 res;
551 +
552 +       spin_lock_irqsave(&cc->gpio_lock, flags);
553 +       res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOPOL, mask, value);
554 +       spin_unlock_irqrestore(&cc->gpio_lock, flags);
555 +
556 +       return res;
557 +}
558 +
559 +u32 bcma_chipco_gpio_pullup(struct bcma_drv_cc *cc, u32 mask, u32 value)
560 +{
561 +       unsigned long flags;
562 +       u32 res;
563 +
564 +       if (cc->core->id.rev < 20)
565 +               return 0;
566 +
567 +       spin_lock_irqsave(&cc->gpio_lock, flags);
568 +       res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOPULLUP, mask, value);
569 +       spin_unlock_irqrestore(&cc->gpio_lock, flags);
570 +
571 +       return res;
572 +}
573 +
574 +u32 bcma_chipco_gpio_pulldown(struct bcma_drv_cc *cc, u32 mask, u32 value)
575 +{
576 +       unsigned long flags;
577 +       u32 res;
578 +
579 +       if (cc->core->id.rev < 20)
580 +               return 0;
581 +
582 +       spin_lock_irqsave(&cc->gpio_lock, flags);
583 +       res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOPULLDOWN, mask, value);
584 +       spin_unlock_irqrestore(&cc->gpio_lock, flags);
585 +
586 +       return res;
587  }
588  
589  #ifdef CONFIG_BCMA_DRIVER_MIPS
590 @@ -118,8 +317,7 @@ void bcma_chipco_serial_init(struct bcma
591         struct bcma_serial_port *ports = cc->serial_ports;
592  
593         if (ccrev >= 11 && ccrev != 15) {
594 -               /* Fixed ALP clock */
595 -               baud_base = bcma_pmu_alp_clock(cc);
596 +               baud_base = bcma_chipco_get_alp_clock(cc);
597                 if (ccrev >= 21) {
598                         /* Turn off UART clock before switching clocksource. */
599                         bcma_cc_write32(cc, BCMA_CC_CORECTL,
600 @@ -137,12 +335,11 @@ void bcma_chipco_serial_init(struct bcma
601                                        | BCMA_CC_CORECTL_UARTCLKEN);
602                 }
603         } else {
604 -               pr_err("serial not supported on this device ccrev: 0x%x\n",
605 -                      ccrev);
606 +               bcma_err(cc->core->bus, "serial not supported on this device ccrev: 0x%x\n", ccrev);
607                 return;
608         }
609  
610 -       irq = bcma_core_mips_irq(cc->core);
611 +       irq = bcma_core_irq(cc->core);
612  
613         /* Determine the registers of the UARTs */
614         cc->nr_serial_ports = (cc->capabilities & BCMA_CC_CAP_NRUART);
615 --- /dev/null
616 +++ b/drivers/bcma/driver_chipcommon_nflash.c
617 @@ -0,0 +1,44 @@
618 +/*
619 + * Broadcom specific AMBA
620 + * ChipCommon NAND flash interface
621 + *
622 + * Licensed under the GNU/GPL. See COPYING for details.
623 + */
624 +
625 +#include "bcma_private.h"
626 +
627 +#include <linux/platform_device.h>
628 +#include <linux/bcma/bcma.h>
629 +
630 +struct platform_device bcma_nflash_dev = {
631 +       .name           = "bcma_nflash",
632 +       .num_resources  = 0,
633 +};
634 +
635 +/* Initialize NAND flash access */
636 +int bcma_nflash_init(struct bcma_drv_cc *cc)
637 +{
638 +       struct bcma_bus *bus = cc->core->bus;
639 +
640 +       if (bus->chipinfo.id != BCMA_CHIP_ID_BCM4706 &&
641 +           cc->core->id.rev != 38) {
642 +               bcma_err(bus, "NAND flash on unsupported board!\n");
643 +               return -ENOTSUPP;
644 +       }
645 +
646 +       if (!(cc->capabilities & BCMA_CC_CAP_NFLASH)) {
647 +               bcma_err(bus, "NAND flash not present according to ChipCommon\n");
648 +               return -ENODEV;
649 +       }
650 +
651 +       cc->nflash.present = true;
652 +       if (cc->core->id.rev == 38 &&
653 +           (cc->status & BCMA_CC_CHIPST_5357_NAND_BOOT))
654 +               cc->nflash.boot = true;
655 +
656 +       /* Prepare platform device, but don't register it yet. It's too early,
657 +        * malloc (required by device_private_init) is not available yet. */
658 +       bcma_nflash_dev.dev.platform_data = &cc->nflash;
659 +
660 +       return 0;
661 +}
662 --- a/drivers/bcma/driver_chipcommon_pmu.c
663 +++ b/drivers/bcma/driver_chipcommon_pmu.c
664 @@ -3,7 +3,8 @@
665   * ChipCommon Power Management Unit driver
666   *
667   * Copyright 2009, Michael Buesch <m@bues.ch>
668 - * Copyright 2007, Broadcom Corporation
669 + * Copyright 2007, 2011, Broadcom Corporation
670 + * Copyright 2011, 2012, Hauke Mehrtens <hauke@hauke-m.de>
671   *
672   * Licensed under the GNU/GPL. See COPYING for details.
673   */
674 @@ -12,12 +13,13 @@
675  #include <linux/export.h>
676  #include <linux/bcma/bcma.h>
677  
678 -static u32 bcma_chipco_pll_read(struct bcma_drv_cc *cc, u32 offset)
679 +u32 bcma_chipco_pll_read(struct bcma_drv_cc *cc, u32 offset)
680  {
681         bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
682         bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
683         return bcma_cc_read32(cc, BCMA_CC_PLLCTL_DATA);
684  }
685 +EXPORT_SYMBOL_GPL(bcma_chipco_pll_read);
686  
687  void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset, u32 value)
688  {
689 @@ -54,19 +56,106 @@ void bcma_chipco_regctl_maskset(struct b
690  }
691  EXPORT_SYMBOL_GPL(bcma_chipco_regctl_maskset);
692  
693 +static u32 bcma_pmu_xtalfreq(struct bcma_drv_cc *cc)
694 +{
695 +       u32 ilp_ctl, alp_hz;
696 +
697 +       if (!(bcma_cc_read32(cc, BCMA_CC_PMU_STAT) &
698 +             BCMA_CC_PMU_STAT_EXT_LPO_AVAIL))
699 +               return 0;
700 +
701 +       bcma_cc_write32(cc, BCMA_CC_PMU_XTAL_FREQ,
702 +                       BIT(BCMA_CC_PMU_XTAL_FREQ_MEASURE_SHIFT));
703 +       usleep_range(1000, 2000);
704 +
705 +       ilp_ctl = bcma_cc_read32(cc, BCMA_CC_PMU_XTAL_FREQ);
706 +       ilp_ctl &= BCMA_CC_PMU_XTAL_FREQ_ILPCTL_MASK;
707 +
708 +       bcma_cc_write32(cc, BCMA_CC_PMU_XTAL_FREQ, 0);
709 +
710 +       alp_hz = ilp_ctl * 32768 / 4;
711 +       return (alp_hz + 50000) / 100000 * 100;
712 +}
713 +
714 +static void bcma_pmu2_pll_init0(struct bcma_drv_cc *cc, u32 xtalfreq)
715 +{
716 +       struct bcma_bus *bus = cc->core->bus;
717 +       u32 freq_tgt_target = 0, freq_tgt_current;
718 +       u32 pll0, mask;
719 +
720 +       switch (bus->chipinfo.id) {
721 +       case BCMA_CHIP_ID_BCM43142:
722 +               /* pmu2_xtaltab0_adfll_485 */
723 +               switch (xtalfreq) {
724 +               case 12000:
725 +                       freq_tgt_target = 0x50D52;
726 +                       break;
727 +               case 20000:
728 +                       freq_tgt_target = 0x307FE;
729 +                       break;
730 +               case 26000:
731 +                       freq_tgt_target = 0x254EA;
732 +                       break;
733 +               case 37400:
734 +                       freq_tgt_target = 0x19EF8;
735 +                       break;
736 +               case 52000:
737 +                       freq_tgt_target = 0x12A75;
738 +                       break;
739 +               }
740 +               break;
741 +       }
742 +
743 +       if (!freq_tgt_target) {
744 +               bcma_err(bus, "Unknown TGT frequency for xtalfreq %d\n",
745 +                        xtalfreq);
746 +               return;
747 +       }
748 +
749 +       pll0 = bcma_chipco_pll_read(cc, BCMA_CC_PMU15_PLL_PLLCTL0);
750 +       freq_tgt_current = (pll0 & BCMA_CC_PMU15_PLL_PC0_FREQTGT_MASK) >>
751 +               BCMA_CC_PMU15_PLL_PC0_FREQTGT_SHIFT;
752 +
753 +       if (freq_tgt_current == freq_tgt_target) {
754 +               bcma_debug(bus, "Target TGT frequency already set\n");
755 +               return;
756 +       }
757 +
758 +       /* Turn off PLL */
759 +       switch (bus->chipinfo.id) {
760 +       case BCMA_CHIP_ID_BCM43142:
761 +               mask = (u32)~(BCMA_RES_4314_HT_AVAIL |
762 +                             BCMA_RES_4314_MACPHY_CLK_AVAIL);
763 +
764 +               bcma_cc_mask32(cc, BCMA_CC_PMU_MINRES_MSK, mask);
765 +               bcma_cc_mask32(cc, BCMA_CC_PMU_MAXRES_MSK, mask);
766 +               bcma_wait_value(cc->core, BCMA_CLKCTLST,
767 +                               BCMA_CLKCTLST_HAVEHT, 0, 20000);
768 +               break;
769 +       }
770 +
771 +       pll0 &= ~BCMA_CC_PMU15_PLL_PC0_FREQTGT_MASK;
772 +       pll0 |= freq_tgt_target << BCMA_CC_PMU15_PLL_PC0_FREQTGT_SHIFT;
773 +       bcma_chipco_pll_write(cc, BCMA_CC_PMU15_PLL_PLLCTL0, pll0);
774 +
775 +       /* Flush */
776 +       if (cc->pmu.rev >= 2)
777 +               bcma_cc_set32(cc, BCMA_CC_PMU_CTL, BCMA_CC_PMU_CTL_PLL_UPD);
778 +
779 +       /* TODO: Do we need to update OTP? */
780 +}
781 +
782  static void bcma_pmu_pll_init(struct bcma_drv_cc *cc)
783  {
784         struct bcma_bus *bus = cc->core->bus;
785 +       u32 xtalfreq = bcma_pmu_xtalfreq(cc);
786  
787         switch (bus->chipinfo.id) {
788 -       case 0x4313:
789 -       case 0x4331:
790 -       case 43224:
791 -       case 43225:
792 +       case BCMA_CHIP_ID_BCM43142:
793 +               if (xtalfreq == 0)
794 +                       xtalfreq = 20000;
795 +               bcma_pmu2_pll_init0(cc, xtalfreq);
796                 break;
797 -       default:
798 -               pr_err("PLL init unknown for device 0x%04X\n",
799 -                       bus->chipinfo.id);
800         }
801  }
802  
803 @@ -76,16 +165,32 @@ static void bcma_pmu_resources_init(stru
804         u32 min_msk = 0, max_msk = 0;
805  
806         switch (bus->chipinfo.id) {
807 -       case 0x4313:
808 +       case BCMA_CHIP_ID_BCM4313:
809                 min_msk = 0x200D;
810                 max_msk = 0xFFFF;
811                 break;
812 -       case 43224:
813 -       case 43225:
814 +       case BCMA_CHIP_ID_BCM43142:
815 +               min_msk = BCMA_RES_4314_LPLDO_PU |
816 +                         BCMA_RES_4314_PMU_SLEEP_DIS |
817 +                         BCMA_RES_4314_PMU_BG_PU |
818 +                         BCMA_RES_4314_CBUCK_LPOM_PU |
819 +                         BCMA_RES_4314_CBUCK_PFM_PU |
820 +                         BCMA_RES_4314_CLDO_PU |
821 +                         BCMA_RES_4314_LPLDO2_LVM |
822 +                         BCMA_RES_4314_WL_PMU_PU |
823 +                         BCMA_RES_4314_LDO3P3_PU |
824 +                         BCMA_RES_4314_OTP_PU |
825 +                         BCMA_RES_4314_WL_PWRSW_PU |
826 +                         BCMA_RES_4314_LQ_AVAIL |
827 +                         BCMA_RES_4314_LOGIC_RET |
828 +                         BCMA_RES_4314_MEM_SLEEP |
829 +                         BCMA_RES_4314_MACPHY_RET |
830 +                         BCMA_RES_4314_WL_CORE_READY;
831 +               max_msk = 0x3FFFFFFF;
832                 break;
833         default:
834 -               pr_err("PMU resource config unknown for device 0x%04X\n",
835 -                       bus->chipinfo.id);
836 +               bcma_debug(bus, "PMU resource config unknown or not needed for device 0x%04X\n",
837 +                          bus->chipinfo.id);
838         }
839  
840         /* Set the resource masks. */
841 @@ -93,22 +198,12 @@ static void bcma_pmu_resources_init(stru
842                 bcma_cc_write32(cc, BCMA_CC_PMU_MINRES_MSK, min_msk);
843         if (max_msk)
844                 bcma_cc_write32(cc, BCMA_CC_PMU_MAXRES_MSK, max_msk);
845 -}
846  
847 -void bcma_pmu_swreg_init(struct bcma_drv_cc *cc)
848 -{
849 -       struct bcma_bus *bus = cc->core->bus;
850 -
851 -       switch (bus->chipinfo.id) {
852 -       case 0x4313:
853 -       case 0x4331:
854 -       case 43224:
855 -       case 43225:
856 -               break;
857 -       default:
858 -               pr_err("PMU switch/regulators init unknown for device "
859 -                       "0x%04X\n", bus->chipinfo.id);
860 -       }
861 +       /*
862 +        * Add some delay; allow resources to come up and settle.
863 +        * Delay is required for SoC (early init).
864 +        */
865 +       mdelay(2);
866  }
867  
868  /* Disable to allow reading SPROM. Don't know the adventages of enabling it. */
869 @@ -122,51 +217,69 @@ void bcma_chipco_bcm4331_ext_pa_lines_ct
870                 val |= BCMA_CHIPCTL_4331_EXTPA_EN;
871                 if (bus->chipinfo.pkg == 9 || bus->chipinfo.pkg == 11)
872                         val |= BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5;
873 +               else if (bus->chipinfo.rev > 0)
874 +                       val |= BCMA_CHIPCTL_4331_EXTPA_EN2;
875         } else {
876                 val &= ~BCMA_CHIPCTL_4331_EXTPA_EN;
877 +               val &= ~BCMA_CHIPCTL_4331_EXTPA_EN2;
878                 val &= ~BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5;
879         }
880         bcma_cc_write32(cc, BCMA_CC_CHIPCTL, val);
881  }
882  
883 -void bcma_pmu_workarounds(struct bcma_drv_cc *cc)
884 +static void bcma_pmu_workarounds(struct bcma_drv_cc *cc)
885  {
886         struct bcma_bus *bus = cc->core->bus;
887  
888         switch (bus->chipinfo.id) {
889 -       case 0x4313:
890 -               bcma_chipco_chipctl_maskset(cc, 0, ~0, 0x7);
891 +       case BCMA_CHIP_ID_BCM4313:
892 +               /* enable 12 mA drive strenth for 4313 and set chipControl
893 +                  register bit 1 */
894 +               bcma_chipco_chipctl_maskset(cc, 0,
895 +                                           ~BCMA_CCTRL_4313_12MA_LED_DRIVE,
896 +                                           BCMA_CCTRL_4313_12MA_LED_DRIVE);
897                 break;
898 -       case 0x4331:
899 -               /* BCM4331 workaround is SPROM-related, we put it in sprom.c */
900 +       case BCMA_CHIP_ID_BCM4331:
901 +       case BCMA_CHIP_ID_BCM43431:
902 +               /* Ext PA lines must be enabled for tx on BCM4331 */
903 +               bcma_chipco_bcm4331_ext_pa_lines_ctl(cc, true);
904                 break;
905 -       case 43224:
906 +       case BCMA_CHIP_ID_BCM43224:
907 +       case BCMA_CHIP_ID_BCM43421:
908 +               /* enable 12 mA drive strenth for 43224 and set chipControl
909 +                  register bit 15 */
910                 if (bus->chipinfo.rev == 0) {
911 -                       pr_err("Workarounds for 43224 rev 0 not fully "
912 -                               "implemented\n");
913 -                       bcma_chipco_chipctl_maskset(cc, 0, ~0, 0x00F000F0);
914 +                       bcma_cc_maskset32(cc, BCMA_CC_CHIPCTL,
915 +                                         ~BCMA_CCTRL_43224_GPIO_TOGGLE,
916 +                                         BCMA_CCTRL_43224_GPIO_TOGGLE);
917 +                       bcma_chipco_chipctl_maskset(cc, 0,
918 +                                                   ~BCMA_CCTRL_43224A0_12MA_LED_DRIVE,
919 +                                                   BCMA_CCTRL_43224A0_12MA_LED_DRIVE);
920                 } else {
921 -                       bcma_chipco_chipctl_maskset(cc, 0, ~0, 0xF0);
922 +                       bcma_chipco_chipctl_maskset(cc, 0,
923 +                                                   ~BCMA_CCTRL_43224B0_12MA_LED_DRIVE,
924 +                                                   BCMA_CCTRL_43224B0_12MA_LED_DRIVE);
925                 }
926                 break;
927 -       case 43225:
928 -               break;
929         default:
930 -               pr_err("Workarounds unknown for device 0x%04X\n",
931 -                       bus->chipinfo.id);
932 +               bcma_debug(bus, "Workarounds unknown or not needed for device 0x%04X\n",
933 +                          bus->chipinfo.id);
934         }
935  }
936  
937 -void bcma_pmu_init(struct bcma_drv_cc *cc)
938 +void bcma_pmu_early_init(struct bcma_drv_cc *cc)
939  {
940         u32 pmucap;
941  
942         pmucap = bcma_cc_read32(cc, BCMA_CC_PMU_CAP);
943         cc->pmu.rev = (pmucap & BCMA_CC_PMU_CAP_REVISION);
944  
945 -       pr_debug("Found rev %u PMU (capabilities 0x%08X)\n", cc->pmu.rev,
946 -                pmucap);
947 +       bcma_debug(cc->core->bus, "Found rev %u PMU (capabilities 0x%08X)\n",
948 +                  cc->pmu.rev, pmucap);
949 +}
950  
951 +void bcma_pmu_init(struct bcma_drv_cc *cc)
952 +{
953         if (cc->pmu.rev == 1)
954                 bcma_cc_mask32(cc, BCMA_CC_PMU_CTL,
955                               ~BCMA_CC_PMU_CTL_NOILPONW);
956 @@ -174,37 +287,48 @@ void bcma_pmu_init(struct bcma_drv_cc *c
957                 bcma_cc_set32(cc, BCMA_CC_PMU_CTL,
958                              BCMA_CC_PMU_CTL_NOILPONW);
959  
960 -       if (cc->core->id.id == 0x4329 && cc->core->id.rev == 2)
961 -               pr_err("Fix for 4329b0 bad LPOM state not implemented!\n");
962 -
963         bcma_pmu_pll_init(cc);
964         bcma_pmu_resources_init(cc);
965 -       bcma_pmu_swreg_init(cc);
966         bcma_pmu_workarounds(cc);
967  }
968  
969 -u32 bcma_pmu_alp_clock(struct bcma_drv_cc *cc)
970 +u32 bcma_pmu_get_alp_clock(struct bcma_drv_cc *cc)
971  {
972         struct bcma_bus *bus = cc->core->bus;
973  
974         switch (bus->chipinfo.id) {
975 -       case 0x4716:
976 -       case 0x4748:
977 -       case 47162:
978 -       case 0x4313:
979 -       case 0x5357:
980 -       case 0x4749:
981 -       case 53572:
982 +       case BCMA_CHIP_ID_BCM4313:
983 +       case BCMA_CHIP_ID_BCM43224:
984 +       case BCMA_CHIP_ID_BCM43225:
985 +       case BCMA_CHIP_ID_BCM43227:
986 +       case BCMA_CHIP_ID_BCM43228:
987 +       case BCMA_CHIP_ID_BCM4331:
988 +       case BCMA_CHIP_ID_BCM43421:
989 +       case BCMA_CHIP_ID_BCM43428:
990 +       case BCMA_CHIP_ID_BCM43431:
991 +       case BCMA_CHIP_ID_BCM4716:
992 +       case BCMA_CHIP_ID_BCM47162:
993 +       case BCMA_CHIP_ID_BCM4748:
994 +       case BCMA_CHIP_ID_BCM4749:
995 +       case BCMA_CHIP_ID_BCM5357:
996 +       case BCMA_CHIP_ID_BCM53572:
997 +       case BCMA_CHIP_ID_BCM6362:
998                 /* always 20Mhz */
999                 return 20000 * 1000;
1000 -       case 0x5356:
1001 -       case 0x5300:
1002 +       case BCMA_CHIP_ID_BCM4706:
1003 +       case BCMA_CHIP_ID_BCM5356:
1004                 /* always 25Mhz */
1005                 return 25000 * 1000;
1006 +       case BCMA_CHIP_ID_BCM43460:
1007 +       case BCMA_CHIP_ID_BCM4352:
1008 +       case BCMA_CHIP_ID_BCM4360:
1009 +               if (cc->status & BCMA_CC_CHIPST_4360_XTAL_40MZ)
1010 +                       return 40000 * 1000;
1011 +               else
1012 +                       return 20000 * 1000;
1013         default:
1014 -               pr_warn("No ALP clock specified for %04X device, "
1015 -                       "pmu rev. %d, using default %d Hz\n",
1016 -                       bus->chipinfo.id, cc->pmu.rev, BCMA_CC_PMU_ALP_CLOCK);
1017 +               bcma_warn(bus, "No ALP clock specified for %04X device, pmu rev. %d, using default %d Hz\n",
1018 +                         bus->chipinfo.id, cc->pmu.rev, BCMA_CC_PMU_ALP_CLOCK);
1019         }
1020         return BCMA_CC_PMU_ALP_CLOCK;
1021  }
1022 @@ -212,7 +336,7 @@ u32 bcma_pmu_alp_clock(struct bcma_drv_c
1023  /* Find the output of the "m" pll divider given pll controls that start with
1024   * pllreg "pll0" i.e. 12 for main 6 for phy, 0 for misc.
1025   */
1026 -static u32 bcma_pmu_clock(struct bcma_drv_cc *cc, u32 pll0, u32 m)
1027 +static u32 bcma_pmu_pll_clock(struct bcma_drv_cc *cc, u32 pll0, u32 m)
1028  {
1029         u32 tmp, div, ndiv, p1, p2, fc;
1030         struct bcma_bus *bus = cc->core->bus;
1031 @@ -221,7 +345,8 @@ static u32 bcma_pmu_clock(struct bcma_dr
1032  
1033         BUG_ON(!m || m > 4);
1034  
1035 -       if (bus->chipinfo.id == 0x5357 || bus->chipinfo.id == 0x4749) {
1036 +       if (bus->chipinfo.id == BCMA_CHIP_ID_BCM5357 ||
1037 +           bus->chipinfo.id == BCMA_CHIP_ID_BCM4749) {
1038                 /* Detect failure in clock setting */
1039                 tmp = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
1040                 if (tmp & 0x40000)
1041 @@ -240,60 +365,96 @@ static u32 bcma_pmu_clock(struct bcma_dr
1042         ndiv = (tmp & BCMA_CC_PPL_NDIV_MASK) >> BCMA_CC_PPL_NDIV_SHIFT;
1043  
1044         /* Do calculation in Mhz */
1045 -       fc = bcma_pmu_alp_clock(cc) / 1000000;
1046 +       fc = bcma_pmu_get_alp_clock(cc) / 1000000;
1047         fc = (p1 * ndiv * fc) / p2;
1048  
1049         /* Return clock in Hertz */
1050         return (fc / div) * 1000000;
1051  }
1052  
1053 +static u32 bcma_pmu_pll_clock_bcm4706(struct bcma_drv_cc *cc, u32 pll0, u32 m)
1054 +{
1055 +       u32 tmp, ndiv, p1div, p2div;
1056 +       u32 clock;
1057 +
1058 +       BUG_ON(!m || m > 4);
1059 +
1060 +       /* Get N, P1 and P2 dividers to determine CPU clock */
1061 +       tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PMU6_4706_PROCPLL_OFF);
1062 +       ndiv = (tmp & BCMA_CC_PMU6_4706_PROC_NDIV_INT_MASK)
1063 +               >> BCMA_CC_PMU6_4706_PROC_NDIV_INT_SHIFT;
1064 +       p1div = (tmp & BCMA_CC_PMU6_4706_PROC_P1DIV_MASK)
1065 +               >> BCMA_CC_PMU6_4706_PROC_P1DIV_SHIFT;
1066 +       p2div = (tmp & BCMA_CC_PMU6_4706_PROC_P2DIV_MASK)
1067 +               >> BCMA_CC_PMU6_4706_PROC_P2DIV_SHIFT;
1068 +
1069 +       tmp = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
1070 +       if (tmp & BCMA_CC_CHIPST_4706_PKG_OPTION)
1071 +               /* Low cost bonding: Fixed reference clock 25MHz and m = 4 */
1072 +               clock = (25000000 / 4) * ndiv * p2div / p1div;
1073 +       else
1074 +               /* Fixed reference clock 25MHz and m = 2 */
1075 +               clock = (25000000 / 2) * ndiv * p2div / p1div;
1076 +
1077 +       if (m == BCMA_CC_PMU5_MAINPLL_SSB)
1078 +               clock = clock / 4;
1079 +
1080 +       return clock;
1081 +}
1082 +
1083  /* query bus clock frequency for PMU-enabled chipcommon */
1084 -u32 bcma_pmu_get_clockcontrol(struct bcma_drv_cc *cc)
1085 +u32 bcma_pmu_get_bus_clock(struct bcma_drv_cc *cc)
1086  {
1087         struct bcma_bus *bus = cc->core->bus;
1088  
1089         switch (bus->chipinfo.id) {
1090 -       case 0x4716:
1091 -       case 0x4748:
1092 -       case 47162:
1093 -               return bcma_pmu_clock(cc, BCMA_CC_PMU4716_MAINPLL_PLL0,
1094 -                                     BCMA_CC_PMU5_MAINPLL_SSB);
1095 -       case 0x5356:
1096 -               return bcma_pmu_clock(cc, BCMA_CC_PMU5356_MAINPLL_PLL0,
1097 -                                     BCMA_CC_PMU5_MAINPLL_SSB);
1098 -       case 0x5357:
1099 -       case 0x4749:
1100 -               return bcma_pmu_clock(cc, BCMA_CC_PMU5357_MAINPLL_PLL0,
1101 -                                     BCMA_CC_PMU5_MAINPLL_SSB);
1102 -       case 0x5300:
1103 -               return bcma_pmu_clock(cc, BCMA_CC_PMU4706_MAINPLL_PLL0,
1104 -                                     BCMA_CC_PMU5_MAINPLL_SSB);
1105 -       case 53572:
1106 +       case BCMA_CHIP_ID_BCM4716:
1107 +       case BCMA_CHIP_ID_BCM4748:
1108 +       case BCMA_CHIP_ID_BCM47162:
1109 +               return bcma_pmu_pll_clock(cc, BCMA_CC_PMU4716_MAINPLL_PLL0,
1110 +                                         BCMA_CC_PMU5_MAINPLL_SSB);
1111 +       case BCMA_CHIP_ID_BCM5356:
1112 +               return bcma_pmu_pll_clock(cc, BCMA_CC_PMU5356_MAINPLL_PLL0,
1113 +                                         BCMA_CC_PMU5_MAINPLL_SSB);
1114 +       case BCMA_CHIP_ID_BCM5357:
1115 +       case BCMA_CHIP_ID_BCM4749:
1116 +               return bcma_pmu_pll_clock(cc, BCMA_CC_PMU5357_MAINPLL_PLL0,
1117 +                                         BCMA_CC_PMU5_MAINPLL_SSB);
1118 +       case BCMA_CHIP_ID_BCM4706:
1119 +               return bcma_pmu_pll_clock_bcm4706(cc,
1120 +                                                 BCMA_CC_PMU4706_MAINPLL_PLL0,
1121 +                                                 BCMA_CC_PMU5_MAINPLL_SSB);
1122 +       case BCMA_CHIP_ID_BCM53572:
1123                 return 75000000;
1124         default:
1125 -               pr_warn("No backplane clock specified for %04X device, "
1126 -                       "pmu rev. %d, using default %d Hz\n",
1127 -                       bus->chipinfo.id, cc->pmu.rev, BCMA_CC_PMU_HT_CLOCK);
1128 +               bcma_warn(bus, "No bus clock specified for %04X device, pmu rev. %d, using default %d Hz\n",
1129 +                         bus->chipinfo.id, cc->pmu.rev, BCMA_CC_PMU_HT_CLOCK);
1130         }
1131         return BCMA_CC_PMU_HT_CLOCK;
1132  }
1133 +EXPORT_SYMBOL_GPL(bcma_pmu_get_bus_clock);
1134  
1135  /* query cpu clock frequency for PMU-enabled chipcommon */
1136 -u32 bcma_pmu_get_clockcpu(struct bcma_drv_cc *cc)
1137 +u32 bcma_pmu_get_cpu_clock(struct bcma_drv_cc *cc)
1138  {
1139         struct bcma_bus *bus = cc->core->bus;
1140  
1141 -       if (bus->chipinfo.id == 53572)
1142 +       if (bus->chipinfo.id == BCMA_CHIP_ID_BCM53572)
1143                 return 300000000;
1144  
1145 +       /* New PMUs can have different clock for bus and CPU */
1146         if (cc->pmu.rev >= 5) {
1147                 u32 pll;
1148                 switch (bus->chipinfo.id) {
1149 -               case 0x5356:
1150 +               case BCMA_CHIP_ID_BCM4706:
1151 +                       return bcma_pmu_pll_clock_bcm4706(cc,
1152 +                                               BCMA_CC_PMU4706_MAINPLL_PLL0,
1153 +                                               BCMA_CC_PMU5_MAINPLL_CPU);
1154 +               case BCMA_CHIP_ID_BCM5356:
1155                         pll = BCMA_CC_PMU5356_MAINPLL_PLL0;
1156                         break;
1157 -               case 0x5357:
1158 -               case 0x4749:
1159 +               case BCMA_CHIP_ID_BCM5357:
1160 +               case BCMA_CHIP_ID_BCM4749:
1161                         pll = BCMA_CC_PMU5357_MAINPLL_PLL0;
1162                         break;
1163                 default:
1164 @@ -301,10 +462,189 @@ u32 bcma_pmu_get_clockcpu(struct bcma_dr
1165                         break;
1166                 }
1167  
1168 -               /* TODO: if (bus->chipinfo.id == 0x5300)
1169 -                 return si_4706_pmu_clock(sih, osh, cc, PMU4706_MAINPLL_PLL0, PMU5_MAINPLL_CPU); */
1170 -               return bcma_pmu_clock(cc, pll, BCMA_CC_PMU5_MAINPLL_CPU);
1171 +               return bcma_pmu_pll_clock(cc, pll, BCMA_CC_PMU5_MAINPLL_CPU);
1172 +       }
1173 +
1174 +       /* On old PMUs CPU has the same clock as the bus */
1175 +       return bcma_pmu_get_bus_clock(cc);
1176 +}
1177 +
1178 +static void bcma_pmu_spuravoid_pll_write(struct bcma_drv_cc *cc, u32 offset,
1179 +                                        u32 value)
1180 +{
1181 +       bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
1182 +       bcma_cc_write32(cc, BCMA_CC_PLLCTL_DATA, value);
1183 +}
1184 +
1185 +void bcma_pmu_spuravoid_pllupdate(struct bcma_drv_cc *cc, int spuravoid)
1186 +{
1187 +       u32 tmp = 0;
1188 +       u8 phypll_offset = 0;
1189 +       u8 bcm5357_bcm43236_p1div[] = {0x1, 0x5, 0x5};
1190 +       u8 bcm5357_bcm43236_ndiv[] = {0x30, 0xf6, 0xfc};
1191 +       struct bcma_bus *bus = cc->core->bus;
1192 +
1193 +       switch (bus->chipinfo.id) {
1194 +       case BCMA_CHIP_ID_BCM5357:
1195 +       case BCMA_CHIP_ID_BCM4749:
1196 +       case BCMA_CHIP_ID_BCM53572:
1197 +               /* 5357[ab]0, 43236[ab]0, and 6362b0 */
1198 +
1199 +               /* BCM5357 needs to touch PLL1_PLLCTL[02],
1200 +                  so offset PLL0_PLLCTL[02] by 6 */
1201 +               phypll_offset = (bus->chipinfo.id == BCMA_CHIP_ID_BCM5357 ||
1202 +                      bus->chipinfo.id == BCMA_CHIP_ID_BCM4749 ||
1203 +                      bus->chipinfo.id == BCMA_CHIP_ID_BCM53572) ? 6 : 0;
1204 +
1205 +               /* RMW only the P1 divider */
1206 +               bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR,
1207 +                               BCMA_CC_PMU_PLL_CTL0 + phypll_offset);
1208 +               tmp = bcma_cc_read32(cc, BCMA_CC_PLLCTL_DATA);
1209 +               tmp &= (~(BCMA_CC_PMU1_PLL0_PC0_P1DIV_MASK));
1210 +               tmp |= (bcm5357_bcm43236_p1div[spuravoid] << BCMA_CC_PMU1_PLL0_PC0_P1DIV_SHIFT);
1211 +               bcma_cc_write32(cc, BCMA_CC_PLLCTL_DATA, tmp);
1212 +
1213 +               /* RMW only the int feedback divider */
1214 +               bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR,
1215 +                               BCMA_CC_PMU_PLL_CTL2 + phypll_offset);
1216 +               tmp = bcma_cc_read32(cc, BCMA_CC_PLLCTL_DATA);
1217 +               tmp &= ~(BCMA_CC_PMU1_PLL0_PC2_NDIV_INT_MASK);
1218 +               tmp |= (bcm5357_bcm43236_ndiv[spuravoid]) << BCMA_CC_PMU1_PLL0_PC2_NDIV_INT_SHIFT;
1219 +               bcma_cc_write32(cc, BCMA_CC_PLLCTL_DATA, tmp);
1220 +
1221 +               tmp = BCMA_CC_PMU_CTL_PLL_UPD;
1222 +               break;
1223 +
1224 +       case BCMA_CHIP_ID_BCM4331:
1225 +       case BCMA_CHIP_ID_BCM43431:
1226 +               if (spuravoid == 2) {
1227 +                       bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL0,
1228 +                                                    0x11500014);
1229 +                       bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL2,
1230 +                                                    0x0FC00a08);
1231 +               } else if (spuravoid == 1) {
1232 +                       bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL0,
1233 +                                                    0x11500014);
1234 +                       bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL2,
1235 +                                                    0x0F600a08);
1236 +               } else {
1237 +                       bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL0,
1238 +                                                    0x11100014);
1239 +                       bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL2,
1240 +                                                    0x03000a08);
1241 +               }
1242 +               tmp = BCMA_CC_PMU_CTL_PLL_UPD;
1243 +               break;
1244 +
1245 +       case BCMA_CHIP_ID_BCM43224:
1246 +       case BCMA_CHIP_ID_BCM43225:
1247 +       case BCMA_CHIP_ID_BCM43421:
1248 +               if (spuravoid == 1) {
1249 +                       bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL0,
1250 +                                                    0x11500010);
1251 +                       bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL1,
1252 +                                                    0x000C0C06);
1253 +                       bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL2,
1254 +                                                    0x0F600a08);
1255 +                       bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL3,
1256 +                                                    0x00000000);
1257 +                       bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL4,
1258 +                                                    0x2001E920);
1259 +                       bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL5,
1260 +                                                    0x88888815);
1261 +               } else {
1262 +                       bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL0,
1263 +                                                    0x11100010);
1264 +                       bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL1,
1265 +                                                    0x000c0c06);
1266 +                       bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL2,
1267 +                                                    0x03000a08);
1268 +                       bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL3,
1269 +                                                    0x00000000);
1270 +                       bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL4,
1271 +                                                    0x200005c0);
1272 +                       bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL5,
1273 +                                                    0x88888815);
1274 +               }
1275 +               tmp = BCMA_CC_PMU_CTL_PLL_UPD;
1276 +               break;
1277 +
1278 +       case BCMA_CHIP_ID_BCM4716:
1279 +       case BCMA_CHIP_ID_BCM4748:
1280 +       case BCMA_CHIP_ID_BCM47162:
1281 +               if (spuravoid == 1) {
1282 +                       bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL0,
1283 +                                                    0x11500060);
1284 +                       bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL1,
1285 +                                                    0x080C0C06);
1286 +                       bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL2,
1287 +                                                    0x0F600000);
1288 +                       bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL3,
1289 +                                                    0x00000000);
1290 +                       bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL4,
1291 +                                                    0x2001E924);
1292 +                       bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL5,
1293 +                                                    0x88888815);
1294 +               } else {
1295 +                       bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL0,
1296 +                                                    0x11100060);
1297 +                       bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL1,
1298 +                                                    0x080c0c06);
1299 +                       bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL2,
1300 +                                                    0x03000000);
1301 +                       bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL3,
1302 +                                                    0x00000000);
1303 +                       bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL4,
1304 +                                                    0x200005c0);
1305 +                       bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL5,
1306 +                                                    0x88888815);
1307 +               }
1308 +
1309 +               tmp = BCMA_CC_PMU_CTL_PLL_UPD | BCMA_CC_PMU_CTL_NOILPONW;
1310 +               break;
1311 +
1312 +       case BCMA_CHIP_ID_BCM43227:
1313 +       case BCMA_CHIP_ID_BCM43228:
1314 +       case BCMA_CHIP_ID_BCM43428:
1315 +               /* LCNXN */
1316 +               /* PLL Settings for spur avoidance on/off mode,
1317 +                  no on2 support for 43228A0 */
1318 +               if (spuravoid == 1) {
1319 +                       bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL0,
1320 +                                                    0x01100014);
1321 +                       bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL1,
1322 +                                                    0x040C0C06);
1323 +                       bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL2,
1324 +                                                    0x03140A08);
1325 +                       bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL3,
1326 +                                                    0x00333333);
1327 +                       bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL4,
1328 +                                                    0x202C2820);
1329 +                       bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL5,
1330 +                                                    0x88888815);
1331 +               } else {
1332 +                       bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL0,
1333 +                                                    0x11100014);
1334 +                       bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL1,
1335 +                                                    0x040c0c06);
1336 +                       bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL2,
1337 +                                                    0x03000a08);
1338 +                       bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL3,
1339 +                                                    0x00000000);
1340 +                       bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL4,
1341 +                                                    0x200005c0);
1342 +                       bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL5,
1343 +                                                    0x88888815);
1344 +               }
1345 +               tmp = BCMA_CC_PMU_CTL_PLL_UPD;
1346 +               break;
1347 +       default:
1348 +               bcma_err(bus, "Unknown spuravoidance settings for chip 0x%04X, not changing PLL\n",
1349 +                        bus->chipinfo.id);
1350 +               break;
1351         }
1352  
1353 -       return bcma_pmu_get_clockcontrol(cc);
1354 +       tmp |= bcma_cc_read32(cc, BCMA_CC_PMU_CTL);
1355 +       bcma_cc_write32(cc, BCMA_CC_PMU_CTL, tmp);
1356  }
1357 +EXPORT_SYMBOL_GPL(bcma_pmu_spuravoid_pllupdate);
1358 --- /dev/null
1359 +++ b/drivers/bcma/driver_chipcommon_sflash.c
1360 @@ -0,0 +1,165 @@
1361 +/*
1362 + * Broadcom specific AMBA
1363 + * ChipCommon serial flash interface
1364 + *
1365 + * Licensed under the GNU/GPL. See COPYING for details.
1366 + */
1367 +
1368 +#include "bcma_private.h"
1369 +
1370 +#include <linux/platform_device.h>
1371 +#include <linux/bcma/bcma.h>
1372 +
1373 +static struct resource bcma_sflash_resource = {
1374 +       .name   = "bcma_sflash",
1375 +       .start  = BCMA_SOC_FLASH2,
1376 +       .end    = 0,
1377 +       .flags  = IORESOURCE_MEM | IORESOURCE_READONLY,
1378 +};
1379 +
1380 +struct platform_device bcma_sflash_dev = {
1381 +       .name           = "bcma_sflash",
1382 +       .resource       = &bcma_sflash_resource,
1383 +       .num_resources  = 1,
1384 +};
1385 +
1386 +struct bcma_sflash_tbl_e {
1387 +       char *name;
1388 +       u32 id;
1389 +       u32 blocksize;
1390 +       u16 numblocks;
1391 +};
1392 +
1393 +static const struct bcma_sflash_tbl_e bcma_sflash_st_tbl[] = {
1394 +       { "M25P20", 0x11, 0x10000, 4, },
1395 +       { "M25P40", 0x12, 0x10000, 8, },
1396 +
1397 +       { "M25P16", 0x14, 0x10000, 32, },
1398 +       { "M25P32", 0x15, 0x10000, 64, },
1399 +       { "M25P64", 0x16, 0x10000, 128, },
1400 +       { "M25FL128", 0x17, 0x10000, 256, },
1401 +       { 0 },
1402 +};
1403 +
1404 +static const struct bcma_sflash_tbl_e bcma_sflash_sst_tbl[] = {
1405 +       { "SST25WF512", 1, 0x1000, 16, },
1406 +       { "SST25VF512", 0x48, 0x1000, 16, },
1407 +       { "SST25WF010", 2, 0x1000, 32, },
1408 +       { "SST25VF010", 0x49, 0x1000, 32, },
1409 +       { "SST25WF020", 3, 0x1000, 64, },
1410 +       { "SST25VF020", 0x43, 0x1000, 64, },
1411 +       { "SST25WF040", 4, 0x1000, 128, },
1412 +       { "SST25VF040", 0x44, 0x1000, 128, },
1413 +       { "SST25VF040B", 0x8d, 0x1000, 128, },
1414 +       { "SST25WF080", 5, 0x1000, 256, },
1415 +       { "SST25VF080B", 0x8e, 0x1000, 256, },
1416 +       { "SST25VF016", 0x41, 0x1000, 512, },
1417 +       { "SST25VF032", 0x4a, 0x1000, 1024, },
1418 +       { "SST25VF064", 0x4b, 0x1000, 2048, },
1419 +       { 0 },
1420 +};
1421 +
1422 +static const struct bcma_sflash_tbl_e bcma_sflash_at_tbl[] = {
1423 +       { "AT45DB011", 0xc, 256, 512, },
1424 +       { "AT45DB021", 0x14, 256, 1024, },
1425 +       { "AT45DB041", 0x1c, 256, 2048, },
1426 +       { "AT45DB081", 0x24, 256, 4096, },
1427 +       { "AT45DB161", 0x2c, 512, 4096, },
1428 +       { "AT45DB321", 0x34, 512, 8192, },
1429 +       { "AT45DB642", 0x3c, 1024, 8192, },
1430 +       { 0 },
1431 +};
1432 +
1433 +static void bcma_sflash_cmd(struct bcma_drv_cc *cc, u32 opcode)
1434 +{
1435 +       int i;
1436 +       bcma_cc_write32(cc, BCMA_CC_FLASHCTL,
1437 +                       BCMA_CC_FLASHCTL_START | opcode);
1438 +       for (i = 0; i < 1000; i++) {
1439 +               if (!(bcma_cc_read32(cc, BCMA_CC_FLASHCTL) &
1440 +                     BCMA_CC_FLASHCTL_BUSY))
1441 +                       return;
1442 +               cpu_relax();
1443 +       }
1444 +       bcma_err(cc->core->bus, "SFLASH control command failed (timeout)!\n");
1445 +}
1446 +
1447 +/* Initialize serial flash access */
1448 +int bcma_sflash_init(struct bcma_drv_cc *cc)
1449 +{
1450 +       struct bcma_bus *bus = cc->core->bus;
1451 +       struct bcma_sflash *sflash = &cc->sflash;
1452 +       const struct bcma_sflash_tbl_e *e;
1453 +       u32 id, id2;
1454 +
1455 +       switch (cc->capabilities & BCMA_CC_CAP_FLASHT) {
1456 +       case BCMA_CC_FLASHT_STSER:
1457 +               bcma_sflash_cmd(cc, BCMA_CC_FLASHCTL_ST_DP);
1458 +
1459 +               bcma_cc_write32(cc, BCMA_CC_FLASHADDR, 0);
1460 +               bcma_sflash_cmd(cc, BCMA_CC_FLASHCTL_ST_RES);
1461 +               id = bcma_cc_read32(cc, BCMA_CC_FLASHDATA);
1462 +
1463 +               bcma_cc_write32(cc, BCMA_CC_FLASHADDR, 1);
1464 +               bcma_sflash_cmd(cc, BCMA_CC_FLASHCTL_ST_RES);
1465 +               id2 = bcma_cc_read32(cc, BCMA_CC_FLASHDATA);
1466 +
1467 +               switch (id) {
1468 +               case 0xbf:
1469 +                       for (e = bcma_sflash_sst_tbl; e->name; e++) {
1470 +                               if (e->id == id2)
1471 +                                       break;
1472 +                       }
1473 +                       break;
1474 +               case 0x13:
1475 +                       return -ENOTSUPP;
1476 +               default:
1477 +                       for (e = bcma_sflash_st_tbl; e->name; e++) {
1478 +                               if (e->id == id)
1479 +                                       break;
1480 +                       }
1481 +                       break;
1482 +               }
1483 +               if (!e->name) {
1484 +                       bcma_err(bus, "Unsupported ST serial flash (id: 0x%X, id2: 0x%X)\n", id, id2);
1485 +                       return -ENOTSUPP;
1486 +               }
1487 +
1488 +               break;
1489 +       case BCMA_CC_FLASHT_ATSER:
1490 +               bcma_sflash_cmd(cc, BCMA_CC_FLASHCTL_AT_STATUS);
1491 +               id = bcma_cc_read32(cc, BCMA_CC_FLASHDATA) & 0x3c;
1492 +
1493 +               for (e = bcma_sflash_at_tbl; e->name; e++) {
1494 +                       if (e->id == id)
1495 +                               break;
1496 +               }
1497 +               if (!e->name) {
1498 +                       bcma_err(bus, "Unsupported Atmel serial flash (id: 0x%X)\n", id);
1499 +                       return -ENOTSUPP;
1500 +               }
1501 +
1502 +               break;
1503 +       default:
1504 +               bcma_err(bus, "Unsupported flash type\n");
1505 +               return -ENOTSUPP;
1506 +       }
1507 +
1508 +       sflash->window = BCMA_SOC_FLASH2;
1509 +       sflash->blocksize = e->blocksize;
1510 +       sflash->numblocks = e->numblocks;
1511 +       sflash->size = sflash->blocksize * sflash->numblocks;
1512 +       sflash->present = true;
1513 +
1514 +       bcma_info(bus, "Found %s serial flash (size: %dKiB, blocksize: 0x%X, blocks: %d)\n",
1515 +                 e->name, sflash->size / 1024, sflash->blocksize,
1516 +                 sflash->numblocks);
1517 +
1518 +       /* Prepare platform device, but don't register it yet. It's too early,
1519 +        * malloc (required by device_private_init) is not available yet. */
1520 +       bcma_sflash_dev.resource[0].end = bcma_sflash_dev.resource[0].start +
1521 +                                         sflash->size;
1522 +       bcma_sflash_dev.dev.platform_data = sflash;
1523 +
1524 +       return 0;
1525 +}
1526 --- /dev/null
1527 +++ b/drivers/bcma/driver_gmac_cmn.c
1528 @@ -0,0 +1,14 @@
1529 +/*
1530 + * Broadcom specific AMBA
1531 + * GBIT MAC COMMON Core
1532 + *
1533 + * Licensed under the GNU/GPL. See COPYING for details.
1534 + */
1535 +
1536 +#include "bcma_private.h"
1537 +#include <linux/bcma/bcma.h>
1538 +
1539 +void __devinit bcma_core_gmac_cmn_init(struct bcma_drv_gmac_cmn *gc)
1540 +{
1541 +       mutex_init(&gc->phy_mutex);
1542 +}
1543 --- /dev/null
1544 +++ b/drivers/bcma/driver_gpio.c
1545 @@ -0,0 +1,114 @@
1546 +/*
1547 + * Broadcom specific AMBA
1548 + * GPIO driver
1549 + *
1550 + * Copyright 2011, Broadcom Corporation
1551 + * Copyright 2012, Hauke Mehrtens <hauke@hauke-m.de>
1552 + *
1553 + * Licensed under the GNU/GPL. See COPYING for details.
1554 + */
1555 +
1556 +#include <linux/gpio.h>
1557 +#include <linux/export.h>
1558 +#include <linux/bcma/bcma.h>
1559 +
1560 +#include "bcma_private.h"
1561 +
1562 +static inline struct bcma_drv_cc *bcma_gpio_get_cc(struct gpio_chip *chip)
1563 +{
1564 +       return container_of(chip, struct bcma_drv_cc, gpio);
1565 +}
1566 +
1567 +static int bcma_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
1568 +{
1569 +       struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip);
1570 +
1571 +       return !!bcma_chipco_gpio_in(cc, 1 << gpio);
1572 +}
1573 +
1574 +static void bcma_gpio_set_value(struct gpio_chip *chip, unsigned gpio,
1575 +                               int value)
1576 +{
1577 +       struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip);
1578 +
1579 +       bcma_chipco_gpio_out(cc, 1 << gpio, value ? 1 << gpio : 0);
1580 +}
1581 +
1582 +static int bcma_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
1583 +{
1584 +       struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip);
1585 +
1586 +       bcma_chipco_gpio_outen(cc, 1 << gpio, 0);
1587 +       return 0;
1588 +}
1589 +
1590 +static int bcma_gpio_direction_output(struct gpio_chip *chip, unsigned gpio,
1591 +                                     int value)
1592 +{
1593 +       struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip);
1594 +
1595 +       bcma_chipco_gpio_outen(cc, 1 << gpio, 1 << gpio);
1596 +       bcma_chipco_gpio_out(cc, 1 << gpio, value ? 1 << gpio : 0);
1597 +       return 0;
1598 +}
1599 +
1600 +static int bcma_gpio_request(struct gpio_chip *chip, unsigned gpio)
1601 +{
1602 +       struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip);
1603 +
1604 +       bcma_chipco_gpio_control(cc, 1 << gpio, 0);
1605 +       /* clear pulldown */
1606 +       bcma_chipco_gpio_pulldown(cc, 1 << gpio, 0);
1607 +       /* Set pullup */
1608 +       bcma_chipco_gpio_pullup(cc, 1 << gpio, 1 << gpio);
1609 +
1610 +       return 0;
1611 +}
1612 +
1613 +static void bcma_gpio_free(struct gpio_chip *chip, unsigned gpio)
1614 +{
1615 +       struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip);
1616 +
1617 +       /* clear pullup */
1618 +       bcma_chipco_gpio_pullup(cc, 1 << gpio, 0);
1619 +}
1620 +
1621 +static int bcma_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
1622 +{
1623 +       struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip);
1624 +
1625 +       if (cc->core->bus->hosttype == BCMA_HOSTTYPE_SOC)
1626 +               return bcma_core_irq(cc->core);
1627 +       else
1628 +               return -EINVAL;
1629 +}
1630 +
1631 +int bcma_gpio_init(struct bcma_drv_cc *cc)
1632 +{
1633 +       struct gpio_chip *chip = &cc->gpio;
1634 +
1635 +       chip->label             = "bcma_gpio";
1636 +       chip->owner             = THIS_MODULE;
1637 +       chip->request           = bcma_gpio_request;
1638 +       chip->free              = bcma_gpio_free;
1639 +       chip->get               = bcma_gpio_get_value;
1640 +       chip->set               = bcma_gpio_set_value;
1641 +       chip->direction_input   = bcma_gpio_direction_input;
1642 +       chip->direction_output  = bcma_gpio_direction_output;
1643 +       chip->to_irq            = bcma_gpio_to_irq;
1644 +       chip->ngpio             = 16;
1645 +       /* There is just one SoC in one device and its GPIO addresses should be
1646 +        * deterministic to address them more easily. The other buses could get
1647 +        * a random base number. */
1648 +       if (cc->core->bus->hosttype == BCMA_HOSTTYPE_SOC)
1649 +               chip->base              = 0;
1650 +       else
1651 +               chip->base              = -1;
1652 +
1653 +       return gpiochip_add(chip);
1654 +}
1655 +
1656 +int bcma_gpio_unregister(struct bcma_drv_cc *cc)
1657 +{
1658 +       return gpiochip_remove(&cc->gpio);
1659 +}
1660 --- a/drivers/bcma/driver_mips.c
1661 +++ b/drivers/bcma/driver_mips.c
1662 @@ -14,23 +14,45 @@
1663  
1664  #include <linux/bcma/bcma.h>
1665  
1666 +#include <linux/mtd/physmap.h>
1667 +#include <linux/platform_device.h>
1668  #include <linux/serial.h>
1669  #include <linux/serial_core.h>
1670  #include <linux/serial_reg.h>
1671  #include <linux/time.h>
1672  
1673 +static const char * const part_probes[] = { "bcm47xxpart", NULL };
1674 +
1675 +static struct physmap_flash_data bcma_pflash_data = {
1676 +       .part_probe_types       = part_probes,
1677 +};
1678 +
1679 +static struct resource bcma_pflash_resource = {
1680 +       .name   = "bcma_pflash",
1681 +       .flags  = IORESOURCE_MEM,
1682 +};
1683 +
1684 +struct platform_device bcma_pflash_dev = {
1685 +       .name           = "physmap-flash",
1686 +       .dev            = {
1687 +               .platform_data  = &bcma_pflash_data,
1688 +       },
1689 +       .resource       = &bcma_pflash_resource,
1690 +       .num_resources  = 1,
1691 +};
1692 +
1693  /* The 47162a0 hangs when reading MIPS DMP registers registers */
1694  static inline bool bcma_core_mips_bcm47162a0_quirk(struct bcma_device *dev)
1695  {
1696 -       return dev->bus->chipinfo.id == 47162 && dev->bus->chipinfo.rev == 0 &&
1697 -              dev->id.id == BCMA_CORE_MIPS_74K;
1698 +       return dev->bus->chipinfo.id == BCMA_CHIP_ID_BCM47162 &&
1699 +              dev->bus->chipinfo.rev == 0 && dev->id.id == BCMA_CORE_MIPS_74K;
1700  }
1701  
1702  /* The 5357b0 hangs when reading USB20H DMP registers */
1703  static inline bool bcma_core_mips_bcm5357b0_quirk(struct bcma_device *dev)
1704  {
1705 -       return (dev->bus->chipinfo.id == 0x5357 ||
1706 -               dev->bus->chipinfo.id == 0x4749) &&
1707 +       return (dev->bus->chipinfo.id == BCMA_CHIP_ID_BCM5357 ||
1708 +               dev->bus->chipinfo.id == BCMA_CHIP_ID_BCM4749) &&
1709                dev->bus->chipinfo.pkg == 11 &&
1710                dev->id.id == BCMA_CORE_USB20_HOST;
1711  }
1712 @@ -74,28 +96,41 @@ static u32 bcma_core_mips_irqflag(struct
1713                 return dev->core_index;
1714         flag = bcma_aread32(dev, BCMA_MIPS_OOBSELOUTA30);
1715  
1716 -       return flag & 0x1F;
1717 +       if (flag)
1718 +               return flag & 0x1F;
1719 +       else
1720 +               return 0x3f;
1721  }
1722  
1723  /* Get the MIPS IRQ assignment for a specified device.
1724   * If unassigned, 0 is returned.
1725 + * If disabled, 5 is returned.
1726 + * If not supported, 6 is returned.
1727   */
1728 -unsigned int bcma_core_mips_irq(struct bcma_device *dev)
1729 +static unsigned int bcma_core_mips_irq(struct bcma_device *dev)
1730  {
1731         struct bcma_device *mdev = dev->bus->drv_mips.core;
1732         u32 irqflag;
1733         unsigned int irq;
1734  
1735         irqflag = bcma_core_mips_irqflag(dev);
1736 +       if (irqflag == 0x3f)
1737 +               return 6;
1738  
1739 -       for (irq = 1; irq <= 4; irq++)
1740 +       for (irq = 0; irq <= 4; irq++)
1741                 if (bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq)) &
1742                     (1 << irqflag))
1743                         return irq;
1744  
1745 -       return 0;
1746 +       return 5;
1747 +}
1748 +
1749 +unsigned int bcma_core_irq(struct bcma_device *dev)
1750 +{
1751 +       unsigned int mips_irq = bcma_core_mips_irq(dev);
1752 +       return mips_irq <= 4 ? mips_irq + 2 : 0;
1753  }
1754 -EXPORT_SYMBOL(bcma_core_mips_irq);
1755 +EXPORT_SYMBOL(bcma_core_irq);
1756  
1757  static void bcma_core_mips_set_irq(struct bcma_device *dev, unsigned int irq)
1758  {
1759 @@ -114,8 +149,8 @@ static void bcma_core_mips_set_irq(struc
1760                 bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0),
1761                             bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) &
1762                             ~(1 << irqflag));
1763 -       else
1764 -               bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq), 0);
1765 +       else if (oldirq != 5)
1766 +               bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(oldirq), 0);
1767  
1768         /* assign the new one */
1769         if (irq == 0) {
1770 @@ -123,17 +158,17 @@ static void bcma_core_mips_set_irq(struc
1771                             bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) |
1772                             (1 << irqflag));
1773         } else {
1774 -               u32 oldirqflag = bcma_read32(mdev,
1775 -                                            BCMA_MIPS_MIPS74K_INTMASK(irq));
1776 -               if (oldirqflag) {
1777 +               u32 irqinitmask = bcma_read32(mdev,
1778 +                                             BCMA_MIPS_MIPS74K_INTMASK(irq));
1779 +               if (irqinitmask) {
1780                         struct bcma_device *core;
1781  
1782                         /* backplane irq line is in use, find out who uses
1783                          * it and set user to irq 0
1784                          */
1785 -                       list_for_each_entry_reverse(core, &bus->cores, list) {
1786 +                       list_for_each_entry(core, &bus->cores, list) {
1787                                 if ((1 << bcma_core_mips_irqflag(core)) ==
1788 -                                   oldirqflag) {
1789 +                                   irqinitmask) {
1790                                         bcma_core_mips_set_irq(core, 0);
1791                                         break;
1792                                 }
1793 @@ -143,15 +178,31 @@ static void bcma_core_mips_set_irq(struc
1794                              1 << irqflag);
1795         }
1796  
1797 -       pr_info("set_irq: core 0x%04x, irq %d => %d\n",
1798 -               dev->id.id, oldirq + 2, irq + 2);
1799 +       bcma_debug(bus, "set_irq: core 0x%04x, irq %d => %d\n",
1800 +                  dev->id.id, oldirq <= 4 ? oldirq + 2 : 0, irq + 2);
1801 +}
1802 +
1803 +static void bcma_core_mips_set_irq_name(struct bcma_bus *bus, unsigned int irq,
1804 +                                       u16 coreid, u8 unit)
1805 +{
1806 +       struct bcma_device *core;
1807 +
1808 +       core = bcma_find_core_unit(bus, coreid, unit);
1809 +       if (!core) {
1810 +               bcma_warn(bus,
1811 +                         "Can not find core (id: 0x%x, unit %i) for IRQ configuration.\n",
1812 +                         coreid, unit);
1813 +               return;
1814 +       }
1815 +
1816 +       bcma_core_mips_set_irq(core, irq);
1817  }
1818  
1819  static void bcma_core_mips_print_irq(struct bcma_device *dev, unsigned int irq)
1820  {
1821         int i;
1822         static const char *irq_name[] = {"2(S)", "3", "4", "5", "6", "D", "I"};
1823 -       printk(KERN_INFO KBUILD_MODNAME ": core 0x%04x, irq :", dev->id.id);
1824 +       printk(KERN_DEBUG KBUILD_MODNAME ": core 0x%04x, irq :", dev->id.id);
1825         for (i = 0; i <= 6; i++)
1826                 printk(" %s%s", irq_name[i], i == irq ? "*" : " ");
1827         printk("\n");
1828 @@ -161,7 +212,7 @@ static void bcma_core_mips_dump_irq(stru
1829  {
1830         struct bcma_device *core;
1831  
1832 -       list_for_each_entry_reverse(core, &bus->cores, list) {
1833 +       list_for_each_entry(core, &bus->cores, list) {
1834                 bcma_core_mips_print_irq(core, bcma_core_mips_irq(core));
1835         }
1836  }
1837 @@ -171,9 +222,9 @@ u32 bcma_cpu_clock(struct bcma_drv_mips
1838         struct bcma_bus *bus = mcore->core->bus;
1839  
1840         if (bus->drv_cc.capabilities & BCMA_CC_CAP_PMU)
1841 -               return bcma_pmu_get_clockcpu(&bus->drv_cc);
1842 +               return bcma_pmu_get_cpu_clock(&bus->drv_cc);
1843  
1844 -       pr_err("No PMU available, need this to get the cpu clock\n");
1845 +       bcma_err(bus, "No PMU available, need this to get the cpu clock\n");
1846         return 0;
1847  }
1848  EXPORT_SYMBOL(bcma_cpu_clock);
1849 @@ -181,25 +232,81 @@ EXPORT_SYMBOL(bcma_cpu_clock);
1850  static void bcma_core_mips_flash_detect(struct bcma_drv_mips *mcore)
1851  {
1852         struct bcma_bus *bus = mcore->core->bus;
1853 +       struct bcma_drv_cc *cc = &bus->drv_cc;
1854 +       struct bcma_pflash *pflash = &cc->pflash;
1855  
1856 -       switch (bus->drv_cc.capabilities & BCMA_CC_CAP_FLASHT) {
1857 +       switch (cc->capabilities & BCMA_CC_CAP_FLASHT) {
1858         case BCMA_CC_FLASHT_STSER:
1859         case BCMA_CC_FLASHT_ATSER:
1860 -               pr_err("Serial flash not supported.\n");
1861 +               bcma_debug(bus, "Found serial flash\n");
1862 +               bcma_sflash_init(cc);
1863                 break;
1864         case BCMA_CC_FLASHT_PARA:
1865 -               pr_info("found parallel flash.\n");
1866 -               bus->drv_cc.pflash.window = 0x1c000000;
1867 -               bus->drv_cc.pflash.window_size = 0x02000000;
1868 +               bcma_debug(bus, "Found parallel flash\n");
1869 +               pflash->present = true;
1870 +               pflash->window = BCMA_SOC_FLASH2;
1871 +               pflash->window_size = BCMA_SOC_FLASH2_SZ;
1872  
1873 -               if ((bcma_read32(bus->drv_cc.core, BCMA_CC_FLASH_CFG) &
1874 +               if ((bcma_read32(cc->core, BCMA_CC_FLASH_CFG) &
1875                      BCMA_CC_FLASH_CFG_DS) == 0)
1876 -                       bus->drv_cc.pflash.buswidth = 1;
1877 +                       pflash->buswidth = 1;
1878                 else
1879 -                       bus->drv_cc.pflash.buswidth = 2;
1880 +                       pflash->buswidth = 2;
1881 +
1882 +               bcma_pflash_data.width = pflash->buswidth;
1883 +               bcma_pflash_resource.start = pflash->window;
1884 +               bcma_pflash_resource.end = pflash->window + pflash->window_size;
1885 +
1886                 break;
1887         default:
1888 -               pr_err("flash not supported.\n");
1889 +               bcma_err(bus, "Flash type not supported\n");
1890 +       }
1891 +
1892 +       if (cc->core->id.rev == 38 ||
1893 +           bus->chipinfo.id == BCMA_CHIP_ID_BCM4706) {
1894 +               if (cc->capabilities & BCMA_CC_CAP_NFLASH) {
1895 +                       bcma_debug(bus, "Found NAND flash\n");
1896 +                       bcma_nflash_init(cc);
1897 +               }
1898 +       }
1899 +}
1900 +
1901 +void bcma_core_mips_early_init(struct bcma_drv_mips *mcore)
1902 +{
1903 +       struct bcma_bus *bus = mcore->core->bus;
1904 +
1905 +       if (mcore->early_setup_done)
1906 +               return;
1907 +
1908 +       bcma_chipco_serial_init(&bus->drv_cc);
1909 +       bcma_core_mips_flash_detect(mcore);
1910 +
1911 +       mcore->early_setup_done = true;
1912 +}
1913 +
1914 +static void bcma_fix_i2s_irqflag(struct bcma_bus *bus)
1915 +{
1916 +       struct bcma_device *cpu, *pcie, *i2s;
1917 +
1918 +       /* Fixup the interrupts in 4716/4748 for i2s core (2010 Broadcom SDK)
1919 +        * (IRQ flags > 7 are ignored when setting the interrupt masks)
1920 +        */
1921 +       if (bus->chipinfo.id != BCMA_CHIP_ID_BCM4716 &&
1922 +           bus->chipinfo.id != BCMA_CHIP_ID_BCM4748)
1923 +               return;
1924 +
1925 +       cpu = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
1926 +       pcie = bcma_find_core(bus, BCMA_CORE_PCIE);
1927 +       i2s = bcma_find_core(bus, BCMA_CORE_I2S);
1928 +       if (cpu && pcie && i2s &&
1929 +           bcma_aread32(cpu, BCMA_MIPS_OOBSELINA74) == 0x08060504 &&
1930 +           bcma_aread32(pcie, BCMA_MIPS_OOBSELINA74) == 0x08060504 &&
1931 +           bcma_aread32(i2s, BCMA_MIPS_OOBSELOUTA30) == 0x88) {
1932 +               bcma_awrite32(cpu, BCMA_MIPS_OOBSELINA74, 0x07060504);
1933 +               bcma_awrite32(pcie, BCMA_MIPS_OOBSELINA74, 0x07060504);
1934 +               bcma_awrite32(i2s, BCMA_MIPS_OOBSELOUTA30, 0x87);
1935 +               bcma_debug(bus,
1936 +                          "Moved i2s interrupt to oob line 7 instead of 8\n");
1937         }
1938  }
1939  
1940 @@ -209,48 +316,59 @@ void bcma_core_mips_init(struct bcma_drv
1941         struct bcma_device *core;
1942         bus = mcore->core->bus;
1943  
1944 -       pr_info("Initializing MIPS core...\n");
1945 +       if (mcore->setup_done)
1946 +               return;
1947  
1948 -       if (!mcore->setup_done)
1949 -               mcore->assigned_irqs = 1;
1950 +       bcma_debug(bus, "Initializing MIPS core...\n");
1951  
1952 -       /* Assign IRQs to all cores on the bus */
1953 -       list_for_each_entry_reverse(core, &bus->cores, list) {
1954 -               int mips_irq;
1955 -               if (core->irq)
1956 -                       continue;
1957 -
1958 -               mips_irq = bcma_core_mips_irq(core);
1959 -               if (mips_irq > 4)
1960 -                       core->irq = 0;
1961 -               else
1962 -                       core->irq = mips_irq + 2;
1963 -               if (core->irq > 5)
1964 -                       continue;
1965 -               switch (core->id.id) {
1966 -               case BCMA_CORE_PCI:
1967 -               case BCMA_CORE_PCIE:
1968 -               case BCMA_CORE_ETHERNET:
1969 -               case BCMA_CORE_ETHERNET_GBIT:
1970 -               case BCMA_CORE_MAC_GBIT:
1971 -               case BCMA_CORE_80211:
1972 -               case BCMA_CORE_USB20_HOST:
1973 -                       /* These devices get their own IRQ line if available,
1974 -                        * the rest goes on IRQ0
1975 -                        */
1976 -                       if (mcore->assigned_irqs <= 4)
1977 -                               bcma_core_mips_set_irq(core,
1978 -                                                      mcore->assigned_irqs++);
1979 -                       break;
1980 +       bcma_core_mips_early_init(mcore);
1981 +
1982 +       bcma_fix_i2s_irqflag(bus);
1983 +
1984 +       switch (bus->chipinfo.id) {
1985 +       case BCMA_CHIP_ID_BCM4716:
1986 +       case BCMA_CHIP_ID_BCM4748:
1987 +               bcma_core_mips_set_irq_name(bus, 1, BCMA_CORE_80211, 0);
1988 +               bcma_core_mips_set_irq_name(bus, 2, BCMA_CORE_MAC_GBIT, 0);
1989 +               bcma_core_mips_set_irq_name(bus, 3, BCMA_CORE_USB20_HOST, 0);
1990 +               bcma_core_mips_set_irq_name(bus, 4, BCMA_CORE_PCIE, 0);
1991 +               bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_CHIPCOMMON, 0);
1992 +               bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_I2S, 0);
1993 +               break;
1994 +       case BCMA_CHIP_ID_BCM5356:
1995 +       case BCMA_CHIP_ID_BCM47162:
1996 +       case BCMA_CHIP_ID_BCM53572:
1997 +               bcma_core_mips_set_irq_name(bus, 1, BCMA_CORE_80211, 0);
1998 +               bcma_core_mips_set_irq_name(bus, 2, BCMA_CORE_MAC_GBIT, 0);
1999 +               bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_CHIPCOMMON, 0);
2000 +               break;
2001 +       case BCMA_CHIP_ID_BCM5357:
2002 +       case BCMA_CHIP_ID_BCM4749:
2003 +               bcma_core_mips_set_irq_name(bus, 1, BCMA_CORE_80211, 0);
2004 +               bcma_core_mips_set_irq_name(bus, 2, BCMA_CORE_MAC_GBIT, 0);
2005 +               bcma_core_mips_set_irq_name(bus, 3, BCMA_CORE_USB20_HOST, 0);
2006 +               bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_CHIPCOMMON, 0);
2007 +               bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_I2S, 0);
2008 +               break;
2009 +       case BCMA_CHIP_ID_BCM4706:
2010 +               bcma_core_mips_set_irq_name(bus, 1, BCMA_CORE_PCIE, 0);
2011 +               bcma_core_mips_set_irq_name(bus, 2, BCMA_CORE_4706_MAC_GBIT,
2012 +                                           0);
2013 +               bcma_core_mips_set_irq_name(bus, 3, BCMA_CORE_PCIE, 1);
2014 +               bcma_core_mips_set_irq_name(bus, 4, BCMA_CORE_USB20_HOST, 0);
2015 +               bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_4706_CHIPCOMMON,
2016 +                                           0);
2017 +               break;
2018 +       default:
2019 +               list_for_each_entry(core, &bus->cores, list) {
2020 +                       core->irq = bcma_core_irq(core);
2021                 }
2022 +               bcma_err(bus,
2023 +                        "Unknown device (0x%x) found, can not configure IRQs\n",
2024 +                        bus->chipinfo.id);
2025         }
2026 -       pr_info("IRQ reconfiguration done\n");
2027 +       bcma_debug(bus, "IRQ reconfiguration done\n");
2028         bcma_core_mips_dump_irq(bus);
2029  
2030 -       if (mcore->setup_done)
2031 -               return;
2032 -
2033 -       bcma_chipco_serial_init(&bus->drv_cc);
2034 -       bcma_core_mips_flash_detect(mcore);
2035         mcore->setup_done = true;
2036  }
2037 --- a/drivers/bcma/driver_pci.c
2038 +++ b/drivers/bcma/driver_pci.c
2039 @@ -2,8 +2,9 @@
2040   * Broadcom specific AMBA
2041   * PCI Core
2042   *
2043 - * Copyright 2005, Broadcom Corporation
2044 + * Copyright 2005, 2011, Broadcom Corporation
2045   * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
2046 + * Copyright 2011, 2012, Hauke Mehrtens <hauke@hauke-m.de>
2047   *
2048   * Licensed under the GNU/GPL. See COPYING for details.
2049   */
2050 @@ -16,120 +17,124 @@
2051   * R/W ops.
2052   **************************************************/
2053  
2054 -static u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address)
2055 +u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address)
2056  {
2057 -       pcicore_write32(pc, 0x130, address);
2058 -       pcicore_read32(pc, 0x130);
2059 -       return pcicore_read32(pc, 0x134);
2060 +       pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_ADDR, address);
2061 +       pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_ADDR);
2062 +       return pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_DATA);
2063  }
2064  
2065 -#if 0
2066  static void bcma_pcie_write(struct bcma_drv_pci *pc, u32 address, u32 data)
2067  {
2068 -       pcicore_write32(pc, 0x130, address);
2069 -       pcicore_read32(pc, 0x130);
2070 -       pcicore_write32(pc, 0x134, data);
2071 +       pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_ADDR, address);
2072 +       pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_ADDR);
2073 +       pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_DATA, data);
2074  }
2075 -#endif
2076  
2077  static void bcma_pcie_mdio_set_phy(struct bcma_drv_pci *pc, u8 phy)
2078  {
2079 -       const u16 mdio_control = 0x128;
2080 -       const u16 mdio_data = 0x12C;
2081         u32 v;
2082         int i;
2083  
2084 -       v = (1 << 30); /* Start of Transaction */
2085 -       v |= (1 << 28); /* Write Transaction */
2086 -       v |= (1 << 17); /* Turnaround */
2087 -       v |= (0x1F << 18);
2088 +       v = BCMA_CORE_PCI_MDIODATA_START;
2089 +       v |= BCMA_CORE_PCI_MDIODATA_WRITE;
2090 +       v |= (BCMA_CORE_PCI_MDIODATA_DEV_ADDR <<
2091 +             BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF);
2092 +       v |= (BCMA_CORE_PCI_MDIODATA_BLK_ADDR <<
2093 +             BCMA_CORE_PCI_MDIODATA_REGADDR_SHF);
2094 +       v |= BCMA_CORE_PCI_MDIODATA_TA;
2095         v |= (phy << 4);
2096 -       pcicore_write32(pc, mdio_data, v);
2097 +       pcicore_write32(pc, BCMA_CORE_PCI_MDIO_DATA, v);
2098  
2099         udelay(10);
2100         for (i = 0; i < 200; i++) {
2101 -               v = pcicore_read32(pc, mdio_control);
2102 -               if (v & 0x100 /* Trans complete */)
2103 +               v = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_CONTROL);
2104 +               if (v & BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE)
2105                         break;
2106 -               msleep(1);
2107 +               usleep_range(1000, 2000);
2108         }
2109  }
2110  
2111  static u16 bcma_pcie_mdio_read(struct bcma_drv_pci *pc, u8 device, u8 address)
2112  {
2113 -       const u16 mdio_control = 0x128;
2114 -       const u16 mdio_data = 0x12C;
2115         int max_retries = 10;
2116         u16 ret = 0;
2117         u32 v;
2118         int i;
2119  
2120 -       v = 0x80; /* Enable Preamble Sequence */
2121 -       v |= 0x2; /* MDIO Clock Divisor */
2122 -       pcicore_write32(pc, mdio_control, v);
2123 +       /* enable mdio access to SERDES */
2124 +       v = BCMA_CORE_PCI_MDIOCTL_PREAM_EN;
2125 +       v |= BCMA_CORE_PCI_MDIOCTL_DIVISOR_VAL;
2126 +       pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, v);
2127  
2128         if (pc->core->id.rev >= 10) {
2129                 max_retries = 200;
2130                 bcma_pcie_mdio_set_phy(pc, device);
2131 +               v = (BCMA_CORE_PCI_MDIODATA_DEV_ADDR <<
2132 +                    BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF);
2133 +               v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF);
2134 +       } else {
2135 +               v = (device << BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF_OLD);
2136 +               v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF_OLD);
2137         }
2138  
2139 -       v = (1 << 30); /* Start of Transaction */
2140 -       v |= (1 << 29); /* Read Transaction */
2141 -       v |= (1 << 17); /* Turnaround */
2142 -       if (pc->core->id.rev < 10)
2143 -               v |= (u32)device << 22;
2144 -       v |= (u32)address << 18;
2145 -       pcicore_write32(pc, mdio_data, v);
2146 +       v = BCMA_CORE_PCI_MDIODATA_START;
2147 +       v |= BCMA_CORE_PCI_MDIODATA_READ;
2148 +       v |= BCMA_CORE_PCI_MDIODATA_TA;
2149 +
2150 +       pcicore_write32(pc, BCMA_CORE_PCI_MDIO_DATA, v);
2151         /* Wait for the device to complete the transaction */
2152         udelay(10);
2153         for (i = 0; i < max_retries; i++) {
2154 -               v = pcicore_read32(pc, mdio_control);
2155 -               if (v & 0x100 /* Trans complete */) {
2156 +               v = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_CONTROL);
2157 +               if (v & BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE) {
2158                         udelay(10);
2159 -                       ret = pcicore_read32(pc, mdio_data);
2160 +                       ret = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_DATA);
2161                         break;
2162                 }
2163 -               msleep(1);
2164 +               usleep_range(1000, 2000);
2165         }
2166 -       pcicore_write32(pc, mdio_control, 0);
2167 +       pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, 0);
2168         return ret;
2169  }
2170  
2171  static void bcma_pcie_mdio_write(struct bcma_drv_pci *pc, u8 device,
2172                                 u8 address, u16 data)
2173  {
2174 -       const u16 mdio_control = 0x128;
2175 -       const u16 mdio_data = 0x12C;
2176         int max_retries = 10;
2177         u32 v;
2178         int i;
2179  
2180 -       v = 0x80; /* Enable Preamble Sequence */
2181 -       v |= 0x2; /* MDIO Clock Divisor */
2182 -       pcicore_write32(pc, mdio_control, v);
2183 +       /* enable mdio access to SERDES */
2184 +       v = BCMA_CORE_PCI_MDIOCTL_PREAM_EN;
2185 +       v |= BCMA_CORE_PCI_MDIOCTL_DIVISOR_VAL;
2186 +       pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, v);
2187  
2188         if (pc->core->id.rev >= 10) {
2189                 max_retries = 200;
2190                 bcma_pcie_mdio_set_phy(pc, device);
2191 +               v = (BCMA_CORE_PCI_MDIODATA_DEV_ADDR <<
2192 +                    BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF);
2193 +               v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF);
2194 +       } else {
2195 +               v = (device << BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF_OLD);
2196 +               v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF_OLD);
2197         }
2198  
2199 -       v = (1 << 30); /* Start of Transaction */
2200 -       v |= (1 << 28); /* Write Transaction */
2201 -       v |= (1 << 17); /* Turnaround */
2202 -       if (pc->core->id.rev < 10)
2203 -               v |= (u32)device << 22;
2204 -       v |= (u32)address << 18;
2205 +       v = BCMA_CORE_PCI_MDIODATA_START;
2206 +       v |= BCMA_CORE_PCI_MDIODATA_WRITE;
2207 +       v |= BCMA_CORE_PCI_MDIODATA_TA;
2208         v |= data;
2209 -       pcicore_write32(pc, mdio_data, v);
2210 +       pcicore_write32(pc, BCMA_CORE_PCI_MDIO_DATA, v);
2211         /* Wait for the device to complete the transaction */
2212         udelay(10);
2213         for (i = 0; i < max_retries; i++) {
2214 -               v = pcicore_read32(pc, mdio_control);
2215 -               if (v & 0x100 /* Trans complete */)
2216 +               v = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_CONTROL);
2217 +               if (v & BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE)
2218                         break;
2219 -               msleep(1);
2220 +               usleep_range(1000, 2000);
2221         }
2222 -       pcicore_write32(pc, mdio_control, 0);
2223 +       pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, 0);
2224  }
2225  
2226  /**************************************************
2227 @@ -138,88 +143,108 @@ static void bcma_pcie_mdio_write(struct
2228  
2229  static u8 bcma_pcicore_polarity_workaround(struct bcma_drv_pci *pc)
2230  {
2231 -       return (bcma_pcie_read(pc, 0x204) & 0x10) ? 0xC0 : 0x80;
2232 +       u32 tmp;
2233 +
2234 +       tmp = bcma_pcie_read(pc, BCMA_CORE_PCI_PLP_STATUSREG);
2235 +       if (tmp & BCMA_CORE_PCI_PLP_POLARITYINV_STAT)
2236 +               return BCMA_CORE_PCI_SERDES_RX_CTRL_FORCE |
2237 +                      BCMA_CORE_PCI_SERDES_RX_CTRL_POLARITY;
2238 +       else
2239 +               return BCMA_CORE_PCI_SERDES_RX_CTRL_FORCE;
2240  }
2241  
2242  static void bcma_pcicore_serdes_workaround(struct bcma_drv_pci *pc)
2243  {
2244 -       const u8 serdes_pll_device = 0x1D;
2245 -       const u8 serdes_rx_device = 0x1F;
2246         u16 tmp;
2247  
2248 -       bcma_pcie_mdio_write(pc, serdes_rx_device, 1 /* Control */,
2249 -                             bcma_pcicore_polarity_workaround(pc));
2250 -       tmp = bcma_pcie_mdio_read(pc, serdes_pll_device, 1 /* Control */);
2251 -       if (tmp & 0x4000)
2252 -               bcma_pcie_mdio_write(pc, serdes_pll_device, 1, tmp & ~0x4000);
2253 +       bcma_pcie_mdio_write(pc, BCMA_CORE_PCI_MDIODATA_DEV_RX,
2254 +                            BCMA_CORE_PCI_SERDES_RX_CTRL,
2255 +                            bcma_pcicore_polarity_workaround(pc));
2256 +       tmp = bcma_pcie_mdio_read(pc, BCMA_CORE_PCI_MDIODATA_DEV_PLL,
2257 +                                 BCMA_CORE_PCI_SERDES_PLL_CTRL);
2258 +       if (tmp & BCMA_CORE_PCI_PLL_CTRL_FREQDET_EN)
2259 +               bcma_pcie_mdio_write(pc, BCMA_CORE_PCI_MDIODATA_DEV_PLL,
2260 +                                    BCMA_CORE_PCI_SERDES_PLL_CTRL,
2261 +                                    tmp & ~BCMA_CORE_PCI_PLL_CTRL_FREQDET_EN);
2262 +}
2263 +
2264 +static void bcma_core_pci_fixcfg(struct bcma_drv_pci *pc)
2265 +{
2266 +       struct bcma_device *core = pc->core;
2267 +       u16 val16, core_index;
2268 +       uint regoff;
2269 +
2270 +       regoff = BCMA_CORE_PCI_SPROM(BCMA_CORE_PCI_SPROM_PI_OFFSET);
2271 +       core_index = (u16)core->core_index;
2272 +
2273 +       val16 = pcicore_read16(pc, regoff);
2274 +       if (((val16 & BCMA_CORE_PCI_SPROM_PI_MASK) >> BCMA_CORE_PCI_SPROM_PI_SHIFT)
2275 +            != core_index) {
2276 +               val16 = (core_index << BCMA_CORE_PCI_SPROM_PI_SHIFT) |
2277 +                       (val16 & ~BCMA_CORE_PCI_SPROM_PI_MASK);
2278 +               pcicore_write16(pc, regoff, val16);
2279 +       }
2280 +}
2281 +
2282 +/* Fix MISC config to allow coming out of L2/L3-Ready state w/o PRST */
2283 +/* Needs to happen when coming out of 'standby'/'hibernate' */
2284 +static void bcma_core_pci_config_fixup(struct bcma_drv_pci *pc)
2285 +{
2286 +       u16 val16;
2287 +       uint regoff;
2288 +
2289 +       regoff = BCMA_CORE_PCI_SPROM(BCMA_CORE_PCI_SPROM_MISC_CONFIG);
2290 +
2291 +       val16 = pcicore_read16(pc, regoff);
2292 +
2293 +       if (!(val16 & BCMA_CORE_PCI_SPROM_L23READY_EXIT_NOPERST)) {
2294 +               val16 |= BCMA_CORE_PCI_SPROM_L23READY_EXIT_NOPERST;
2295 +               pcicore_write16(pc, regoff, val16);
2296 +       }
2297  }
2298  
2299  /**************************************************
2300   * Init.
2301   **************************************************/
2302  
2303 -static void bcma_core_pci_clientmode_init(struct bcma_drv_pci *pc)
2304 +static void __devinit bcma_core_pci_clientmode_init(struct bcma_drv_pci *pc)
2305  {
2306 +       bcma_core_pci_fixcfg(pc);
2307         bcma_pcicore_serdes_workaround(pc);
2308 +       bcma_core_pci_config_fixup(pc);
2309  }
2310  
2311 -static bool bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc)
2312 -{
2313 -       struct bcma_bus *bus = pc->core->bus;
2314 -       u16 chipid_top;
2315 -
2316 -       chipid_top = (bus->chipinfo.id & 0xFF00);
2317 -       if (chipid_top != 0x4700 &&
2318 -           chipid_top != 0x5300)
2319 -               return false;
2320 -
2321 -#ifdef CONFIG_SSB_DRIVER_PCICORE
2322 -       if (bus->sprom.boardflags_lo & SSB_BFL_NOPCI)
2323 -               return false;
2324 -#endif /* CONFIG_SSB_DRIVER_PCICORE */
2325 -
2326 -#if 0
2327 -       /* TODO: on BCMA we use address from EROM instead of magic formula */
2328 -       u32 tmp;
2329 -       return !mips_busprobe32(tmp, (bus->mmio +
2330 -               (pc->core->core_index * BCMA_CORE_SIZE)));
2331 -#endif
2332 -
2333 -       return true;
2334 -}
2335 -
2336 -void bcma_core_pci_init(struct bcma_drv_pci *pc)
2337 +void __devinit bcma_core_pci_init(struct bcma_drv_pci *pc)
2338  {
2339         if (pc->setup_done)
2340                 return;
2341  
2342 -       if (bcma_core_pci_is_in_hostmode(pc)) {
2343  #ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
2344 +       pc->hostmode = bcma_core_pci_is_in_hostmode(pc);
2345 +       if (pc->hostmode)
2346                 bcma_core_pci_hostmode_init(pc);
2347 -#else
2348 -               pr_err("Driver compiled without support for hostmode PCI\n");
2349  #endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */
2350 -       } else {
2351 -               bcma_core_pci_clientmode_init(pc);
2352 -       }
2353  
2354 -       pc->setup_done = true;
2355 +       if (!pc->hostmode)
2356 +               bcma_core_pci_clientmode_init(pc);
2357  }
2358  
2359  int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core,
2360                           bool enable)
2361  {
2362 -       struct pci_dev *pdev = pc->core->bus->host_pci;
2363 +       struct pci_dev *pdev;
2364         u32 coremask, tmp;
2365         int err = 0;
2366  
2367 -       if (core->bus->hosttype != BCMA_HOSTTYPE_PCI) {
2368 +       if (!pc || core->bus->hosttype != BCMA_HOSTTYPE_PCI) {
2369                 /* This bcma device is not on a PCI host-bus. So the IRQs are
2370                  * not routed through the PCI core.
2371                  * So we must not enable routing through the PCI core. */
2372                 goto out;
2373         }
2374  
2375 +       pdev = pc->core->bus->host_pci;
2376 +
2377         err = pci_read_config_dword(pdev, BCMA_PCI_IRQMASK, &tmp);
2378         if (err)
2379                 goto out;
2380 @@ -236,3 +261,17 @@ out:
2381         return err;
2382  }
2383  EXPORT_SYMBOL_GPL(bcma_core_pci_irq_ctl);
2384 +
2385 +void bcma_core_pci_extend_L1timer(struct bcma_drv_pci *pc, bool extend)
2386 +{
2387 +       u32 w;
2388 +
2389 +       w = bcma_pcie_read(pc, BCMA_CORE_PCI_DLLP_PMTHRESHREG);
2390 +       if (extend)
2391 +               w |= BCMA_CORE_PCI_ASPMTIMER_EXTEND;
2392 +       else
2393 +               w &= ~BCMA_CORE_PCI_ASPMTIMER_EXTEND;
2394 +       bcma_pcie_write(pc, BCMA_CORE_PCI_DLLP_PMTHRESHREG, w);
2395 +       bcma_pcie_read(pc, BCMA_CORE_PCI_DLLP_PMTHRESHREG);
2396 +}
2397 +EXPORT_SYMBOL_GPL(bcma_core_pci_extend_L1timer);
2398 --- a/drivers/bcma/driver_pci_host.c
2399 +++ b/drivers/bcma/driver_pci_host.c
2400 @@ -2,13 +2,616 @@
2401   * Broadcom specific AMBA
2402   * PCI Core in hostmode
2403   *
2404 + * Copyright 2005 - 2011, Broadcom Corporation
2405 + * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
2406 + * Copyright 2011, 2012, Hauke Mehrtens <hauke@hauke-m.de>
2407 + *
2408   * Licensed under the GNU/GPL. See COPYING for details.
2409   */
2410  
2411  #include "bcma_private.h"
2412 +#include <linux/pci.h>
2413 +#include <linux/export.h>
2414  #include <linux/bcma/bcma.h>
2415 +#include <asm/paccess.h>
2416 +
2417 +/* Probe a 32bit value on the bus and catch bus exceptions.
2418 + * Returns nonzero on a bus exception.
2419 + * This is MIPS specific */
2420 +#define mips_busprobe32(val, addr)     get_dbe((val), ((u32 *)(addr)))
2421 +
2422 +/* Assume one-hot slot wiring */
2423 +#define BCMA_PCI_SLOT_MAX      16
2424 +#define        PCI_CONFIG_SPACE_SIZE   256
2425 +
2426 +bool __devinit bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc)
2427 +{
2428 +       struct bcma_bus *bus = pc->core->bus;
2429 +       u16 chipid_top;
2430 +       u32 tmp;
2431 +
2432 +       chipid_top = (bus->chipinfo.id & 0xFF00);
2433 +       if (chipid_top != 0x4700 &&
2434 +           chipid_top != 0x5300)
2435 +               return false;
2436 +
2437 +       bcma_core_enable(pc->core, 0);
2438 +
2439 +       return !mips_busprobe32(tmp, pc->core->io_addr);
2440 +}
2441 +
2442 +static u32 bcma_pcie_read_config(struct bcma_drv_pci *pc, u32 address)
2443 +{
2444 +       pcicore_write32(pc, BCMA_CORE_PCI_CONFIG_ADDR, address);
2445 +       pcicore_read32(pc, BCMA_CORE_PCI_CONFIG_ADDR);
2446 +       return pcicore_read32(pc, BCMA_CORE_PCI_CONFIG_DATA);
2447 +}
2448 +
2449 +static void bcma_pcie_write_config(struct bcma_drv_pci *pc, u32 address,
2450 +                                  u32 data)
2451 +{
2452 +       pcicore_write32(pc, BCMA_CORE_PCI_CONFIG_ADDR, address);
2453 +       pcicore_read32(pc, BCMA_CORE_PCI_CONFIG_ADDR);
2454 +       pcicore_write32(pc, BCMA_CORE_PCI_CONFIG_DATA, data);
2455 +}
2456 +
2457 +static u32 bcma_get_cfgspace_addr(struct bcma_drv_pci *pc, unsigned int dev,
2458 +                            unsigned int func, unsigned int off)
2459 +{
2460 +       u32 addr = 0;
2461 +
2462 +       /* Issue config commands only when the data link is up (atleast
2463 +        * one external pcie device is present).
2464 +        */
2465 +       if (dev >= 2 || !(bcma_pcie_read(pc, BCMA_CORE_PCI_DLLP_LSREG)
2466 +                         & BCMA_CORE_PCI_DLLP_LSREG_LINKUP))
2467 +               goto out;
2468 +
2469 +       /* Type 0 transaction */
2470 +       /* Slide the PCI window to the appropriate slot */
2471 +       pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI1, BCMA_CORE_PCI_SBTOPCI_CFG0);
2472 +       /* Calculate the address */
2473 +       addr = pc->host_controller->host_cfg_addr;
2474 +       addr |= (dev << BCMA_CORE_PCI_CFG_SLOT_SHIFT);
2475 +       addr |= (func << BCMA_CORE_PCI_CFG_FUN_SHIFT);
2476 +       addr |= (off & ~3);
2477 +
2478 +out:
2479 +       return addr;
2480 +}
2481 +
2482 +static int bcma_extpci_read_config(struct bcma_drv_pci *pc, unsigned int dev,
2483 +                                 unsigned int func, unsigned int off,
2484 +                                 void *buf, int len)
2485 +{
2486 +       int err = -EINVAL;
2487 +       u32 addr, val;
2488 +       void __iomem *mmio = 0;
2489 +
2490 +       WARN_ON(!pc->hostmode);
2491 +       if (unlikely(len != 1 && len != 2 && len != 4))
2492 +               goto out;
2493 +       if (dev == 0) {
2494 +               /* we support only two functions on device 0 */
2495 +               if (func > 1)
2496 +                       goto out;
2497 +
2498 +               /* accesses to config registers with offsets >= 256
2499 +                * requires indirect access.
2500 +                */
2501 +               if (off >= PCI_CONFIG_SPACE_SIZE) {
2502 +                       addr = (func << 12);
2503 +                       addr |= (off & 0x0FFC);
2504 +                       val = bcma_pcie_read_config(pc, addr);
2505 +               } else {
2506 +                       addr = BCMA_CORE_PCI_PCICFG0;
2507 +                       addr |= (func << 8);
2508 +                       addr |= (off & 0xFC);
2509 +                       val = pcicore_read32(pc, addr);
2510 +               }
2511 +       } else {
2512 +               addr = bcma_get_cfgspace_addr(pc, dev, func, off);
2513 +               if (unlikely(!addr))
2514 +                       goto out;
2515 +               err = -ENOMEM;
2516 +               mmio = ioremap_nocache(addr, sizeof(val));
2517 +               if (!mmio)
2518 +                       goto out;
2519 +
2520 +               if (mips_busprobe32(val, mmio)) {
2521 +                       val = 0xFFFFFFFF;
2522 +                       goto unmap;
2523 +               }
2524 +       }
2525 +       val >>= (8 * (off & 3));
2526 +
2527 +       switch (len) {
2528 +       case 1:
2529 +               *((u8 *)buf) = (u8)val;
2530 +               break;
2531 +       case 2:
2532 +               *((u16 *)buf) = (u16)val;
2533 +               break;
2534 +       case 4:
2535 +               *((u32 *)buf) = (u32)val;
2536 +               break;
2537 +       }
2538 +       err = 0;
2539 +unmap:
2540 +       if (mmio)
2541 +               iounmap(mmio);
2542 +out:
2543 +       return err;
2544 +}
2545  
2546 -void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc)
2547 +static int bcma_extpci_write_config(struct bcma_drv_pci *pc, unsigned int dev,
2548 +                                  unsigned int func, unsigned int off,
2549 +                                  const void *buf, int len)
2550  {
2551 -       pr_err("No support for PCI core in hostmode yet\n");
2552 +       int err = -EINVAL;
2553 +       u32 addr, val;
2554 +       void __iomem *mmio = 0;
2555 +       u16 chipid = pc->core->bus->chipinfo.id;
2556 +
2557 +       WARN_ON(!pc->hostmode);
2558 +       if (unlikely(len != 1 && len != 2 && len != 4))
2559 +               goto out;
2560 +       if (dev == 0) {
2561 +               /* we support only two functions on device 0 */
2562 +               if (func > 1)
2563 +                       goto out;
2564 +
2565 +               /* accesses to config registers with offsets >= 256
2566 +                * requires indirect access.
2567 +                */
2568 +               if (off >= PCI_CONFIG_SPACE_SIZE) {
2569 +                       addr = (func << 12);
2570 +                       addr |= (off & 0x0FFC);
2571 +                       val = bcma_pcie_read_config(pc, addr);
2572 +               } else {
2573 +                       addr = BCMA_CORE_PCI_PCICFG0;
2574 +                       addr |= (func << 8);
2575 +                       addr |= (off & 0xFC);
2576 +                       val = pcicore_read32(pc, addr);
2577 +               }
2578 +       } else {
2579 +               addr = bcma_get_cfgspace_addr(pc, dev, func, off);
2580 +               if (unlikely(!addr))
2581 +                       goto out;
2582 +               err = -ENOMEM;
2583 +               mmio = ioremap_nocache(addr, sizeof(val));
2584 +               if (!mmio)
2585 +                       goto out;
2586 +
2587 +               if (mips_busprobe32(val, mmio)) {
2588 +                       val = 0xFFFFFFFF;
2589 +                       goto unmap;
2590 +               }
2591 +       }
2592 +
2593 +       switch (len) {
2594 +       case 1:
2595 +               val &= ~(0xFF << (8 * (off & 3)));
2596 +               val |= *((const u8 *)buf) << (8 * (off & 3));
2597 +               break;
2598 +       case 2:
2599 +               val &= ~(0xFFFF << (8 * (off & 3)));
2600 +               val |= *((const u16 *)buf) << (8 * (off & 3));
2601 +               break;
2602 +       case 4:
2603 +               val = *((const u32 *)buf);
2604 +               break;
2605 +       }
2606 +       if (dev == 0) {
2607 +               /* accesses to config registers with offsets >= 256
2608 +                * requires indirect access.
2609 +                */
2610 +               if (off >= PCI_CONFIG_SPACE_SIZE)
2611 +                       bcma_pcie_write_config(pc, addr, val);
2612 +               else
2613 +                       pcicore_write32(pc, addr, val);
2614 +       } else {
2615 +               writel(val, mmio);
2616 +
2617 +               if (chipid == BCMA_CHIP_ID_BCM4716 ||
2618 +                   chipid == BCMA_CHIP_ID_BCM4748)
2619 +                       readl(mmio);
2620 +       }
2621 +
2622 +       err = 0;
2623 +unmap:
2624 +       if (mmio)
2625 +               iounmap(mmio);
2626 +out:
2627 +       return err;
2628 +}
2629 +
2630 +static int bcma_core_pci_hostmode_read_config(struct pci_bus *bus,
2631 +                                             unsigned int devfn,
2632 +                                             int reg, int size, u32 *val)
2633 +{
2634 +       unsigned long flags;
2635 +       int err;
2636 +       struct bcma_drv_pci *pc;
2637 +       struct bcma_drv_pci_host *pc_host;
2638 +
2639 +       pc_host = container_of(bus->ops, struct bcma_drv_pci_host, pci_ops);
2640 +       pc = pc_host->pdev;
2641 +
2642 +       spin_lock_irqsave(&pc_host->cfgspace_lock, flags);
2643 +       err = bcma_extpci_read_config(pc, PCI_SLOT(devfn),
2644 +                                    PCI_FUNC(devfn), reg, val, size);
2645 +       spin_unlock_irqrestore(&pc_host->cfgspace_lock, flags);
2646 +
2647 +       return err ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
2648 +}
2649 +
2650 +static int bcma_core_pci_hostmode_write_config(struct pci_bus *bus,
2651 +                                              unsigned int devfn,
2652 +                                              int reg, int size, u32 val)
2653 +{
2654 +       unsigned long flags;
2655 +       int err;
2656 +       struct bcma_drv_pci *pc;
2657 +       struct bcma_drv_pci_host *pc_host;
2658 +
2659 +       pc_host = container_of(bus->ops, struct bcma_drv_pci_host, pci_ops);
2660 +       pc = pc_host->pdev;
2661 +
2662 +       spin_lock_irqsave(&pc_host->cfgspace_lock, flags);
2663 +       err = bcma_extpci_write_config(pc, PCI_SLOT(devfn),
2664 +                                     PCI_FUNC(devfn), reg, &val, size);
2665 +       spin_unlock_irqrestore(&pc_host->cfgspace_lock, flags);
2666 +
2667 +       return err ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
2668 +}
2669 +
2670 +/* return cap_offset if requested capability exists in the PCI config space */
2671 +static u8 __devinit bcma_find_pci_capability(struct bcma_drv_pci *pc,
2672 +                                            unsigned int dev,
2673 +                                            unsigned int func, u8 req_cap_id,
2674 +                                            unsigned char *buf, u32 *buflen)
2675 +{
2676 +       u8 cap_id;
2677 +       u8 cap_ptr = 0;
2678 +       u32 bufsize;
2679 +       u8 byte_val;
2680 +
2681 +       /* check for Header type 0 */
2682 +       bcma_extpci_read_config(pc, dev, func, PCI_HEADER_TYPE, &byte_val,
2683 +                               sizeof(u8));
2684 +       if ((byte_val & 0x7F) != PCI_HEADER_TYPE_NORMAL)
2685 +               return cap_ptr;
2686 +
2687 +       /* check if the capability pointer field exists */
2688 +       bcma_extpci_read_config(pc, dev, func, PCI_STATUS, &byte_val,
2689 +                               sizeof(u8));
2690 +       if (!(byte_val & PCI_STATUS_CAP_LIST))
2691 +               return cap_ptr;
2692 +
2693 +       /* check if the capability pointer is 0x00 */
2694 +       bcma_extpci_read_config(pc, dev, func, PCI_CAPABILITY_LIST, &cap_ptr,
2695 +                               sizeof(u8));
2696 +       if (cap_ptr == 0x00)
2697 +               return cap_ptr;
2698 +
2699 +       /* loop thr'u the capability list and see if the requested capabilty
2700 +        * exists */
2701 +       bcma_extpci_read_config(pc, dev, func, cap_ptr, &cap_id, sizeof(u8));
2702 +       while (cap_id != req_cap_id) {
2703 +               bcma_extpci_read_config(pc, dev, func, cap_ptr + 1, &cap_ptr,
2704 +                                       sizeof(u8));
2705 +               if (cap_ptr == 0x00)
2706 +                       return cap_ptr;
2707 +               bcma_extpci_read_config(pc, dev, func, cap_ptr, &cap_id,
2708 +                                       sizeof(u8));
2709 +       }
2710 +
2711 +       /* found the caller requested capability */
2712 +       if ((buf != NULL) && (buflen != NULL)) {
2713 +               u8 cap_data;
2714 +
2715 +               bufsize = *buflen;
2716 +               if (!bufsize)
2717 +                       return cap_ptr;
2718 +
2719 +               *buflen = 0;
2720 +
2721 +               /* copy the cpability data excluding cap ID and next ptr */
2722 +               cap_data = cap_ptr + 2;
2723 +               if ((bufsize + cap_data)  > PCI_CONFIG_SPACE_SIZE)
2724 +                       bufsize = PCI_CONFIG_SPACE_SIZE - cap_data;
2725 +               *buflen = bufsize;
2726 +               while (bufsize--) {
2727 +                       bcma_extpci_read_config(pc, dev, func, cap_data, buf,
2728 +                                               sizeof(u8));
2729 +                       cap_data++;
2730 +                       buf++;
2731 +               }
2732 +       }
2733 +
2734 +       return cap_ptr;
2735 +}
2736 +
2737 +/* If the root port is capable of returning Config Request
2738 + * Retry Status (CRS) Completion Status to software then
2739 + * enable the feature.
2740 + */
2741 +static void __devinit bcma_core_pci_enable_crs(struct bcma_drv_pci *pc)
2742 +{
2743 +       struct bcma_bus *bus = pc->core->bus;
2744 +       u8 cap_ptr, root_ctrl, root_cap, dev;
2745 +       u16 val16;
2746 +       int i;
2747 +
2748 +       cap_ptr = bcma_find_pci_capability(pc, 0, 0, PCI_CAP_ID_EXP, NULL,
2749 +                                          NULL);
2750 +       root_cap = cap_ptr + PCI_EXP_RTCAP;
2751 +       bcma_extpci_read_config(pc, 0, 0, root_cap, &val16, sizeof(u16));
2752 +       if (val16 & BCMA_CORE_PCI_RC_CRS_VISIBILITY) {
2753 +               /* Enable CRS software visibility */
2754 +               root_ctrl = cap_ptr + PCI_EXP_RTCTL;
2755 +               val16 = PCI_EXP_RTCTL_CRSSVE;
2756 +               bcma_extpci_read_config(pc, 0, 0, root_ctrl, &val16,
2757 +                                       sizeof(u16));
2758 +
2759 +               /* Initiate a configuration request to read the vendor id
2760 +                * field of the device function's config space header after
2761 +                * 100 ms wait time from the end of Reset. If the device is
2762 +                * not done with its internal initialization, it must at
2763 +                * least return a completion TLP, with a completion status
2764 +                * of "Configuration Request Retry Status (CRS)". The root
2765 +                * complex must complete the request to the host by returning
2766 +                * a read-data value of 0001h for the Vendor ID field and
2767 +                * all 1s for any additional bytes included in the request.
2768 +                * Poll using the config reads for max wait time of 1 sec or
2769 +                * until we receive the successful completion status. Repeat
2770 +                * the procedure for all the devices.
2771 +                */
2772 +               for (dev = 1; dev < BCMA_PCI_SLOT_MAX; dev++) {
2773 +                       for (i = 0; i < 100000; i++) {
2774 +                               bcma_extpci_read_config(pc, dev, 0,
2775 +                                                       PCI_VENDOR_ID, &val16,
2776 +                                                       sizeof(val16));
2777 +                               if (val16 != 0x1)
2778 +                                       break;
2779 +                               udelay(10);
2780 +                       }
2781 +                       if (val16 == 0x1)
2782 +                               bcma_err(bus, "PCI: Broken device in slot %d\n",
2783 +                                        dev);
2784 +               }
2785 +       }
2786 +}
2787 +
2788 +void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc)
2789 +{
2790 +       struct bcma_bus *bus = pc->core->bus;
2791 +       struct bcma_drv_pci_host *pc_host;
2792 +       u32 tmp;
2793 +       u32 pci_membase_1G;
2794 +       unsigned long io_map_base;
2795 +
2796 +       bcma_info(bus, "PCIEcore in host mode found\n");
2797 +
2798 +       if (bus->sprom.boardflags_lo & BCMA_CORE_PCI_BFL_NOPCI) {
2799 +               bcma_info(bus, "This PCIE core is disabled and not working\n");
2800 +               return;
2801 +       }
2802 +
2803 +       pc_host = kzalloc(sizeof(*pc_host), GFP_KERNEL);
2804 +       if (!pc_host)  {
2805 +               bcma_err(bus, "can not allocate memory");
2806 +               return;
2807 +       }
2808 +
2809 +       spin_lock_init(&pc_host->cfgspace_lock);
2810 +
2811 +       pc->host_controller = pc_host;
2812 +       pc_host->pci_controller.io_resource = &pc_host->io_resource;
2813 +       pc_host->pci_controller.mem_resource = &pc_host->mem_resource;
2814 +       pc_host->pci_controller.pci_ops = &pc_host->pci_ops;
2815 +       pc_host->pdev = pc;
2816 +
2817 +       pci_membase_1G = BCMA_SOC_PCI_DMA;
2818 +       pc_host->host_cfg_addr = BCMA_SOC_PCI_CFG;
2819 +
2820 +       pc_host->pci_ops.read = bcma_core_pci_hostmode_read_config;
2821 +       pc_host->pci_ops.write = bcma_core_pci_hostmode_write_config;
2822 +
2823 +       pc_host->mem_resource.name = "BCMA PCIcore external memory",
2824 +       pc_host->mem_resource.start = BCMA_SOC_PCI_DMA;
2825 +       pc_host->mem_resource.end = BCMA_SOC_PCI_DMA + BCMA_SOC_PCI_DMA_SZ - 1;
2826 +       pc_host->mem_resource.flags = IORESOURCE_MEM | IORESOURCE_PCI_FIXED;
2827 +
2828 +       pc_host->io_resource.name = "BCMA PCIcore external I/O",
2829 +       pc_host->io_resource.start = 0x100;
2830 +       pc_host->io_resource.end = 0x7FF;
2831 +       pc_host->io_resource.flags = IORESOURCE_IO | IORESOURCE_PCI_FIXED;
2832 +
2833 +       /* Reset RC */
2834 +       usleep_range(3000, 5000);
2835 +       pcicore_write32(pc, BCMA_CORE_PCI_CTL, BCMA_CORE_PCI_CTL_RST_OE);
2836 +       msleep(50);
2837 +       pcicore_write32(pc, BCMA_CORE_PCI_CTL, BCMA_CORE_PCI_CTL_RST |
2838 +                       BCMA_CORE_PCI_CTL_RST_OE);
2839 +
2840 +       /* 64 MB I/O access window. On 4716, use
2841 +        * sbtopcie0 to access the device registers. We
2842 +        * can't use address match 2 (1 GB window) region
2843 +        * as mips can't generate 64-bit address on the
2844 +        * backplane.
2845 +        */
2846 +       if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4716 ||
2847 +           bus->chipinfo.id == BCMA_CHIP_ID_BCM4748) {
2848 +               pc_host->mem_resource.start = BCMA_SOC_PCI_MEM;
2849 +               pc_host->mem_resource.end = BCMA_SOC_PCI_MEM +
2850 +                                           BCMA_SOC_PCI_MEM_SZ - 1;
2851 +               pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0,
2852 +                               BCMA_CORE_PCI_SBTOPCI_MEM | BCMA_SOC_PCI_MEM);
2853 +       } else if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4706) {
2854 +               tmp = BCMA_CORE_PCI_SBTOPCI_MEM;
2855 +               tmp |= BCMA_CORE_PCI_SBTOPCI_PREF;
2856 +               tmp |= BCMA_CORE_PCI_SBTOPCI_BURST;
2857 +               if (pc->core->core_unit == 0) {
2858 +                       pc_host->mem_resource.start = BCMA_SOC_PCI_MEM;
2859 +                       pc_host->mem_resource.end = BCMA_SOC_PCI_MEM +
2860 +                                                   BCMA_SOC_PCI_MEM_SZ - 1;
2861 +                       pc_host->io_resource.start = 0x100;
2862 +                       pc_host->io_resource.end = 0x47F;
2863 +                       pci_membase_1G = BCMA_SOC_PCIE_DMA_H32;
2864 +                       pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0,
2865 +                                       tmp | BCMA_SOC_PCI_MEM);
2866 +               } else if (pc->core->core_unit == 1) {
2867 +                       pc_host->mem_resource.start = BCMA_SOC_PCI1_MEM;
2868 +                       pc_host->mem_resource.end = BCMA_SOC_PCI1_MEM +
2869 +                                                   BCMA_SOC_PCI_MEM_SZ - 1;
2870 +                       pc_host->io_resource.start = 0x480;
2871 +                       pc_host->io_resource.end = 0x7FF;
2872 +                       pci_membase_1G = BCMA_SOC_PCIE1_DMA_H32;
2873 +                       pc_host->host_cfg_addr = BCMA_SOC_PCI1_CFG;
2874 +                       pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0,
2875 +                                       tmp | BCMA_SOC_PCI1_MEM);
2876 +               }
2877 +       } else
2878 +               pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0,
2879 +                               BCMA_CORE_PCI_SBTOPCI_IO);
2880 +
2881 +       /* 64 MB configuration access window */
2882 +       pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI1, BCMA_CORE_PCI_SBTOPCI_CFG0);
2883 +
2884 +       /* 1 GB memory access window */
2885 +       pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI2,
2886 +                       BCMA_CORE_PCI_SBTOPCI_MEM | pci_membase_1G);
2887 +
2888 +
2889 +       /* As per PCI Express Base Spec 1.1 we need to wait for
2890 +        * at least 100 ms from the end of a reset (cold/warm/hot)
2891 +        * before issuing configuration requests to PCI Express
2892 +        * devices.
2893 +        */
2894 +       msleep(100);
2895 +
2896 +       bcma_core_pci_enable_crs(pc);
2897 +
2898 +       if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4706 ||
2899 +           bus->chipinfo.id == BCMA_CHIP_ID_BCM4716) {
2900 +               u16 val16;
2901 +               bcma_extpci_read_config(pc, 0, 0, BCMA_CORE_PCI_CFG_DEVCTRL,
2902 +                                       &val16, sizeof(val16));
2903 +               val16 |= (2 << 5);      /* Max payload size of 512 */
2904 +               val16 |= (2 << 12);     /* MRRS 512 */
2905 +               bcma_extpci_write_config(pc, 0, 0, BCMA_CORE_PCI_CFG_DEVCTRL,
2906 +                                        &val16, sizeof(val16));
2907 +       }
2908 +
2909 +       /* Enable PCI bridge BAR0 memory & master access */
2910 +       tmp = PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
2911 +       bcma_extpci_write_config(pc, 0, 0, PCI_COMMAND, &tmp, sizeof(tmp));
2912 +
2913 +       /* Enable PCI interrupts */
2914 +       pcicore_write32(pc, BCMA_CORE_PCI_IMASK, BCMA_CORE_PCI_IMASK_INTA);
2915 +
2916 +       /* Ok, ready to run, register it to the system.
2917 +        * The following needs change, if we want to port hostmode
2918 +        * to non-MIPS platform. */
2919 +       io_map_base = (unsigned long)ioremap_nocache(pc_host->mem_resource.start,
2920 +                                                    resource_size(&pc_host->mem_resource));
2921 +       pc_host->pci_controller.io_map_base = io_map_base;
2922 +       set_io_port_base(pc_host->pci_controller.io_map_base);
2923 +       /* Give some time to the PCI controller to configure itself with the new
2924 +        * values. Not waiting at this point causes crashes of the machine. */
2925 +       usleep_range(10000, 15000);
2926 +       register_pci_controller(&pc_host->pci_controller);
2927 +       return;
2928 +}
2929 +
2930 +/* Early PCI fixup for a device on the PCI-core bridge. */
2931 +static void bcma_core_pci_fixup_pcibridge(struct pci_dev *dev)
2932 +{
2933 +       if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) {
2934 +               /* This is not a device on the PCI-core bridge. */
2935 +               return;
2936 +       }
2937 +       if (PCI_SLOT(dev->devfn) != 0)
2938 +               return;
2939 +
2940 +       pr_info("PCI: Fixing up bridge %s\n", pci_name(dev));
2941 +
2942 +       /* Enable PCI bridge bus mastering and memory space */
2943 +       pci_set_master(dev);
2944 +       if (pcibios_enable_device(dev, ~0) < 0) {
2945 +               pr_err("PCI: BCMA bridge enable failed\n");
2946 +               return;
2947 +       }
2948 +
2949 +       /* Enable PCI bridge BAR1 prefetch and burst */
2950 +       pci_write_config_dword(dev, BCMA_PCI_BAR1_CONTROL, 3);
2951 +}
2952 +DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, bcma_core_pci_fixup_pcibridge);
2953 +
2954 +/* Early PCI fixup for all PCI-cores to set the correct memory address. */
2955 +static void bcma_core_pci_fixup_addresses(struct pci_dev *dev)
2956 +{
2957 +       struct resource *res;
2958 +       int pos, err;
2959 +
2960 +       if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) {
2961 +               /* This is not a device on the PCI-core bridge. */
2962 +               return;
2963 +       }
2964 +       if (PCI_SLOT(dev->devfn) == 0)
2965 +               return;
2966 +
2967 +       pr_info("PCI: Fixing up addresses %s\n", pci_name(dev));
2968 +
2969 +       for (pos = 0; pos < 6; pos++) {
2970 +               res = &dev->resource[pos];
2971 +               if (res->flags & (IORESOURCE_IO | IORESOURCE_MEM)) {
2972 +                       err = pci_assign_resource(dev, pos);
2973 +                       if (err)
2974 +                               pr_err("PCI: Problem fixing up the addresses on %s\n",
2975 +                                      pci_name(dev));
2976 +               }
2977 +       }
2978 +}
2979 +DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, bcma_core_pci_fixup_addresses);
2980 +
2981 +/* This function is called when doing a pci_enable_device().
2982 + * We must first check if the device is a device on the PCI-core bridge. */
2983 +int bcma_core_pci_plat_dev_init(struct pci_dev *dev)
2984 +{
2985 +       struct bcma_drv_pci_host *pc_host;
2986 +
2987 +       if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) {
2988 +               /* This is not a device on the PCI-core bridge. */
2989 +               return -ENODEV;
2990 +       }
2991 +       pc_host = container_of(dev->bus->ops, struct bcma_drv_pci_host,
2992 +                              pci_ops);
2993 +
2994 +       pr_info("PCI: Fixing up device %s\n", pci_name(dev));
2995 +
2996 +       /* Fix up interrupt lines */
2997 +       dev->irq = bcma_core_irq(pc_host->pdev->core);
2998 +       pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
2999 +
3000 +       return 0;
3001 +}
3002 +EXPORT_SYMBOL(bcma_core_pci_plat_dev_init);
3003 +
3004 +/* PCI device IRQ mapping. */
3005 +int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev)
3006 +{
3007 +       struct bcma_drv_pci_host *pc_host;
3008 +
3009 +       if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) {
3010 +               /* This is not a device on the PCI-core bridge. */
3011 +               return -ENODEV;
3012 +       }
3013 +
3014 +       pc_host = container_of(dev->bus->ops, struct bcma_drv_pci_host,
3015 +                              pci_ops);
3016 +       return bcma_core_irq(pc_host->pdev->core);
3017  }
3018 +EXPORT_SYMBOL(bcma_core_pci_pcibios_map_irq);
3019 --- a/drivers/bcma/host_pci.c
3020 +++ b/drivers/bcma/host_pci.c
3021 @@ -18,7 +18,7 @@ static void bcma_host_pci_switch_core(st
3022         pci_write_config_dword(core->bus->host_pci, BCMA_PCI_BAR0_WIN2,
3023                                core->wrap);
3024         core->bus->mapped_core = core;
3025 -       pr_debug("Switched to core: 0x%X\n", core->id.id);
3026 +       bcma_debug(core->bus, "Switched to core: 0x%X\n", core->id.id);
3027  }
3028  
3029  /* Provides access to the requested core. Returns base offset that has to be
3030 @@ -77,8 +77,8 @@ static void bcma_host_pci_write32(struct
3031  }
3032  
3033  #ifdef CONFIG_BCMA_BLOCKIO
3034 -void bcma_host_pci_block_read(struct bcma_device *core, void *buffer,
3035 -                             size_t count, u16 offset, u8 reg_width)
3036 +static void bcma_host_pci_block_read(struct bcma_device *core, void *buffer,
3037 +                                    size_t count, u16 offset, u8 reg_width)
3038  {
3039         void __iomem *addr = core->bus->mmio + offset;
3040         if (core->bus->mapped_core != core)
3041 @@ -100,8 +100,9 @@ void bcma_host_pci_block_read(struct bcm
3042         }
3043  }
3044  
3045 -void bcma_host_pci_block_write(struct bcma_device *core, const void *buffer,
3046 -                              size_t count, u16 offset, u8 reg_width)
3047 +static void bcma_host_pci_block_write(struct bcma_device *core,
3048 +                                     const void *buffer, size_t count,
3049 +                                     u16 offset, u8 reg_width)
3050  {
3051         void __iomem *addr = core->bus->mmio + offset;
3052         if (core->bus->mapped_core != core)
3053 @@ -139,7 +140,7 @@ static void bcma_host_pci_awrite32(struc
3054         iowrite32(value, core->bus->mmio + (1 * BCMA_CORE_SIZE) + offset);
3055  }
3056  
3057 -const struct bcma_host_ops bcma_host_pci_ops = {
3058 +static const struct bcma_host_ops bcma_host_pci_ops = {
3059         .read8          = bcma_host_pci_read8,
3060         .read16         = bcma_host_pci_read16,
3061         .read32         = bcma_host_pci_read32,
3062 @@ -154,8 +155,8 @@ const struct bcma_host_ops bcma_host_pci
3063         .awrite32       = bcma_host_pci_awrite32,
3064  };
3065  
3066 -static int bcma_host_pci_probe(struct pci_dev *dev,
3067 -                            const struct pci_device_id *id)
3068 +static int __devinit bcma_host_pci_probe(struct pci_dev *dev,
3069 +                                        const struct pci_device_id *id)
3070  {
3071         struct bcma_bus *bus;
3072         int err = -ENOMEM;
3073 @@ -188,7 +189,7 @@ static int bcma_host_pci_probe(struct pc
3074  
3075         /* SSB needed additional powering up, do we have any AMBA PCI cards? */
3076         if (!pci_is_pcie(dev))
3077 -               pr_err("PCI card detected, report problems.\n");
3078 +               bcma_err(bus, "PCI card detected, report problems.\n");
3079  
3080         /* Map MMIO */
3081         err = -ENOMEM;
3082 @@ -201,6 +202,9 @@ static int bcma_host_pci_probe(struct pc
3083         bus->hosttype = BCMA_HOSTTYPE_PCI;
3084         bus->ops = &bcma_host_pci_ops;
3085  
3086 +       bus->boardinfo.vendor = bus->host_pci->subsystem_vendor;
3087 +       bus->boardinfo.type = bus->host_pci->subsystem_device;
3088 +
3089         /* Register */
3090         err = bcma_bus_register(bus);
3091         if (err)
3092 @@ -222,7 +226,7 @@ err_kfree_bus:
3093         return err;
3094  }
3095  
3096 -static void bcma_host_pci_remove(struct pci_dev *dev)
3097 +static void __devexit bcma_host_pci_remove(struct pci_dev *dev)
3098  {
3099         struct bcma_bus *bus = pci_get_drvdata(dev);
3100  
3101 @@ -234,7 +238,7 @@ static void bcma_host_pci_remove(struct
3102         pci_set_drvdata(dev, NULL);
3103  }
3104  
3105 -#ifdef CONFIG_PM
3106 +#ifdef CONFIG_PM_SLEEP
3107  static int bcma_host_pci_suspend(struct device *dev)
3108  {
3109         struct pci_dev *pdev = to_pci_dev(dev);
3110 @@ -257,17 +261,21 @@ static SIMPLE_DEV_PM_OPS(bcma_pm_ops, bc
3111                          bcma_host_pci_resume);
3112  #define BCMA_PM_OPS    (&bcma_pm_ops)
3113  
3114 -#else /* CONFIG_PM */
3115 +#else /* CONFIG_PM_SLEEP */
3116  
3117  #define BCMA_PM_OPS     NULL
3118  
3119 -#endif /* CONFIG_PM */
3120 +#endif /* CONFIG_PM_SLEEP */
3121  
3122  static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = {
3123         { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) },
3124 +       { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 43224) },
3125         { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) },
3126         { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4353) },
3127         { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4357) },
3128 +       { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4358) },
3129 +       { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4359) },
3130 +       { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4365) },
3131         { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) },
3132         { 0, },
3133  };
3134 @@ -277,7 +285,7 @@ static struct pci_driver bcma_pci_bridge
3135         .name = "bcma-pci-bridge",
3136         .id_table = bcma_pci_bridge_tbl,
3137         .probe = bcma_host_pci_probe,
3138 -       .remove = bcma_host_pci_remove,
3139 +       .remove = __devexit_p(bcma_host_pci_remove),
3140         .driver.pm = BCMA_PM_OPS,
3141  };
3142  
3143 --- a/drivers/bcma/host_soc.c
3144 +++ b/drivers/bcma/host_soc.c
3145 @@ -143,7 +143,7 @@ static void bcma_host_soc_awrite32(struc
3146         writel(value, core->io_wrap + offset);
3147  }
3148  
3149 -const struct bcma_host_ops bcma_host_soc_ops = {
3150 +static const struct bcma_host_ops bcma_host_soc_ops = {
3151         .read8          = bcma_host_soc_read8,
3152         .read16         = bcma_host_soc_read16,
3153         .read32         = bcma_host_soc_read32,
3154 --- a/drivers/bcma/main.c
3155 +++ b/drivers/bcma/main.c
3156 @@ -7,12 +7,19 @@
3157  
3158  #include "bcma_private.h"
3159  #include <linux/module.h>
3160 +#include <linux/platform_device.h>
3161  #include <linux/bcma/bcma.h>
3162  #include <linux/slab.h>
3163  
3164  MODULE_DESCRIPTION("Broadcom's specific AMBA driver");
3165  MODULE_LICENSE("GPL");
3166  
3167 +/* contains the number the next bus should get. */
3168 +static unsigned int bcma_bus_next_num = 0;
3169 +
3170 +/* bcma_buses_mutex locks the bcma_bus_next_num */
3171 +static DEFINE_MUTEX(bcma_buses_mutex);
3172 +
3173  static int bcma_bus_match(struct device *dev, struct device_driver *drv);
3174  static int bcma_device_probe(struct device *dev);
3175  static int bcma_device_remove(struct device *dev);
3176 @@ -55,7 +62,14 @@ static struct bus_type bcma_bus_type = {
3177         .dev_attrs      = bcma_device_attrs,
3178  };
3179  
3180 -static struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid)
3181 +static u16 bcma_cc_core_id(struct bcma_bus *bus)
3182 +{
3183 +       if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4706)
3184 +               return BCMA_CORE_4706_CHIPCOMMON;
3185 +       return BCMA_CORE_CHIPCOMMON;
3186 +}
3187 +
3188 +struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid)
3189  {
3190         struct bcma_device *core;
3191  
3192 @@ -65,6 +79,38 @@ static struct bcma_device *bcma_find_cor
3193         }
3194         return NULL;
3195  }
3196 +EXPORT_SYMBOL_GPL(bcma_find_core);
3197 +
3198 +struct bcma_device *bcma_find_core_unit(struct bcma_bus *bus, u16 coreid,
3199 +                                       u8 unit)
3200 +{
3201 +       struct bcma_device *core;
3202 +
3203 +       list_for_each_entry(core, &bus->cores, list) {
3204 +               if (core->id.id == coreid && core->core_unit == unit)
3205 +                       return core;
3206 +       }
3207 +       return NULL;
3208 +}
3209 +
3210 +bool bcma_wait_value(struct bcma_device *core, u16 reg, u32 mask, u32 value,
3211 +                    int timeout)
3212 +{
3213 +       unsigned long deadline = jiffies + timeout;
3214 +       u32 val;
3215 +
3216 +       do {
3217 +               val = bcma_read32(core, reg);
3218 +               if ((val & mask) == value)
3219 +                       return true;
3220 +               cpu_relax();
3221 +               udelay(10);
3222 +       } while (!time_after_eq(jiffies, deadline));
3223 +
3224 +       bcma_warn(core->bus, "Timeout waiting for register 0x%04X!\n", reg);
3225 +
3226 +       return false;
3227 +}
3228  
3229  static void bcma_release_core_dev(struct device *dev)
3230  {
3231 @@ -84,16 +130,23 @@ static int bcma_register_cores(struct bc
3232         list_for_each_entry(core, &bus->cores, list) {
3233                 /* We support that cores ourself */
3234                 switch (core->id.id) {
3235 +               case BCMA_CORE_4706_CHIPCOMMON:
3236                 case BCMA_CORE_CHIPCOMMON:
3237                 case BCMA_CORE_PCI:
3238                 case BCMA_CORE_PCIE:
3239                 case BCMA_CORE_MIPS_74K:
3240 +               case BCMA_CORE_4706_MAC_GBIT_COMMON:
3241                         continue;
3242                 }
3243  
3244 +               /* Only first GMAC core on BCM4706 is connected and working */
3245 +               if (core->id.id == BCMA_CORE_4706_MAC_GBIT &&
3246 +                   core->core_unit > 0)
3247 +                       continue;
3248 +
3249                 core->dev.release = bcma_release_core_dev;
3250                 core->dev.bus = &bcma_bus_type;
3251 -               dev_set_name(&core->dev, "bcma%d:%d", 0/*bus->num*/, dev_id);
3252 +               dev_set_name(&core->dev, "bcma%d:%d", bus->num, dev_id);
3253  
3254                 switch (bus->hosttype) {
3255                 case BCMA_HOSTTYPE_PCI:
3256 @@ -111,41 +164,98 @@ static int bcma_register_cores(struct bc
3257  
3258                 err = device_register(&core->dev);
3259                 if (err) {
3260 -                       pr_err("Could not register dev for core 0x%03X\n",
3261 -                              core->id.id);
3262 +                       bcma_err(bus,
3263 +                                "Could not register dev for core 0x%03X\n",
3264 +                                core->id.id);
3265                         continue;
3266                 }
3267                 core->dev_registered = true;
3268                 dev_id++;
3269         }
3270  
3271 +#ifdef CONFIG_BCMA_DRIVER_MIPS
3272 +       if (bus->drv_cc.pflash.present) {
3273 +               err = platform_device_register(&bcma_pflash_dev);
3274 +               if (err)
3275 +                       bcma_err(bus, "Error registering parallel flash\n");
3276 +       }
3277 +#endif
3278 +
3279 +#ifdef CONFIG_BCMA_SFLASH
3280 +       if (bus->drv_cc.sflash.present) {
3281 +               err = platform_device_register(&bcma_sflash_dev);
3282 +               if (err)
3283 +                       bcma_err(bus, "Error registering serial flash\n");
3284 +       }
3285 +#endif
3286 +
3287 +#ifdef CONFIG_BCMA_NFLASH
3288 +       if (bus->drv_cc.nflash.present) {
3289 +               err = platform_device_register(&bcma_nflash_dev);
3290 +               if (err)
3291 +                       bcma_err(bus, "Error registering NAND flash\n");
3292 +       }
3293 +#endif
3294 +       err = bcma_gpio_init(&bus->drv_cc);
3295 +       if (err == -ENOTSUPP)
3296 +               bcma_debug(bus, "GPIO driver not activated\n");
3297 +       else if (err)
3298 +               bcma_err(bus, "Error registering GPIO driver: %i\n", err);
3299 +
3300 +       if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
3301 +               err = bcma_chipco_watchdog_register(&bus->drv_cc);
3302 +               if (err)
3303 +                       bcma_err(bus, "Error registering watchdog driver\n");
3304 +       }
3305 +
3306         return 0;
3307  }
3308  
3309  static void bcma_unregister_cores(struct bcma_bus *bus)
3310  {
3311 -       struct bcma_device *core;
3312 +       struct bcma_device *core, *tmp;
3313  
3314 -       list_for_each_entry(core, &bus->cores, list) {
3315 +       list_for_each_entry_safe(core, tmp, &bus->cores, list) {
3316 +               list_del(&core->list);
3317                 if (core->dev_registered)
3318                         device_unregister(&core->dev);
3319         }
3320 +       if (bus->hosttype == BCMA_HOSTTYPE_SOC)
3321 +               platform_device_unregister(bus->drv_cc.watchdog);
3322  }
3323  
3324 -int bcma_bus_register(struct bcma_bus *bus)
3325 +int __devinit bcma_bus_register(struct bcma_bus *bus)
3326  {
3327         int err;
3328         struct bcma_device *core;
3329  
3330 +       mutex_lock(&bcma_buses_mutex);
3331 +       bus->num = bcma_bus_next_num++;
3332 +       mutex_unlock(&bcma_buses_mutex);
3333 +
3334         /* Scan for devices (cores) */
3335         err = bcma_bus_scan(bus);
3336         if (err) {
3337 -               pr_err("Failed to scan: %d\n", err);
3338 +               bcma_err(bus, "Failed to scan: %d\n", err);
3339                 return -1;
3340         }
3341  
3342 +       /* Early init CC core */
3343 +       core = bcma_find_core(bus, bcma_cc_core_id(bus));
3344 +       if (core) {
3345 +               bus->drv_cc.core = core;
3346 +               bcma_core_chipcommon_early_init(&bus->drv_cc);
3347 +       }
3348 +
3349 +       /* Try to get SPROM */
3350 +       err = bcma_sprom_get(bus);
3351 +       if (err == -ENOENT) {
3352 +               bcma_err(bus, "No SPROM available\n");
3353 +       } else if (err)
3354 +               bcma_err(bus, "Failed to get SPROM: %d\n", err);
3355 +
3356         /* Init CC core */
3357 -       core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON);
3358 +       core = bcma_find_core(bus, bcma_cc_core_id(bus));
3359         if (core) {
3360                 bus->drv_cc.core = core;
3361                 bcma_core_chipcommon_init(&bus->drv_cc);
3362 @@ -159,30 +269,54 @@ int bcma_bus_register(struct bcma_bus *b
3363         }
3364  
3365         /* Init PCIE core */
3366 -       core = bcma_find_core(bus, BCMA_CORE_PCIE);
3367 +       core = bcma_find_core_unit(bus, BCMA_CORE_PCIE, 0);
3368         if (core) {
3369 -               bus->drv_pci.core = core;
3370 -               bcma_core_pci_init(&bus->drv_pci);
3371 +               bus->drv_pci[0].core = core;
3372 +               bcma_core_pci_init(&bus->drv_pci[0]);
3373         }
3374  
3375 -       /* Try to get SPROM */
3376 -       err = bcma_sprom_get(bus);
3377 -       if (err == -ENOENT) {
3378 -               pr_err("No SPROM available\n");
3379 -       } else if (err)
3380 -               pr_err("Failed to get SPROM: %d\n", err);
3381 +       /* Init PCIE core */
3382 +       core = bcma_find_core_unit(bus, BCMA_CORE_PCIE, 1);
3383 +       if (core) {
3384 +               bus->drv_pci[1].core = core;
3385 +               bcma_core_pci_init(&bus->drv_pci[1]);
3386 +       }
3387 +
3388 +       /* Init GBIT MAC COMMON core */
3389 +       core = bcma_find_core(bus, BCMA_CORE_4706_MAC_GBIT_COMMON);
3390 +       if (core) {
3391 +               bus->drv_gmac_cmn.core = core;
3392 +               bcma_core_gmac_cmn_init(&bus->drv_gmac_cmn);
3393 +       }
3394  
3395         /* Register found cores */
3396         bcma_register_cores(bus);
3397  
3398 -       pr_info("Bus registered\n");
3399 +       bcma_info(bus, "Bus registered\n");
3400  
3401         return 0;
3402  }
3403  
3404  void bcma_bus_unregister(struct bcma_bus *bus)
3405  {
3406 +       struct bcma_device *cores[3];
3407 +       int err;
3408 +
3409 +       err = bcma_gpio_unregister(&bus->drv_cc);
3410 +       if (err == -EBUSY)
3411 +               bcma_err(bus, "Some GPIOs are still in use.\n");
3412 +       else if (err)
3413 +               bcma_err(bus, "Can not unregister GPIO driver: %i\n", err);
3414 +
3415 +       cores[0] = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
3416 +       cores[1] = bcma_find_core(bus, BCMA_CORE_PCIE);
3417 +       cores[2] = bcma_find_core(bus, BCMA_CORE_4706_MAC_GBIT_COMMON);
3418 +
3419         bcma_unregister_cores(bus);
3420 +
3421 +       kfree(cores[2]);
3422 +       kfree(cores[1]);
3423 +       kfree(cores[0]);
3424  }
3425  
3426  int __init bcma_bus_early_register(struct bcma_bus *bus,
3427 @@ -196,14 +330,14 @@ int __init bcma_bus_early_register(struc
3428         bcma_init_bus(bus);
3429  
3430         match.manuf = BCMA_MANUF_BCM;
3431 -       match.id = BCMA_CORE_CHIPCOMMON;
3432 +       match.id = bcma_cc_core_id(bus);
3433         match.class = BCMA_CL_SIM;
3434         match.rev = BCMA_ANY_REV;
3435  
3436         /* Scan for chip common core */
3437         err = bcma_bus_scan_early(bus, &match, core_cc);
3438         if (err) {
3439 -               pr_err("Failed to scan for common core: %d\n", err);
3440 +               bcma_err(bus, "Failed to scan for common core: %d\n", err);
3441                 return -1;
3442         }
3443  
3444 @@ -215,25 +349,25 @@ int __init bcma_bus_early_register(struc
3445         /* Scan for mips core */
3446         err = bcma_bus_scan_early(bus, &match, core_mips);
3447         if (err) {
3448 -               pr_err("Failed to scan for mips core: %d\n", err);
3449 +               bcma_err(bus, "Failed to scan for mips core: %d\n", err);
3450                 return -1;
3451         }
3452  
3453 -       /* Init CC core */
3454 -       core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON);
3455 +       /* Early init CC core */
3456 +       core = bcma_find_core(bus, bcma_cc_core_id(bus));
3457         if (core) {
3458                 bus->drv_cc.core = core;
3459 -               bcma_core_chipcommon_init(&bus->drv_cc);
3460 +               bcma_core_chipcommon_early_init(&bus->drv_cc);
3461         }
3462  
3463 -       /* Init MIPS core */
3464 +       /* Early init MIPS core */
3465         core = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
3466         if (core) {
3467                 bus->drv_mips.core = core;
3468 -               bcma_core_mips_init(&bus->drv_mips);
3469 +               bcma_core_mips_early_init(&bus->drv_mips);
3470         }
3471  
3472 -       pr_info("Early bus registered\n");
3473 +       bcma_info(bus, "Early bus registered\n");
3474  
3475         return 0;
3476  }
3477 @@ -259,8 +393,7 @@ int bcma_bus_resume(struct bcma_bus *bus
3478         struct bcma_device *core;
3479  
3480         /* Init CC core */
3481 -       core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON);
3482 -       if (core) {
3483 +       if (bus->drv_cc.core) {
3484                 bus->drv_cc.setup_done = false;
3485                 bcma_core_chipcommon_init(&bus->drv_cc);
3486         }
3487 --- a/drivers/bcma/scan.c
3488 +++ b/drivers/bcma/scan.c
3489 @@ -19,15 +19,27 @@ struct bcma_device_id_name {
3490         u16 id;
3491         const char *name;
3492  };
3493 -struct bcma_device_id_name bcma_device_names[] = {
3494 +
3495 +static const struct bcma_device_id_name bcma_arm_device_names[] = {
3496 +       { BCMA_CORE_4706_MAC_GBIT_COMMON, "BCM4706 GBit MAC Common" },
3497 +       { BCMA_CORE_ARM_1176, "ARM 1176" },
3498 +       { BCMA_CORE_ARM_7TDMI, "ARM 7TDMI" },
3499 +       { BCMA_CORE_ARM_CM3, "ARM CM3" },
3500 +};
3501 +
3502 +static const struct bcma_device_id_name bcma_bcm_device_names[] = {
3503         { BCMA_CORE_OOB_ROUTER, "OOB Router" },
3504 +       { BCMA_CORE_4706_CHIPCOMMON, "BCM4706 ChipCommon" },
3505 +       { BCMA_CORE_4706_SOC_RAM, "BCM4706 SOC RAM" },
3506 +       { BCMA_CORE_4706_MAC_GBIT, "BCM4706 GBit MAC" },
3507 +       { BCMA_CORE_AMEMC, "AMEMC (DDR)" },
3508 +       { BCMA_CORE_ALTA, "ALTA (I2S)" },
3509         { BCMA_CORE_INVALID, "Invalid" },
3510         { BCMA_CORE_CHIPCOMMON, "ChipCommon" },
3511         { BCMA_CORE_ILINE20, "ILine 20" },
3512         { BCMA_CORE_SRAM, "SRAM" },
3513         { BCMA_CORE_SDRAM, "SDRAM" },
3514         { BCMA_CORE_PCI, "PCI" },
3515 -       { BCMA_CORE_MIPS, "MIPS" },
3516         { BCMA_CORE_ETHERNET, "Fast Ethernet" },
3517         { BCMA_CORE_V90, "V90" },
3518         { BCMA_CORE_USB11_HOSTDEV, "USB 1.1 Hostdev" },
3519 @@ -44,7 +56,6 @@ struct bcma_device_id_name bcma_device_n
3520         { BCMA_CORE_PHY_A, "PHY A" },
3521         { BCMA_CORE_PHY_B, "PHY B" },
3522         { BCMA_CORE_PHY_G, "PHY G" },
3523 -       { BCMA_CORE_MIPS_3302, "MIPS 3302" },
3524         { BCMA_CORE_USB11_HOST, "USB 1.1 Host" },
3525         { BCMA_CORE_USB11_DEV, "USB 1.1 Device" },
3526         { BCMA_CORE_USB20_HOST, "USB 2.0 Host" },
3527 @@ -58,15 +69,11 @@ struct bcma_device_id_name bcma_device_n
3528         { BCMA_CORE_PHY_N, "PHY N" },
3529         { BCMA_CORE_SRAM_CTL, "SRAM Controller" },
3530         { BCMA_CORE_MINI_MACPHY, "Mini MACPHY" },
3531 -       { BCMA_CORE_ARM_1176, "ARM 1176" },
3532 -       { BCMA_CORE_ARM_7TDMI, "ARM 7TDMI" },
3533         { BCMA_CORE_PHY_LP, "PHY LP" },
3534         { BCMA_CORE_PMU, "PMU" },
3535         { BCMA_CORE_PHY_SSN, "PHY SSN" },
3536         { BCMA_CORE_SDIO_DEV, "SDIO Device" },
3537 -       { BCMA_CORE_ARM_CM3, "ARM CM3" },
3538         { BCMA_CORE_PHY_HT, "PHY HT" },
3539 -       { BCMA_CORE_MIPS_74K, "MIPS 74K" },
3540         { BCMA_CORE_MAC_GBIT, "GBit MAC" },
3541         { BCMA_CORE_DDR12_MEM_CTL, "DDR1/DDR2 Memory Controller" },
3542         { BCMA_CORE_PCIE_RC, "PCIe Root Complex" },
3543 @@ -77,18 +84,45 @@ struct bcma_device_id_name bcma_device_n
3544         { BCMA_CORE_I2S, "I2S" },
3545         { BCMA_CORE_SDR_DDR1_MEM_CTL, "SDR/DDR1 Memory Controller" },
3546         { BCMA_CORE_SHIM, "SHIM" },
3547 +       { BCMA_CORE_PCIE2, "PCIe Gen2" },
3548 +       { BCMA_CORE_ARM_CR4, "ARM CR4" },
3549         { BCMA_CORE_DEFAULT, "Default" },
3550  };
3551 -const char *bcma_device_name(struct bcma_device_id *id)
3552 +
3553 +static const struct bcma_device_id_name bcma_mips_device_names[] = {
3554 +       { BCMA_CORE_MIPS, "MIPS" },
3555 +       { BCMA_CORE_MIPS_3302, "MIPS 3302" },
3556 +       { BCMA_CORE_MIPS_74K, "MIPS 74K" },
3557 +};
3558 +
3559 +static const char *bcma_device_name(const struct bcma_device_id *id)
3560  {
3561 -       int i;
3562 +       const struct bcma_device_id_name *names;
3563 +       int size, i;
3564  
3565 -       if (id->manuf == BCMA_MANUF_BCM) {
3566 -               for (i = 0; i < ARRAY_SIZE(bcma_device_names); i++) {
3567 -                       if (bcma_device_names[i].id == id->id)
3568 -                               return bcma_device_names[i].name;
3569 -               }
3570 +       /* search manufacturer specific names */
3571 +       switch (id->manuf) {
3572 +       case BCMA_MANUF_ARM:
3573 +               names = bcma_arm_device_names;
3574 +               size = ARRAY_SIZE(bcma_arm_device_names);
3575 +               break;
3576 +       case BCMA_MANUF_BCM:
3577 +               names = bcma_bcm_device_names;
3578 +               size = ARRAY_SIZE(bcma_bcm_device_names);
3579 +               break;
3580 +       case BCMA_MANUF_MIPS:
3581 +               names = bcma_mips_device_names;
3582 +               size = ARRAY_SIZE(bcma_mips_device_names);
3583 +               break;
3584 +       default:
3585 +               return "UNKNOWN";
3586         }
3587 +
3588 +       for (i = 0; i < size; i++) {
3589 +               if (names[i].id == id->id)
3590 +                       return names[i].name;
3591 +       }
3592 +
3593         return "UNKNOWN";
3594  }
3595  
3596 @@ -105,19 +139,19 @@ static void bcma_scan_switch_core(struct
3597                                        addr);
3598  }
3599  
3600 -static u32 bcma_erom_get_ent(struct bcma_bus *bus, u32 **eromptr)
3601 +static u32 bcma_erom_get_ent(struct bcma_bus *bus, u32 __iomem **eromptr)
3602  {
3603         u32 ent = readl(*eromptr);
3604         (*eromptr)++;
3605         return ent;
3606  }
3607  
3608 -static void bcma_erom_push_ent(u32 **eromptr)
3609 +static void bcma_erom_push_ent(u32 __iomem **eromptr)
3610  {
3611         (*eromptr)--;
3612  }
3613  
3614 -static s32 bcma_erom_get_ci(struct bcma_bus *bus, u32 **eromptr)
3615 +static s32 bcma_erom_get_ci(struct bcma_bus *bus, u32 __iomem **eromptr)
3616  {
3617         u32 ent = bcma_erom_get_ent(bus, eromptr);
3618         if (!(ent & SCAN_ER_VALID))
3619 @@ -127,14 +161,14 @@ static s32 bcma_erom_get_ci(struct bcma_
3620         return ent;
3621  }
3622  
3623 -static bool bcma_erom_is_end(struct bcma_bus *bus, u32 **eromptr)
3624 +static bool bcma_erom_is_end(struct bcma_bus *bus, u32 __iomem **eromptr)
3625  {
3626         u32 ent = bcma_erom_get_ent(bus, eromptr);
3627         bcma_erom_push_ent(eromptr);
3628         return (ent == (SCAN_ER_TAG_END | SCAN_ER_VALID));
3629  }
3630  
3631 -static bool bcma_erom_is_bridge(struct bcma_bus *bus, u32 **eromptr)
3632 +static bool bcma_erom_is_bridge(struct bcma_bus *bus, u32 __iomem **eromptr)
3633  {
3634         u32 ent = bcma_erom_get_ent(bus, eromptr);
3635         bcma_erom_push_ent(eromptr);
3636 @@ -143,7 +177,7 @@ static bool bcma_erom_is_bridge(struct b
3637                 ((ent & SCAN_ADDR_TYPE) == SCAN_ADDR_TYPE_BRIDGE));
3638  }
3639  
3640 -static void bcma_erom_skip_component(struct bcma_bus *bus, u32 **eromptr)
3641 +static void bcma_erom_skip_component(struct bcma_bus *bus, u32 __iomem **eromptr)
3642  {
3643         u32 ent;
3644         while (1) {
3645 @@ -157,7 +191,7 @@ static void bcma_erom_skip_component(str
3646         bcma_erom_push_ent(eromptr);
3647  }
3648  
3649 -static s32 bcma_erom_get_mst_port(struct bcma_bus *bus, u32 **eromptr)
3650 +static s32 bcma_erom_get_mst_port(struct bcma_bus *bus, u32 __iomem **eromptr)
3651  {
3652         u32 ent = bcma_erom_get_ent(bus, eromptr);
3653         if (!(ent & SCAN_ER_VALID))
3654 @@ -167,7 +201,7 @@ static s32 bcma_erom_get_mst_port(struct
3655         return ent;
3656  }
3657  
3658 -static s32 bcma_erom_get_addr_desc(struct bcma_bus *bus, u32 **eromptr,
3659 +static s32 bcma_erom_get_addr_desc(struct bcma_bus *bus, u32 __iomem **eromptr,
3660                                   u32 type, u8 port)
3661  {
3662         u32 addrl, addrh, sizel, sizeh = 0;
3663 @@ -212,6 +246,17 @@ static struct bcma_device *bcma_find_cor
3664         return NULL;
3665  }
3666  
3667 +static struct bcma_device *bcma_find_core_reverse(struct bcma_bus *bus, u16 coreid)
3668 +{
3669 +       struct bcma_device *core;
3670 +
3671 +       list_for_each_entry_reverse(core, &bus->cores, list) {
3672 +               if (core->id.id == coreid)
3673 +                       return core;
3674 +       }
3675 +       return NULL;
3676 +}
3677 +
3678  static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
3679                               struct bcma_device_id *match, int core_num,
3680                               struct bcma_device *core)
3681 @@ -252,11 +297,15 @@ static int bcma_get_next_core(struct bcm
3682  
3683         /* check if component is a core at all */
3684         if (wrappers[0] + wrappers[1] == 0) {
3685 -               /* we could save addrl of the router
3686 -               if (cid == BCMA_CORE_OOB_ROUTER)
3687 -                */
3688 -               bcma_erom_skip_component(bus, eromptr);
3689 -               return -ENXIO;
3690 +               /* Some specific cores don't need wrappers */
3691 +               switch (core->id.id) {
3692 +               case BCMA_CORE_4706_MAC_GBIT_COMMON:
3693 +               /* Not used yet: case BCMA_CORE_OOB_ROUTER: */
3694 +                       break;
3695 +               default:
3696 +                       bcma_erom_skip_component(bus, eromptr);
3697 +                       return -ENXIO;
3698 +               }
3699         }
3700  
3701         if (bcma_erom_is_bridge(bus, eromptr)) {
3702 @@ -286,6 +335,23 @@ static int bcma_get_next_core(struct bcm
3703                         return -EILSEQ;
3704         }
3705  
3706 +       /* First Slave Address Descriptor should be port 0:
3707 +        * the main register space for the core
3708 +        */
3709 +       tmp = bcma_erom_get_addr_desc(bus, eromptr, SCAN_ADDR_TYPE_SLAVE, 0);
3710 +       if (tmp <= 0) {
3711 +               /* Try again to see if it is a bridge */
3712 +               tmp = bcma_erom_get_addr_desc(bus, eromptr,
3713 +                                             SCAN_ADDR_TYPE_BRIDGE, 0);
3714 +               if (tmp <= 0) {
3715 +                       return -EILSEQ;
3716 +               } else {
3717 +                       bcma_info(bus, "Bridge found\n");
3718 +                       return -ENXIO;
3719 +               }
3720 +       }
3721 +       core->addr = tmp;
3722 +
3723         /* get & parse slave ports */
3724         for (i = 0; i < ports[1]; i++) {
3725                 for (j = 0; ; j++) {
3726 @@ -298,7 +364,7 @@ static int bcma_get_next_core(struct bcm
3727                                 break;
3728                         } else {
3729                                 if (i == 0 && j == 0)
3730 -                                       core->addr = tmp;
3731 +                                       core->addr1 = tmp;
3732                         }
3733                 }
3734         }
3735 @@ -353,6 +419,7 @@ static int bcma_get_next_core(struct bcm
3736  void bcma_init_bus(struct bcma_bus *bus)
3737  {
3738         s32 tmp;
3739 +       struct bcma_chipinfo *chipinfo = &(bus->chipinfo);
3740  
3741         if (bus->init_done)
3742                 return;
3743 @@ -363,9 +430,12 @@ void bcma_init_bus(struct bcma_bus *bus)
3744         bcma_scan_switch_core(bus, BCMA_ADDR_BASE);
3745  
3746         tmp = bcma_scan_read32(bus, 0, BCMA_CC_ID);
3747 -       bus->chipinfo.id = (tmp & BCMA_CC_ID_ID) >> BCMA_CC_ID_ID_SHIFT;
3748 -       bus->chipinfo.rev = (tmp & BCMA_CC_ID_REV) >> BCMA_CC_ID_REV_SHIFT;
3749 -       bus->chipinfo.pkg = (tmp & BCMA_CC_ID_PKG) >> BCMA_CC_ID_PKG_SHIFT;
3750 +       chipinfo->id = (tmp & BCMA_CC_ID_ID) >> BCMA_CC_ID_ID_SHIFT;
3751 +       chipinfo->rev = (tmp & BCMA_CC_ID_REV) >> BCMA_CC_ID_REV_SHIFT;
3752 +       chipinfo->pkg = (tmp & BCMA_CC_ID_PKG) >> BCMA_CC_ID_PKG_SHIFT;
3753 +       bcma_info(bus, "Found chip with id 0x%04X, rev 0x%02X and package 0x%02X\n",
3754 +                 chipinfo->id, chipinfo->rev, chipinfo->pkg);
3755 +
3756         bus->init_done = true;
3757  }
3758  
3759 @@ -392,9 +462,12 @@ int bcma_bus_scan(struct bcma_bus *bus)
3760         bcma_scan_switch_core(bus, erombase);
3761  
3762         while (eromptr < eromend) {
3763 +               struct bcma_device *other_core;
3764                 struct bcma_device *core = kzalloc(sizeof(*core), GFP_KERNEL);
3765 -               if (!core)
3766 -                       return -ENOMEM;
3767 +               if (!core) {
3768 +                       err = -ENOMEM;
3769 +                       goto out;
3770 +               }
3771                 INIT_LIST_HEAD(&core->list);
3772                 core->bus = bus;
3773  
3774 @@ -409,25 +482,28 @@ int bcma_bus_scan(struct bcma_bus *bus)
3775                         } else if (err == -ESPIPE) {
3776                                 break;
3777                         }
3778 -                       return err;
3779 +                       goto out;
3780                 }
3781  
3782                 core->core_index = core_num++;
3783                 bus->nr_cores++;
3784 +               other_core = bcma_find_core_reverse(bus, core->id.id);
3785 +               core->core_unit = (other_core == NULL) ? 0 : other_core->core_unit + 1;
3786  
3787 -               pr_info("Core %d found: %s "
3788 -                       "(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
3789 -                       core->core_index, bcma_device_name(&core->id),
3790 -                       core->id.manuf, core->id.id, core->id.rev,
3791 -                       core->id.class);
3792 +               bcma_info(bus, "Core %d found: %s (manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
3793 +                         core->core_index, bcma_device_name(&core->id),
3794 +                         core->id.manuf, core->id.id, core->id.rev,
3795 +                         core->id.class);
3796  
3797 -               list_add(&core->list, &bus->cores);
3798 +               list_add_tail(&core->list, &bus->cores);
3799         }
3800  
3801 +       err = 0;
3802 +out:
3803         if (bus->hosttype == BCMA_HOSTTYPE_SOC)
3804                 iounmap(eromptr);
3805  
3806 -       return 0;
3807 +       return err;
3808  }
3809  
3810  int __init bcma_bus_scan_early(struct bcma_bus *bus,
3811 @@ -467,21 +543,21 @@ int __init bcma_bus_scan_early(struct bc
3812                 else if (err == -ESPIPE)
3813                         break;
3814                 else if (err < 0)
3815 -                       return err;
3816 +                       goto out;
3817  
3818                 core->core_index = core_num++;
3819                 bus->nr_cores++;
3820 -               pr_info("Core %d found: %s "
3821 -                       "(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
3822 -                       core->core_index, bcma_device_name(&core->id),
3823 -                       core->id.manuf, core->id.id, core->id.rev,
3824 -                       core->id.class);
3825 +               bcma_info(bus, "Core %d found: %s (manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
3826 +                         core->core_index, bcma_device_name(&core->id),
3827 +                         core->id.manuf, core->id.id, core->id.rev,
3828 +                         core->id.class);
3829  
3830 -               list_add(&core->list, &bus->cores);
3831 +               list_add_tail(&core->list, &bus->cores);
3832                 err = 0;
3833                 break;
3834         }
3835  
3836 +out:
3837         if (bus->hosttype == BCMA_HOSTTYPE_SOC)
3838                 iounmap(eromptr);
3839  
3840 --- a/drivers/bcma/scan.h
3841 +++ b/drivers/bcma/scan.h
3842 @@ -27,7 +27,7 @@
3843  #define SCAN_CIB_NMW           0x0007C000
3844  #define SCAN_CIB_NMW_SHIFT     14
3845  #define SCAN_CIB_NSW           0x00F80000
3846 -#define SCAN_CIB_NSW_SHIFT     17
3847 +#define SCAN_CIB_NSW_SHIFT     19
3848  #define SCAN_CIB_REV           0xFF000000
3849  #define SCAN_CIB_REV_SHIFT     24
3850  
3851 --- a/drivers/bcma/sprom.c
3852 +++ b/drivers/bcma/sprom.c
3853 @@ -2,6 +2,8 @@
3854   * Broadcom specific AMBA
3855   * SPROM reading
3856   *
3857 + * Copyright 2011, 2012, Hauke Mehrtens <hauke@hauke-m.de>
3858 + *
3859   * Licensed under the GNU/GPL. See COPYING for details.
3860   */
3861  
3862 @@ -14,18 +16,68 @@
3863  #include <linux/dma-mapping.h>
3864  #include <linux/slab.h>
3865  
3866 -#define SPOFF(offset)  ((offset) / sizeof(u16))
3867 +static int(*get_fallback_sprom)(struct bcma_bus *dev, struct ssb_sprom *out);
3868 +
3869 +/**
3870 + * bcma_arch_register_fallback_sprom - Registers a method providing a
3871 + * fallback SPROM if no SPROM is found.
3872 + *
3873 + * @sprom_callback: The callback function.
3874 + *
3875 + * With this function the architecture implementation may register a
3876 + * callback handler which fills the SPROM data structure. The fallback is
3877 + * used for PCI based BCMA devices, where no valid SPROM can be found
3878 + * in the shadow registers and to provide the SPROM for SoCs where BCMA is
3879 + * to controll the system bus.
3880 + *
3881 + * This function is useful for weird architectures that have a half-assed
3882 + * BCMA device hardwired to their PCI bus.
3883 + *
3884 + * This function is available for architecture code, only. So it is not
3885 + * exported.
3886 + */
3887 +int bcma_arch_register_fallback_sprom(int (*sprom_callback)(struct bcma_bus *bus,
3888 +                                    struct ssb_sprom *out))
3889 +{
3890 +       if (get_fallback_sprom)
3891 +               return -EEXIST;
3892 +       get_fallback_sprom = sprom_callback;
3893 +
3894 +       return 0;
3895 +}
3896 +
3897 +static int bcma_fill_sprom_with_fallback(struct bcma_bus *bus,
3898 +                                        struct ssb_sprom *out)
3899 +{
3900 +       int err;
3901 +
3902 +       if (!get_fallback_sprom) {
3903 +               err = -ENOENT;
3904 +               goto fail;
3905 +       }
3906 +
3907 +       err = get_fallback_sprom(bus, out);
3908 +       if (err)
3909 +               goto fail;
3910 +
3911 +       bcma_debug(bus, "Using SPROM revision %d provided by platform.\n",
3912 +                  bus->sprom.revision);
3913 +       return 0;
3914 +fail:
3915 +       bcma_warn(bus, "Using fallback SPROM failed (err %d)\n", err);
3916 +       return err;
3917 +}
3918  
3919  /**************************************************
3920   * R/W ops.
3921   **************************************************/
3922  
3923 -static void bcma_sprom_read(struct bcma_bus *bus, u16 offset, u16 *sprom)
3924 +static void bcma_sprom_read(struct bcma_bus *bus, u16 offset, u16 *sprom,
3925 +                           size_t words)
3926  {
3927         int i;
3928 -       for (i = 0; i < SSB_SPROMSIZE_WORDS_R4; i++)
3929 -               sprom[i] = bcma_read16(bus->drv_cc.core,
3930 -                                      offset + (i * 2));
3931 +       for (i = 0; i < words; i++)
3932 +               sprom[i] = bcma_read16(bus->drv_cc.core, offset + (i * 2));
3933  }
3934  
3935  /**************************************************
3936 @@ -72,29 +124,29 @@ static inline u8 bcma_crc8(u8 crc, u8 da
3937         return t[crc ^ data];
3938  }
3939  
3940 -static u8 bcma_sprom_crc(const u16 *sprom)
3941 +static u8 bcma_sprom_crc(const u16 *sprom, size_t words)
3942  {
3943         int word;
3944         u8 crc = 0xFF;
3945  
3946 -       for (word = 0; word < SSB_SPROMSIZE_WORDS_R4 - 1; word++) {
3947 +       for (word = 0; word < words - 1; word++) {
3948                 crc = bcma_crc8(crc, sprom[word] & 0x00FF);
3949                 crc = bcma_crc8(crc, (sprom[word] & 0xFF00) >> 8);
3950         }
3951 -       crc = bcma_crc8(crc, sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & 0x00FF);
3952 +       crc = bcma_crc8(crc, sprom[words - 1] & 0x00FF);
3953         crc ^= 0xFF;
3954  
3955         return crc;
3956  }
3957  
3958 -static int bcma_sprom_check_crc(const u16 *sprom)
3959 +static int bcma_sprom_check_crc(const u16 *sprom, size_t words)
3960  {
3961         u8 crc;
3962         u8 expected_crc;
3963         u16 tmp;
3964  
3965 -       crc = bcma_sprom_crc(sprom);
3966 -       tmp = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & SSB_SPROM_REVISION_CRC;
3967 +       crc = bcma_sprom_crc(sprom, words);
3968 +       tmp = sprom[words - 1] & SSB_SPROM_REVISION_CRC;
3969         expected_crc = tmp >> SSB_SPROM_REVISION_CRC_SHIFT;
3970         if (crc != expected_crc)
3971                 return -EPROTO;
3972 @@ -102,21 +154,25 @@ static int bcma_sprom_check_crc(const u1
3973         return 0;
3974  }
3975  
3976 -static int bcma_sprom_valid(const u16 *sprom)
3977 +static int bcma_sprom_valid(struct bcma_bus *bus, const u16 *sprom,
3978 +                           size_t words)
3979  {
3980         u16 revision;
3981         int err;
3982  
3983 -       err = bcma_sprom_check_crc(sprom);
3984 +       err = bcma_sprom_check_crc(sprom, words);
3985         if (err)
3986                 return err;
3987  
3988 -       revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & SSB_SPROM_REVISION_REV;
3989 -       if (revision != 8 && revision != 9) {
3990 +       revision = sprom[words - 1] & SSB_SPROM_REVISION_REV;
3991 +       if (revision != 8 && revision != 9 && revision != 10) {
3992                 pr_err("Unsupported SPROM revision: %d\n", revision);
3993                 return -ENOENT;
3994         }
3995  
3996 +       bus->sprom.revision = revision;
3997 +       bcma_debug(bus, "Found SPROM revision %d\n", revision);
3998 +
3999         return 0;
4000  }
4001  
4002 @@ -124,124 +180,439 @@ static int bcma_sprom_valid(const u16 *s
4003   * SPROM extraction.
4004   **************************************************/
4005  
4006 +#define SPOFF(offset)  ((offset) / sizeof(u16))
4007 +
4008 +#define SPEX(_field, _offset, _mask, _shift)   \
4009 +       bus->sprom._field = ((sprom[SPOFF(_offset)] & (_mask)) >> (_shift))
4010 +
4011 +#define SPEX32(_field, _offset, _mask, _shift) \
4012 +       bus->sprom._field = ((((u32)sprom[SPOFF((_offset)+2)] << 16 | \
4013 +                               sprom[SPOFF(_offset)]) & (_mask)) >> (_shift))
4014 +
4015 +#define SPEX_ARRAY8(_field, _offset, _mask, _shift)    \
4016 +       do {    \
4017 +               SPEX(_field[0], _offset +  0, _mask, _shift);   \
4018 +               SPEX(_field[1], _offset +  2, _mask, _shift);   \
4019 +               SPEX(_field[2], _offset +  4, _mask, _shift);   \
4020 +               SPEX(_field[3], _offset +  6, _mask, _shift);   \
4021 +               SPEX(_field[4], _offset +  8, _mask, _shift);   \
4022 +               SPEX(_field[5], _offset + 10, _mask, _shift);   \
4023 +               SPEX(_field[6], _offset + 12, _mask, _shift);   \
4024 +               SPEX(_field[7], _offset + 14, _mask, _shift);   \
4025 +       } while (0)
4026 +
4027  static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
4028  {
4029 -       u16 v;
4030 +       u16 v, o;
4031         int i;
4032 -
4033 -       bus->sprom.revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] &
4034 -               SSB_SPROM_REVISION_REV;
4035 +       u16 pwr_info_offset[] = {
4036 +               SSB_SROM8_PWR_INFO_CORE0, SSB_SROM8_PWR_INFO_CORE1,
4037 +               SSB_SROM8_PWR_INFO_CORE2, SSB_SROM8_PWR_INFO_CORE3
4038 +       };
4039 +       BUILD_BUG_ON(ARRAY_SIZE(pwr_info_offset) !=
4040 +                       ARRAY_SIZE(bus->sprom.core_pwr_info));
4041  
4042         for (i = 0; i < 3; i++) {
4043                 v = sprom[SPOFF(SSB_SPROM8_IL0MAC) + i];
4044                 *(((__be16 *)bus->sprom.il0mac) + i) = cpu_to_be16(v);
4045         }
4046  
4047 -       bus->sprom.board_rev = sprom[SPOFF(SSB_SPROM8_BOARDREV)];
4048 +       SPEX(board_rev, SSB_SPROM8_BOARDREV, ~0, 0);
4049 +       SPEX(board_type, SSB_SPROM1_SPID, ~0, 0);
4050 +
4051 +       SPEX(txpid2g[0], SSB_SPROM4_TXPID2G01, SSB_SPROM4_TXPID2G0,
4052 +            SSB_SPROM4_TXPID2G0_SHIFT);
4053 +       SPEX(txpid2g[1], SSB_SPROM4_TXPID2G01, SSB_SPROM4_TXPID2G1,
4054 +            SSB_SPROM4_TXPID2G1_SHIFT);
4055 +       SPEX(txpid2g[2], SSB_SPROM4_TXPID2G23, SSB_SPROM4_TXPID2G2,
4056 +            SSB_SPROM4_TXPID2G2_SHIFT);
4057 +       SPEX(txpid2g[3], SSB_SPROM4_TXPID2G23, SSB_SPROM4_TXPID2G3,
4058 +            SSB_SPROM4_TXPID2G3_SHIFT);
4059 +
4060 +       SPEX(txpid5gl[0], SSB_SPROM4_TXPID5GL01, SSB_SPROM4_TXPID5GL0,
4061 +            SSB_SPROM4_TXPID5GL0_SHIFT);
4062 +       SPEX(txpid5gl[1], SSB_SPROM4_TXPID5GL01, SSB_SPROM4_TXPID5GL1,
4063 +            SSB_SPROM4_TXPID5GL1_SHIFT);
4064 +       SPEX(txpid5gl[2], SSB_SPROM4_TXPID5GL23, SSB_SPROM4_TXPID5GL2,
4065 +            SSB_SPROM4_TXPID5GL2_SHIFT);
4066 +       SPEX(txpid5gl[3], SSB_SPROM4_TXPID5GL23, SSB_SPROM4_TXPID5GL3,
4067 +            SSB_SPROM4_TXPID5GL3_SHIFT);
4068 +
4069 +       SPEX(txpid5g[0], SSB_SPROM4_TXPID5G01, SSB_SPROM4_TXPID5G0,
4070 +            SSB_SPROM4_TXPID5G0_SHIFT);
4071 +       SPEX(txpid5g[1], SSB_SPROM4_TXPID5G01, SSB_SPROM4_TXPID5G1,
4072 +            SSB_SPROM4_TXPID5G1_SHIFT);
4073 +       SPEX(txpid5g[2], SSB_SPROM4_TXPID5G23, SSB_SPROM4_TXPID5G2,
4074 +            SSB_SPROM4_TXPID5G2_SHIFT);
4075 +       SPEX(txpid5g[3], SSB_SPROM4_TXPID5G23, SSB_SPROM4_TXPID5G3,
4076 +            SSB_SPROM4_TXPID5G3_SHIFT);
4077 +
4078 +       SPEX(txpid5gh[0], SSB_SPROM4_TXPID5GH01, SSB_SPROM4_TXPID5GH0,
4079 +            SSB_SPROM4_TXPID5GH0_SHIFT);
4080 +       SPEX(txpid5gh[1], SSB_SPROM4_TXPID5GH01, SSB_SPROM4_TXPID5GH1,
4081 +            SSB_SPROM4_TXPID5GH1_SHIFT);
4082 +       SPEX(txpid5gh[2], SSB_SPROM4_TXPID5GH23, SSB_SPROM4_TXPID5GH2,
4083 +            SSB_SPROM4_TXPID5GH2_SHIFT);
4084 +       SPEX(txpid5gh[3], SSB_SPROM4_TXPID5GH23, SSB_SPROM4_TXPID5GH3,
4085 +            SSB_SPROM4_TXPID5GH3_SHIFT);
4086 +
4087 +       SPEX(boardflags_lo, SSB_SPROM8_BFLLO, ~0, 0);
4088 +       SPEX(boardflags_hi, SSB_SPROM8_BFLHI, ~0, 0);
4089 +       SPEX(boardflags2_lo, SSB_SPROM8_BFL2LO, ~0, 0);
4090 +       SPEX(boardflags2_hi, SSB_SPROM8_BFL2HI, ~0, 0);
4091 +
4092 +       SPEX(alpha2[0], SSB_SPROM8_CCODE, 0xff00, 8);
4093 +       SPEX(alpha2[1], SSB_SPROM8_CCODE, 0x00ff, 0);
4094 +
4095 +       /* Extract cores power info info */
4096 +       for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) {
4097 +               o = pwr_info_offset[i];
4098 +               SPEX(core_pwr_info[i].itssi_2g, o + SSB_SROM8_2G_MAXP_ITSSI,
4099 +                       SSB_SPROM8_2G_ITSSI, SSB_SPROM8_2G_ITSSI_SHIFT);
4100 +               SPEX(core_pwr_info[i].maxpwr_2g, o + SSB_SROM8_2G_MAXP_ITSSI,
4101 +                       SSB_SPROM8_2G_MAXP, 0);
4102 +
4103 +               SPEX(core_pwr_info[i].pa_2g[0], o + SSB_SROM8_2G_PA_0, ~0, 0);
4104 +               SPEX(core_pwr_info[i].pa_2g[1], o + SSB_SROM8_2G_PA_1, ~0, 0);
4105 +               SPEX(core_pwr_info[i].pa_2g[2], o + SSB_SROM8_2G_PA_2, ~0, 0);
4106 +
4107 +               SPEX(core_pwr_info[i].itssi_5g, o + SSB_SROM8_5G_MAXP_ITSSI,
4108 +                       SSB_SPROM8_5G_ITSSI, SSB_SPROM8_5G_ITSSI_SHIFT);
4109 +               SPEX(core_pwr_info[i].maxpwr_5g, o + SSB_SROM8_5G_MAXP_ITSSI,
4110 +                       SSB_SPROM8_5G_MAXP, 0);
4111 +               SPEX(core_pwr_info[i].maxpwr_5gh, o + SSB_SPROM8_5GHL_MAXP,
4112 +                       SSB_SPROM8_5GH_MAXP, 0);
4113 +               SPEX(core_pwr_info[i].maxpwr_5gl, o + SSB_SPROM8_5GHL_MAXP,
4114 +                       SSB_SPROM8_5GL_MAXP, SSB_SPROM8_5GL_MAXP_SHIFT);
4115 +
4116 +               SPEX(core_pwr_info[i].pa_5gl[0], o + SSB_SROM8_5GL_PA_0, ~0, 0);
4117 +               SPEX(core_pwr_info[i].pa_5gl[1], o + SSB_SROM8_5GL_PA_1, ~0, 0);
4118 +               SPEX(core_pwr_info[i].pa_5gl[2], o + SSB_SROM8_5GL_PA_2, ~0, 0);
4119 +               SPEX(core_pwr_info[i].pa_5g[0], o + SSB_SROM8_5G_PA_0, ~0, 0);
4120 +               SPEX(core_pwr_info[i].pa_5g[1], o + SSB_SROM8_5G_PA_1, ~0, 0);
4121 +               SPEX(core_pwr_info[i].pa_5g[2], o + SSB_SROM8_5G_PA_2, ~0, 0);
4122 +               SPEX(core_pwr_info[i].pa_5gh[0], o + SSB_SROM8_5GH_PA_0, ~0, 0);
4123 +               SPEX(core_pwr_info[i].pa_5gh[1], o + SSB_SROM8_5GH_PA_1, ~0, 0);
4124 +               SPEX(core_pwr_info[i].pa_5gh[2], o + SSB_SROM8_5GH_PA_2, ~0, 0);
4125 +       }
4126 +
4127 +       SPEX(fem.ghz2.tssipos, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_TSSIPOS,
4128 +            SSB_SROM8_FEM_TSSIPOS_SHIFT);
4129 +       SPEX(fem.ghz2.extpa_gain, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_EXTPA_GAIN,
4130 +            SSB_SROM8_FEM_EXTPA_GAIN_SHIFT);
4131 +       SPEX(fem.ghz2.pdet_range, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_PDET_RANGE,
4132 +            SSB_SROM8_FEM_PDET_RANGE_SHIFT);
4133 +       SPEX(fem.ghz2.tr_iso, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_TR_ISO,
4134 +            SSB_SROM8_FEM_TR_ISO_SHIFT);
4135 +       SPEX(fem.ghz2.antswlut, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_ANTSWLUT,
4136 +            SSB_SROM8_FEM_ANTSWLUT_SHIFT);
4137 +
4138 +       SPEX(fem.ghz5.tssipos, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_TSSIPOS,
4139 +            SSB_SROM8_FEM_TSSIPOS_SHIFT);
4140 +       SPEX(fem.ghz5.extpa_gain, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_EXTPA_GAIN,
4141 +            SSB_SROM8_FEM_EXTPA_GAIN_SHIFT);
4142 +       SPEX(fem.ghz5.pdet_range, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_PDET_RANGE,
4143 +            SSB_SROM8_FEM_PDET_RANGE_SHIFT);
4144 +       SPEX(fem.ghz5.tr_iso, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_TR_ISO,
4145 +            SSB_SROM8_FEM_TR_ISO_SHIFT);
4146 +       SPEX(fem.ghz5.antswlut, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_ANTSWLUT,
4147 +            SSB_SROM8_FEM_ANTSWLUT_SHIFT);
4148 +
4149 +       SPEX(ant_available_a, SSB_SPROM8_ANTAVAIL, SSB_SPROM8_ANTAVAIL_A,
4150 +            SSB_SPROM8_ANTAVAIL_A_SHIFT);
4151 +       SPEX(ant_available_bg, SSB_SPROM8_ANTAVAIL, SSB_SPROM8_ANTAVAIL_BG,
4152 +            SSB_SPROM8_ANTAVAIL_BG_SHIFT);
4153 +       SPEX(maxpwr_bg, SSB_SPROM8_MAXP_BG, SSB_SPROM8_MAXP_BG_MASK, 0);
4154 +       SPEX(itssi_bg, SSB_SPROM8_MAXP_BG, SSB_SPROM8_ITSSI_BG,
4155 +            SSB_SPROM8_ITSSI_BG_SHIFT);
4156 +       SPEX(maxpwr_a, SSB_SPROM8_MAXP_A, SSB_SPROM8_MAXP_A_MASK, 0);
4157 +       SPEX(itssi_a, SSB_SPROM8_MAXP_A, SSB_SPROM8_ITSSI_A,
4158 +            SSB_SPROM8_ITSSI_A_SHIFT);
4159 +       SPEX(maxpwr_ah, SSB_SPROM8_MAXP_AHL, SSB_SPROM8_MAXP_AH_MASK, 0);
4160 +       SPEX(maxpwr_al, SSB_SPROM8_MAXP_AHL, SSB_SPROM8_MAXP_AL_MASK,
4161 +            SSB_SPROM8_MAXP_AL_SHIFT);
4162 +       SPEX(gpio0, SSB_SPROM8_GPIOA, SSB_SPROM8_GPIOA_P0, 0);
4163 +       SPEX(gpio1, SSB_SPROM8_GPIOA, SSB_SPROM8_GPIOA_P1,
4164 +            SSB_SPROM8_GPIOA_P1_SHIFT);
4165 +       SPEX(gpio2, SSB_SPROM8_GPIOB, SSB_SPROM8_GPIOB_P2, 0);
4166 +       SPEX(gpio3, SSB_SPROM8_GPIOB, SSB_SPROM8_GPIOB_P3,
4167 +            SSB_SPROM8_GPIOB_P3_SHIFT);
4168 +       SPEX(tri2g, SSB_SPROM8_TRI25G, SSB_SPROM8_TRI2G, 0);
4169 +       SPEX(tri5g, SSB_SPROM8_TRI25G, SSB_SPROM8_TRI5G,
4170 +            SSB_SPROM8_TRI5G_SHIFT);
4171 +       SPEX(tri5gl, SSB_SPROM8_TRI5GHL, SSB_SPROM8_TRI5GL, 0);
4172 +       SPEX(tri5gh, SSB_SPROM8_TRI5GHL, SSB_SPROM8_TRI5GH,
4173 +            SSB_SPROM8_TRI5GH_SHIFT);
4174 +       SPEX(rxpo2g, SSB_SPROM8_RXPO, SSB_SPROM8_RXPO2G,
4175 +            SSB_SPROM8_RXPO2G_SHIFT);
4176 +       SPEX(rxpo5g, SSB_SPROM8_RXPO, SSB_SPROM8_RXPO5G,
4177 +            SSB_SPROM8_RXPO5G_SHIFT);
4178 +       SPEX(rssismf2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISMF2G, 0);
4179 +       SPEX(rssismc2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISMC2G,
4180 +            SSB_SPROM8_RSSISMC2G_SHIFT);
4181 +       SPEX(rssisav2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISAV2G,
4182 +            SSB_SPROM8_RSSISAV2G_SHIFT);
4183 +       SPEX(bxa2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_BXA2G,
4184 +            SSB_SPROM8_BXA2G_SHIFT);
4185 +       SPEX(rssismf5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISMF5G, 0);
4186 +       SPEX(rssismc5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISMC5G,
4187 +            SSB_SPROM8_RSSISMC5G_SHIFT);
4188 +       SPEX(rssisav5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISAV5G,
4189 +            SSB_SPROM8_RSSISAV5G_SHIFT);
4190 +       SPEX(bxa5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_BXA5G,
4191 +            SSB_SPROM8_BXA5G_SHIFT);
4192 +
4193 +       SPEX(pa0b0, SSB_SPROM8_PA0B0, ~0, 0);
4194 +       SPEX(pa0b1, SSB_SPROM8_PA0B1, ~0, 0);
4195 +       SPEX(pa0b2, SSB_SPROM8_PA0B2, ~0, 0);
4196 +       SPEX(pa1b0, SSB_SPROM8_PA1B0, ~0, 0);
4197 +       SPEX(pa1b1, SSB_SPROM8_PA1B1, ~0, 0);
4198 +       SPEX(pa1b2, SSB_SPROM8_PA1B2, ~0, 0);
4199 +       SPEX(pa1lob0, SSB_SPROM8_PA1LOB0, ~0, 0);
4200 +       SPEX(pa1lob1, SSB_SPROM8_PA1LOB1, ~0, 0);
4201 +       SPEX(pa1lob2, SSB_SPROM8_PA1LOB2, ~0, 0);
4202 +       SPEX(pa1hib0, SSB_SPROM8_PA1HIB0, ~0, 0);
4203 +       SPEX(pa1hib1, SSB_SPROM8_PA1HIB1, ~0, 0);
4204 +       SPEX(pa1hib2, SSB_SPROM8_PA1HIB2, ~0, 0);
4205 +       SPEX(cck2gpo, SSB_SPROM8_CCK2GPO, ~0, 0);
4206 +       SPEX32(ofdm2gpo, SSB_SPROM8_OFDM2GPO, ~0, 0);
4207 +       SPEX32(ofdm5glpo, SSB_SPROM8_OFDM5GLPO, ~0, 0);
4208 +       SPEX32(ofdm5gpo, SSB_SPROM8_OFDM5GPO, ~0, 0);
4209 +       SPEX32(ofdm5ghpo, SSB_SPROM8_OFDM5GHPO, ~0, 0);
4210 +
4211 +       /* Extract the antenna gain values. */
4212 +       SPEX(antenna_gain.a0, SSB_SPROM8_AGAIN01,
4213 +            SSB_SPROM8_AGAIN0, SSB_SPROM8_AGAIN0_SHIFT);
4214 +       SPEX(antenna_gain.a1, SSB_SPROM8_AGAIN01,
4215 +            SSB_SPROM8_AGAIN1, SSB_SPROM8_AGAIN1_SHIFT);
4216 +       SPEX(antenna_gain.a2, SSB_SPROM8_AGAIN23,
4217 +            SSB_SPROM8_AGAIN2, SSB_SPROM8_AGAIN2_SHIFT);
4218 +       SPEX(antenna_gain.a3, SSB_SPROM8_AGAIN23,
4219 +            SSB_SPROM8_AGAIN3, SSB_SPROM8_AGAIN3_SHIFT);
4220 +
4221 +       SPEX(leddc_on_time, SSB_SPROM8_LEDDC, SSB_SPROM8_LEDDC_ON,
4222 +            SSB_SPROM8_LEDDC_ON_SHIFT);
4223 +       SPEX(leddc_off_time, SSB_SPROM8_LEDDC, SSB_SPROM8_LEDDC_OFF,
4224 +            SSB_SPROM8_LEDDC_OFF_SHIFT);
4225 +
4226 +       SPEX(txchain, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_TXCHAIN,
4227 +            SSB_SPROM8_TXRXC_TXCHAIN_SHIFT);
4228 +       SPEX(rxchain, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_RXCHAIN,
4229 +            SSB_SPROM8_TXRXC_RXCHAIN_SHIFT);
4230 +       SPEX(antswitch, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_SWITCH,
4231 +            SSB_SPROM8_TXRXC_SWITCH_SHIFT);
4232 +
4233 +       SPEX(opo, SSB_SPROM8_OFDM2GPO, 0x00ff, 0);
4234 +
4235 +       SPEX_ARRAY8(mcs2gpo, SSB_SPROM8_2G_MCSPO, ~0, 0);
4236 +       SPEX_ARRAY8(mcs5gpo, SSB_SPROM8_5G_MCSPO, ~0, 0);
4237 +       SPEX_ARRAY8(mcs5glpo, SSB_SPROM8_5GL_MCSPO, ~0, 0);
4238 +       SPEX_ARRAY8(mcs5ghpo, SSB_SPROM8_5GH_MCSPO, ~0, 0);
4239 +
4240 +       SPEX(rawtempsense, SSB_SPROM8_RAWTS, SSB_SPROM8_RAWTS_RAWTEMP,
4241 +            SSB_SPROM8_RAWTS_RAWTEMP_SHIFT);
4242 +       SPEX(measpower, SSB_SPROM8_RAWTS, SSB_SPROM8_RAWTS_MEASPOWER,
4243 +            SSB_SPROM8_RAWTS_MEASPOWER_SHIFT);
4244 +       SPEX(tempsense_slope, SSB_SPROM8_OPT_CORRX,
4245 +            SSB_SPROM8_OPT_CORRX_TEMP_SLOPE,
4246 +            SSB_SPROM8_OPT_CORRX_TEMP_SLOPE_SHIFT);
4247 +       SPEX(tempcorrx, SSB_SPROM8_OPT_CORRX, SSB_SPROM8_OPT_CORRX_TEMPCORRX,
4248 +            SSB_SPROM8_OPT_CORRX_TEMPCORRX_SHIFT);
4249 +       SPEX(tempsense_option, SSB_SPROM8_OPT_CORRX,
4250 +            SSB_SPROM8_OPT_CORRX_TEMP_OPTION,
4251 +            SSB_SPROM8_OPT_CORRX_TEMP_OPTION_SHIFT);
4252 +       SPEX(freqoffset_corr, SSB_SPROM8_HWIQ_IQSWP,
4253 +            SSB_SPROM8_HWIQ_IQSWP_FREQ_CORR,
4254 +            SSB_SPROM8_HWIQ_IQSWP_FREQ_CORR_SHIFT);
4255 +       SPEX(iqcal_swp_dis, SSB_SPROM8_HWIQ_IQSWP,
4256 +            SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP,
4257 +            SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP_SHIFT);
4258 +       SPEX(hw_iqcal_en, SSB_SPROM8_HWIQ_IQSWP, SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL,
4259 +            SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL_SHIFT);
4260 +
4261 +       SPEX(bw40po, SSB_SPROM8_BW40PO, ~0, 0);
4262 +       SPEX(cddpo, SSB_SPROM8_CDDPO, ~0, 0);
4263 +       SPEX(stbcpo, SSB_SPROM8_STBCPO, ~0, 0);
4264 +       SPEX(bwduppo, SSB_SPROM8_BWDUPPO, ~0, 0);
4265 +
4266 +       SPEX(tempthresh, SSB_SPROM8_THERMAL, SSB_SPROM8_THERMAL_TRESH,
4267 +            SSB_SPROM8_THERMAL_TRESH_SHIFT);
4268 +       SPEX(tempoffset, SSB_SPROM8_THERMAL, SSB_SPROM8_THERMAL_OFFSET,
4269 +            SSB_SPROM8_THERMAL_OFFSET_SHIFT);
4270 +       SPEX(phycal_tempdelta, SSB_SPROM8_TEMPDELTA,
4271 +            SSB_SPROM8_TEMPDELTA_PHYCAL,
4272 +            SSB_SPROM8_TEMPDELTA_PHYCAL_SHIFT);
4273 +       SPEX(temps_period, SSB_SPROM8_TEMPDELTA, SSB_SPROM8_TEMPDELTA_PERIOD,
4274 +            SSB_SPROM8_TEMPDELTA_PERIOD_SHIFT);
4275 +       SPEX(temps_hysteresis, SSB_SPROM8_TEMPDELTA,
4276 +            SSB_SPROM8_TEMPDELTA_HYSTERESIS,
4277 +            SSB_SPROM8_TEMPDELTA_HYSTERESIS_SHIFT);
4278 +}
4279 +
4280 +/*
4281 + * Indicates the presence of external SPROM.
4282 + */
4283 +static bool bcma_sprom_ext_available(struct bcma_bus *bus)
4284 +{
4285 +       u32 chip_status;
4286 +       u32 srom_control;
4287 +       u32 present_mask;
4288 +
4289 +       if (bus->drv_cc.core->id.rev >= 31) {
4290 +               if (!(bus->drv_cc.capabilities & BCMA_CC_CAP_SPROM))
4291 +                       return false;
4292 +
4293 +               srom_control = bcma_read32(bus->drv_cc.core,
4294 +                                          BCMA_CC_SROM_CONTROL);
4295 +               return srom_control & BCMA_CC_SROM_CONTROL_PRESENT;
4296 +       }
4297 +
4298 +       /* older chipcommon revisions use chip status register */
4299 +       chip_status = bcma_read32(bus->drv_cc.core, BCMA_CC_CHIPSTAT);
4300 +       switch (bus->chipinfo.id) {
4301 +       case BCMA_CHIP_ID_BCM4313:
4302 +               present_mask = BCMA_CC_CHIPST_4313_SPROM_PRESENT;
4303 +               break;
4304 +
4305 +       case BCMA_CHIP_ID_BCM4331:
4306 +               present_mask = BCMA_CC_CHIPST_4331_SPROM_PRESENT;
4307 +               break;
4308  
4309 -       bus->sprom.txpid2g[0] = (sprom[SPOFF(SSB_SPROM4_TXPID2G01)] &
4310 -            SSB_SPROM4_TXPID2G0) >> SSB_SPROM4_TXPID2G0_SHIFT;
4311 -       bus->sprom.txpid2g[1] = (sprom[SPOFF(SSB_SPROM4_TXPID2G01)] &
4312 -            SSB_SPROM4_TXPID2G1) >> SSB_SPROM4_TXPID2G1_SHIFT;
4313 -       bus->sprom.txpid2g[2] = (sprom[SPOFF(SSB_SPROM4_TXPID2G23)] &
4314 -            SSB_SPROM4_TXPID2G2) >> SSB_SPROM4_TXPID2G2_SHIFT;
4315 -       bus->sprom.txpid2g[3] = (sprom[SPOFF(SSB_SPROM4_TXPID2G23)] &
4316 -            SSB_SPROM4_TXPID2G3) >> SSB_SPROM4_TXPID2G3_SHIFT;
4317 -
4318 -       bus->sprom.txpid5gl[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL01)] &
4319 -            SSB_SPROM4_TXPID5GL0) >> SSB_SPROM4_TXPID5GL0_SHIFT;
4320 -       bus->sprom.txpid5gl[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL01)] &
4321 -            SSB_SPROM4_TXPID5GL1) >> SSB_SPROM4_TXPID5GL1_SHIFT;
4322 -       bus->sprom.txpid5gl[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL23)] &
4323 -            SSB_SPROM4_TXPID5GL2) >> SSB_SPROM4_TXPID5GL2_SHIFT;
4324 -       bus->sprom.txpid5gl[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL23)] &
4325 -            SSB_SPROM4_TXPID5GL3) >> SSB_SPROM4_TXPID5GL3_SHIFT;
4326 -
4327 -       bus->sprom.txpid5g[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5G01)] &
4328 -            SSB_SPROM4_TXPID5G0) >> SSB_SPROM4_TXPID5G0_SHIFT;
4329 -       bus->sprom.txpid5g[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5G01)] &
4330 -            SSB_SPROM4_TXPID5G1) >> SSB_SPROM4_TXPID5G1_SHIFT;
4331 -       bus->sprom.txpid5g[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5G23)] &
4332 -            SSB_SPROM4_TXPID5G2) >> SSB_SPROM4_TXPID5G2_SHIFT;
4333 -       bus->sprom.txpid5g[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5G23)] &
4334 -            SSB_SPROM4_TXPID5G3) >> SSB_SPROM4_TXPID5G3_SHIFT;
4335 -
4336 -       bus->sprom.txpid5gh[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH01)] &
4337 -            SSB_SPROM4_TXPID5GH0) >> SSB_SPROM4_TXPID5GH0_SHIFT;
4338 -       bus->sprom.txpid5gh[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH01)] &
4339 -            SSB_SPROM4_TXPID5GH1) >> SSB_SPROM4_TXPID5GH1_SHIFT;
4340 -       bus->sprom.txpid5gh[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH23)] &
4341 -            SSB_SPROM4_TXPID5GH2) >> SSB_SPROM4_TXPID5GH2_SHIFT;
4342 -       bus->sprom.txpid5gh[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH23)] &
4343 -            SSB_SPROM4_TXPID5GH3) >> SSB_SPROM4_TXPID5GH3_SHIFT;
4344 -
4345 -       bus->sprom.boardflags_lo = sprom[SPOFF(SSB_SPROM8_BFLLO)];
4346 -       bus->sprom.boardflags_hi = sprom[SPOFF(SSB_SPROM8_BFLHI)];
4347 -       bus->sprom.boardflags2_lo = sprom[SPOFF(SSB_SPROM8_BFL2LO)];
4348 -       bus->sprom.boardflags2_hi = sprom[SPOFF(SSB_SPROM8_BFL2HI)];
4349 -
4350 -       bus->sprom.country_code = sprom[SPOFF(SSB_SPROM8_CCODE)];
4351 -
4352 -       bus->sprom.fem.ghz2.tssipos = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
4353 -               SSB_SROM8_FEM_TSSIPOS) >> SSB_SROM8_FEM_TSSIPOS_SHIFT;
4354 -       bus->sprom.fem.ghz2.extpa_gain = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
4355 -               SSB_SROM8_FEM_EXTPA_GAIN) >> SSB_SROM8_FEM_EXTPA_GAIN_SHIFT;
4356 -       bus->sprom.fem.ghz2.pdet_range = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
4357 -               SSB_SROM8_FEM_PDET_RANGE) >> SSB_SROM8_FEM_PDET_RANGE_SHIFT;
4358 -       bus->sprom.fem.ghz2.tr_iso = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
4359 -               SSB_SROM8_FEM_TR_ISO) >> SSB_SROM8_FEM_TR_ISO_SHIFT;
4360 -       bus->sprom.fem.ghz2.antswlut = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
4361 -               SSB_SROM8_FEM_ANTSWLUT) >> SSB_SROM8_FEM_ANTSWLUT_SHIFT;
4362 -
4363 -       bus->sprom.fem.ghz5.tssipos = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
4364 -               SSB_SROM8_FEM_TSSIPOS) >> SSB_SROM8_FEM_TSSIPOS_SHIFT;
4365 -       bus->sprom.fem.ghz5.extpa_gain = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
4366 -               SSB_SROM8_FEM_EXTPA_GAIN) >> SSB_SROM8_FEM_EXTPA_GAIN_SHIFT;
4367 -       bus->sprom.fem.ghz5.pdet_range = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
4368 -               SSB_SROM8_FEM_PDET_RANGE) >> SSB_SROM8_FEM_PDET_RANGE_SHIFT;
4369 -       bus->sprom.fem.ghz5.tr_iso = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
4370 -               SSB_SROM8_FEM_TR_ISO) >> SSB_SROM8_FEM_TR_ISO_SHIFT;
4371 -       bus->sprom.fem.ghz5.antswlut = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
4372 -               SSB_SROM8_FEM_ANTSWLUT) >> SSB_SROM8_FEM_ANTSWLUT_SHIFT;
4373 +       default:
4374 +               return true;
4375 +       }
4376 +
4377 +       return chip_status & present_mask;
4378 +}
4379 +
4380 +/*
4381 + * Indicates that on-chip OTP memory is present and enabled.
4382 + */
4383 +static bool bcma_sprom_onchip_available(struct bcma_bus *bus)
4384 +{
4385 +       u32 chip_status;
4386 +       u32 otpsize = 0;
4387 +       bool present;
4388 +
4389 +       chip_status = bcma_read32(bus->drv_cc.core, BCMA_CC_CHIPSTAT);
4390 +       switch (bus->chipinfo.id) {
4391 +       case BCMA_CHIP_ID_BCM4313:
4392 +               present = chip_status & BCMA_CC_CHIPST_4313_OTP_PRESENT;
4393 +               break;
4394 +
4395 +       case BCMA_CHIP_ID_BCM4331:
4396 +               present = chip_status & BCMA_CC_CHIPST_4331_OTP_PRESENT;
4397 +               break;
4398 +       case BCMA_CHIP_ID_BCM43142:
4399 +       case BCMA_CHIP_ID_BCM43224:
4400 +       case BCMA_CHIP_ID_BCM43225:
4401 +               /* for these chips OTP is always available */
4402 +               present = true;
4403 +               break;
4404 +       case BCMA_CHIP_ID_BCM43227:
4405 +       case BCMA_CHIP_ID_BCM43228:
4406 +       case BCMA_CHIP_ID_BCM43428:
4407 +               present = chip_status & BCMA_CC_CHIPST_43228_OTP_PRESENT;
4408 +               break;
4409 +       default:
4410 +               present = false;
4411 +               break;
4412 +       }
4413 +
4414 +       if (present) {
4415 +               otpsize = bus->drv_cc.capabilities & BCMA_CC_CAP_OTPS;
4416 +               otpsize >>= BCMA_CC_CAP_OTPS_SHIFT;
4417 +       }
4418 +
4419 +       return otpsize != 0;
4420 +}
4421 +
4422 +/*
4423 + * Verify OTP is filled and determine the byte
4424 + * offset where SPROM data is located.
4425 + *
4426 + * On error, returns 0; byte offset otherwise.
4427 + */
4428 +static int bcma_sprom_onchip_offset(struct bcma_bus *bus)
4429 +{
4430 +       struct bcma_device *cc = bus->drv_cc.core;
4431 +       u32 offset;
4432 +
4433 +       /* verify OTP status */
4434 +       if ((bcma_read32(cc, BCMA_CC_OTPS) & BCMA_CC_OTPS_GU_PROG_HW) == 0)
4435 +               return 0;
4436 +
4437 +       /* obtain bit offset from otplayout register */
4438 +       offset = (bcma_read32(cc, BCMA_CC_OTPL) & BCMA_CC_OTPL_GURGN_OFFSET);
4439 +       return BCMA_CC_SPROM + (offset >> 3);
4440  }
4441  
4442  int bcma_sprom_get(struct bcma_bus *bus)
4443  {
4444 -       u16 offset;
4445 +       u16 offset = BCMA_CC_SPROM;
4446         u16 *sprom;
4447 -       int err = 0;
4448 +       size_t sprom_sizes[] = { SSB_SPROMSIZE_WORDS_R4,
4449 +                                SSB_SPROMSIZE_WORDS_R10, };
4450 +       int i, err = 0;
4451  
4452         if (!bus->drv_cc.core)
4453                 return -EOPNOTSUPP;
4454  
4455 -       if (!(bus->drv_cc.capabilities & BCMA_CC_CAP_SPROM))
4456 -               return -ENOENT;
4457 +       if (!bcma_sprom_ext_available(bus)) {
4458 +               bool sprom_onchip;
4459  
4460 -       sprom = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16),
4461 -                       GFP_KERNEL);
4462 -       if (!sprom)
4463 -               return -ENOMEM;
4464 +               /*
4465 +                * External SPROM takes precedence so check
4466 +                * on-chip OTP only when no external SPROM
4467 +                * is present.
4468 +                */
4469 +               sprom_onchip = bcma_sprom_onchip_available(bus);
4470 +               if (sprom_onchip) {
4471 +                       /* determine offset */
4472 +                       offset = bcma_sprom_onchip_offset(bus);
4473 +               }
4474 +               if (!offset || !sprom_onchip) {
4475 +                       /*
4476 +                        * Maybe there is no SPROM on the device?
4477 +                        * Now we ask the arch code if there is some sprom
4478 +                        * available for this device in some other storage.
4479 +                        */
4480 +                       err = bcma_fill_sprom_with_fallback(bus, &bus->sprom);
4481 +                       return err;
4482 +               }
4483 +       }
4484  
4485 -       if (bus->chipinfo.id == 0x4331)
4486 +       if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4331 ||
4487 +           bus->chipinfo.id == BCMA_CHIP_ID_BCM43431)
4488                 bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, false);
4489  
4490 -       /* Most cards have SPROM moved by additional offset 0x30 (48 dwords).
4491 -        * According to brcm80211 this applies to cards with PCIe rev >= 6
4492 -        * TODO: understand this condition and use it */
4493 -       offset = (bus->chipinfo.id == 0x4331) ? BCMA_CC_SPROM :
4494 -               BCMA_CC_SPROM_PCIE6;
4495 -       bcma_sprom_read(bus, offset, sprom);
4496 +       bcma_debug(bus, "SPROM offset 0x%x\n", offset);
4497 +       for (i = 0; i < ARRAY_SIZE(sprom_sizes); i++) {
4498 +               size_t words = sprom_sizes[i];
4499 +
4500 +               sprom = kcalloc(words, sizeof(u16), GFP_KERNEL);
4501 +               if (!sprom)
4502 +                       return -ENOMEM;
4503 +
4504 +               bcma_sprom_read(bus, offset, sprom, words);
4505 +               err = bcma_sprom_valid(bus, sprom, words);
4506 +               if (!err)
4507 +                       break;
4508  
4509 -       if (bus->chipinfo.id == 0x4331)
4510 -               bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, true);
4511 +               kfree(sprom);
4512 +       }
4513  
4514 -       err = bcma_sprom_valid(sprom);
4515 -       if (err)
4516 -               goto out;
4517 +       if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4331 ||
4518 +           bus->chipinfo.id == BCMA_CHIP_ID_BCM43431)
4519 +               bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, true);
4520  
4521 -       bcma_sprom_extract_r8(bus, sprom);
4522 +       if (err) {
4523 +               bcma_warn(bus, "Invalid SPROM read from the PCIe card, trying to use fallback SPROM\n");
4524 +               err = bcma_fill_sprom_with_fallback(bus, &bus->sprom);
4525 +       } else {
4526 +               bcma_sprom_extract_r8(bus, sprom);
4527 +               kfree(sprom);
4528 +       }
4529  
4530 -out:
4531 -       kfree(sprom);
4532         return err;
4533  }
4534 --- a/include/linux/bcma/bcma.h
4535 +++ b/include/linux/bcma/bcma.h
4536 @@ -7,9 +7,10 @@
4537  #include <linux/bcma/bcma_driver_chipcommon.h>
4538  #include <linux/bcma/bcma_driver_pci.h>
4539  #include <linux/bcma/bcma_driver_mips.h>
4540 +#include <linux/bcma/bcma_driver_gmac_cmn.h>
4541  #include <linux/ssb/ssb.h> /* SPROM sharing */
4542  
4543 -#include "bcma_regs.h"
4544 +#include <linux/bcma/bcma_regs.h>
4545  
4546  struct bcma_device;
4547  struct bcma_bus;
4548 @@ -26,6 +27,11 @@ struct bcma_chipinfo {
4549         u8 pkg;
4550  };
4551  
4552 +struct bcma_boardinfo {
4553 +       u16 vendor;
4554 +       u16 type;
4555 +};
4556 +
4557  enum bcma_clkmode {
4558         BCMA_CLKMODE_FAST,
4559         BCMA_CLKMODE_DYNAMIC,
4560 @@ -65,6 +71,13 @@ struct bcma_host_ops {
4561  
4562  /* Core-ID values. */
4563  #define BCMA_CORE_OOB_ROUTER           0x367   /* Out of band */
4564 +#define BCMA_CORE_4706_CHIPCOMMON      0x500
4565 +#define BCMA_CORE_4706_SOC_RAM         0x50E
4566 +#define BCMA_CORE_4706_MAC_GBIT                0x52D
4567 +#define BCMA_CORE_AMEMC                        0x52E   /* DDR1/2 memory controller core */
4568 +#define BCMA_CORE_ALTA                 0x534   /* I2S core */
4569 +#define BCMA_CORE_4706_MAC_GBIT_COMMON 0x5DC
4570 +#define BCMA_CORE_DDR23_PHY            0x5DD
4571  #define BCMA_CORE_INVALID              0x700
4572  #define BCMA_CORE_CHIPCOMMON           0x800
4573  #define BCMA_CORE_ILINE20              0x801
4574 @@ -121,10 +134,104 @@ struct bcma_host_ops {
4575  #define BCMA_CORE_I2S                  0x834
4576  #define BCMA_CORE_SDR_DDR1_MEM_CTL     0x835   /* SDR/DDR1 memory controller core */
4577  #define BCMA_CORE_SHIM                 0x837   /* SHIM component in ubus/6362 */
4578 +#define BCMA_CORE_PHY_AC               0x83B
4579 +#define BCMA_CORE_PCIE2                        0x83C   /* PCI Express Gen2 */
4580 +#define BCMA_CORE_USB30_DEV            0x83D
4581 +#define BCMA_CORE_ARM_CR4              0x83E
4582  #define BCMA_CORE_DEFAULT              0xFFF
4583  
4584  #define BCMA_MAX_NR_CORES              16
4585  
4586 +/* Chip IDs of PCIe devices */
4587 +#define BCMA_CHIP_ID_BCM4313   0x4313
4588 +#define BCMA_CHIP_ID_BCM43142  43142
4589 +#define BCMA_CHIP_ID_BCM43224  43224
4590 +#define  BCMA_PKG_ID_BCM43224_FAB_CSM  0x8
4591 +#define  BCMA_PKG_ID_BCM43224_FAB_SMIC 0xa
4592 +#define BCMA_CHIP_ID_BCM43225  43225
4593 +#define BCMA_CHIP_ID_BCM43227  43227
4594 +#define BCMA_CHIP_ID_BCM43228  43228
4595 +#define BCMA_CHIP_ID_BCM43421  43421
4596 +#define BCMA_CHIP_ID_BCM43428  43428
4597 +#define BCMA_CHIP_ID_BCM43431  43431
4598 +#define BCMA_CHIP_ID_BCM43460  43460
4599 +#define BCMA_CHIP_ID_BCM4331   0x4331
4600 +#define BCMA_CHIP_ID_BCM6362   0x6362
4601 +#define BCMA_CHIP_ID_BCM4360   0x4360
4602 +#define BCMA_CHIP_ID_BCM4352   0x4352
4603 +
4604 +/* Chip IDs of SoCs */
4605 +#define BCMA_CHIP_ID_BCM4706   0x5300
4606 +#define  BCMA_PKG_ID_BCM4706L  1
4607 +#define BCMA_CHIP_ID_BCM4716   0x4716
4608 +#define  BCMA_PKG_ID_BCM4716   8
4609 +#define  BCMA_PKG_ID_BCM4717   9
4610 +#define  BCMA_PKG_ID_BCM4718   10
4611 +#define BCMA_CHIP_ID_BCM47162  47162
4612 +#define BCMA_CHIP_ID_BCM4748   0x4748
4613 +#define BCMA_CHIP_ID_BCM4749   0x4749
4614 +#define BCMA_CHIP_ID_BCM5356   0x5356
4615 +#define BCMA_CHIP_ID_BCM5357   0x5357
4616 +#define  BCMA_PKG_ID_BCM5358   9
4617 +#define  BCMA_PKG_ID_BCM47186  10
4618 +#define  BCMA_PKG_ID_BCM5357   11
4619 +#define BCMA_CHIP_ID_BCM53572  53572
4620 +#define  BCMA_PKG_ID_BCM47188  9
4621 +
4622 +/* Board types (on PCI usually equals to the subsystem dev id) */
4623 +/* BCM4313 */
4624 +#define BCMA_BOARD_TYPE_BCM94313BU     0X050F
4625 +#define BCMA_BOARD_TYPE_BCM94313HM     0X0510
4626 +#define BCMA_BOARD_TYPE_BCM94313EPA    0X0511
4627 +#define BCMA_BOARD_TYPE_BCM94313HMG    0X051C
4628 +/* BCM4716 */
4629 +#define BCMA_BOARD_TYPE_BCM94716NR2    0X04CD
4630 +/* BCM43224 */
4631 +#define BCMA_BOARD_TYPE_BCM943224X21   0X056E
4632 +#define BCMA_BOARD_TYPE_BCM943224X21_FCC       0X00D1
4633 +#define BCMA_BOARD_TYPE_BCM943224X21B  0X00E9
4634 +#define BCMA_BOARD_TYPE_BCM943224M93   0X008B
4635 +#define BCMA_BOARD_TYPE_BCM943224M93A  0X0090
4636 +#define BCMA_BOARD_TYPE_BCM943224X16   0X0093
4637 +#define BCMA_BOARD_TYPE_BCM94322X9     0X008D
4638 +#define BCMA_BOARD_TYPE_BCM94322M35E   0X008E
4639 +/* BCM43228 */
4640 +#define BCMA_BOARD_TYPE_BCM943228BU8   0X0540
4641 +#define BCMA_BOARD_TYPE_BCM943228BU9   0X0541
4642 +#define BCMA_BOARD_TYPE_BCM943228BU    0X0542
4643 +#define BCMA_BOARD_TYPE_BCM943227HM4L  0X0543
4644 +#define BCMA_BOARD_TYPE_BCM943227HMB   0X0544
4645 +#define BCMA_BOARD_TYPE_BCM943228HM4L  0X0545
4646 +#define BCMA_BOARD_TYPE_BCM943228SD    0X0573
4647 +/* BCM4331 */
4648 +#define BCMA_BOARD_TYPE_BCM94331X19    0X00D6
4649 +#define BCMA_BOARD_TYPE_BCM94331X28    0X00E4
4650 +#define BCMA_BOARD_TYPE_BCM94331X28B   0X010E
4651 +#define BCMA_BOARD_TYPE_BCM94331PCIEBT3AX      0X00E4
4652 +#define BCMA_BOARD_TYPE_BCM94331X12_2G 0X00EC
4653 +#define BCMA_BOARD_TYPE_BCM94331X12_5G 0X00ED
4654 +#define BCMA_BOARD_TYPE_BCM94331X29B   0X00EF
4655 +#define BCMA_BOARD_TYPE_BCM94331CSAX   0X00EF
4656 +#define BCMA_BOARD_TYPE_BCM94331X19C   0X00F5
4657 +#define BCMA_BOARD_TYPE_BCM94331X33    0X00F4
4658 +#define BCMA_BOARD_TYPE_BCM94331BU     0X0523
4659 +#define BCMA_BOARD_TYPE_BCM94331S9BU   0X0524
4660 +#define BCMA_BOARD_TYPE_BCM94331MC     0X0525
4661 +#define BCMA_BOARD_TYPE_BCM94331MCI    0X0526
4662 +#define BCMA_BOARD_TYPE_BCM94331PCIEBT4        0X0527
4663 +#define BCMA_BOARD_TYPE_BCM94331HM     0X0574
4664 +#define BCMA_BOARD_TYPE_BCM94331PCIEDUAL       0X059B
4665 +#define BCMA_BOARD_TYPE_BCM94331MCH5   0X05A9
4666 +#define BCMA_BOARD_TYPE_BCM94331CS     0X05C6
4667 +#define BCMA_BOARD_TYPE_BCM94331CD     0X05DA
4668 +/* BCM53572 */
4669 +#define BCMA_BOARD_TYPE_BCM953572BU    0X058D
4670 +#define BCMA_BOARD_TYPE_BCM953572NR2   0X058E
4671 +#define BCMA_BOARD_TYPE_BCM947188NR2   0X058F
4672 +#define BCMA_BOARD_TYPE_BCM953572SDRNR2        0X0590
4673 +/* BCM43142 */
4674 +#define BCMA_BOARD_TYPE_BCM943142HM    0X05E0
4675 +
4676  struct bcma_device {
4677         struct bcma_bus *bus;
4678         struct bcma_device_id id;
4679 @@ -136,8 +243,10 @@ struct bcma_device {
4680         bool dev_registered;
4681  
4682         u8 core_index;
4683 +       u8 core_unit;
4684  
4685         u32 addr;
4686 +       u32 addr1;
4687         u32 wrap;
4688  
4689         void __iomem *io_addr;
4690 @@ -175,6 +284,12 @@ int __bcma_driver_register(struct bcma_d
4691  
4692  extern void bcma_driver_unregister(struct bcma_driver *drv);
4693  
4694 +/* Set a fallback SPROM.
4695 + * See kdoc at the function definition for complete documentation. */
4696 +extern int bcma_arch_register_fallback_sprom(
4697 +               int (*sprom_callback)(struct bcma_bus *bus,
4698 +               struct ssb_sprom *out));
4699 +
4700  struct bcma_bus {
4701         /* The MMIO area. */
4702         void __iomem *mmio;
4703 @@ -191,14 +306,18 @@ struct bcma_bus {
4704  
4705         struct bcma_chipinfo chipinfo;
4706  
4707 +       struct bcma_boardinfo boardinfo;
4708 +
4709         struct bcma_device *mapped_core;
4710         struct list_head cores;
4711         u8 nr_cores;
4712         u8 init_done:1;
4713 +       u8 num;
4714  
4715         struct bcma_drv_cc drv_cc;
4716 -       struct bcma_drv_pci drv_pci;
4717 +       struct bcma_drv_pci drv_pci[2];
4718         struct bcma_drv_mips drv_mips;
4719 +       struct bcma_drv_gmac_cmn drv_gmac_cmn;
4720  
4721         /* We decided to share SPROM struct with SSB as long as we do not need
4722          * any hacks for BCMA. This simplifies drivers code. */
4723 @@ -282,6 +401,7 @@ static inline void bcma_maskset16(struct
4724         bcma_write16(cc, offset, (bcma_read16(cc, offset) & mask) | set);
4725  }
4726  
4727 +extern struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid);
4728  extern bool bcma_core_is_enabled(struct bcma_device *core);
4729  extern void bcma_core_disable(struct bcma_device *core, u32 flags);
4730  extern int bcma_core_enable(struct bcma_device *core, u32 flags);
4731 @@ -289,6 +409,7 @@ extern void bcma_core_set_clockmode(stru
4732                                     enum bcma_clkmode clkmode);
4733  extern void bcma_core_pll_ctl(struct bcma_device *core, u32 req, u32 status,
4734                               bool on);
4735 +extern u32 bcma_chipco_pll_read(struct bcma_drv_cc *cc, u32 offset);
4736  #define BCMA_DMA_TRANSLATION_MASK      0xC0000000
4737  #define  BCMA_DMA_TRANSLATION_NONE     0x00000000
4738  #define  BCMA_DMA_TRANSLATION_DMA32_CMT        0x40000000 /* Client Mode Translation for 32-bit DMA */
4739 --- a/include/linux/bcma/bcma_driver_chipcommon.h
4740 +++ b/include/linux/bcma/bcma_driver_chipcommon.h
4741 @@ -1,6 +1,9 @@
4742  #ifndef LINUX_BCMA_DRIVER_CC_H_
4743  #define LINUX_BCMA_DRIVER_CC_H_
4744  
4745 +#include <linux/platform_device.h>
4746 +#include <linux/gpio.h>
4747 +
4748  /** ChipCommon core registers. **/
4749  #define BCMA_CC_ID                     0x0000
4750  #define  BCMA_CC_ID_ID                 0x0000FFFF
4751 @@ -24,7 +27,7 @@
4752  #define   BCMA_CC_FLASHT_NONE          0x00000000      /* No flash */
4753  #define   BCMA_CC_FLASHT_STSER         0x00000100      /* ST serial flash */
4754  #define   BCMA_CC_FLASHT_ATSER         0x00000200      /* Atmel serial flash */
4755 -#define   BCMA_CC_FLASHT_NFLASH                0x00000200
4756 +#define   BCMA_CC_FLASHT_NAND          0x00000300      /* NAND flash */
4757  #define          BCMA_CC_FLASHT_PARA           0x00000700      /* Parallel flash */
4758  #define  BCMA_CC_CAP_PLLT              0x00038000      /* PLL Type */
4759  #define   BCMA_PLLTYPE_NONE            0x00000000
4760 @@ -45,6 +48,7 @@
4761  #define  BCMA_CC_CAP_PMU               0x10000000      /* PMU available (rev >= 20) */
4762  #define  BCMA_CC_CAP_ECI               0x20000000      /* ECI available (rev >= 20) */
4763  #define  BCMA_CC_CAP_SPROM             0x40000000      /* SPROM present */
4764 +#define  BCMA_CC_CAP_NFLASH            0x80000000      /* NAND flash present (rev >= 35 or BCM4706?) */
4765  #define BCMA_CC_CORECTL                        0x0008
4766  #define  BCMA_CC_CORECTL_UARTCLK0      0x00000001      /* Drive UART with internal clock */
4767  #define         BCMA_CC_CORECTL_SE             0x00000002      /* sync clk out enable (corerev >= 3) */
4768 @@ -56,6 +60,9 @@
4769  #define         BCMA_CC_OTPS_HW_PROTECT        0x00000001
4770  #define         BCMA_CC_OTPS_SW_PROTECT        0x00000002
4771  #define         BCMA_CC_OTPS_CID_PROTECT       0x00000004
4772 +#define  BCMA_CC_OTPS_GU_PROG_IND      0x00000F00      /* General Use programmed indication */
4773 +#define  BCMA_CC_OTPS_GU_PROG_IND_SHIFT        8
4774 +#define  BCMA_CC_OTPS_GU_PROG_HW       0x00000100      /* HW region programmed */
4775  #define BCMA_CC_OTPC                   0x0014          /* OTP control */
4776  #define         BCMA_CC_OTPC_RECWAIT           0xFF000000
4777  #define         BCMA_CC_OTPC_PROGWAIT          0x00FFFF00
4778 @@ -72,6 +79,8 @@
4779  #define         BCMA_CC_OTPP_READ              0x40000000
4780  #define         BCMA_CC_OTPP_START             0x80000000
4781  #define         BCMA_CC_OTPP_BUSY              0x80000000
4782 +#define BCMA_CC_OTPL                   0x001C          /* OTP layout */
4783 +#define  BCMA_CC_OTPL_GURGN_OFFSET     0x00000FFF      /* offset of general use region */
4784  #define BCMA_CC_IRQSTAT                        0x0020
4785  #define BCMA_CC_IRQMASK                        0x0024
4786  #define         BCMA_CC_IRQ_GPIO               0x00000001      /* gpio intr */
4787 @@ -79,6 +88,23 @@
4788  #define         BCMA_CC_IRQ_WDRESET            0x80000000      /* watchdog reset occurred */
4789  #define BCMA_CC_CHIPCTL                        0x0028          /* Rev >= 11 only */
4790  #define BCMA_CC_CHIPSTAT               0x002C          /* Rev >= 11 only */
4791 +#define  BCMA_CC_CHIPST_4313_SPROM_PRESENT     1
4792 +#define  BCMA_CC_CHIPST_4313_OTP_PRESENT       2
4793 +#define  BCMA_CC_CHIPST_4331_SPROM_PRESENT     2
4794 +#define  BCMA_CC_CHIPST_4331_OTP_PRESENT       4
4795 +#define  BCMA_CC_CHIPST_43228_ILP_DIV_EN       0x00000001
4796 +#define  BCMA_CC_CHIPST_43228_OTP_PRESENT      0x00000002
4797 +#define  BCMA_CC_CHIPST_43228_SERDES_REFCLK_PADSEL     0x00000004
4798 +#define  BCMA_CC_CHIPST_43228_SDIO_MODE                0x00000008
4799 +#define  BCMA_CC_CHIPST_43228_SDIO_OTP_PRESENT 0x00000010
4800 +#define  BCMA_CC_CHIPST_43228_SDIO_RESET       0x00000020
4801 +#define  BCMA_CC_CHIPST_4706_PKG_OPTION                BIT(0) /* 0: full-featured package 1: low-cost package */
4802 +#define  BCMA_CC_CHIPST_4706_SFLASH_PRESENT    BIT(1) /* 0: parallel, 1: serial flash is present */
4803 +#define  BCMA_CC_CHIPST_4706_SFLASH_TYPE       BIT(2) /* 0: 8b-p/ST-s flash, 1: 16b-p/Atmal-s flash */
4804 +#define  BCMA_CC_CHIPST_4706_MIPS_BENDIAN      BIT(3) /* 0: little, 1: big endian */
4805 +#define  BCMA_CC_CHIPST_4706_PCIE1_DISABLE     BIT(5) /* PCIE1 enable strap pin */
4806 +#define  BCMA_CC_CHIPST_5357_NAND_BOOT         BIT(4) /* NAND boot, valid for CC rev 38 and/or BCM5357 */
4807 +#define  BCMA_CC_CHIPST_4360_XTAL_40MZ         0x00000001
4808  #define BCMA_CC_JCMD                   0x0030          /* Rev >= 10 only */
4809  #define  BCMA_CC_JCMD_START            0x80000000
4810  #define  BCMA_CC_JCMD_BUSY             0x80000000
4811 @@ -108,10 +134,58 @@
4812  #define  BCMA_CC_JCTL_EXT_EN           2               /* Enable external targets */
4813  #define  BCMA_CC_JCTL_EN               1               /* Enable Jtag master */
4814  #define BCMA_CC_FLASHCTL               0x0040
4815 +/* Start/busy bit in flashcontrol */
4816 +#define  BCMA_CC_FLASHCTL_OPCODE       0x000000ff
4817 +#define  BCMA_CC_FLASHCTL_ACTION       0x00000700
4818 +#define  BCMA_CC_FLASHCTL_CS_ACTIVE    0x00001000      /* Chip Select Active, rev >= 20 */
4819  #define  BCMA_CC_FLASHCTL_START                0x80000000
4820  #define  BCMA_CC_FLASHCTL_BUSY         BCMA_CC_FLASHCTL_START
4821 +/* Flashcontrol action + opcodes for ST flashes */
4822 +#define  BCMA_CC_FLASHCTL_ST_WREN      0x0006          /* Write Enable */
4823 +#define  BCMA_CC_FLASHCTL_ST_WRDIS     0x0004          /* Write Disable */
4824 +#define  BCMA_CC_FLASHCTL_ST_RDSR      0x0105          /* Read Status Register */
4825 +#define  BCMA_CC_FLASHCTL_ST_WRSR      0x0101          /* Write Status Register */
4826 +#define  BCMA_CC_FLASHCTL_ST_READ      0x0303          /* Read Data Bytes */
4827 +#define  BCMA_CC_FLASHCTL_ST_PP                0x0302          /* Page Program */
4828 +#define  BCMA_CC_FLASHCTL_ST_SE                0x02d8          /* Sector Erase */
4829 +#define  BCMA_CC_FLASHCTL_ST_BE                0x00c7          /* Bulk Erase */
4830 +#define  BCMA_CC_FLASHCTL_ST_DP                0x00b9          /* Deep Power-down */
4831 +#define  BCMA_CC_FLASHCTL_ST_RES       0x03ab          /* Read Electronic Signature */
4832 +#define  BCMA_CC_FLASHCTL_ST_CSA       0x1000          /* Keep chip select asserted */
4833 +#define  BCMA_CC_FLASHCTL_ST_SSE       0x0220          /* Sub-sector Erase */
4834 +/* Flashcontrol action + opcodes for Atmel flashes */
4835 +#define  BCMA_CC_FLASHCTL_AT_READ                      0x07e8
4836 +#define  BCMA_CC_FLASHCTL_AT_PAGE_READ                 0x07d2
4837 +#define  BCMA_CC_FLASHCTL_AT_STATUS                    0x01d7
4838 +#define  BCMA_CC_FLASHCTL_AT_BUF1_WRITE                        0x0384
4839 +#define  BCMA_CC_FLASHCTL_AT_BUF2_WRITE                        0x0387
4840 +#define  BCMA_CC_FLASHCTL_AT_BUF1_ERASE_PROGRAM                0x0283
4841 +#define  BCMA_CC_FLASHCTL_AT_BUF2_ERASE_PROGRAM                0x0286
4842 +#define  BCMA_CC_FLASHCTL_AT_BUF1_PROGRAM              0x0288
4843 +#define  BCMA_CC_FLASHCTL_AT_BUF2_PROGRAM              0x0289
4844 +#define  BCMA_CC_FLASHCTL_AT_PAGE_ERASE                        0x0281
4845 +#define  BCMA_CC_FLASHCTL_AT_BLOCK_ERASE               0x0250
4846 +#define  BCMA_CC_FLASHCTL_AT_BUF1_WRITE_ERASE_PROGRAM  0x0382
4847 +#define  BCMA_CC_FLASHCTL_AT_BUF2_WRITE_ERASE_PROGRAM  0x0385
4848 +#define  BCMA_CC_FLASHCTL_AT_BUF1_LOAD                 0x0253
4849 +#define  BCMA_CC_FLASHCTL_AT_BUF2_LOAD                 0x0255
4850 +#define  BCMA_CC_FLASHCTL_AT_BUF1_COMPARE              0x0260
4851 +#define  BCMA_CC_FLASHCTL_AT_BUF2_COMPARE              0x0261
4852 +#define  BCMA_CC_FLASHCTL_AT_BUF1_REPROGRAM            0x0258
4853 +#define  BCMA_CC_FLASHCTL_AT_BUF2_REPROGRAM            0x0259
4854  #define BCMA_CC_FLASHADDR              0x0044
4855  #define BCMA_CC_FLASHDATA              0x0048
4856 +/* Status register bits for ST flashes */
4857 +#define  BCMA_CC_FLASHDATA_ST_WIP      0x01            /* Write In Progress */
4858 +#define  BCMA_CC_FLASHDATA_ST_WEL      0x02            /* Write Enable Latch */
4859 +#define  BCMA_CC_FLASHDATA_ST_BP_MASK  0x1c            /* Block Protect */
4860 +#define  BCMA_CC_FLASHDATA_ST_BP_SHIFT 2
4861 +#define  BCMA_CC_FLASHDATA_ST_SRWD     0x80            /* Status Register Write Disable */
4862 +/* Status register bits for Atmel flashes */
4863 +#define  BCMA_CC_FLASHDATA_AT_READY    0x80
4864 +#define  BCMA_CC_FLASHDATA_AT_MISMATCH 0x40
4865 +#define  BCMA_CC_FLASHDATA_AT_ID_MASK  0x38
4866 +#define  BCMA_CC_FLASHDATA_AT_ID_SHIFT 3
4867  #define BCMA_CC_BCAST_ADDR             0x0050
4868  #define BCMA_CC_BCAST_DATA             0x0054
4869  #define BCMA_CC_GPIOPULLUP             0x0058          /* Rev >= 20 only */
4870 @@ -181,6 +255,45 @@
4871  #define BCMA_CC_FLASH_CFG              0x0128
4872  #define  BCMA_CC_FLASH_CFG_DS          0x0010  /* Data size, 0=8bit, 1=16bit */
4873  #define BCMA_CC_FLASH_WAITCNT          0x012C
4874 +#define BCMA_CC_SROM_CONTROL           0x0190
4875 +#define  BCMA_CC_SROM_CONTROL_START    0x80000000
4876 +#define  BCMA_CC_SROM_CONTROL_BUSY     0x80000000
4877 +#define  BCMA_CC_SROM_CONTROL_OPCODE   0x60000000
4878 +#define  BCMA_CC_SROM_CONTROL_OP_READ  0x00000000
4879 +#define  BCMA_CC_SROM_CONTROL_OP_WRITE 0x20000000
4880 +#define  BCMA_CC_SROM_CONTROL_OP_WRDIS 0x40000000
4881 +#define  BCMA_CC_SROM_CONTROL_OP_WREN  0x60000000
4882 +#define  BCMA_CC_SROM_CONTROL_OTPSEL   0x00000010
4883 +#define  BCMA_CC_SROM_CONTROL_LOCK     0x00000008
4884 +#define  BCMA_CC_SROM_CONTROL_SIZE_MASK        0x00000006
4885 +#define  BCMA_CC_SROM_CONTROL_SIZE_1K  0x00000000
4886 +#define  BCMA_CC_SROM_CONTROL_SIZE_4K  0x00000002
4887 +#define  BCMA_CC_SROM_CONTROL_SIZE_16K 0x00000004
4888 +#define  BCMA_CC_SROM_CONTROL_SIZE_SHIFT       1
4889 +#define  BCMA_CC_SROM_CONTROL_PRESENT  0x00000001
4890 +/* Block 0x140 - 0x190 registers are chipset specific */
4891 +#define BCMA_CC_4706_FLASHSCFG         0x18C           /* Flash struct configuration */
4892 +#define  BCMA_CC_4706_FLASHSCFG_MASK   0x000000ff
4893 +#define  BCMA_CC_4706_FLASHSCFG_SF1    0x00000001      /* 2nd serial flash present */
4894 +#define  BCMA_CC_4706_FLASHSCFG_PF1    0x00000002      /* 2nd parallel flash present */
4895 +#define  BCMA_CC_4706_FLASHSCFG_SF1_TYPE       0x00000004      /* 2nd serial flash type : 0 : ST, 1 : Atmel */
4896 +#define  BCMA_CC_4706_FLASHSCFG_NF1    0x00000008      /* 2nd NAND flash present */
4897 +#define  BCMA_CC_4706_FLASHSCFG_1ST_MADDR_SEG_MASK     0x000000f0
4898 +#define  BCMA_CC_4706_FLASHSCFG_1ST_MADDR_SEG_4MB      0x00000010      /* 4MB */
4899 +#define  BCMA_CC_4706_FLASHSCFG_1ST_MADDR_SEG_8MB      0x00000020      /* 8MB */
4900 +#define  BCMA_CC_4706_FLASHSCFG_1ST_MADDR_SEG_16MB     0x00000030      /* 16MB */
4901 +#define  BCMA_CC_4706_FLASHSCFG_1ST_MADDR_SEG_32MB     0x00000040      /* 32MB */
4902 +#define  BCMA_CC_4706_FLASHSCFG_1ST_MADDR_SEG_64MB     0x00000050      /* 64MB */
4903 +#define  BCMA_CC_4706_FLASHSCFG_1ST_MADDR_SEG_128MB    0x00000060      /* 128MB */
4904 +#define  BCMA_CC_4706_FLASHSCFG_1ST_MADDR_SEG_256MB    0x00000070      /* 256MB */
4905 +/* NAND flash registers for BCM4706 (corerev = 31) */
4906 +#define BCMA_CC_NFLASH_CTL             0x01A0
4907 +#define  BCMA_CC_NFLASH_CTL_ERR                0x08000000
4908 +#define BCMA_CC_NFLASH_CONF            0x01A4
4909 +#define BCMA_CC_NFLASH_COL_ADDR                0x01A8
4910 +#define BCMA_CC_NFLASH_ROW_ADDR                0x01AC
4911 +#define BCMA_CC_NFLASH_DATA            0x01B0
4912 +#define BCMA_CC_NFLASH_WAITCNT0                0x01B4
4913  /* 0x1E0 is defined as shared BCMA_CLKCTLST */
4914  #define BCMA_CC_HW_WORKAROUND          0x01E4 /* Hardware workaround (rev >= 20) */
4915  #define BCMA_CC_UART0_DATA             0x0300
4916 @@ -203,6 +316,9 @@
4917  #define BCMA_CC_PMU_CTL                        0x0600 /* PMU control */
4918  #define  BCMA_CC_PMU_CTL_ILP_DIV       0xFFFF0000 /* ILP div mask */
4919  #define  BCMA_CC_PMU_CTL_ILP_DIV_SHIFT 16
4920 +#define  BCMA_CC_PMU_CTL_RES           0x00006000 /* reset control mask */
4921 +#define  BCMA_CC_PMU_CTL_RES_SHIFT     13
4922 +#define  BCMA_CC_PMU_CTL_RES_RELOAD    0x2     /* reload POR values */
4923  #define  BCMA_CC_PMU_CTL_PLL_UPD       0x00000400
4924  #define  BCMA_CC_PMU_CTL_NOILPONW      0x00000200 /* No ILP on wait */
4925  #define  BCMA_CC_PMU_CTL_HTREQEN       0x00000100 /* HT req enable */
4926 @@ -214,6 +330,8 @@
4927  #define BCMA_CC_PMU_CAP                        0x0604 /* PMU capabilities */
4928  #define  BCMA_CC_PMU_CAP_REVISION      0x000000FF /* Revision mask */
4929  #define BCMA_CC_PMU_STAT               0x0608 /* PMU status */
4930 +#define  BCMA_CC_PMU_STAT_EXT_LPO_AVAIL        0x00000100
4931 +#define  BCMA_CC_PMU_STAT_WDRESET      0x00000080
4932  #define  BCMA_CC_PMU_STAT_INTPEND      0x00000040 /* Interrupt pending */
4933  #define  BCMA_CC_PMU_STAT_SBCLKST      0x00000030 /* Backplane clock status? */
4934  #define  BCMA_CC_PMU_STAT_HAVEALP      0x00000008 /* ALP available */
4935 @@ -239,8 +357,66 @@
4936  #define BCMA_CC_REGCTL_DATA            0x065C
4937  #define BCMA_CC_PLLCTL_ADDR            0x0660
4938  #define BCMA_CC_PLLCTL_DATA            0x0664
4939 +#define BCMA_CC_PMU_STRAPOPT           0x0668 /* (corerev >= 28) */
4940 +#define BCMA_CC_PMU_XTAL_FREQ          0x066C /* (pmurev >= 10) */
4941 +#define  BCMA_CC_PMU_XTAL_FREQ_ILPCTL_MASK     0x00001FFF
4942 +#define  BCMA_CC_PMU_XTAL_FREQ_MEASURE_MASK    0x80000000
4943 +#define  BCMA_CC_PMU_XTAL_FREQ_MEASURE_SHIFT   31
4944  #define BCMA_CC_SPROM                  0x0800 /* SPROM beginning */
4945 -#define BCMA_CC_SPROM_PCIE6            0x0830 /* SPROM beginning on PCIe rev >= 6 */
4946 +/* NAND flash MLC controller registers (corerev >= 38) */
4947 +#define BCMA_CC_NAND_REVISION          0x0C00
4948 +#define BCMA_CC_NAND_CMD_START         0x0C04
4949 +#define BCMA_CC_NAND_CMD_ADDR_X                0x0C08
4950 +#define BCMA_CC_NAND_CMD_ADDR          0x0C0C
4951 +#define BCMA_CC_NAND_CMD_END_ADDR      0x0C10
4952 +#define BCMA_CC_NAND_CS_NAND_SELECT    0x0C14
4953 +#define BCMA_CC_NAND_CS_NAND_XOR       0x0C18
4954 +#define BCMA_CC_NAND_SPARE_RD0         0x0C20
4955 +#define BCMA_CC_NAND_SPARE_RD4         0x0C24
4956 +#define BCMA_CC_NAND_SPARE_RD8         0x0C28
4957 +#define BCMA_CC_NAND_SPARE_RD12                0x0C2C
4958 +#define BCMA_CC_NAND_SPARE_WR0         0x0C30
4959 +#define BCMA_CC_NAND_SPARE_WR4         0x0C34
4960 +#define BCMA_CC_NAND_SPARE_WR8         0x0C38
4961 +#define BCMA_CC_NAND_SPARE_WR12                0x0C3C
4962 +#define BCMA_CC_NAND_ACC_CONTROL       0x0C40
4963 +#define BCMA_CC_NAND_CONFIG            0x0C48
4964 +#define BCMA_CC_NAND_TIMING_1          0x0C50
4965 +#define BCMA_CC_NAND_TIMING_2          0x0C54
4966 +#define BCMA_CC_NAND_SEMAPHORE         0x0C58
4967 +#define BCMA_CC_NAND_DEVID             0x0C60
4968 +#define BCMA_CC_NAND_DEVID_X           0x0C64
4969 +#define BCMA_CC_NAND_BLOCK_LOCK_STATUS 0x0C68
4970 +#define BCMA_CC_NAND_INTFC_STATUS      0x0C6C
4971 +#define BCMA_CC_NAND_ECC_CORR_ADDR_X   0x0C70
4972 +#define BCMA_CC_NAND_ECC_CORR_ADDR     0x0C74
4973 +#define BCMA_CC_NAND_ECC_UNC_ADDR_X    0x0C78
4974 +#define BCMA_CC_NAND_ECC_UNC_ADDR      0x0C7C
4975 +#define BCMA_CC_NAND_READ_ERROR_COUNT  0x0C80
4976 +#define BCMA_CC_NAND_CORR_STAT_THRESHOLD       0x0C84
4977 +#define BCMA_CC_NAND_READ_ADDR_X       0x0C90
4978 +#define BCMA_CC_NAND_READ_ADDR         0x0C94
4979 +#define BCMA_CC_NAND_PAGE_PROGRAM_ADDR_X       0x0C98
4980 +#define BCMA_CC_NAND_PAGE_PROGRAM_ADDR 0x0C9C
4981 +#define BCMA_CC_NAND_COPY_BACK_ADDR_X  0x0CA0
4982 +#define BCMA_CC_NAND_COPY_BACK_ADDR    0x0CA4
4983 +#define BCMA_CC_NAND_BLOCK_ERASE_ADDR_X        0x0CA8
4984 +#define BCMA_CC_NAND_BLOCK_ERASE_ADDR  0x0CAC
4985 +#define BCMA_CC_NAND_INV_READ_ADDR_X   0x0CB0
4986 +#define BCMA_CC_NAND_INV_READ_ADDR     0x0CB4
4987 +#define BCMA_CC_NAND_BLK_WR_PROTECT    0x0CC0
4988 +#define BCMA_CC_NAND_ACC_CONTROL_CS1   0x0CD0
4989 +#define BCMA_CC_NAND_CONFIG_CS1                0x0CD4
4990 +#define BCMA_CC_NAND_TIMING_1_CS1      0x0CD8
4991 +#define BCMA_CC_NAND_TIMING_2_CS1      0x0CDC
4992 +#define BCMA_CC_NAND_SPARE_RD16                0x0D30
4993 +#define BCMA_CC_NAND_SPARE_RD20                0x0D34
4994 +#define BCMA_CC_NAND_SPARE_RD24                0x0D38
4995 +#define BCMA_CC_NAND_SPARE_RD28                0x0D3C
4996 +#define BCMA_CC_NAND_CACHE_ADDR                0x0D40
4997 +#define BCMA_CC_NAND_CACHE_DATA                0x0D44
4998 +#define BCMA_CC_NAND_CTRL_CONFIG       0x0D48
4999 +#define BCMA_CC_NAND_CTRL_STATUS       0x0D4C
5000  
5001  /* Divider allocation in 4716/47162/5356 */
5002  #define BCMA_CC_PMU5_MAINPLL_CPU       1
5003 @@ -256,6 +432,32 @@
5004  
5005  /* 4706 PMU */
5006  #define BCMA_CC_PMU4706_MAINPLL_PLL0   0
5007 +#define BCMA_CC_PMU6_4706_PROCPLL_OFF  4       /* The CPU PLL */
5008 +#define  BCMA_CC_PMU6_4706_PROC_P2DIV_MASK     0x000f0000
5009 +#define  BCMA_CC_PMU6_4706_PROC_P2DIV_SHIFT    16
5010 +#define  BCMA_CC_PMU6_4706_PROC_P1DIV_MASK     0x0000f000
5011 +#define  BCMA_CC_PMU6_4706_PROC_P1DIV_SHIFT    12
5012 +#define  BCMA_CC_PMU6_4706_PROC_NDIV_INT_MASK  0x00000ff8
5013 +#define  BCMA_CC_PMU6_4706_PROC_NDIV_INT_SHIFT 3
5014 +#define  BCMA_CC_PMU6_4706_PROC_NDIV_MODE_MASK 0x00000007
5015 +#define  BCMA_CC_PMU6_4706_PROC_NDIV_MODE_SHIFT        0
5016 +
5017 +/* PMU rev 15 */
5018 +#define BCMA_CC_PMU15_PLL_PLLCTL0      0
5019 +#define  BCMA_CC_PMU15_PLL_PC0_CLKSEL_MASK     0x00000003
5020 +#define  BCMA_CC_PMU15_PLL_PC0_CLKSEL_SHIFT    0
5021 +#define  BCMA_CC_PMU15_PLL_PC0_FREQTGT_MASK    0x003FFFFC
5022 +#define  BCMA_CC_PMU15_PLL_PC0_FREQTGT_SHIFT   2
5023 +#define  BCMA_CC_PMU15_PLL_PC0_PRESCALE_MASK   0x00C00000
5024 +#define  BCMA_CC_PMU15_PLL_PC0_PRESCALE_SHIFT  22
5025 +#define  BCMA_CC_PMU15_PLL_PC0_KPCTRL_MASK     0x07000000
5026 +#define  BCMA_CC_PMU15_PLL_PC0_KPCTRL_SHIFT    24
5027 +#define  BCMA_CC_PMU15_PLL_PC0_FCNTCTRL_MASK   0x38000000
5028 +#define  BCMA_CC_PMU15_PLL_PC0_FCNTCTRL_SHIFT  27
5029 +#define  BCMA_CC_PMU15_PLL_PC0_FDCMODE_MASK    0x40000000
5030 +#define  BCMA_CC_PMU15_PLL_PC0_FDCMODE_SHIFT   30
5031 +#define  BCMA_CC_PMU15_PLL_PC0_CTRLBIAS_MASK   0x80000000
5032 +#define  BCMA_CC_PMU15_PLL_PC0_CTRLBIAS_SHIFT  31
5033  
5034  /* ALP clock on pre-PMU chips */
5035  #define BCMA_CC_PMU_ALP_CLOCK          20000000
5036 @@ -284,6 +486,19 @@
5037  #define BCMA_CC_PPL_PCHI_OFF           5
5038  #define BCMA_CC_PPL_PCHI_MASK          0x0000003f
5039  
5040 +#define BCMA_CC_PMU_PLL_CTL0           0
5041 +#define BCMA_CC_PMU_PLL_CTL1           1
5042 +#define BCMA_CC_PMU_PLL_CTL2           2
5043 +#define BCMA_CC_PMU_PLL_CTL3           3
5044 +#define BCMA_CC_PMU_PLL_CTL4           4
5045 +#define BCMA_CC_PMU_PLL_CTL5           5
5046 +
5047 +#define BCMA_CC_PMU1_PLL0_PC0_P1DIV_MASK       0x00f00000
5048 +#define BCMA_CC_PMU1_PLL0_PC0_P1DIV_SHIFT      20
5049 +
5050 +#define BCMA_CC_PMU1_PLL0_PC2_NDIV_INT_MASK    0x1ff00000
5051 +#define BCMA_CC_PMU1_PLL0_PC2_NDIV_INT_SHIFT   20
5052 +
5053  /* BCM4331 ChipControl numbers. */
5054  #define BCMA_CHIPCTL_4331_BT_COEXIST           BIT(0)  /* 0 disable */
5055  #define BCMA_CHIPCTL_4331_SECI                 BIT(1)  /* 0 SECI is disabled (JATG functional) */
5056 @@ -297,9 +512,56 @@
5057  #define BCMA_CHIPCTL_4331_OVR_PIPEAUXPWRDOWN   BIT(9)  /* override core control on pipe_AuxPowerDown */
5058  #define BCMA_CHIPCTL_4331_PCIE_AUXCLKEN                BIT(10) /* pcie_auxclkenable */
5059  #define BCMA_CHIPCTL_4331_PCIE_PIPE_PLLDOWN    BIT(11) /* pcie_pipe_pllpowerdown */
5060 +#define BCMA_CHIPCTL_4331_EXTPA_EN2            BIT(12) /* 0 ext pa disable, 1 ext pa enabled */
5061  #define BCMA_CHIPCTL_4331_BT_SHD0_ON_GPIO4     BIT(16) /* enable bt_shd0 at gpio4 */
5062  #define BCMA_CHIPCTL_4331_BT_SHD1_ON_GPIO5     BIT(17) /* enable bt_shd1 at gpio5 */
5063  
5064 +/* 43224 chip-specific ChipControl register bits */
5065 +#define BCMA_CCTRL_43224_GPIO_TOGGLE           0x8000          /* gpio[3:0] pins as btcoex or s/w gpio */
5066 +#define BCMA_CCTRL_43224A0_12MA_LED_DRIVE      0x00F000F0      /* 12 mA drive strength */
5067 +#define BCMA_CCTRL_43224B0_12MA_LED_DRIVE      0xF0            /* 12 mA drive strength for later 43224s */
5068 +
5069 +/* 4313 Chip specific ChipControl register bits */
5070 +#define BCMA_CCTRL_4313_12MA_LED_DRIVE         0x00000007      /* 12 mA drive strengh for later 4313 */
5071 +
5072 +/* BCM5357 ChipControl register bits */
5073 +#define BCMA_CHIPCTL_5357_EXTPA                        BIT(14)
5074 +#define BCMA_CHIPCTL_5357_ANT_MUX_2O3          BIT(15)
5075 +#define BCMA_CHIPCTL_5357_NFLASH               BIT(16)
5076 +#define BCMA_CHIPCTL_5357_I2S_PINS_ENABLE      BIT(18)
5077 +#define BCMA_CHIPCTL_5357_I2CSPI_PINS_ENABLE   BIT(19)
5078 +
5079 +#define BCMA_RES_4314_LPLDO_PU                 BIT(0)
5080 +#define BCMA_RES_4314_PMU_SLEEP_DIS            BIT(1)
5081 +#define BCMA_RES_4314_PMU_BG_PU                        BIT(2)
5082 +#define BCMA_RES_4314_CBUCK_LPOM_PU            BIT(3)
5083 +#define BCMA_RES_4314_CBUCK_PFM_PU             BIT(4)
5084 +#define BCMA_RES_4314_CLDO_PU                  BIT(5)
5085 +#define BCMA_RES_4314_LPLDO2_LVM               BIT(6)
5086 +#define BCMA_RES_4314_WL_PMU_PU                        BIT(7)
5087 +#define BCMA_RES_4314_LNLDO_PU                 BIT(8)
5088 +#define BCMA_RES_4314_LDO3P3_PU                        BIT(9)
5089 +#define BCMA_RES_4314_OTP_PU                   BIT(10)
5090 +#define BCMA_RES_4314_XTAL_PU                  BIT(11)
5091 +#define BCMA_RES_4314_WL_PWRSW_PU              BIT(12)
5092 +#define BCMA_RES_4314_LQ_AVAIL                 BIT(13)
5093 +#define BCMA_RES_4314_LOGIC_RET                        BIT(14)
5094 +#define BCMA_RES_4314_MEM_SLEEP                        BIT(15)
5095 +#define BCMA_RES_4314_MACPHY_RET               BIT(16)
5096 +#define BCMA_RES_4314_WL_CORE_READY            BIT(17)
5097 +#define BCMA_RES_4314_ILP_REQ                  BIT(18)
5098 +#define BCMA_RES_4314_ALP_AVAIL                        BIT(19)
5099 +#define BCMA_RES_4314_MISC_PWRSW_PU            BIT(20)
5100 +#define BCMA_RES_4314_SYNTH_PWRSW_PU           BIT(21)
5101 +#define BCMA_RES_4314_RX_PWRSW_PU              BIT(22)
5102 +#define BCMA_RES_4314_RADIO_PU                 BIT(23)
5103 +#define BCMA_RES_4314_VCO_LDO_PU               BIT(24)
5104 +#define BCMA_RES_4314_AFE_LDO_PU               BIT(25)
5105 +#define BCMA_RES_4314_RX_LDO_PU                        BIT(26)
5106 +#define BCMA_RES_4314_TX_LDO_PU                        BIT(27)
5107 +#define BCMA_RES_4314_HT_AVAIL                 BIT(28)
5108 +#define BCMA_RES_4314_MACPHY_CLK_AVAIL         BIT(29)
5109 +
5110  /* Data for the PMU, if available.
5111   * Check availability with ((struct bcma_chipcommon)->capabilities & BCMA_CC_CAP_PMU)
5112   */
5113 @@ -310,11 +572,36 @@ struct bcma_chipcommon_pmu {
5114  
5115  #ifdef CONFIG_BCMA_DRIVER_MIPS
5116  struct bcma_pflash {
5117 +       bool present;
5118         u8 buswidth;
5119         u32 window;
5120         u32 window_size;
5121  };
5122  
5123 +#ifdef CONFIG_BCMA_SFLASH
5124 +struct bcma_sflash {
5125 +       bool present;
5126 +       u32 window;
5127 +       u32 blocksize;
5128 +       u16 numblocks;
5129 +       u32 size;
5130 +
5131 +       struct mtd_info *mtd;
5132 +       void *priv;
5133 +};
5134 +#endif
5135 +
5136 +#ifdef CONFIG_BCMA_NFLASH
5137 +struct mtd_info;
5138 +
5139 +struct bcma_nflash {
5140 +       bool present;
5141 +       bool boot;              /* This is the flash the SoC boots from */
5142 +
5143 +       struct mtd_info *mtd;
5144 +};
5145 +#endif
5146 +
5147  struct bcma_serial_port {
5148         void *regs;
5149         unsigned long clockspeed;
5150 @@ -330,15 +617,30 @@ struct bcma_drv_cc {
5151         u32 capabilities;
5152         u32 capabilities_ext;
5153         u8 setup_done:1;
5154 +       u8 early_setup_done:1;
5155         /* Fast Powerup Delay constant */
5156         u16 fast_pwrup_delay;
5157         struct bcma_chipcommon_pmu pmu;
5158  #ifdef CONFIG_BCMA_DRIVER_MIPS
5159         struct bcma_pflash pflash;
5160 +#ifdef CONFIG_BCMA_SFLASH
5161 +       struct bcma_sflash sflash;
5162 +#endif
5163 +#ifdef CONFIG_BCMA_NFLASH
5164 +       struct bcma_nflash nflash;
5165 +#endif
5166  
5167         int nr_serial_ports;
5168         struct bcma_serial_port serial_ports[4];
5169  #endif /* CONFIG_BCMA_DRIVER_MIPS */
5170 +       u32 ticks_per_ms;
5171 +       struct platform_device *watchdog;
5172 +
5173 +       /* Lock for GPIO register access. */
5174 +       spinlock_t gpio_lock;
5175 +#ifdef CONFIG_BCMA_DRIVER_GPIO
5176 +       struct gpio_chip gpio;
5177 +#endif
5178  };
5179  
5180  /* Register access */
5181 @@ -355,14 +657,16 @@ struct bcma_drv_cc {
5182         bcma_cc_write32(cc, offset, (bcma_cc_read32(cc, offset) & (mask)) | (set))
5183  
5184  extern void bcma_core_chipcommon_init(struct bcma_drv_cc *cc);
5185 +extern void bcma_core_chipcommon_early_init(struct bcma_drv_cc *cc);
5186  
5187  extern void bcma_chipco_suspend(struct bcma_drv_cc *cc);
5188  extern void bcma_chipco_resume(struct bcma_drv_cc *cc);
5189  
5190  void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable);
5191  
5192 -extern void bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc,
5193 -                                         u32 ticks);
5194 +extern u32 bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc, u32 ticks);
5195 +
5196 +extern u32 bcma_chipco_get_alp_clock(struct bcma_drv_cc *cc);
5197  
5198  void bcma_chipco_irq_mask(struct bcma_drv_cc *cc, u32 mask, u32 value);
5199  
5200 @@ -375,9 +679,12 @@ u32 bcma_chipco_gpio_outen(struct bcma_d
5201  u32 bcma_chipco_gpio_control(struct bcma_drv_cc *cc, u32 mask, u32 value);
5202  u32 bcma_chipco_gpio_intmask(struct bcma_drv_cc *cc, u32 mask, u32 value);
5203  u32 bcma_chipco_gpio_polarity(struct bcma_drv_cc *cc, u32 mask, u32 value);
5204 +u32 bcma_chipco_gpio_pullup(struct bcma_drv_cc *cc, u32 mask, u32 value);
5205 +u32 bcma_chipco_gpio_pulldown(struct bcma_drv_cc *cc, u32 mask, u32 value);
5206  
5207  /* PMU support */
5208  extern void bcma_pmu_init(struct bcma_drv_cc *cc);
5209 +extern void bcma_pmu_early_init(struct bcma_drv_cc *cc);
5210  
5211  extern void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset,
5212                                   u32 value);
5213 @@ -387,5 +694,8 @@ extern void bcma_chipco_chipctl_maskset(
5214                                         u32 offset, u32 mask, u32 set);
5215  extern void bcma_chipco_regctl_maskset(struct bcma_drv_cc *cc,
5216                                        u32 offset, u32 mask, u32 set);
5217 +extern void bcma_pmu_spuravoid_pllupdate(struct bcma_drv_cc *cc, int spuravoid);
5218 +
5219 +extern u32 bcma_pmu_get_bus_clock(struct bcma_drv_cc *cc);
5220  
5221  #endif /* LINUX_BCMA_DRIVER_CC_H_ */
5222 --- /dev/null
5223 +++ b/include/linux/bcma/bcma_driver_gmac_cmn.h
5224 @@ -0,0 +1,100 @@
5225 +#ifndef LINUX_BCMA_DRIVER_GMAC_CMN_H_
5226 +#define LINUX_BCMA_DRIVER_GMAC_CMN_H_
5227 +
5228 +#include <linux/types.h>
5229 +
5230 +#define BCMA_GMAC_CMN_STAG0            0x000
5231 +#define BCMA_GMAC_CMN_STAG1            0x004
5232 +#define BCMA_GMAC_CMN_STAG2            0x008
5233 +#define BCMA_GMAC_CMN_STAG3            0x00C
5234 +#define BCMA_GMAC_CMN_PARSER_CTL       0x020
5235 +#define BCMA_GMAC_CMN_MIB_MAX_LEN      0x024
5236 +#define BCMA_GMAC_CMN_PHY_ACCESS       0x100
5237 +#define  BCMA_GMAC_CMN_PA_DATA_MASK    0x0000ffff
5238 +#define  BCMA_GMAC_CMN_PA_ADDR_MASK    0x001f0000
5239 +#define  BCMA_GMAC_CMN_PA_ADDR_SHIFT   16
5240 +#define  BCMA_GMAC_CMN_PA_REG_MASK     0x1f000000
5241 +#define  BCMA_GMAC_CMN_PA_REG_SHIFT    24
5242 +#define  BCMA_GMAC_CMN_PA_WRITE                0x20000000
5243 +#define  BCMA_GMAC_CMN_PA_START                0x40000000
5244 +#define BCMA_GMAC_CMN_PHY_CTL          0x104
5245 +#define  BCMA_GMAC_CMN_PC_EPA_MASK     0x0000001f
5246 +#define  BCMA_GMAC_CMN_PC_MCT_MASK     0x007f0000
5247 +#define  BCMA_GMAC_CMN_PC_MCT_SHIFT    16
5248 +#define  BCMA_GMAC_CMN_PC_MTE          0x00800000
5249 +#define BCMA_GMAC_CMN_GMAC0_RGMII_CTL  0x110
5250 +#define BCMA_GMAC_CMN_CFP_ACCESS       0x200
5251 +#define BCMA_GMAC_CMN_CFP_TCAM_DATA0   0x210
5252 +#define BCMA_GMAC_CMN_CFP_TCAM_DATA1   0x214
5253 +#define BCMA_GMAC_CMN_CFP_TCAM_DATA2   0x218
5254 +#define BCMA_GMAC_CMN_CFP_TCAM_DATA3   0x21C
5255 +#define BCMA_GMAC_CMN_CFP_TCAM_DATA4   0x220
5256 +#define BCMA_GMAC_CMN_CFP_TCAM_DATA5   0x224
5257 +#define BCMA_GMAC_CMN_CFP_TCAM_DATA6   0x228
5258 +#define BCMA_GMAC_CMN_CFP_TCAM_DATA7   0x22C
5259 +#define BCMA_GMAC_CMN_CFP_TCAM_MASK0   0x230
5260 +#define BCMA_GMAC_CMN_CFP_TCAM_MASK1   0x234
5261 +#define BCMA_GMAC_CMN_CFP_TCAM_MASK2   0x238
5262 +#define BCMA_GMAC_CMN_CFP_TCAM_MASK3   0x23C
5263 +#define BCMA_GMAC_CMN_CFP_TCAM_MASK4   0x240
5264 +#define BCMA_GMAC_CMN_CFP_TCAM_MASK5   0x244
5265 +#define BCMA_GMAC_CMN_CFP_TCAM_MASK6   0x248
5266 +#define BCMA_GMAC_CMN_CFP_TCAM_MASK7   0x24C
5267 +#define BCMA_GMAC_CMN_CFP_ACTION_DATA  0x250
5268 +#define BCMA_GMAC_CMN_TCAM_BIST_CTL    0x2A0
5269 +#define BCMA_GMAC_CMN_TCAM_BIST_STATUS 0x2A4
5270 +#define BCMA_GMAC_CMN_TCAM_CMP_STATUS  0x2A8
5271 +#define BCMA_GMAC_CMN_TCAM_DISABLE     0x2AC
5272 +#define BCMA_GMAC_CMN_TCAM_TEST_CTL    0x2F0
5273 +#define BCMA_GMAC_CMN_UDF_0_A3_A0      0x300
5274 +#define BCMA_GMAC_CMN_UDF_0_A7_A4      0x304
5275 +#define BCMA_GMAC_CMN_UDF_0_A8         0x308
5276 +#define BCMA_GMAC_CMN_UDF_1_A3_A0      0x310
5277 +#define BCMA_GMAC_CMN_UDF_1_A7_A4      0x314
5278 +#define BCMA_GMAC_CMN_UDF_1_A8         0x318
5279 +#define BCMA_GMAC_CMN_UDF_2_A3_A0      0x320
5280 +#define BCMA_GMAC_CMN_UDF_2_A7_A4      0x324
5281 +#define BCMA_GMAC_CMN_UDF_2_A8         0x328
5282 +#define BCMA_GMAC_CMN_UDF_0_B3_B0      0x330
5283 +#define BCMA_GMAC_CMN_UDF_0_B7_B4      0x334
5284 +#define BCMA_GMAC_CMN_UDF_0_B8         0x338
5285 +#define BCMA_GMAC_CMN_UDF_1_B3_B0      0x340
5286 +#define BCMA_GMAC_CMN_UDF_1_B7_B4      0x344
5287 +#define BCMA_GMAC_CMN_UDF_1_B8         0x348
5288 +#define BCMA_GMAC_CMN_UDF_2_B3_B0      0x350
5289 +#define BCMA_GMAC_CMN_UDF_2_B7_B4      0x354
5290 +#define BCMA_GMAC_CMN_UDF_2_B8         0x358
5291 +#define BCMA_GMAC_CMN_UDF_0_C3_C0      0x360
5292 +#define BCMA_GMAC_CMN_UDF_0_C7_C4      0x364
5293 +#define BCMA_GMAC_CMN_UDF_0_C8         0x368
5294 +#define BCMA_GMAC_CMN_UDF_1_C3_C0      0x370
5295 +#define BCMA_GMAC_CMN_UDF_1_C7_C4      0x374
5296 +#define BCMA_GMAC_CMN_UDF_1_C8         0x378
5297 +#define BCMA_GMAC_CMN_UDF_2_C3_C0      0x380
5298 +#define BCMA_GMAC_CMN_UDF_2_C7_C4      0x384
5299 +#define BCMA_GMAC_CMN_UDF_2_C8         0x388
5300 +#define BCMA_GMAC_CMN_UDF_0_D3_D0      0x390
5301 +#define BCMA_GMAC_CMN_UDF_0_D7_D4      0x394
5302 +#define BCMA_GMAC_CMN_UDF_0_D11_D8     0x394
5303 +
5304 +struct bcma_drv_gmac_cmn {
5305 +       struct bcma_device *core;
5306 +
5307 +       /* Drivers accessing BCMA_GMAC_CMN_PHY_ACCESS and
5308 +        * BCMA_GMAC_CMN_PHY_CTL need to take that mutex first. */
5309 +       struct mutex phy_mutex;
5310 +};
5311 +
5312 +/* Register access */
5313 +#define gmac_cmn_read16(gc, offset)            bcma_read16((gc)->core, offset)
5314 +#define gmac_cmn_read32(gc, offset)            bcma_read32((gc)->core, offset)
5315 +#define gmac_cmn_write16(gc, offset, val)      bcma_write16((gc)->core, offset, val)
5316 +#define gmac_cmn_write32(gc, offset, val)      bcma_write32((gc)->core, offset, val)
5317 +
5318 +#ifdef CONFIG_BCMA_DRIVER_GMAC_CMN
5319 +extern void __devinit bcma_core_gmac_cmn_init(struct bcma_drv_gmac_cmn *gc);
5320 +#else
5321 +static inline void bcma_core_gmac_cmn_init(struct bcma_drv_gmac_cmn *gc) { }
5322 +#endif
5323 +
5324 +#endif /* LINUX_BCMA_DRIVER_GMAC_CMN_H_ */
5325 --- a/include/linux/bcma/bcma_driver_mips.h
5326 +++ b/include/linux/bcma/bcma_driver_mips.h
5327 @@ -28,6 +28,7 @@
5328  #define BCMA_MIPS_MIPS74K_GPIOEN       0x0048
5329  #define BCMA_MIPS_MIPS74K_CLKCTLST     0x01E0
5330  
5331 +#define BCMA_MIPS_OOBSELINA74          0x004
5332  #define BCMA_MIPS_OOBSELOUTA30         0x100
5333  
5334  struct bcma_device;
5335 @@ -35,17 +36,24 @@ struct bcma_device;
5336  struct bcma_drv_mips {
5337         struct bcma_device *core;
5338         u8 setup_done:1;
5339 -       unsigned int assigned_irqs;
5340 +       u8 early_setup_done:1;
5341  };
5342  
5343  #ifdef CONFIG_BCMA_DRIVER_MIPS
5344  extern void bcma_core_mips_init(struct bcma_drv_mips *mcore);
5345 +extern void bcma_core_mips_early_init(struct bcma_drv_mips *mcore);
5346 +
5347 +extern unsigned int bcma_core_irq(struct bcma_device *core);
5348  #else
5349  static inline void bcma_core_mips_init(struct bcma_drv_mips *mcore) { }
5350 +static inline void bcma_core_mips_early_init(struct bcma_drv_mips *mcore) { }
5351 +
5352 +static inline unsigned int bcma_core_irq(struct bcma_device *core)
5353 +{
5354 +       return 0;
5355 +}
5356  #endif
5357  
5358  extern u32 bcma_cpu_clock(struct bcma_drv_mips *mcore);
5359  
5360 -extern unsigned int bcma_core_mips_irq(struct bcma_device *dev);
5361 -
5362  #endif /* LINUX_BCMA_DRIVER_MIPS_H_ */
5363 --- a/include/linux/bcma/bcma_driver_pci.h
5364 +++ b/include/linux/bcma/bcma_driver_pci.h
5365 @@ -53,11 +53,47 @@ struct pci_dev;
5366  #define  BCMA_CORE_PCI_SBTOPCI1_MASK           0xFC000000
5367  #define BCMA_CORE_PCI_SBTOPCI2                 0x0108  /* Backplane to PCI translation 2 (sbtopci2) */
5368  #define  BCMA_CORE_PCI_SBTOPCI2_MASK           0xC0000000
5369 +#define BCMA_CORE_PCI_CONFIG_ADDR              0x0120  /* pcie config space access */
5370 +#define BCMA_CORE_PCI_CONFIG_DATA              0x0124  /* pcie config space access */
5371 +#define BCMA_CORE_PCI_MDIO_CONTROL             0x0128  /* controls the mdio access */
5372 +#define  BCMA_CORE_PCI_MDIOCTL_DIVISOR_MASK    0x7f    /* clock to be used on MDIO */
5373 +#define  BCMA_CORE_PCI_MDIOCTL_DIVISOR_VAL     0x2
5374 +#define  BCMA_CORE_PCI_MDIOCTL_PREAM_EN                0x80    /* Enable preamble sequnce */
5375 +#define  BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE     0x100   /* Tranaction complete */
5376 +#define BCMA_CORE_PCI_MDIO_DATA                        0x012c  /* Data to the mdio access */
5377 +#define  BCMA_CORE_PCI_MDIODATA_MASK           0x0000ffff /* data 2 bytes */
5378 +#define  BCMA_CORE_PCI_MDIODATA_TA             0x00020000 /* Turnaround */
5379 +#define  BCMA_CORE_PCI_MDIODATA_REGADDR_SHF_OLD        18      /* Regaddr shift (rev < 10) */
5380 +#define  BCMA_CORE_PCI_MDIODATA_REGADDR_MASK_OLD       0x003c0000 /* Regaddr Mask (rev < 10) */
5381 +#define  BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF_OLD        22      /* Physmedia devaddr shift (rev < 10) */
5382 +#define  BCMA_CORE_PCI_MDIODATA_DEVADDR_MASK_OLD       0x0fc00000 /* Physmedia devaddr Mask (rev < 10) */
5383 +#define  BCMA_CORE_PCI_MDIODATA_REGADDR_SHF    18      /* Regaddr shift */
5384 +#define  BCMA_CORE_PCI_MDIODATA_REGADDR_MASK   0x007c0000 /* Regaddr Mask */
5385 +#define  BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF    23      /* Physmedia devaddr shift */
5386 +#define  BCMA_CORE_PCI_MDIODATA_DEVADDR_MASK   0x0f800000 /* Physmedia devaddr Mask */
5387 +#define  BCMA_CORE_PCI_MDIODATA_WRITE          0x10000000 /* write Transaction */
5388 +#define  BCMA_CORE_PCI_MDIODATA_READ           0x20000000 /* Read Transaction */
5389 +#define  BCMA_CORE_PCI_MDIODATA_START          0x40000000 /* start of Transaction */
5390 +#define  BCMA_CORE_PCI_MDIODATA_DEV_ADDR       0x0     /* dev address for serdes */
5391 +#define  BCMA_CORE_PCI_MDIODATA_BLK_ADDR       0x1F    /* blk address for serdes */
5392 +#define  BCMA_CORE_PCI_MDIODATA_DEV_PLL                0x1d    /* SERDES PLL Dev */
5393 +#define  BCMA_CORE_PCI_MDIODATA_DEV_TX         0x1e    /* SERDES TX Dev */
5394 +#define  BCMA_CORE_PCI_MDIODATA_DEV_RX         0x1f    /* SERDES RX Dev */
5395 +#define BCMA_CORE_PCI_PCIEIND_ADDR             0x0130  /* indirect access to the internal register */
5396 +#define BCMA_CORE_PCI_PCIEIND_DATA             0x0134  /* Data to/from the internal regsiter */
5397 +#define BCMA_CORE_PCI_CLKREQENCTRL             0x0138  /*  >= rev 6, Clkreq rdma control */
5398  #define BCMA_CORE_PCI_PCICFG0                  0x0400  /* PCI config space 0 (rev >= 8) */
5399  #define BCMA_CORE_PCI_PCICFG1                  0x0500  /* PCI config space 1 (rev >= 8) */
5400  #define BCMA_CORE_PCI_PCICFG2                  0x0600  /* PCI config space 2 (rev >= 8) */
5401  #define BCMA_CORE_PCI_PCICFG3                  0x0700  /* PCI config space 3 (rev >= 8) */
5402  #define BCMA_CORE_PCI_SPROM(wordoffset)                (0x0800 + ((wordoffset) * 2)) /* SPROM shadow area (72 bytes) */
5403 +#define  BCMA_CORE_PCI_SPROM_PI_OFFSET         0       /* first word */
5404 +#define   BCMA_CORE_PCI_SPROM_PI_MASK          0xf000  /* bit 15:12 */
5405 +#define   BCMA_CORE_PCI_SPROM_PI_SHIFT         12      /* bit 15:12 */
5406 +#define  BCMA_CORE_PCI_SPROM_MISC_CONFIG       5       /* word 5 */
5407 +#define   BCMA_CORE_PCI_SPROM_L23READY_EXIT_NOPERST    0x8000  /* bit 15 */
5408 +#define   BCMA_CORE_PCI_SPROM_CLKREQ_OFFSET_REV5       20      /* word 20 for srom rev <= 5 */
5409 +#define   BCMA_CORE_PCI_SPROM_CLKREQ_ENB       0x0800  /* bit 11 */
5410  
5411  /* SBtoPCIx */
5412  #define BCMA_CORE_PCI_SBTOPCI_MEM              0x00000000
5413 @@ -72,20 +108,120 @@ struct pci_dev;
5414  #define  BCMA_CORE_PCI_SBTOPCI_RC_READL                0x00000010 /* Memory read line */
5415  #define  BCMA_CORE_PCI_SBTOPCI_RC_READM                0x00000020 /* Memory read multiple */
5416  
5417 +/* PCIE protocol PHY diagnostic registers */
5418 +#define BCMA_CORE_PCI_PLP_MODEREG              0x200   /* Mode */
5419 +#define BCMA_CORE_PCI_PLP_STATUSREG            0x204   /* Status */
5420 +#define  BCMA_CORE_PCI_PLP_POLARITYINV_STAT    0x10    /* Status reg PCIE_PLP_STATUSREG */
5421 +#define BCMA_CORE_PCI_PLP_LTSSMCTRLREG         0x208   /* LTSSM control */
5422 +#define BCMA_CORE_PCI_PLP_LTLINKNUMREG         0x20c   /* Link Training Link number */
5423 +#define BCMA_CORE_PCI_PLP_LTLANENUMREG         0x210   /* Link Training Lane number */
5424 +#define BCMA_CORE_PCI_PLP_LTNFTSREG            0x214   /* Link Training N_FTS */
5425 +#define BCMA_CORE_PCI_PLP_ATTNREG              0x218   /* Attention */
5426 +#define BCMA_CORE_PCI_PLP_ATTNMASKREG          0x21C   /* Attention Mask */
5427 +#define BCMA_CORE_PCI_PLP_RXERRCTR             0x220   /* Rx Error */
5428 +#define BCMA_CORE_PCI_PLP_RXFRMERRCTR          0x224   /* Rx Framing Error */
5429 +#define BCMA_CORE_PCI_PLP_RXERRTHRESHREG       0x228   /* Rx Error threshold */
5430 +#define BCMA_CORE_PCI_PLP_TESTCTRLREG          0x22C   /* Test Control reg */
5431 +#define BCMA_CORE_PCI_PLP_SERDESCTRLOVRDREG    0x230   /* SERDES Control Override */
5432 +#define BCMA_CORE_PCI_PLP_TIMINGOVRDREG                0x234   /* Timing param override */
5433 +#define BCMA_CORE_PCI_PLP_RXTXSMDIAGREG                0x238   /* RXTX State Machine Diag */
5434 +#define BCMA_CORE_PCI_PLP_LTSSMDIAGREG         0x23C   /* LTSSM State Machine Diag */
5435 +
5436 +/* PCIE protocol DLLP diagnostic registers */
5437 +#define BCMA_CORE_PCI_DLLP_LCREG               0x100   /* Link Control */
5438 +#define BCMA_CORE_PCI_DLLP_LSREG               0x104   /* Link Status */
5439 +#define BCMA_CORE_PCI_DLLP_LAREG               0x108   /* Link Attention */
5440 +#define  BCMA_CORE_PCI_DLLP_LSREG_LINKUP       (1 << 16)
5441 +#define BCMA_CORE_PCI_DLLP_LAMASKREG           0x10C   /* Link Attention Mask */
5442 +#define BCMA_CORE_PCI_DLLP_NEXTTXSEQNUMREG     0x110   /* Next Tx Seq Num */
5443 +#define BCMA_CORE_PCI_DLLP_ACKEDTXSEQNUMREG    0x114   /* Acked Tx Seq Num */
5444 +#define BCMA_CORE_PCI_DLLP_PURGEDTXSEQNUMREG   0x118   /* Purged Tx Seq Num */
5445 +#define BCMA_CORE_PCI_DLLP_RXSEQNUMREG         0x11C   /* Rx Sequence Number */
5446 +#define BCMA_CORE_PCI_DLLP_LRREG               0x120   /* Link Replay */
5447 +#define BCMA_CORE_PCI_DLLP_LACKTOREG           0x124   /* Link Ack Timeout */
5448 +#define BCMA_CORE_PCI_DLLP_PMTHRESHREG         0x128   /* Power Management Threshold */
5449 +#define  BCMA_CORE_PCI_ASPMTIMER_EXTEND                0x01000000 /* > rev7: enable extend ASPM timer */
5450 +#define BCMA_CORE_PCI_DLLP_RTRYWPREG           0x12C   /* Retry buffer write ptr */
5451 +#define BCMA_CORE_PCI_DLLP_RTRYRPREG           0x130   /* Retry buffer Read ptr */
5452 +#define BCMA_CORE_PCI_DLLP_RTRYPPREG           0x134   /* Retry buffer Purged ptr */
5453 +#define BCMA_CORE_PCI_DLLP_RTRRWREG            0x138   /* Retry buffer Read/Write */
5454 +#define BCMA_CORE_PCI_DLLP_ECTHRESHREG         0x13C   /* Error Count Threshold */
5455 +#define BCMA_CORE_PCI_DLLP_TLPERRCTRREG                0x140   /* TLP Error Counter */
5456 +#define BCMA_CORE_PCI_DLLP_ERRCTRREG           0x144   /* Error Counter */
5457 +#define BCMA_CORE_PCI_DLLP_NAKRXCTRREG         0x148   /* NAK Received Counter */
5458 +#define BCMA_CORE_PCI_DLLP_TESTREG             0x14C   /* Test */
5459 +#define BCMA_CORE_PCI_DLLP_PKTBIST             0x150   /* Packet BIST */
5460 +#define BCMA_CORE_PCI_DLLP_PCIE11              0x154   /* DLLP PCIE 1.1 reg */
5461 +
5462 +/* SERDES RX registers */
5463 +#define BCMA_CORE_PCI_SERDES_RX_CTRL           1       /* Rx cntrl */
5464 +#define  BCMA_CORE_PCI_SERDES_RX_CTRL_FORCE    0x80    /* rxpolarity_force */
5465 +#define  BCMA_CORE_PCI_SERDES_RX_CTRL_POLARITY 0x40    /* rxpolarity_value */
5466 +#define BCMA_CORE_PCI_SERDES_RX_TIMER1         2       /* Rx Timer1 */
5467 +#define BCMA_CORE_PCI_SERDES_RX_CDR            6       /* CDR */
5468 +#define BCMA_CORE_PCI_SERDES_RX_CDRBW          7       /* CDR BW */
5469 +
5470 +/* SERDES PLL registers */
5471 +#define BCMA_CORE_PCI_SERDES_PLL_CTRL          1       /* PLL control reg */
5472 +#define BCMA_CORE_PCI_PLL_CTRL_FREQDET_EN      0x4000  /* bit 14 is FREQDET on */
5473 +
5474  /* PCIcore specific boardflags */
5475  #define BCMA_CORE_PCI_BFL_NOPCI                        0x00000400 /* Board leaves PCI floating */
5476  
5477 +/* PCIE Config space accessing MACROS */
5478 +#define BCMA_CORE_PCI_CFG_BUS_SHIFT            24      /* Bus shift */
5479 +#define BCMA_CORE_PCI_CFG_SLOT_SHIFT           19      /* Slot/Device shift */
5480 +#define BCMA_CORE_PCI_CFG_FUN_SHIFT            16      /* Function shift */
5481 +#define BCMA_CORE_PCI_CFG_OFF_SHIFT            0       /* Register shift */
5482 +
5483 +#define BCMA_CORE_PCI_CFG_BUS_MASK             0xff    /* Bus mask */
5484 +#define BCMA_CORE_PCI_CFG_SLOT_MASK            0x1f    /* Slot/Device mask */
5485 +#define BCMA_CORE_PCI_CFG_FUN_MASK             7       /* Function mask */
5486 +#define BCMA_CORE_PCI_CFG_OFF_MASK             0xfff   /* Register mask */
5487 +
5488 +#define BCMA_CORE_PCI_CFG_DEVCTRL              0xd8
5489 +
5490 +/* PCIE Root Capability Register bits (Host mode only) */
5491 +#define BCMA_CORE_PCI_RC_CRS_VISIBILITY                0x0001
5492 +
5493 +struct bcma_drv_pci;
5494 +
5495 +#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
5496 +struct bcma_drv_pci_host {
5497 +       struct bcma_drv_pci *pdev;
5498 +
5499 +       u32 host_cfg_addr;
5500 +       spinlock_t cfgspace_lock;
5501 +
5502 +       struct pci_controller pci_controller;
5503 +       struct pci_ops pci_ops;
5504 +       struct resource mem_resource;
5505 +       struct resource io_resource;
5506 +};
5507 +#endif
5508 +
5509  struct bcma_drv_pci {
5510         struct bcma_device *core;
5511         u8 setup_done:1;
5512 +       u8 hostmode:1;
5513 +
5514 +#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
5515 +       struct bcma_drv_pci_host *host_controller;
5516 +#endif
5517  };
5518  
5519  /* Register access */
5520 +#define pcicore_read16(pc, offset)             bcma_read16((pc)->core, offset)
5521  #define pcicore_read32(pc, offset)             bcma_read32((pc)->core, offset)
5522 +#define pcicore_write16(pc, offset, val)       bcma_write16((pc)->core, offset, val)
5523  #define pcicore_write32(pc, offset, val)       bcma_write32((pc)->core, offset, val)
5524  
5525 -extern void bcma_core_pci_init(struct bcma_drv_pci *pc);
5526 +extern void __devinit bcma_core_pci_init(struct bcma_drv_pci *pc);
5527  extern int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc,
5528                                  struct bcma_device *core, bool enable);
5529 +extern void bcma_core_pci_extend_L1timer(struct bcma_drv_pci *pc, bool extend);
5530 +
5531 +extern int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev);
5532 +extern int bcma_core_pci_plat_dev_init(struct pci_dev *dev);
5533  
5534  #endif /* LINUX_BCMA_DRIVER_PCI_H_ */
5535 --- a/include/linux/bcma/bcma_regs.h
5536 +++ b/include/linux/bcma/bcma_regs.h
5537 @@ -11,11 +11,13 @@
5538  #define  BCMA_CLKCTLST_HAVEHTREQ       0x00000010 /* HT available request */
5539  #define  BCMA_CLKCTLST_HWCROFF         0x00000020 /* Force HW clock request off */
5540  #define  BCMA_CLKCTLST_EXTRESREQ       0x00000700 /* Mask of external resource requests */
5541 +#define  BCMA_CLKCTLST_EXTRESREQ_SHIFT 8
5542  #define  BCMA_CLKCTLST_HAVEALP         0x00010000 /* ALP available */
5543  #define  BCMA_CLKCTLST_HAVEHT          0x00020000 /* HT available */
5544  #define  BCMA_CLKCTLST_BP_ON_ALP       0x00040000 /* RO: running on ALP clock */
5545  #define  BCMA_CLKCTLST_BP_ON_HT                0x00080000 /* RO: running on HT clock */
5546  #define  BCMA_CLKCTLST_EXTRESST                0x07000000 /* Mask of external resource status */
5547 +#define  BCMA_CLKCTLST_EXTRESST_SHIFT  24
5548  /* Is there any BCM4328 on BCMA bus? */
5549  #define  BCMA_CLKCTLST_4328A0_HAVEHT   0x00010000 /* 4328a0 has reversed bits */
5550  #define  BCMA_CLKCTLST_4328A0_HAVEALP  0x00020000 /* 4328a0 has reversed bits */
5551 @@ -35,6 +37,7 @@
5552  #define  BCMA_IOST_BIST_DONE           0x8000
5553  #define BCMA_RESET_CTL                 0x0800
5554  #define  BCMA_RESET_CTL_RESET          0x0001
5555 +#define BCMA_RESET_ST                  0x0804
5556  
5557  /* BCMA PCI config space registers. */
5558  #define BCMA_PCI_PMCSR                 0x44
5559 @@ -56,4 +59,36 @@
5560  #define  BCMA_PCI_GPIO_XTAL            0x40    /* PCI config space GPIO 14 for Xtal powerup */
5561  #define  BCMA_PCI_GPIO_PLL             0x80    /* PCI config space GPIO 15 for PLL powerdown */
5562  
5563 +/* SiliconBackplane Address Map.
5564 + * All regions may not exist on all chips.
5565 + */
5566 +#define BCMA_SOC_SDRAM_BASE            0x00000000U     /* Physical SDRAM */
5567 +#define BCMA_SOC_PCI_MEM               0x08000000U     /* Host Mode sb2pcitranslation0 (64 MB) */
5568 +#define BCMA_SOC_PCI_MEM_SZ            (64 * 1024 * 1024)
5569 +#define BCMA_SOC_PCI_CFG               0x0c000000U     /* Host Mode sb2pcitranslation1 (64 MB) */
5570 +#define BCMA_SOC_SDRAM_SWAPPED         0x10000000U     /* Byteswapped Physical SDRAM */
5571 +#define BCMA_SOC_SDRAM_R2              0x80000000U     /* Region 2 for sdram (512 MB) */
5572 +
5573 +
5574 +#define BCMA_SOC_PCI_DMA               0x40000000U     /* Client Mode sb2pcitranslation2 (1 GB) */
5575 +#define BCMA_SOC_PCI_DMA2              0x80000000U     /* Client Mode sb2pcitranslation2 (1 GB) */
5576 +#define BCMA_SOC_PCI_DMA_SZ            0x40000000U     /* Client Mode sb2pcitranslation2 size in bytes */
5577 +#define BCMA_SOC_PCIE_DMA_L32          0x00000000U     /* PCIE Client Mode sb2pcitranslation2
5578 +                                                        * (2 ZettaBytes), low 32 bits
5579 +                                                        */
5580 +#define BCMA_SOC_PCIE_DMA_H32          0x80000000U     /* PCIE Client Mode sb2pcitranslation2
5581 +                                                        * (2 ZettaBytes), high 32 bits
5582 +                                                        */
5583 +
5584 +#define BCMA_SOC_PCI1_MEM              0x40000000U     /* Host Mode sb2pcitranslation0 (64 MB) */
5585 +#define BCMA_SOC_PCI1_CFG              0x44000000U     /* Host Mode sb2pcitranslation1 (64 MB) */
5586 +#define BCMA_SOC_PCIE1_DMA_H32         0xc0000000U     /* PCIE Client Mode sb2pcitranslation2
5587 +                                                        * (2 ZettaBytes), high 32 bits
5588 +                                                        */
5589 +
5590 +#define BCMA_SOC_FLASH1                        0x1fc00000      /* MIPS Flash Region 1 */
5591 +#define BCMA_SOC_FLASH1_SZ             0x00400000      /* MIPS Size of Flash Region 1 */
5592 +#define BCMA_SOC_FLASH2                        0x1c000000      /* Flash Region 2 (region 1 shadowed here) */
5593 +#define BCMA_SOC_FLASH2_SZ             0x02000000      /* Size of Flash Region 2 */
5594 +
5595  #endif /* LINUX_BCMA_REGS_H_ */
5596 --- a/drivers/net/wireless/b43/main.c
5597 +++ b/drivers/net/wireless/b43/main.c
5598 @@ -4618,7 +4618,7 @@ static int b43_wireless_core_init(struct
5599         switch (dev->dev->bus_type) {
5600  #ifdef CONFIG_B43_BCMA
5601         case B43_BUS_BCMA:
5602 -               bcma_core_pci_irq_ctl(&dev->dev->bdev->bus->drv_pci,
5603 +               bcma_core_pci_irq_ctl(&dev->dev->bdev->bus->drv_pci[0],
5604                                       dev->dev->bdev, true);
5605                 break;
5606  #endif
5607 --- a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c
5608 +++ b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c
5609 @@ -533,7 +533,7 @@ ai_buscore_setup(struct si_info *sii, st
5610  
5611         /* fixup necessary chip/core configurations */
5612         if (!sii->pch) {
5613 -               sii->pch = pcicore_init(&sii->pub, sii->icbus->drv_pci.core);
5614 +               sii->pch = pcicore_init(&sii->pub, sii->icbus->drv_pci[0].core);
5615                 if (sii->pch == NULL)
5616                         return false;
5617         }