kernel: update bcma to the version from wireless-testing master-2014-09-04 tag
[openwrt.git] / target / linux / generic / patches-3.10 / 025-bcma_backport.patch
1 --- a/drivers/bcma/Kconfig
2 +++ b/drivers/bcma/Kconfig
3 @@ -26,6 +26,7 @@ config BCMA_HOST_PCI_POSSIBLE
4  config BCMA_HOST_PCI
5         bool "Support for BCMA on PCI-host bus"
6         depends on BCMA_HOST_PCI_POSSIBLE
7 +       default y
8  
9  config BCMA_DRIVER_PCI_HOSTMODE
10         bool "Driver for PCI core working in hostmode"
11 @@ -34,8 +35,14 @@ config BCMA_DRIVER_PCI_HOSTMODE
12           PCI core hostmode operation (external PCI bus).
13  
14  config BCMA_HOST_SOC
15 -       bool
16 -       depends on BCMA_DRIVER_MIPS
17 +       bool "Support for BCMA in a SoC"
18 +       depends on BCMA
19 +       help
20 +         Host interface for a Broadcom AIX bus directly mapped into
21 +         the memory. This only works with the Broadcom SoCs from the
22 +         BCM47XX line.
23 +
24 +         If unsure, say N
25  
26  config BCMA_DRIVER_MIPS
27         bool "BCMA Broadcom MIPS core driver"
28 @@ -68,6 +75,7 @@ config BCMA_DRIVER_GMAC_CMN
29  config BCMA_DRIVER_GPIO
30         bool "BCMA GPIO driver"
31         depends on BCMA && GPIOLIB
32 +       select IRQ_DOMAIN if BCMA_HOST_SOC
33         help
34           Driver to provide access to the GPIO pins of the bcma bus.
35  
36 --- a/drivers/bcma/Makefile
37 +++ b/drivers/bcma/Makefile
38 @@ -3,6 +3,7 @@ bcma-y                                  += driver_chipcommon.o driver
39  bcma-$(CONFIG_BCMA_SFLASH)             += driver_chipcommon_sflash.o
40  bcma-$(CONFIG_BCMA_NFLASH)             += driver_chipcommon_nflash.o
41  bcma-y                                 += driver_pci.o
42 +bcma-y                                 += driver_pcie2.o
43  bcma-$(CONFIG_BCMA_DRIVER_PCI_HOSTMODE)        += driver_pci_host.o
44  bcma-$(CONFIG_BCMA_DRIVER_MIPS)                += driver_mips.o
45  bcma-$(CONFIG_BCMA_DRIVER_GMAC_CMN)    += driver_gmac_cmn.o
46 --- a/drivers/bcma/bcma_private.h
47 +++ b/drivers/bcma/bcma_private.h
48 @@ -22,6 +22,8 @@
49  struct bcma_bus;
50  
51  /* main.c */
52 +bool bcma_wait_value(struct bcma_device *core, u16 reg, u32 mask, u32 value,
53 +                    int timeout);
54  int bcma_bus_register(struct bcma_bus *bus);
55  void bcma_bus_unregister(struct bcma_bus *bus);
56  int __init bcma_bus_early_register(struct bcma_bus *bus,
57 @@ -31,8 +33,6 @@ int __init bcma_bus_early_register(struc
58  int bcma_bus_suspend(struct bcma_bus *bus);
59  int bcma_bus_resume(struct bcma_bus *bus);
60  #endif
61 -struct bcma_device *bcma_find_core_unit(struct bcma_bus *bus, u16 coreid,
62 -                                       u8 unit);
63  
64  /* scan.c */
65  int bcma_bus_scan(struct bcma_bus *bus);
66 --- a/drivers/bcma/core.c
67 +++ b/drivers/bcma/core.c
68 @@ -9,6 +9,25 @@
69  #include <linux/export.h>
70  #include <linux/bcma/bcma.h>
71  
72 +static bool bcma_core_wait_value(struct bcma_device *core, u16 reg, u32 mask,
73 +                                u32 value, int timeout)
74 +{
75 +       unsigned long deadline = jiffies + timeout;
76 +       u32 val;
77 +
78 +       do {
79 +               val = bcma_aread32(core, reg);
80 +               if ((val & mask) == value)
81 +                       return true;
82 +               cpu_relax();
83 +               udelay(10);
84 +       } while (!time_after_eq(jiffies, deadline));
85 +
86 +       bcma_warn(core->bus, "Timeout waiting for register 0x%04X!\n", reg);
87 +
88 +       return false;
89 +}
90 +
91  bool bcma_core_is_enabled(struct bcma_device *core)
92  {
93         if ((bcma_aread32(core, BCMA_IOCTL) & (BCMA_IOCTL_CLK | BCMA_IOCTL_FGC))
94 @@ -25,13 +44,15 @@ void bcma_core_disable(struct bcma_devic
95         if (bcma_aread32(core, BCMA_RESET_CTL) & BCMA_RESET_CTL_RESET)
96                 return;
97  
98 -       bcma_awrite32(core, BCMA_IOCTL, flags);
99 -       bcma_aread32(core, BCMA_IOCTL);
100 -       udelay(10);
101 +       bcma_core_wait_value(core, BCMA_RESET_ST, ~0, 0, 300);
102  
103         bcma_awrite32(core, BCMA_RESET_CTL, BCMA_RESET_CTL_RESET);
104         bcma_aread32(core, BCMA_RESET_CTL);
105         udelay(1);
106 +
107 +       bcma_awrite32(core, BCMA_IOCTL, flags);
108 +       bcma_aread32(core, BCMA_IOCTL);
109 +       udelay(10);
110  }
111  EXPORT_SYMBOL_GPL(bcma_core_disable);
112  
113 @@ -43,6 +64,7 @@ int bcma_core_enable(struct bcma_device
114         bcma_aread32(core, BCMA_IOCTL);
115  
116         bcma_awrite32(core, BCMA_RESET_CTL, 0);
117 +       bcma_aread32(core, BCMA_RESET_CTL);
118         udelay(1);
119  
120         bcma_awrite32(core, BCMA_IOCTL, (BCMA_IOCTL_CLK | flags));
121 --- a/drivers/bcma/driver_chipcommon.c
122 +++ b/drivers/bcma/driver_chipcommon.c
123 @@ -140,8 +140,15 @@ void bcma_core_chipcommon_init(struct bc
124         bcma_core_chipcommon_early_init(cc);
125  
126         if (cc->core->id.rev >= 20) {
127 -               bcma_cc_write32(cc, BCMA_CC_GPIOPULLUP, 0);
128 -               bcma_cc_write32(cc, BCMA_CC_GPIOPULLDOWN, 0);
129 +               u32 pullup = 0, pulldown = 0;
130 +
131 +               if (cc->core->bus->chipinfo.id == BCMA_CHIP_ID_BCM43142) {
132 +                       pullup = 0x402e0;
133 +                       pulldown = 0x20500;
134 +               }
135 +
136 +               bcma_cc_write32(cc, BCMA_CC_GPIOPULLUP, pullup);
137 +               bcma_cc_write32(cc, BCMA_CC_GPIOPULLDOWN, pulldown);
138         }
139  
140         if (cc->capabilities & BCMA_CC_CAP_PMU)
141 --- a/drivers/bcma/driver_chipcommon_pmu.c
142 +++ b/drivers/bcma/driver_chipcommon_pmu.c
143 @@ -56,6 +56,109 @@ void bcma_chipco_regctl_maskset(struct b
144  }
145  EXPORT_SYMBOL_GPL(bcma_chipco_regctl_maskset);
146  
147 +static u32 bcma_pmu_xtalfreq(struct bcma_drv_cc *cc)
148 +{
149 +       u32 ilp_ctl, alp_hz;
150 +
151 +       if (!(bcma_cc_read32(cc, BCMA_CC_PMU_STAT) &
152 +             BCMA_CC_PMU_STAT_EXT_LPO_AVAIL))
153 +               return 0;
154 +
155 +       bcma_cc_write32(cc, BCMA_CC_PMU_XTAL_FREQ,
156 +                       BIT(BCMA_CC_PMU_XTAL_FREQ_MEASURE_SHIFT));
157 +       usleep_range(1000, 2000);
158 +
159 +       ilp_ctl = bcma_cc_read32(cc, BCMA_CC_PMU_XTAL_FREQ);
160 +       ilp_ctl &= BCMA_CC_PMU_XTAL_FREQ_ILPCTL_MASK;
161 +
162 +       bcma_cc_write32(cc, BCMA_CC_PMU_XTAL_FREQ, 0);
163 +
164 +       alp_hz = ilp_ctl * 32768 / 4;
165 +       return (alp_hz + 50000) / 100000 * 100;
166 +}
167 +
168 +static void bcma_pmu2_pll_init0(struct bcma_drv_cc *cc, u32 xtalfreq)
169 +{
170 +       struct bcma_bus *bus = cc->core->bus;
171 +       u32 freq_tgt_target = 0, freq_tgt_current;
172 +       u32 pll0, mask;
173 +
174 +       switch (bus->chipinfo.id) {
175 +       case BCMA_CHIP_ID_BCM43142:
176 +               /* pmu2_xtaltab0_adfll_485 */
177 +               switch (xtalfreq) {
178 +               case 12000:
179 +                       freq_tgt_target = 0x50D52;
180 +                       break;
181 +               case 20000:
182 +                       freq_tgt_target = 0x307FE;
183 +                       break;
184 +               case 26000:
185 +                       freq_tgt_target = 0x254EA;
186 +                       break;
187 +               case 37400:
188 +                       freq_tgt_target = 0x19EF8;
189 +                       break;
190 +               case 52000:
191 +                       freq_tgt_target = 0x12A75;
192 +                       break;
193 +               }
194 +               break;
195 +       }
196 +
197 +       if (!freq_tgt_target) {
198 +               bcma_err(bus, "Unknown TGT frequency for xtalfreq %d\n",
199 +                        xtalfreq);
200 +               return;
201 +       }
202 +
203 +       pll0 = bcma_chipco_pll_read(cc, BCMA_CC_PMU15_PLL_PLLCTL0);
204 +       freq_tgt_current = (pll0 & BCMA_CC_PMU15_PLL_PC0_FREQTGT_MASK) >>
205 +               BCMA_CC_PMU15_PLL_PC0_FREQTGT_SHIFT;
206 +
207 +       if (freq_tgt_current == freq_tgt_target) {
208 +               bcma_debug(bus, "Target TGT frequency already set\n");
209 +               return;
210 +       }
211 +
212 +       /* Turn off PLL */
213 +       switch (bus->chipinfo.id) {
214 +       case BCMA_CHIP_ID_BCM43142:
215 +               mask = (u32)~(BCMA_RES_4314_HT_AVAIL |
216 +                             BCMA_RES_4314_MACPHY_CLK_AVAIL);
217 +
218 +               bcma_cc_mask32(cc, BCMA_CC_PMU_MINRES_MSK, mask);
219 +               bcma_cc_mask32(cc, BCMA_CC_PMU_MAXRES_MSK, mask);
220 +               bcma_wait_value(cc->core, BCMA_CLKCTLST,
221 +                               BCMA_CLKCTLST_HAVEHT, 0, 20000);
222 +               break;
223 +       }
224 +
225 +       pll0 &= ~BCMA_CC_PMU15_PLL_PC0_FREQTGT_MASK;
226 +       pll0 |= freq_tgt_target << BCMA_CC_PMU15_PLL_PC0_FREQTGT_SHIFT;
227 +       bcma_chipco_pll_write(cc, BCMA_CC_PMU15_PLL_PLLCTL0, pll0);
228 +
229 +       /* Flush */
230 +       if (cc->pmu.rev >= 2)
231 +               bcma_cc_set32(cc, BCMA_CC_PMU_CTL, BCMA_CC_PMU_CTL_PLL_UPD);
232 +
233 +       /* TODO: Do we need to update OTP? */
234 +}
235 +
236 +static void bcma_pmu_pll_init(struct bcma_drv_cc *cc)
237 +{
238 +       struct bcma_bus *bus = cc->core->bus;
239 +       u32 xtalfreq = bcma_pmu_xtalfreq(cc);
240 +
241 +       switch (bus->chipinfo.id) {
242 +       case BCMA_CHIP_ID_BCM43142:
243 +               if (xtalfreq == 0)
244 +                       xtalfreq = 20000;
245 +               bcma_pmu2_pll_init0(cc, xtalfreq);
246 +               break;
247 +       }
248 +}
249 +
250  static void bcma_pmu_resources_init(struct bcma_drv_cc *cc)
251  {
252         struct bcma_bus *bus = cc->core->bus;
253 @@ -66,6 +169,25 @@ static void bcma_pmu_resources_init(stru
254                 min_msk = 0x200D;
255                 max_msk = 0xFFFF;
256                 break;
257 +       case BCMA_CHIP_ID_BCM43142:
258 +               min_msk = BCMA_RES_4314_LPLDO_PU |
259 +                         BCMA_RES_4314_PMU_SLEEP_DIS |
260 +                         BCMA_RES_4314_PMU_BG_PU |
261 +                         BCMA_RES_4314_CBUCK_LPOM_PU |
262 +                         BCMA_RES_4314_CBUCK_PFM_PU |
263 +                         BCMA_RES_4314_CLDO_PU |
264 +                         BCMA_RES_4314_LPLDO2_LVM |
265 +                         BCMA_RES_4314_WL_PMU_PU |
266 +                         BCMA_RES_4314_LDO3P3_PU |
267 +                         BCMA_RES_4314_OTP_PU |
268 +                         BCMA_RES_4314_WL_PWRSW_PU |
269 +                         BCMA_RES_4314_LQ_AVAIL |
270 +                         BCMA_RES_4314_LOGIC_RET |
271 +                         BCMA_RES_4314_MEM_SLEEP |
272 +                         BCMA_RES_4314_MACPHY_RET |
273 +                         BCMA_RES_4314_WL_CORE_READY;
274 +               max_msk = 0x3FFFFFFF;
275 +               break;
276         default:
277                 bcma_debug(bus, "PMU resource config unknown or not needed for device 0x%04X\n",
278                            bus->chipinfo.id);
279 @@ -165,6 +287,7 @@ void bcma_pmu_init(struct bcma_drv_cc *c
280                 bcma_cc_set32(cc, BCMA_CC_PMU_CTL,
281                              BCMA_CC_PMU_CTL_NOILPONW);
282  
283 +       bcma_pmu_pll_init(cc);
284         bcma_pmu_resources_init(cc);
285         bcma_pmu_workarounds(cc);
286  }
287 @@ -480,6 +603,8 @@ void bcma_pmu_spuravoid_pllupdate(struct
288                 tmp = BCMA_CC_PMU_CTL_PLL_UPD | BCMA_CC_PMU_CTL_NOILPONW;
289                 break;
290  
291 +       case BCMA_CHIP_ID_BCM43131:
292 +       case BCMA_CHIP_ID_BCM43217:
293         case BCMA_CHIP_ID_BCM43227:
294         case BCMA_CHIP_ID_BCM43228:
295         case BCMA_CHIP_ID_BCM43428:
296 --- a/drivers/bcma/driver_chipcommon_sflash.c
297 +++ b/drivers/bcma/driver_chipcommon_sflash.c
298 @@ -30,7 +30,7 @@ struct bcma_sflash_tbl_e {
299         u16 numblocks;
300  };
301  
302 -static struct bcma_sflash_tbl_e bcma_sflash_st_tbl[] = {
303 +static const struct bcma_sflash_tbl_e bcma_sflash_st_tbl[] = {
304         { "M25P20", 0x11, 0x10000, 4, },
305         { "M25P40", 0x12, 0x10000, 8, },
306  
307 @@ -38,10 +38,10 @@ static struct bcma_sflash_tbl_e bcma_sfl
308         { "M25P32", 0x15, 0x10000, 64, },
309         { "M25P64", 0x16, 0x10000, 128, },
310         { "M25FL128", 0x17, 0x10000, 256, },
311 -       { 0 },
312 +       { NULL },
313  };
314  
315 -static struct bcma_sflash_tbl_e bcma_sflash_sst_tbl[] = {
316 +static const struct bcma_sflash_tbl_e bcma_sflash_sst_tbl[] = {
317         { "SST25WF512", 1, 0x1000, 16, },
318         { "SST25VF512", 0x48, 0x1000, 16, },
319         { "SST25WF010", 2, 0x1000, 32, },
320 @@ -56,10 +56,10 @@ static struct bcma_sflash_tbl_e bcma_sfl
321         { "SST25VF016", 0x41, 0x1000, 512, },
322         { "SST25VF032", 0x4a, 0x1000, 1024, },
323         { "SST25VF064", 0x4b, 0x1000, 2048, },
324 -       { 0 },
325 +       { NULL },
326  };
327  
328 -static struct bcma_sflash_tbl_e bcma_sflash_at_tbl[] = {
329 +static const struct bcma_sflash_tbl_e bcma_sflash_at_tbl[] = {
330         { "AT45DB011", 0xc, 256, 512, },
331         { "AT45DB021", 0x14, 256, 1024, },
332         { "AT45DB041", 0x1c, 256, 2048, },
333 @@ -67,7 +67,7 @@ static struct bcma_sflash_tbl_e bcma_sfl
334         { "AT45DB161", 0x2c, 512, 4096, },
335         { "AT45DB321", 0x34, 512, 8192, },
336         { "AT45DB642", 0x3c, 1024, 8192, },
337 -       { 0 },
338 +       { NULL },
339  };
340  
341  static void bcma_sflash_cmd(struct bcma_drv_cc *cc, u32 opcode)
342 @@ -89,7 +89,7 @@ int bcma_sflash_init(struct bcma_drv_cc
343  {
344         struct bcma_bus *bus = cc->core->bus;
345         struct bcma_sflash *sflash = &cc->sflash;
346 -       struct bcma_sflash_tbl_e *e;
347 +       const struct bcma_sflash_tbl_e *e;
348         u32 id, id2;
349  
350         switch (cc->capabilities & BCMA_CC_CAP_FLASHT) {
351 --- a/drivers/bcma/driver_gpio.c
352 +++ b/drivers/bcma/driver_gpio.c
353 @@ -9,6 +9,9 @@
354   */
355  
356  #include <linux/gpio.h>
357 +#include <linux/irq.h>
358 +#include <linux/interrupt.h>
359 +#include <linux/irqdomain.h>
360  #include <linux/export.h>
361  #include <linux/bcma/bcma.h>
362  
363 @@ -73,19 +76,136 @@ static void bcma_gpio_free(struct gpio_c
364         bcma_chipco_gpio_pullup(cc, 1 << gpio, 0);
365  }
366  
367 +#if IS_BUILTIN(CONFIG_BCMA_HOST_SOC)
368  static int bcma_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
369  {
370         struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip);
371  
372         if (cc->core->bus->hosttype == BCMA_HOSTTYPE_SOC)
373 -               return bcma_core_irq(cc->core);
374 +               return irq_find_mapping(cc->irq_domain, gpio);
375         else
376                 return -EINVAL;
377  }
378  
379 +static void bcma_gpio_irq_unmask(struct irq_data *d)
380 +{
381 +       struct bcma_drv_cc *cc = irq_data_get_irq_chip_data(d);
382 +       int gpio = irqd_to_hwirq(d);
383 +       u32 val = bcma_chipco_gpio_in(cc, BIT(gpio));
384 +
385 +       bcma_chipco_gpio_polarity(cc, BIT(gpio), val);
386 +       bcma_chipco_gpio_intmask(cc, BIT(gpio), BIT(gpio));
387 +}
388 +
389 +static void bcma_gpio_irq_mask(struct irq_data *d)
390 +{
391 +       struct bcma_drv_cc *cc = irq_data_get_irq_chip_data(d);
392 +       int gpio = irqd_to_hwirq(d);
393 +
394 +       bcma_chipco_gpio_intmask(cc, BIT(gpio), 0);
395 +}
396 +
397 +static struct irq_chip bcma_gpio_irq_chip = {
398 +       .name           = "BCMA-GPIO",
399 +       .irq_mask       = bcma_gpio_irq_mask,
400 +       .irq_unmask     = bcma_gpio_irq_unmask,
401 +};
402 +
403 +static irqreturn_t bcma_gpio_irq_handler(int irq, void *dev_id)
404 +{
405 +       struct bcma_drv_cc *cc = dev_id;
406 +       u32 val = bcma_cc_read32(cc, BCMA_CC_GPIOIN);
407 +       u32 mask = bcma_cc_read32(cc, BCMA_CC_GPIOIRQ);
408 +       u32 pol = bcma_cc_read32(cc, BCMA_CC_GPIOPOL);
409 +       unsigned long irqs = (val ^ pol) & mask;
410 +       int gpio;
411 +
412 +       if (!irqs)
413 +               return IRQ_NONE;
414 +
415 +       for_each_set_bit(gpio, &irqs, cc->gpio.ngpio)
416 +               generic_handle_irq(bcma_gpio_to_irq(&cc->gpio, gpio));
417 +       bcma_chipco_gpio_polarity(cc, irqs, val & irqs);
418 +
419 +       return IRQ_HANDLED;
420 +}
421 +
422 +static int bcma_gpio_irq_domain_init(struct bcma_drv_cc *cc)
423 +{
424 +       struct gpio_chip *chip = &cc->gpio;
425 +       int gpio, hwirq, err;
426 +
427 +       if (cc->core->bus->hosttype != BCMA_HOSTTYPE_SOC)
428 +               return 0;
429 +
430 +       cc->irq_domain = irq_domain_add_linear(NULL, chip->ngpio,
431 +                                              &irq_domain_simple_ops, cc);
432 +       if (!cc->irq_domain) {
433 +               err = -ENODEV;
434 +               goto err_irq_domain;
435 +       }
436 +       for (gpio = 0; gpio < chip->ngpio; gpio++) {
437 +               int irq = irq_create_mapping(cc->irq_domain, gpio);
438 +
439 +               irq_set_chip_data(irq, cc);
440 +               irq_set_chip_and_handler(irq, &bcma_gpio_irq_chip,
441 +                                        handle_simple_irq);
442 +       }
443 +
444 +       hwirq = bcma_core_irq(cc->core);
445 +       err = request_irq(hwirq, bcma_gpio_irq_handler, IRQF_SHARED, "gpio",
446 +                         cc);
447 +       if (err)
448 +               goto err_req_irq;
449 +
450 +       bcma_chipco_gpio_intmask(cc, ~0, 0);
451 +       bcma_cc_set32(cc, BCMA_CC_IRQMASK, BCMA_CC_IRQ_GPIO);
452 +
453 +       return 0;
454 +
455 +err_req_irq:
456 +       for (gpio = 0; gpio < chip->ngpio; gpio++) {
457 +               int irq = irq_find_mapping(cc->irq_domain, gpio);
458 +
459 +               irq_dispose_mapping(irq);
460 +       }
461 +       irq_domain_remove(cc->irq_domain);
462 +err_irq_domain:
463 +       return err;
464 +}
465 +
466 +static void bcma_gpio_irq_domain_exit(struct bcma_drv_cc *cc)
467 +{
468 +       struct gpio_chip *chip = &cc->gpio;
469 +       int gpio;
470 +
471 +       if (cc->core->bus->hosttype != BCMA_HOSTTYPE_SOC)
472 +               return;
473 +
474 +       bcma_cc_mask32(cc, BCMA_CC_IRQMASK, ~BCMA_CC_IRQ_GPIO);
475 +       free_irq(bcma_core_irq(cc->core), cc);
476 +       for (gpio = 0; gpio < chip->ngpio; gpio++) {
477 +               int irq = irq_find_mapping(cc->irq_domain, gpio);
478 +
479 +               irq_dispose_mapping(irq);
480 +       }
481 +       irq_domain_remove(cc->irq_domain);
482 +}
483 +#else
484 +static int bcma_gpio_irq_domain_init(struct bcma_drv_cc *cc)
485 +{
486 +       return 0;
487 +}
488 +
489 +static void bcma_gpio_irq_domain_exit(struct bcma_drv_cc *cc)
490 +{
491 +}
492 +#endif
493 +
494  int bcma_gpio_init(struct bcma_drv_cc *cc)
495  {
496         struct gpio_chip *chip = &cc->gpio;
497 +       int err;
498  
499         chip->label             = "bcma_gpio";
500         chip->owner             = THIS_MODULE;
501 @@ -95,8 +215,18 @@ int bcma_gpio_init(struct bcma_drv_cc *c
502         chip->set               = bcma_gpio_set_value;
503         chip->direction_input   = bcma_gpio_direction_input;
504         chip->direction_output  = bcma_gpio_direction_output;
505 +#if IS_BUILTIN(CONFIG_BCMA_HOST_SOC)
506         chip->to_irq            = bcma_gpio_to_irq;
507 -       chip->ngpio             = 16;
508 +#endif
509 +       switch (cc->core->bus->chipinfo.id) {
510 +       case BCMA_CHIP_ID_BCM5357:
511 +       case BCMA_CHIP_ID_BCM53572:
512 +               chip->ngpio     = 32;
513 +               break;
514 +       default:
515 +               chip->ngpio     = 16;
516 +       }
517 +
518         /* There is just one SoC in one device and its GPIO addresses should be
519          * deterministic to address them more easily. The other buses could get
520          * a random base number. */
521 @@ -105,10 +235,21 @@ int bcma_gpio_init(struct bcma_drv_cc *c
522         else
523                 chip->base              = -1;
524  
525 -       return gpiochip_add(chip);
526 +       err = bcma_gpio_irq_domain_init(cc);
527 +       if (err)
528 +               return err;
529 +
530 +       err = gpiochip_add(chip);
531 +       if (err) {
532 +               bcma_gpio_irq_domain_exit(cc);
533 +               return err;
534 +       }
535 +
536 +       return 0;
537  }
538  
539  int bcma_gpio_unregister(struct bcma_drv_cc *cc)
540  {
541 +       bcma_gpio_irq_domain_exit(cc);
542         return gpiochip_remove(&cc->gpio);
543  }
544 --- a/drivers/bcma/driver_pci.c
545 +++ b/drivers/bcma/driver_pci.c
546 @@ -31,7 +31,7 @@ static void bcma_pcie_write(struct bcma_
547         pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_DATA, data);
548  }
549  
550 -static void bcma_pcie_mdio_set_phy(struct bcma_drv_pci *pc, u8 phy)
551 +static void bcma_pcie_mdio_set_phy(struct bcma_drv_pci *pc, u16 phy)
552  {
553         u32 v;
554         int i;
555 @@ -55,7 +55,7 @@ static void bcma_pcie_mdio_set_phy(struc
556         }
557  }
558  
559 -static u16 bcma_pcie_mdio_read(struct bcma_drv_pci *pc, u8 device, u8 address)
560 +static u16 bcma_pcie_mdio_read(struct bcma_drv_pci *pc, u16 device, u8 address)
561  {
562         int max_retries = 10;
563         u16 ret = 0;
564 @@ -98,7 +98,7 @@ static u16 bcma_pcie_mdio_read(struct bc
565         return ret;
566  }
567  
568 -static void bcma_pcie_mdio_write(struct bcma_drv_pci *pc, u8 device,
569 +static void bcma_pcie_mdio_write(struct bcma_drv_pci *pc, u16 device,
570                                 u8 address, u16 data)
571  {
572         int max_retries = 10;
573 @@ -137,6 +137,13 @@ static void bcma_pcie_mdio_write(struct
574         pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, 0);
575  }
576  
577 +static u16 bcma_pcie_mdio_writeread(struct bcma_drv_pci *pc, u16 device,
578 +                                   u8 address, u16 data)
579 +{
580 +       bcma_pcie_mdio_write(pc, device, address, data);
581 +       return bcma_pcie_mdio_read(pc, device, address);
582 +}
583 +
584  /**************************************************
585   * Workarounds.
586   **************************************************/
587 @@ -229,6 +236,32 @@ void bcma_core_pci_init(struct bcma_drv_
588                 bcma_core_pci_clientmode_init(pc);
589  }
590  
591 +void bcma_core_pci_power_save(struct bcma_bus *bus, bool up)
592 +{
593 +       struct bcma_drv_pci *pc;
594 +       u16 data;
595 +
596 +       if (bus->hosttype != BCMA_HOSTTYPE_PCI)
597 +               return;
598 +
599 +       pc = &bus->drv_pci[0];
600 +
601 +       if (pc->core->id.rev >= 15 && pc->core->id.rev <= 20) {
602 +               data = up ? 0x74 : 0x7C;
603 +               bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1,
604 +                                        BCMA_CORE_PCI_MDIO_BLK1_MGMT1, 0x7F64);
605 +               bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1,
606 +                                        BCMA_CORE_PCI_MDIO_BLK1_MGMT3, data);
607 +       } else if (pc->core->id.rev >= 21 && pc->core->id.rev <= 22) {
608 +               data = up ? 0x75 : 0x7D;
609 +               bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1,
610 +                                        BCMA_CORE_PCI_MDIO_BLK1_MGMT1, 0x7E65);
611 +               bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1,
612 +                                        BCMA_CORE_PCI_MDIO_BLK1_MGMT3, data);
613 +       }
614 +}
615 +EXPORT_SYMBOL_GPL(bcma_core_pci_power_save);
616 +
617  int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core,
618                           bool enable)
619  {
620 @@ -262,7 +295,7 @@ out:
621  }
622  EXPORT_SYMBOL_GPL(bcma_core_pci_irq_ctl);
623  
624 -void bcma_core_pci_extend_L1timer(struct bcma_drv_pci *pc, bool extend)
625 +static void bcma_core_pci_extend_L1timer(struct bcma_drv_pci *pc, bool extend)
626  {
627         u32 w;
628  
629 @@ -274,4 +307,29 @@ void bcma_core_pci_extend_L1timer(struct
630         bcma_pcie_write(pc, BCMA_CORE_PCI_DLLP_PMTHRESHREG, w);
631         bcma_pcie_read(pc, BCMA_CORE_PCI_DLLP_PMTHRESHREG);
632  }
633 -EXPORT_SYMBOL_GPL(bcma_core_pci_extend_L1timer);
634 +
635 +void bcma_core_pci_up(struct bcma_bus *bus)
636 +{
637 +       struct bcma_drv_pci *pc;
638 +
639 +       if (bus->hosttype != BCMA_HOSTTYPE_PCI)
640 +               return;
641 +
642 +       pc = &bus->drv_pci[0];
643 +
644 +       bcma_core_pci_extend_L1timer(pc, true);
645 +}
646 +EXPORT_SYMBOL_GPL(bcma_core_pci_up);
647 +
648 +void bcma_core_pci_down(struct bcma_bus *bus)
649 +{
650 +       struct bcma_drv_pci *pc;
651 +
652 +       if (bus->hosttype != BCMA_HOSTTYPE_PCI)
653 +               return;
654 +
655 +       pc = &bus->drv_pci[0];
656 +
657 +       bcma_core_pci_extend_L1timer(pc, false);
658 +}
659 +EXPORT_SYMBOL_GPL(bcma_core_pci_down);
660 --- a/drivers/bcma/driver_pci_host.c
661 +++ b/drivers/bcma/driver_pci_host.c
662 @@ -581,6 +581,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI
663  int bcma_core_pci_plat_dev_init(struct pci_dev *dev)
664  {
665         struct bcma_drv_pci_host *pc_host;
666 +       int readrq;
667  
668         if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) {
669                 /* This is not a device on the PCI-core bridge. */
670 @@ -595,6 +596,11 @@ int bcma_core_pci_plat_dev_init(struct p
671         dev->irq = bcma_core_irq(pc_host->pdev->core);
672         pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
673  
674 +       readrq = pcie_get_readrq(dev);
675 +       if (readrq > 128) {
676 +               pr_info("change PCIe max read request size from %i to 128\n", readrq);
677 +               pcie_set_readrq(dev, 128);
678 +       }
679         return 0;
680  }
681  EXPORT_SYMBOL(bcma_core_pci_plat_dev_init);
682 --- /dev/null
683 +++ b/drivers/bcma/driver_pcie2.c
684 @@ -0,0 +1,175 @@
685 +/*
686 + * Broadcom specific AMBA
687 + * PCIe Gen 2 Core
688 + *
689 + * Copyright 2014, Broadcom Corporation
690 + * Copyright 2014, RafaÅ‚ MiÅ‚ecki <zajec5@gmail.com>
691 + *
692 + * Licensed under the GNU/GPL. See COPYING for details.
693 + */
694 +
695 +#include "bcma_private.h"
696 +#include <linux/bcma/bcma.h>
697 +
698 +/**************************************************
699 + * R/W ops.
700 + **************************************************/
701 +
702 +#if 0
703 +static u32 bcma_core_pcie2_cfg_read(struct bcma_drv_pcie2 *pcie2, u32 addr)
704 +{
705 +       pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, addr);
706 +       pcie2_read32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR);
707 +       return pcie2_read32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA);
708 +}
709 +#endif
710 +
711 +static void bcma_core_pcie2_cfg_write(struct bcma_drv_pcie2 *pcie2, u32 addr,
712 +                                     u32 val)
713 +{
714 +       pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, addr);
715 +       pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, val);
716 +}
717 +
718 +/**************************************************
719 + * Init.
720 + **************************************************/
721 +
722 +static u32 bcma_core_pcie2_war_delay_perst_enab(struct bcma_drv_pcie2 *pcie2,
723 +                                               bool enable)
724 +{
725 +       u32 val;
726 +
727 +       /* restore back to default */
728 +       val = pcie2_read32(pcie2, BCMA_CORE_PCIE2_CLK_CONTROL);
729 +       val |= PCIE2_CLKC_DLYPERST;
730 +       val &= ~PCIE2_CLKC_DISSPROMLD;
731 +       if (enable) {
732 +               val &= ~PCIE2_CLKC_DLYPERST;
733 +               val |= PCIE2_CLKC_DISSPROMLD;
734 +       }
735 +       pcie2_write32(pcie2, (BCMA_CORE_PCIE2_CLK_CONTROL), val);
736 +       /* flush */
737 +       return pcie2_read32(pcie2, BCMA_CORE_PCIE2_CLK_CONTROL);
738 +}
739 +
740 +static void bcma_core_pcie2_set_ltr_vals(struct bcma_drv_pcie2 *pcie2)
741 +{
742 +       /* LTR0 */
743 +       pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, 0x844);
744 +       pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, 0x883c883c);
745 +       /* LTR1 */
746 +       pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, 0x848);
747 +       pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, 0x88648864);
748 +       /* LTR2 */
749 +       pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, 0x84C);
750 +       pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, 0x90039003);
751 +}
752 +
753 +static void bcma_core_pcie2_hw_ltr_war(struct bcma_drv_pcie2 *pcie2)
754 +{
755 +       u8 core_rev = pcie2->core->id.rev;
756 +       u32 devstsctr2;
757 +
758 +       if (core_rev < 2 || core_rev == 10 || core_rev > 13)
759 +               return;
760 +
761 +       pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR,
762 +                     PCIE2_CAP_DEVSTSCTRL2_OFFSET);
763 +       devstsctr2 = pcie2_read32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA);
764 +       if (devstsctr2 & PCIE2_CAP_DEVSTSCTRL2_LTRENAB) {
765 +               /* force the right LTR values */
766 +               bcma_core_pcie2_set_ltr_vals(pcie2);
767 +
768 +               /* TODO:
769 +               si_core_wrapperreg(pcie2, 3, 0x60, 0x8080, 0); */
770 +
771 +               /* enable the LTR */
772 +               devstsctr2 |= PCIE2_CAP_DEVSTSCTRL2_LTRENAB;
773 +               pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR,
774 +                             PCIE2_CAP_DEVSTSCTRL2_OFFSET);
775 +               pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, devstsctr2);
776 +
777 +               /* set the LTR state to be active */
778 +               pcie2_write32(pcie2, BCMA_CORE_PCIE2_LTR_STATE,
779 +                             PCIE2_LTR_ACTIVE);
780 +               usleep_range(1000, 2000);
781 +
782 +               /* set the LTR state to be sleep */
783 +               pcie2_write32(pcie2, BCMA_CORE_PCIE2_LTR_STATE,
784 +                             PCIE2_LTR_SLEEP);
785 +               usleep_range(1000, 2000);
786 +       }
787 +}
788 +
789 +static void pciedev_crwlpciegen2(struct bcma_drv_pcie2 *pcie2)
790 +{
791 +       u8 core_rev = pcie2->core->id.rev;
792 +       bool pciewar160, pciewar162;
793 +
794 +       pciewar160 = core_rev == 7 || core_rev == 9 || core_rev == 11;
795 +       pciewar162 = core_rev == 5 || core_rev == 7 || core_rev == 8 ||
796 +                    core_rev == 9 || core_rev == 11;
797 +
798 +       if (!pciewar160 && !pciewar162)
799 +               return;
800 +
801 +/* TODO */
802 +#if 0
803 +       pcie2_set32(pcie2, BCMA_CORE_PCIE2_CLK_CONTROL,
804 +                   PCIE_DISABLE_L1CLK_GATING);
805 +#if 0
806 +       pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR,
807 +                     PCIEGEN2_COE_PVT_TL_CTRL_0);
808 +       pcie2_mask32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA,
809 +                    ~(1 << COE_PVT_TL_CTRL_0_PM_DIS_L1_REENTRY_BIT));
810 +#endif
811 +#endif
812 +}
813 +
814 +static void pciedev_crwlpciegen2_180(struct bcma_drv_pcie2 *pcie2)
815 +{
816 +       pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, PCIE2_PMCR_REFUP);
817 +       pcie2_set32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, 0x1f);
818 +}
819 +
820 +static void pciedev_crwlpciegen2_182(struct bcma_drv_pcie2 *pcie2)
821 +{
822 +       pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, PCIE2_SBMBX);
823 +       pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, 1 << 0);
824 +}
825 +
826 +static void pciedev_reg_pm_clk_period(struct bcma_drv_pcie2 *pcie2)
827 +{
828 +       struct bcma_drv_cc *drv_cc = &pcie2->core->bus->drv_cc;
829 +       u8 core_rev = pcie2->core->id.rev;
830 +       u32 alp_khz, pm_value;
831 +
832 +       if (core_rev <= 13) {
833 +               alp_khz = bcma_pmu_get_alp_clock(drv_cc) / 1000;
834 +               pm_value = (1000000 * 2) / alp_khz;
835 +               pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR,
836 +                             PCIE2_PVT_REG_PM_CLK_PERIOD);
837 +               pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, pm_value);
838 +       }
839 +}
840 +
841 +void bcma_core_pcie2_init(struct bcma_drv_pcie2 *pcie2)
842 +{
843 +       struct bcma_chipinfo *ci = &pcie2->core->bus->chipinfo;
844 +       u32 tmp;
845 +
846 +       tmp = pcie2_read32(pcie2, BCMA_CORE_PCIE2_SPROM(54));
847 +       if ((tmp & 0xe) >> 1 == 2)
848 +               bcma_core_pcie2_cfg_write(pcie2, 0x4e0, 0x17);
849 +
850 +       /* TODO: Do we need pcie_reqsize? */
851 +
852 +       if (ci->id == BCMA_CHIP_ID_BCM4360 && ci->rev > 3)
853 +               bcma_core_pcie2_war_delay_perst_enab(pcie2, true);
854 +       bcma_core_pcie2_hw_ltr_war(pcie2);
855 +       pciedev_crwlpciegen2(pcie2);
856 +       pciedev_reg_pm_clk_period(pcie2);
857 +       pciedev_crwlpciegen2_180(pcie2);
858 +       pciedev_crwlpciegen2_182(pcie2);
859 +}
860 --- a/drivers/bcma/host_pci.c
861 +++ b/drivers/bcma/host_pci.c
862 @@ -188,8 +188,11 @@ static int bcma_host_pci_probe(struct pc
863                 pci_write_config_dword(dev, 0x40, val & 0xffff00ff);
864  
865         /* SSB needed additional powering up, do we have any AMBA PCI cards? */
866 -       if (!pci_is_pcie(dev))
867 -               bcma_err(bus, "PCI card detected, report problems.\n");
868 +       if (!pci_is_pcie(dev)) {
869 +               bcma_err(bus, "PCI card detected, they are not supported.\n");
870 +               err = -ENXIO;
871 +               goto err_pci_release_regions;
872 +       }
873  
874         /* Map MMIO */
875         err = -ENOMEM;
876 @@ -235,7 +238,6 @@ static void bcma_host_pci_remove(struct
877         pci_release_regions(dev);
878         pci_disable_device(dev);
879         kfree(bus);
880 -       pci_set_drvdata(dev, NULL);
881  }
882  
883  #ifdef CONFIG_PM_SLEEP
884 @@ -267,14 +269,18 @@ static SIMPLE_DEV_PM_OPS(bcma_pm_ops, bc
885  
886  #endif /* CONFIG_PM_SLEEP */
887  
888 -static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = {
889 +static const struct pci_device_id bcma_pci_bridge_tbl[] = {
890         { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) },
891 +       { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4313) },
892         { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 43224) },
893         { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) },
894         { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4353) },
895         { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4357) },
896         { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4358) },
897         { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4359) },
898 +       { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4365) },
899 +       { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43a9) },
900 +       { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43aa) },
901         { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) },
902         { 0, },
903  };
904 --- a/drivers/bcma/main.c
905 +++ b/drivers/bcma/main.c
906 @@ -69,28 +69,36 @@ static u16 bcma_cc_core_id(struct bcma_b
907         return BCMA_CORE_CHIPCOMMON;
908  }
909  
910 -struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid)
911 +struct bcma_device *bcma_find_core_unit(struct bcma_bus *bus, u16 coreid,
912 +                                       u8 unit)
913  {
914         struct bcma_device *core;
915  
916         list_for_each_entry(core, &bus->cores, list) {
917 -               if (core->id.id == coreid)
918 +               if (core->id.id == coreid && core->core_unit == unit)
919                         return core;
920         }
921         return NULL;
922  }
923 -EXPORT_SYMBOL_GPL(bcma_find_core);
924 +EXPORT_SYMBOL_GPL(bcma_find_core_unit);
925  
926 -struct bcma_device *bcma_find_core_unit(struct bcma_bus *bus, u16 coreid,
927 -                                       u8 unit)
928 +bool bcma_wait_value(struct bcma_device *core, u16 reg, u32 mask, u32 value,
929 +                    int timeout)
930  {
931 -       struct bcma_device *core;
932 +       unsigned long deadline = jiffies + timeout;
933 +       u32 val;
934  
935 -       list_for_each_entry(core, &bus->cores, list) {
936 -               if (core->id.id == coreid && core->core_unit == unit)
937 -                       return core;
938 -       }
939 -       return NULL;
940 +       do {
941 +               val = bcma_read32(core, reg);
942 +               if ((val & mask) == value)
943 +                       return true;
944 +               cpu_relax();
945 +               udelay(10);
946 +       } while (!time_after_eq(jiffies, deadline));
947 +
948 +       bcma_warn(core->bus, "Timeout waiting for register 0x%04X!\n", reg);
949 +
950 +       return false;
951  }
952  
953  static void bcma_release_core_dev(struct device *dev)
954 @@ -115,6 +123,7 @@ static int bcma_register_cores(struct bc
955                 case BCMA_CORE_CHIPCOMMON:
956                 case BCMA_CORE_PCI:
957                 case BCMA_CORE_PCIE:
958 +               case BCMA_CORE_PCIE2:
959                 case BCMA_CORE_MIPS_74K:
960                 case BCMA_CORE_4706_MAC_GBIT_COMMON:
961                         continue;
962 @@ -148,6 +157,7 @@ static int bcma_register_cores(struct bc
963                         bcma_err(bus,
964                                  "Could not register dev for core 0x%03X\n",
965                                  core->id.id);
966 +                       put_device(&core->dev);
967                         continue;
968                 }
969                 core->dev_registered = true;
970 @@ -218,7 +228,7 @@ int bcma_bus_register(struct bcma_bus *b
971         err = bcma_bus_scan(bus);
972         if (err) {
973                 bcma_err(bus, "Failed to scan: %d\n", err);
974 -               return -1;
975 +               return err;
976         }
977  
978         /* Early init CC core */
979 @@ -263,6 +273,13 @@ int bcma_bus_register(struct bcma_bus *b
980                 bcma_core_pci_init(&bus->drv_pci[1]);
981         }
982  
983 +       /* Init PCIe Gen 2 core */
984 +       core = bcma_find_core_unit(bus, BCMA_CORE_PCIE2, 0);
985 +       if (core) {
986 +               bus->drv_pcie2.core = core;
987 +               bcma_core_pcie2_init(&bus->drv_pcie2);
988 +       }
989 +
990         /* Init GBIT MAC COMMON core */
991         core = bcma_find_core(bus, BCMA_CORE_4706_MAC_GBIT_COMMON);
992         if (core) {
993 --- a/drivers/bcma/scan.c
994 +++ b/drivers/bcma/scan.c
995 @@ -32,6 +32,18 @@ static const struct bcma_device_id_name
996         { BCMA_CORE_4706_CHIPCOMMON, "BCM4706 ChipCommon" },
997         { BCMA_CORE_4706_SOC_RAM, "BCM4706 SOC RAM" },
998         { BCMA_CORE_4706_MAC_GBIT, "BCM4706 GBit MAC" },
999 +       { BCMA_CORE_NS_PCIEG2, "PCIe Gen 2" },
1000 +       { BCMA_CORE_NS_DMA, "DMA" },
1001 +       { BCMA_CORE_NS_SDIO3, "SDIO3" },
1002 +       { BCMA_CORE_NS_USB20, "USB 2.0" },
1003 +       { BCMA_CORE_NS_USB30, "USB 3.0" },
1004 +       { BCMA_CORE_NS_A9JTAG, "ARM Cortex A9 JTAG" },
1005 +       { BCMA_CORE_NS_DDR23, "Denali DDR2/DDR3 memory controller" },
1006 +       { BCMA_CORE_NS_ROM, "ROM" },
1007 +       { BCMA_CORE_NS_NAND, "NAND flash controller" },
1008 +       { BCMA_CORE_NS_QSPI, "SPI flash controller" },
1009 +       { BCMA_CORE_NS_CHIPCOMMON_B, "Chipcommon B" },
1010 +       { BCMA_CORE_ARMCA9, "ARM Cortex A9 core (ihost)" },
1011         { BCMA_CORE_AMEMC, "AMEMC (DDR)" },
1012         { BCMA_CORE_ALTA, "ALTA (I2S)" },
1013         { BCMA_CORE_INVALID, "Invalid" },
1014 @@ -201,7 +213,7 @@ static s32 bcma_erom_get_mst_port(struct
1015         return ent;
1016  }
1017  
1018 -static s32 bcma_erom_get_addr_desc(struct bcma_bus *bus, u32 __iomem **eromptr,
1019 +static u32 bcma_erom_get_addr_desc(struct bcma_bus *bus, u32 __iomem **eromptr,
1020                                   u32 type, u8 port)
1021  {
1022         u32 addrl, addrh, sizel, sizeh = 0;
1023 @@ -213,7 +225,7 @@ static s32 bcma_erom_get_addr_desc(struc
1024             ((ent & SCAN_ADDR_TYPE) != type) ||
1025             (((ent & SCAN_ADDR_PORT) >> SCAN_ADDR_PORT_SHIFT) != port)) {
1026                 bcma_erom_push_ent(eromptr);
1027 -               return -EINVAL;
1028 +               return (u32)-EINVAL;
1029         }
1030  
1031         addrl = ent & SCAN_ADDR_ADDR;
1032 @@ -257,11 +269,13 @@ static struct bcma_device *bcma_find_cor
1033         return NULL;
1034  }
1035  
1036 +#define IS_ERR_VALUE_U32(x) ((x) >= (u32)-MAX_ERRNO)
1037 +
1038  static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
1039                               struct bcma_device_id *match, int core_num,
1040                               struct bcma_device *core)
1041  {
1042 -       s32 tmp;
1043 +       u32 tmp;
1044         u8 i, j;
1045         s32 cia, cib;
1046         u8 ports[2], wrappers[2];
1047 @@ -339,11 +353,11 @@ static int bcma_get_next_core(struct bcm
1048          * the main register space for the core
1049          */
1050         tmp = bcma_erom_get_addr_desc(bus, eromptr, SCAN_ADDR_TYPE_SLAVE, 0);
1051 -       if (tmp <= 0) {
1052 +       if (tmp == 0 || IS_ERR_VALUE_U32(tmp)) {
1053                 /* Try again to see if it is a bridge */
1054                 tmp = bcma_erom_get_addr_desc(bus, eromptr,
1055                                               SCAN_ADDR_TYPE_BRIDGE, 0);
1056 -               if (tmp <= 0) {
1057 +               if (tmp == 0 || IS_ERR_VALUE_U32(tmp)) {
1058                         return -EILSEQ;
1059                 } else {
1060                         bcma_info(bus, "Bridge found\n");
1061 @@ -357,7 +371,7 @@ static int bcma_get_next_core(struct bcm
1062                 for (j = 0; ; j++) {
1063                         tmp = bcma_erom_get_addr_desc(bus, eromptr,
1064                                 SCAN_ADDR_TYPE_SLAVE, i);
1065 -                       if (tmp < 0) {
1066 +                       if (IS_ERR_VALUE_U32(tmp)) {
1067                                 /* no more entries for port _i_ */
1068                                 /* pr_debug("erom: slave port %d "
1069                                  * "has %d descriptors\n", i, j); */
1070 @@ -374,7 +388,7 @@ static int bcma_get_next_core(struct bcm
1071                 for (j = 0; ; j++) {
1072                         tmp = bcma_erom_get_addr_desc(bus, eromptr,
1073                                 SCAN_ADDR_TYPE_MWRAP, i);
1074 -                       if (tmp < 0) {
1075 +                       if (IS_ERR_VALUE_U32(tmp)) {
1076                                 /* no more entries for port _i_ */
1077                                 /* pr_debug("erom: master wrapper %d "
1078                                  * "has %d descriptors\n", i, j); */
1079 @@ -392,7 +406,7 @@ static int bcma_get_next_core(struct bcm
1080                 for (j = 0; ; j++) {
1081                         tmp = bcma_erom_get_addr_desc(bus, eromptr,
1082                                 SCAN_ADDR_TYPE_SWRAP, i + hack);
1083 -                       if (tmp < 0) {
1084 +                       if (IS_ERR_VALUE_U32(tmp)) {
1085                                 /* no more entries for port _i_ */
1086                                 /* pr_debug("erom: master wrapper %d "
1087                                  * has %d descriptors\n", i, j); */
1088 @@ -407,10 +421,13 @@ static int bcma_get_next_core(struct bcm
1089                 core->io_addr = ioremap_nocache(core->addr, BCMA_CORE_SIZE);
1090                 if (!core->io_addr)
1091                         return -ENOMEM;
1092 -               core->io_wrap = ioremap_nocache(core->wrap, BCMA_CORE_SIZE);
1093 -               if (!core->io_wrap) {
1094 -                       iounmap(core->io_addr);
1095 -                       return -ENOMEM;
1096 +               if (core->wrap) {
1097 +                       core->io_wrap = ioremap_nocache(core->wrap,
1098 +                                                       BCMA_CORE_SIZE);
1099 +                       if (!core->io_wrap) {
1100 +                               iounmap(core->io_addr);
1101 +                               return -ENOMEM;
1102 +                       }
1103                 }
1104         }
1105         return 0;
1106 --- a/drivers/bcma/sprom.c
1107 +++ b/drivers/bcma/sprom.c
1108 @@ -72,12 +72,12 @@ fail:
1109   * R/W ops.
1110   **************************************************/
1111  
1112 -static void bcma_sprom_read(struct bcma_bus *bus, u16 offset, u16 *sprom)
1113 +static void bcma_sprom_read(struct bcma_bus *bus, u16 offset, u16 *sprom,
1114 +                           size_t words)
1115  {
1116         int i;
1117 -       for (i = 0; i < SSB_SPROMSIZE_WORDS_R4; i++)
1118 -               sprom[i] = bcma_read16(bus->drv_cc.core,
1119 -                                      offset + (i * 2));
1120 +       for (i = 0; i < words; i++)
1121 +               sprom[i] = bcma_read16(bus->drv_cc.core, offset + (i * 2));
1122  }
1123  
1124  /**************************************************
1125 @@ -124,29 +124,29 @@ static inline u8 bcma_crc8(u8 crc, u8 da
1126         return t[crc ^ data];
1127  }
1128  
1129 -static u8 bcma_sprom_crc(const u16 *sprom)
1130 +static u8 bcma_sprom_crc(const u16 *sprom, size_t words)
1131  {
1132         int word;
1133         u8 crc = 0xFF;
1134  
1135 -       for (word = 0; word < SSB_SPROMSIZE_WORDS_R4 - 1; word++) {
1136 +       for (word = 0; word < words - 1; word++) {
1137                 crc = bcma_crc8(crc, sprom[word] & 0x00FF);
1138                 crc = bcma_crc8(crc, (sprom[word] & 0xFF00) >> 8);
1139         }
1140 -       crc = bcma_crc8(crc, sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & 0x00FF);
1141 +       crc = bcma_crc8(crc, sprom[words - 1] & 0x00FF);
1142         crc ^= 0xFF;
1143  
1144         return crc;
1145  }
1146  
1147 -static int bcma_sprom_check_crc(const u16 *sprom)
1148 +static int bcma_sprom_check_crc(const u16 *sprom, size_t words)
1149  {
1150         u8 crc;
1151         u8 expected_crc;
1152         u16 tmp;
1153  
1154 -       crc = bcma_sprom_crc(sprom);
1155 -       tmp = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & SSB_SPROM_REVISION_CRC;
1156 +       crc = bcma_sprom_crc(sprom, words);
1157 +       tmp = sprom[words - 1] & SSB_SPROM_REVISION_CRC;
1158         expected_crc = tmp >> SSB_SPROM_REVISION_CRC_SHIFT;
1159         if (crc != expected_crc)
1160                 return -EPROTO;
1161 @@ -154,21 +154,25 @@ static int bcma_sprom_check_crc(const u1
1162         return 0;
1163  }
1164  
1165 -static int bcma_sprom_valid(const u16 *sprom)
1166 +static int bcma_sprom_valid(struct bcma_bus *bus, const u16 *sprom,
1167 +                           size_t words)
1168  {
1169         u16 revision;
1170         int err;
1171  
1172 -       err = bcma_sprom_check_crc(sprom);
1173 +       err = bcma_sprom_check_crc(sprom, words);
1174         if (err)
1175                 return err;
1176  
1177 -       revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & SSB_SPROM_REVISION_REV;
1178 -       if (revision != 8 && revision != 9) {
1179 +       revision = sprom[words - 1] & SSB_SPROM_REVISION_REV;
1180 +       if (revision != 8 && revision != 9 && revision != 10) {
1181                 pr_err("Unsupported SPROM revision: %d\n", revision);
1182                 return -ENOENT;
1183         }
1184  
1185 +       bus->sprom.revision = revision;
1186 +       bcma_debug(bus, "Found SPROM revision %d\n", revision);
1187 +
1188         return 0;
1189  }
1190  
1191 @@ -197,6 +201,23 @@ static int bcma_sprom_valid(const u16 *s
1192                 SPEX(_field[7], _offset + 14, _mask, _shift);   \
1193         } while (0)
1194  
1195 +static s8 sprom_extract_antgain(const u16 *in, u16 offset, u16 mask, u16 shift)
1196 +{
1197 +       u16 v;
1198 +       u8 gain;
1199 +
1200 +       v = in[SPOFF(offset)];
1201 +       gain = (v & mask) >> shift;
1202 +       if (gain == 0xFF) {
1203 +               gain = 8; /* If unset use 2dBm */
1204 +       } else {
1205 +               /* Q5.2 Fractional part is stored in 0xC0 */
1206 +               gain = ((gain & 0xC0) >> 6) | ((gain & 0x3F) << 2);
1207 +       }
1208 +
1209 +       return (s8)gain;
1210 +}
1211 +
1212  static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
1213  {
1214         u16 v, o;
1215 @@ -208,9 +229,6 @@ static void bcma_sprom_extract_r8(struct
1216         BUILD_BUG_ON(ARRAY_SIZE(pwr_info_offset) !=
1217                         ARRAY_SIZE(bus->sprom.core_pwr_info));
1218  
1219 -       bus->sprom.revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] &
1220 -               SSB_SPROM_REVISION_REV;
1221 -
1222         for (i = 0; i < 3; i++) {
1223                 v = sprom[SPOFF(SSB_SPROM8_IL0MAC) + i];
1224                 *(((__be16 *)bus->sprom.il0mac) + i) = cpu_to_be16(v);
1225 @@ -380,14 +398,22 @@ static void bcma_sprom_extract_r8(struct
1226         SPEX32(ofdm5ghpo, SSB_SPROM8_OFDM5GHPO, ~0, 0);
1227  
1228         /* Extract the antenna gain values. */
1229 -       SPEX(antenna_gain.a0, SSB_SPROM8_AGAIN01,
1230 -            SSB_SPROM8_AGAIN0, SSB_SPROM8_AGAIN0_SHIFT);
1231 -       SPEX(antenna_gain.a1, SSB_SPROM8_AGAIN01,
1232 -            SSB_SPROM8_AGAIN1, SSB_SPROM8_AGAIN1_SHIFT);
1233 -       SPEX(antenna_gain.a2, SSB_SPROM8_AGAIN23,
1234 -            SSB_SPROM8_AGAIN2, SSB_SPROM8_AGAIN2_SHIFT);
1235 -       SPEX(antenna_gain.a3, SSB_SPROM8_AGAIN23,
1236 -            SSB_SPROM8_AGAIN3, SSB_SPROM8_AGAIN3_SHIFT);
1237 +       bus->sprom.antenna_gain.a0 = sprom_extract_antgain(sprom,
1238 +                                                          SSB_SPROM8_AGAIN01,
1239 +                                                          SSB_SPROM8_AGAIN0,
1240 +                                                          SSB_SPROM8_AGAIN0_SHIFT);
1241 +       bus->sprom.antenna_gain.a1 = sprom_extract_antgain(sprom,
1242 +                                                          SSB_SPROM8_AGAIN01,
1243 +                                                          SSB_SPROM8_AGAIN1,
1244 +                                                          SSB_SPROM8_AGAIN1_SHIFT);
1245 +       bus->sprom.antenna_gain.a2 = sprom_extract_antgain(sprom,
1246 +                                                          SSB_SPROM8_AGAIN23,
1247 +                                                          SSB_SPROM8_AGAIN2,
1248 +                                                          SSB_SPROM8_AGAIN2_SHIFT);
1249 +       bus->sprom.antenna_gain.a3 = sprom_extract_antgain(sprom,
1250 +                                                          SSB_SPROM8_AGAIN23,
1251 +                                                          SSB_SPROM8_AGAIN3,
1252 +                                                          SSB_SPROM8_AGAIN3_SHIFT);
1253  
1254         SPEX(leddc_on_time, SSB_SPROM8_LEDDC, SSB_SPROM8_LEDDC_ON,
1255              SSB_SPROM8_LEDDC_ON_SHIFT);
1256 @@ -502,12 +528,14 @@ static bool bcma_sprom_onchip_available(
1257         case BCMA_CHIP_ID_BCM4331:
1258                 present = chip_status & BCMA_CC_CHIPST_4331_OTP_PRESENT;
1259                 break;
1260 -
1261 +       case BCMA_CHIP_ID_BCM43142:
1262         case BCMA_CHIP_ID_BCM43224:
1263         case BCMA_CHIP_ID_BCM43225:
1264                 /* for these chips OTP is always available */
1265                 present = true;
1266                 break;
1267 +       case BCMA_CHIP_ID_BCM43131:
1268 +       case BCMA_CHIP_ID_BCM43217:
1269         case BCMA_CHIP_ID_BCM43227:
1270         case BCMA_CHIP_ID_BCM43228:
1271         case BCMA_CHIP_ID_BCM43428:
1272 @@ -550,7 +578,9 @@ int bcma_sprom_get(struct bcma_bus *bus)
1273  {
1274         u16 offset = BCMA_CC_SPROM;
1275         u16 *sprom;
1276 -       int err = 0;
1277 +       size_t sprom_sizes[] = { SSB_SPROMSIZE_WORDS_R4,
1278 +                                SSB_SPROMSIZE_WORDS_R10, };
1279 +       int i, err = 0;
1280  
1281         if (!bus->drv_cc.core)
1282                 return -EOPNOTSUPP;
1283 @@ -579,32 +609,37 @@ int bcma_sprom_get(struct bcma_bus *bus)
1284                 }
1285         }
1286  
1287 -       sprom = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16),
1288 -                       GFP_KERNEL);
1289 -       if (!sprom)
1290 -               return -ENOMEM;
1291 -
1292         if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4331 ||
1293             bus->chipinfo.id == BCMA_CHIP_ID_BCM43431)
1294                 bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, false);
1295  
1296         bcma_debug(bus, "SPROM offset 0x%x\n", offset);
1297 -       bcma_sprom_read(bus, offset, sprom);
1298 +       for (i = 0; i < ARRAY_SIZE(sprom_sizes); i++) {
1299 +               size_t words = sprom_sizes[i];
1300 +
1301 +               sprom = kcalloc(words, sizeof(u16), GFP_KERNEL);
1302 +               if (!sprom)
1303 +                       return -ENOMEM;
1304 +
1305 +               bcma_sprom_read(bus, offset, sprom, words);
1306 +               err = bcma_sprom_valid(bus, sprom, words);
1307 +               if (!err)
1308 +                       break;
1309 +
1310 +               kfree(sprom);
1311 +       }
1312  
1313         if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4331 ||
1314             bus->chipinfo.id == BCMA_CHIP_ID_BCM43431)
1315                 bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, true);
1316  
1317 -       err = bcma_sprom_valid(sprom);
1318         if (err) {
1319 -               bcma_warn(bus, "invalid sprom read from the PCIe card, try to use fallback sprom\n");
1320 +               bcma_warn(bus, "Invalid SPROM read from the PCIe card, trying to use fallback SPROM\n");
1321                 err = bcma_fill_sprom_with_fallback(bus, &bus->sprom);
1322 -               goto out;
1323 +       } else {
1324 +               bcma_sprom_extract_r8(bus, sprom);
1325 +               kfree(sprom);
1326         }
1327  
1328 -       bcma_sprom_extract_r8(bus, sprom);
1329 -
1330 -out:
1331 -       kfree(sprom);
1332         return err;
1333  }
1334 --- a/include/linux/bcma/bcma.h
1335 +++ b/include/linux/bcma/bcma.h
1336 @@ -6,6 +6,7 @@
1337  
1338  #include <linux/bcma/bcma_driver_chipcommon.h>
1339  #include <linux/bcma/bcma_driver_pci.h>
1340 +#include <linux/bcma/bcma_driver_pcie2.h>
1341  #include <linux/bcma/bcma_driver_mips.h>
1342  #include <linux/bcma/bcma_driver_gmac_cmn.h>
1343  #include <linux/ssb/ssb.h> /* SPROM sharing */
1344 @@ -72,7 +73,19 @@ struct bcma_host_ops {
1345  /* Core-ID values. */
1346  #define BCMA_CORE_OOB_ROUTER           0x367   /* Out of band */
1347  #define BCMA_CORE_4706_CHIPCOMMON      0x500
1348 +#define BCMA_CORE_NS_PCIEG2            0x501
1349 +#define BCMA_CORE_NS_DMA               0x502
1350 +#define BCMA_CORE_NS_SDIO3             0x503
1351 +#define BCMA_CORE_NS_USB20             0x504
1352 +#define BCMA_CORE_NS_USB30             0x505
1353 +#define BCMA_CORE_NS_A9JTAG            0x506
1354 +#define BCMA_CORE_NS_DDR23             0x507
1355 +#define BCMA_CORE_NS_ROM               0x508
1356 +#define BCMA_CORE_NS_NAND              0x509
1357 +#define BCMA_CORE_NS_QSPI              0x50A
1358 +#define BCMA_CORE_NS_CHIPCOMMON_B      0x50B
1359  #define BCMA_CORE_4706_SOC_RAM         0x50E
1360 +#define BCMA_CORE_ARMCA9               0x510
1361  #define BCMA_CORE_4706_MAC_GBIT                0x52D
1362  #define BCMA_CORE_AMEMC                        0x52E   /* DDR1/2 memory controller core */
1363  #define BCMA_CORE_ALTA                 0x534   /* I2S core */
1364 @@ -144,6 +157,10 @@ struct bcma_host_ops {
1365  
1366  /* Chip IDs of PCIe devices */
1367  #define BCMA_CHIP_ID_BCM4313   0x4313
1368 +#define BCMA_CHIP_ID_BCM43142  43142
1369 +#define BCMA_CHIP_ID_BCM43131  43131
1370 +#define BCMA_CHIP_ID_BCM43217  43217
1371 +#define BCMA_CHIP_ID_BCM43222  43222
1372  #define BCMA_CHIP_ID_BCM43224  43224
1373  #define  BCMA_PKG_ID_BCM43224_FAB_CSM  0x8
1374  #define  BCMA_PKG_ID_BCM43224_FAB_SMIC 0xa
1375 @@ -176,6 +193,11 @@ struct bcma_host_ops {
1376  #define  BCMA_PKG_ID_BCM5357   11
1377  #define BCMA_CHIP_ID_BCM53572  53572
1378  #define  BCMA_PKG_ID_BCM47188  9
1379 +#define BCMA_CHIP_ID_BCM4707   53010
1380 +#define  BCMA_PKG_ID_BCM4707   1
1381 +#define  BCMA_PKG_ID_BCM4708   2
1382 +#define  BCMA_PKG_ID_BCM4709   0
1383 +#define BCMA_CHIP_ID_BCM53018  53018
1384  
1385  /* Board types (on PCI usually equals to the subsystem dev id) */
1386  /* BCM4313 */
1387 @@ -315,6 +337,7 @@ struct bcma_bus {
1388  
1389         struct bcma_drv_cc drv_cc;
1390         struct bcma_drv_pci drv_pci[2];
1391 +       struct bcma_drv_pcie2 drv_pcie2;
1392         struct bcma_drv_mips drv_mips;
1393         struct bcma_drv_gmac_cmn drv_gmac_cmn;
1394  
1395 @@ -400,7 +423,14 @@ static inline void bcma_maskset16(struct
1396         bcma_write16(cc, offset, (bcma_read16(cc, offset) & mask) | set);
1397  }
1398  
1399 -extern struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid);
1400 +extern struct bcma_device *bcma_find_core_unit(struct bcma_bus *bus, u16 coreid,
1401 +                                              u8 unit);
1402 +static inline struct bcma_device *bcma_find_core(struct bcma_bus *bus,
1403 +                                                u16 coreid)
1404 +{
1405 +       return bcma_find_core_unit(bus, coreid, 0);
1406 +}
1407 +
1408  extern bool bcma_core_is_enabled(struct bcma_device *core);
1409  extern void bcma_core_disable(struct bcma_device *core, u32 flags);
1410  extern int bcma_core_enable(struct bcma_device *core, u32 flags);
1411 --- a/include/linux/bcma/bcma_driver_chipcommon.h
1412 +++ b/include/linux/bcma/bcma_driver_chipcommon.h
1413 @@ -330,6 +330,8 @@
1414  #define BCMA_CC_PMU_CAP                        0x0604 /* PMU capabilities */
1415  #define  BCMA_CC_PMU_CAP_REVISION      0x000000FF /* Revision mask */
1416  #define BCMA_CC_PMU_STAT               0x0608 /* PMU status */
1417 +#define  BCMA_CC_PMU_STAT_EXT_LPO_AVAIL        0x00000100
1418 +#define  BCMA_CC_PMU_STAT_WDRESET      0x00000080
1419  #define  BCMA_CC_PMU_STAT_INTPEND      0x00000040 /* Interrupt pending */
1420  #define  BCMA_CC_PMU_STAT_SBCLKST      0x00000030 /* Backplane clock status? */
1421  #define  BCMA_CC_PMU_STAT_HAVEALP      0x00000008 /* ALP available */
1422 @@ -355,6 +357,11 @@
1423  #define BCMA_CC_REGCTL_DATA            0x065C
1424  #define BCMA_CC_PLLCTL_ADDR            0x0660
1425  #define BCMA_CC_PLLCTL_DATA            0x0664
1426 +#define BCMA_CC_PMU_STRAPOPT           0x0668 /* (corerev >= 28) */
1427 +#define BCMA_CC_PMU_XTAL_FREQ          0x066C /* (pmurev >= 10) */
1428 +#define  BCMA_CC_PMU_XTAL_FREQ_ILPCTL_MASK     0x00001FFF
1429 +#define  BCMA_CC_PMU_XTAL_FREQ_MEASURE_MASK    0x80000000
1430 +#define  BCMA_CC_PMU_XTAL_FREQ_MEASURE_SHIFT   31
1431  #define BCMA_CC_SPROM                  0x0800 /* SPROM beginning */
1432  /* NAND flash MLC controller registers (corerev >= 38) */
1433  #define BCMA_CC_NAND_REVISION          0x0C00
1434 @@ -435,6 +442,23 @@
1435  #define  BCMA_CC_PMU6_4706_PROC_NDIV_MODE_MASK 0x00000007
1436  #define  BCMA_CC_PMU6_4706_PROC_NDIV_MODE_SHIFT        0
1437  
1438 +/* PMU rev 15 */
1439 +#define BCMA_CC_PMU15_PLL_PLLCTL0      0
1440 +#define  BCMA_CC_PMU15_PLL_PC0_CLKSEL_MASK     0x00000003
1441 +#define  BCMA_CC_PMU15_PLL_PC0_CLKSEL_SHIFT    0
1442 +#define  BCMA_CC_PMU15_PLL_PC0_FREQTGT_MASK    0x003FFFFC
1443 +#define  BCMA_CC_PMU15_PLL_PC0_FREQTGT_SHIFT   2
1444 +#define  BCMA_CC_PMU15_PLL_PC0_PRESCALE_MASK   0x00C00000
1445 +#define  BCMA_CC_PMU15_PLL_PC0_PRESCALE_SHIFT  22
1446 +#define  BCMA_CC_PMU15_PLL_PC0_KPCTRL_MASK     0x07000000
1447 +#define  BCMA_CC_PMU15_PLL_PC0_KPCTRL_SHIFT    24
1448 +#define  BCMA_CC_PMU15_PLL_PC0_FCNTCTRL_MASK   0x38000000
1449 +#define  BCMA_CC_PMU15_PLL_PC0_FCNTCTRL_SHIFT  27
1450 +#define  BCMA_CC_PMU15_PLL_PC0_FDCMODE_MASK    0x40000000
1451 +#define  BCMA_CC_PMU15_PLL_PC0_FDCMODE_SHIFT   30
1452 +#define  BCMA_CC_PMU15_PLL_PC0_CTRLBIAS_MASK   0x80000000
1453 +#define  BCMA_CC_PMU15_PLL_PC0_CTRLBIAS_SHIFT  31
1454 +
1455  /* ALP clock on pre-PMU chips */
1456  #define BCMA_CC_PMU_ALP_CLOCK          20000000
1457  /* HT clock for systems with PMU-enabled chipcommon */
1458 @@ -507,6 +531,37 @@
1459  #define BCMA_CHIPCTL_5357_I2S_PINS_ENABLE      BIT(18)
1460  #define BCMA_CHIPCTL_5357_I2CSPI_PINS_ENABLE   BIT(19)
1461  
1462 +#define BCMA_RES_4314_LPLDO_PU                 BIT(0)
1463 +#define BCMA_RES_4314_PMU_SLEEP_DIS            BIT(1)
1464 +#define BCMA_RES_4314_PMU_BG_PU                        BIT(2)
1465 +#define BCMA_RES_4314_CBUCK_LPOM_PU            BIT(3)
1466 +#define BCMA_RES_4314_CBUCK_PFM_PU             BIT(4)
1467 +#define BCMA_RES_4314_CLDO_PU                  BIT(5)
1468 +#define BCMA_RES_4314_LPLDO2_LVM               BIT(6)
1469 +#define BCMA_RES_4314_WL_PMU_PU                        BIT(7)
1470 +#define BCMA_RES_4314_LNLDO_PU                 BIT(8)
1471 +#define BCMA_RES_4314_LDO3P3_PU                        BIT(9)
1472 +#define BCMA_RES_4314_OTP_PU                   BIT(10)
1473 +#define BCMA_RES_4314_XTAL_PU                  BIT(11)
1474 +#define BCMA_RES_4314_WL_PWRSW_PU              BIT(12)
1475 +#define BCMA_RES_4314_LQ_AVAIL                 BIT(13)
1476 +#define BCMA_RES_4314_LOGIC_RET                        BIT(14)
1477 +#define BCMA_RES_4314_MEM_SLEEP                        BIT(15)
1478 +#define BCMA_RES_4314_MACPHY_RET               BIT(16)
1479 +#define BCMA_RES_4314_WL_CORE_READY            BIT(17)
1480 +#define BCMA_RES_4314_ILP_REQ                  BIT(18)
1481 +#define BCMA_RES_4314_ALP_AVAIL                        BIT(19)
1482 +#define BCMA_RES_4314_MISC_PWRSW_PU            BIT(20)
1483 +#define BCMA_RES_4314_SYNTH_PWRSW_PU           BIT(21)
1484 +#define BCMA_RES_4314_RX_PWRSW_PU              BIT(22)
1485 +#define BCMA_RES_4314_RADIO_PU                 BIT(23)
1486 +#define BCMA_RES_4314_VCO_LDO_PU               BIT(24)
1487 +#define BCMA_RES_4314_AFE_LDO_PU               BIT(25)
1488 +#define BCMA_RES_4314_RX_LDO_PU                        BIT(26)
1489 +#define BCMA_RES_4314_TX_LDO_PU                        BIT(27)
1490 +#define BCMA_RES_4314_HT_AVAIL                 BIT(28)
1491 +#define BCMA_RES_4314_MACPHY_CLK_AVAIL         BIT(29)
1492 +
1493  /* Data for the PMU, if available.
1494   * Check availability with ((struct bcma_chipcommon)->capabilities & BCMA_CC_CAP_PMU)
1495   */
1496 @@ -585,6 +640,7 @@ struct bcma_drv_cc {
1497         spinlock_t gpio_lock;
1498  #ifdef CONFIG_BCMA_DRIVER_GPIO
1499         struct gpio_chip gpio;
1500 +       struct irq_domain *irq_domain;
1501  #endif
1502  };
1503  
1504 --- a/include/linux/bcma/bcma_driver_pci.h
1505 +++ b/include/linux/bcma/bcma_driver_pci.h
1506 @@ -181,10 +181,31 @@ struct pci_dev;
1507  
1508  #define BCMA_CORE_PCI_CFG_DEVCTRL              0xd8
1509  
1510 +#define BCMA_CORE_PCI_
1511 +
1512 +/* MDIO devices (SERDES modules) */
1513 +#define BCMA_CORE_PCI_MDIO_IEEE0               0x000
1514 +#define BCMA_CORE_PCI_MDIO_IEEE1               0x001
1515 +#define BCMA_CORE_PCI_MDIO_BLK0                        0x800
1516 +#define BCMA_CORE_PCI_MDIO_BLK1                        0x801
1517 +#define  BCMA_CORE_PCI_MDIO_BLK1_MGMT0         0x16
1518 +#define  BCMA_CORE_PCI_MDIO_BLK1_MGMT1         0x17
1519 +#define  BCMA_CORE_PCI_MDIO_BLK1_MGMT2         0x18
1520 +#define  BCMA_CORE_PCI_MDIO_BLK1_MGMT3         0x19
1521 +#define  BCMA_CORE_PCI_MDIO_BLK1_MGMT4         0x1A
1522 +#define BCMA_CORE_PCI_MDIO_BLK2                        0x802
1523 +#define BCMA_CORE_PCI_MDIO_BLK3                        0x803
1524 +#define BCMA_CORE_PCI_MDIO_BLK4                        0x804
1525 +#define BCMA_CORE_PCI_MDIO_TXPLL               0x808   /* TXPLL register block idx */
1526 +#define BCMA_CORE_PCI_MDIO_TXCTRL0             0x820
1527 +#define BCMA_CORE_PCI_MDIO_SERDESID            0x831
1528 +#define BCMA_CORE_PCI_MDIO_RXCTRL0             0x840
1529 +
1530  /* PCIE Root Capability Register bits (Host mode only) */
1531  #define BCMA_CORE_PCI_RC_CRS_VISIBILITY                0x0001
1532  
1533  struct bcma_drv_pci;
1534 +struct bcma_bus;
1535  
1536  #ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
1537  struct bcma_drv_pci_host {
1538 @@ -219,7 +240,9 @@ struct bcma_drv_pci {
1539  extern void bcma_core_pci_init(struct bcma_drv_pci *pc);
1540  extern int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc,
1541                                  struct bcma_device *core, bool enable);
1542 -extern void bcma_core_pci_extend_L1timer(struct bcma_drv_pci *pc, bool extend);
1543 +extern void bcma_core_pci_up(struct bcma_bus *bus);
1544 +extern void bcma_core_pci_down(struct bcma_bus *bus);
1545 +extern void bcma_core_pci_power_save(struct bcma_bus *bus, bool up);
1546  
1547  extern int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev);
1548  extern int bcma_core_pci_plat_dev_init(struct pci_dev *dev);
1549 --- /dev/null
1550 +++ b/include/linux/bcma/bcma_driver_pcie2.h
1551 @@ -0,0 +1,158 @@
1552 +#ifndef LINUX_BCMA_DRIVER_PCIE2_H_
1553 +#define LINUX_BCMA_DRIVER_PCIE2_H_
1554 +
1555 +#define BCMA_CORE_PCIE2_CLK_CONTROL            0x0000
1556 +#define  PCIE2_CLKC_RST_OE                     0x0001 /* When set, drives PCI_RESET out to pin */
1557 +#define  PCIE2_CLKC_RST                                0x0002 /* Value driven out to pin */
1558 +#define  PCIE2_CLKC_SPERST                     0x0004 /* SurvivePeRst */
1559 +#define  PCIE2_CLKC_DISABLE_L1CLK_GATING       0x0010
1560 +#define  PCIE2_CLKC_DLYPERST                   0x0100 /* Delay PeRst to CoE Core */
1561 +#define  PCIE2_CLKC_DISSPROMLD                 0x0200 /* DisableSpromLoadOnPerst */
1562 +#define  PCIE2_CLKC_WAKE_MODE_L2               0x1000 /* Wake on L2 */
1563 +#define BCMA_CORE_PCIE2_RC_PM_CONTROL          0x0004
1564 +#define BCMA_CORE_PCIE2_RC_PM_STATUS           0x0008
1565 +#define BCMA_CORE_PCIE2_EP_PM_CONTROL          0x000C
1566 +#define BCMA_CORE_PCIE2_EP_PM_STATUS           0x0010
1567 +#define BCMA_CORE_PCIE2_EP_LTR_CONTROL         0x0014
1568 +#define BCMA_CORE_PCIE2_EP_LTR_STATUS          0x0018
1569 +#define BCMA_CORE_PCIE2_EP_OBFF_STATUS         0x001C
1570 +#define BCMA_CORE_PCIE2_PCIE_ERR_STATUS                0x0020
1571 +#define BCMA_CORE_PCIE2_RC_AXI_CONFIG          0x0100
1572 +#define BCMA_CORE_PCIE2_EP_AXI_CONFIG          0x0104
1573 +#define BCMA_CORE_PCIE2_RXDEBUG_STATUS0                0x0108
1574 +#define BCMA_CORE_PCIE2_RXDEBUG_CONTROL0       0x010C
1575 +#define BCMA_CORE_PCIE2_CONFIGINDADDR          0x0120
1576 +#define BCMA_CORE_PCIE2_CONFIGINDDATA          0x0124
1577 +#define BCMA_CORE_PCIE2_MDIOCONTROL            0x0128
1578 +#define BCMA_CORE_PCIE2_MDIOWRDATA             0x012C
1579 +#define BCMA_CORE_PCIE2_MDIORDDATA             0x0130
1580 +#define BCMA_CORE_PCIE2_DATAINTF               0x0180
1581 +#define BCMA_CORE_PCIE2_D2H_INTRLAZY_0         0x0188
1582 +#define BCMA_CORE_PCIE2_H2D_INTRLAZY_0         0x018c
1583 +#define BCMA_CORE_PCIE2_H2D_INTSTAT_0          0x0190
1584 +#define BCMA_CORE_PCIE2_H2D_INTMASK_0          0x0194
1585 +#define BCMA_CORE_PCIE2_D2H_INTSTAT_0          0x0198
1586 +#define BCMA_CORE_PCIE2_D2H_INTMASK_0          0x019c
1587 +#define BCMA_CORE_PCIE2_LTR_STATE              0x01A0 /* Latency Tolerance Reporting */
1588 +#define  PCIE2_LTR_ACTIVE                      2
1589 +#define  PCIE2_LTR_ACTIVE_IDLE                 1
1590 +#define  PCIE2_LTR_SLEEP                       0
1591 +#define  PCIE2_LTR_FINAL_MASK                  0x300
1592 +#define  PCIE2_LTR_FINAL_SHIFT                 8
1593 +#define BCMA_CORE_PCIE2_PWR_INT_STATUS         0x01A4
1594 +#define BCMA_CORE_PCIE2_PWR_INT_MASK           0x01A8
1595 +#define BCMA_CORE_PCIE2_CFG_ADDR               0x01F8
1596 +#define BCMA_CORE_PCIE2_CFG_DATA               0x01FC
1597 +#define BCMA_CORE_PCIE2_SYS_EQ_PAGE            0x0200
1598 +#define BCMA_CORE_PCIE2_SYS_MSI_PAGE           0x0204
1599 +#define BCMA_CORE_PCIE2_SYS_MSI_INTREN         0x0208
1600 +#define BCMA_CORE_PCIE2_SYS_MSI_CTRL0          0x0210
1601 +#define BCMA_CORE_PCIE2_SYS_MSI_CTRL1          0x0214
1602 +#define BCMA_CORE_PCIE2_SYS_MSI_CTRL2          0x0218
1603 +#define BCMA_CORE_PCIE2_SYS_MSI_CTRL3          0x021C
1604 +#define BCMA_CORE_PCIE2_SYS_MSI_CTRL4          0x0220
1605 +#define BCMA_CORE_PCIE2_SYS_MSI_CTRL5          0x0224
1606 +#define BCMA_CORE_PCIE2_SYS_EQ_HEAD0           0x0250
1607 +#define BCMA_CORE_PCIE2_SYS_EQ_TAIL0           0x0254
1608 +#define BCMA_CORE_PCIE2_SYS_EQ_HEAD1           0x0258
1609 +#define BCMA_CORE_PCIE2_SYS_EQ_TAIL1           0x025C
1610 +#define BCMA_CORE_PCIE2_SYS_EQ_HEAD2           0x0260
1611 +#define BCMA_CORE_PCIE2_SYS_EQ_TAIL2           0x0264
1612 +#define BCMA_CORE_PCIE2_SYS_EQ_HEAD3           0x0268
1613 +#define BCMA_CORE_PCIE2_SYS_EQ_TAIL3           0x026C
1614 +#define BCMA_CORE_PCIE2_SYS_EQ_HEAD4           0x0270
1615 +#define BCMA_CORE_PCIE2_SYS_EQ_TAIL4           0x0274
1616 +#define BCMA_CORE_PCIE2_SYS_EQ_HEAD5           0x0278
1617 +#define BCMA_CORE_PCIE2_SYS_EQ_TAIL5           0x027C
1618 +#define BCMA_CORE_PCIE2_SYS_RC_INTX_EN         0x0330
1619 +#define BCMA_CORE_PCIE2_SYS_RC_INTX_CSR                0x0334
1620 +#define BCMA_CORE_PCIE2_SYS_MSI_REQ            0x0340
1621 +#define BCMA_CORE_PCIE2_SYS_HOST_INTR_EN       0x0344
1622 +#define BCMA_CORE_PCIE2_SYS_HOST_INTR_CSR      0x0348
1623 +#define BCMA_CORE_PCIE2_SYS_HOST_INTR0         0x0350
1624 +#define BCMA_CORE_PCIE2_SYS_HOST_INTR1         0x0354
1625 +#define BCMA_CORE_PCIE2_SYS_HOST_INTR2         0x0358
1626 +#define BCMA_CORE_PCIE2_SYS_HOST_INTR3         0x035C
1627 +#define BCMA_CORE_PCIE2_SYS_EP_INT_EN0         0x0360
1628 +#define BCMA_CORE_PCIE2_SYS_EP_INT_EN1         0x0364
1629 +#define BCMA_CORE_PCIE2_SYS_EP_INT_CSR0                0x0370
1630 +#define BCMA_CORE_PCIE2_SYS_EP_INT_CSR1                0x0374
1631 +#define BCMA_CORE_PCIE2_SPROM(wordoffset)      (0x0800 + ((wordoffset) * 2))
1632 +#define BCMA_CORE_PCIE2_FUNC0_IMAP0_0          0x0C00
1633 +#define BCMA_CORE_PCIE2_FUNC0_IMAP0_1          0x0C04
1634 +#define BCMA_CORE_PCIE2_FUNC0_IMAP0_2          0x0C08
1635 +#define BCMA_CORE_PCIE2_FUNC0_IMAP0_3          0x0C0C
1636 +#define BCMA_CORE_PCIE2_FUNC0_IMAP0_4          0x0C10
1637 +#define BCMA_CORE_PCIE2_FUNC0_IMAP0_5          0x0C14
1638 +#define BCMA_CORE_PCIE2_FUNC0_IMAP0_6          0x0C18
1639 +#define BCMA_CORE_PCIE2_FUNC0_IMAP0_7          0x0C1C
1640 +#define BCMA_CORE_PCIE2_FUNC1_IMAP0_0          0x0C20
1641 +#define BCMA_CORE_PCIE2_FUNC1_IMAP0_1          0x0C24
1642 +#define BCMA_CORE_PCIE2_FUNC1_IMAP0_2          0x0C28
1643 +#define BCMA_CORE_PCIE2_FUNC1_IMAP0_3          0x0C2C
1644 +#define BCMA_CORE_PCIE2_FUNC1_IMAP0_4          0x0C30
1645 +#define BCMA_CORE_PCIE2_FUNC1_IMAP0_5          0x0C34
1646 +#define BCMA_CORE_PCIE2_FUNC1_IMAP0_6          0x0C38
1647 +#define BCMA_CORE_PCIE2_FUNC1_IMAP0_7          0x0C3C
1648 +#define BCMA_CORE_PCIE2_FUNC0_IMAP1            0x0C80
1649 +#define BCMA_CORE_PCIE2_FUNC1_IMAP1            0x0C88
1650 +#define BCMA_CORE_PCIE2_FUNC0_IMAP2            0x0CC0
1651 +#define BCMA_CORE_PCIE2_FUNC1_IMAP2            0x0CC8
1652 +#define BCMA_CORE_PCIE2_IARR0_LOWER            0x0D00
1653 +#define BCMA_CORE_PCIE2_IARR0_UPPER            0x0D04
1654 +#define BCMA_CORE_PCIE2_IARR1_LOWER            0x0D08
1655 +#define BCMA_CORE_PCIE2_IARR1_UPPER            0x0D0C
1656 +#define BCMA_CORE_PCIE2_IARR2_LOWER            0x0D10
1657 +#define BCMA_CORE_PCIE2_IARR2_UPPER            0x0D14
1658 +#define BCMA_CORE_PCIE2_OARR0                  0x0D20
1659 +#define BCMA_CORE_PCIE2_OARR1                  0x0D28
1660 +#define BCMA_CORE_PCIE2_OARR2                  0x0D30
1661 +#define BCMA_CORE_PCIE2_OMAP0_LOWER            0x0D40
1662 +#define BCMA_CORE_PCIE2_OMAP0_UPPER            0x0D44
1663 +#define BCMA_CORE_PCIE2_OMAP1_LOWER            0x0D48
1664 +#define BCMA_CORE_PCIE2_OMAP1_UPPER            0x0D4C
1665 +#define BCMA_CORE_PCIE2_OMAP2_LOWER            0x0D50
1666 +#define BCMA_CORE_PCIE2_OMAP2_UPPER            0x0D54
1667 +#define BCMA_CORE_PCIE2_FUNC1_IARR1_SIZE       0x0D58
1668 +#define BCMA_CORE_PCIE2_FUNC1_IARR2_SIZE       0x0D5C
1669 +#define BCMA_CORE_PCIE2_MEM_CONTROL            0x0F00
1670 +#define BCMA_CORE_PCIE2_MEM_ECC_ERRLOG0                0x0F04
1671 +#define BCMA_CORE_PCIE2_MEM_ECC_ERRLOG1                0x0F08
1672 +#define BCMA_CORE_PCIE2_LINK_STATUS            0x0F0C
1673 +#define BCMA_CORE_PCIE2_STRAP_STATUS           0x0F10
1674 +#define BCMA_CORE_PCIE2_RESET_STATUS           0x0F14
1675 +#define BCMA_CORE_PCIE2_RESETEN_IN_LINKDOWN    0x0F18
1676 +#define BCMA_CORE_PCIE2_MISC_INTR_EN           0x0F1C
1677 +#define BCMA_CORE_PCIE2_TX_DEBUG_CFG           0x0F20
1678 +#define BCMA_CORE_PCIE2_MISC_CONFIG            0x0F24
1679 +#define BCMA_CORE_PCIE2_MISC_STATUS            0x0F28
1680 +#define BCMA_CORE_PCIE2_INTR_EN                        0x0F30
1681 +#define BCMA_CORE_PCIE2_INTR_CLEAR             0x0F34
1682 +#define BCMA_CORE_PCIE2_INTR_STATUS            0x0F38
1683 +
1684 +/* PCIE gen2 config regs */
1685 +#define PCIE2_INTSTATUS                                0x090
1686 +#define PCIE2_INTMASK                          0x094
1687 +#define PCIE2_SBMBX                            0x098
1688 +
1689 +#define PCIE2_PMCR_REFUP                       0x1814 /* Trefup time */
1690 +
1691 +#define PCIE2_CAP_DEVSTSCTRL2_OFFSET           0xD4
1692 +#define PCIE2_CAP_DEVSTSCTRL2_LTRENAB          0x400
1693 +#define PCIE2_PVT_REG_PM_CLK_PERIOD            0x184c
1694 +
1695 +struct bcma_drv_pcie2 {
1696 +       struct bcma_device *core;
1697 +};
1698 +
1699 +#define pcie2_read16(pcie2, offset)            bcma_read16((pcie2)->core, offset)
1700 +#define pcie2_read32(pcie2, offset)            bcma_read32((pcie2)->core, offset)
1701 +#define pcie2_write16(pcie2, offset, val)      bcma_write16((pcie2)->core, offset, val)
1702 +#define pcie2_write32(pcie2, offset, val)      bcma_write32((pcie2)->core, offset, val)
1703 +
1704 +#define pcie2_set32(pcie2, offset, set)                bcma_set32((pcie2)->core, offset, set)
1705 +#define pcie2_mask32(pcie2, offset, mask)      bcma_mask32((pcie2)->core, offset, mask)
1706 +
1707 +void bcma_core_pcie2_init(struct bcma_drv_pcie2 *pcie2);
1708 +
1709 +#endif /* LINUX_BCMA_DRIVER_PCIE2_H_ */
1710 --- a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c
1711 +++ b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c
1712 @@ -679,27 +679,6 @@ bool ai_clkctl_cc(struct si_pub *sih, en
1713         return mode == BCMA_CLKMODE_FAST;
1714  }
1715  
1716 -void ai_pci_up(struct si_pub *sih)
1717 -{
1718 -       struct si_info *sii;
1719 -
1720 -       sii = container_of(sih, struct si_info, pub);
1721 -
1722 -       if (sii->icbus->hosttype == BCMA_HOSTTYPE_PCI)
1723 -               bcma_core_pci_extend_L1timer(&sii->icbus->drv_pci[0], true);
1724 -}
1725 -
1726 -/* Unconfigure and/or apply various WARs when going down */
1727 -void ai_pci_down(struct si_pub *sih)
1728 -{
1729 -       struct si_info *sii;
1730 -
1731 -       sii = container_of(sih, struct si_info, pub);
1732 -
1733 -       if (sii->icbus->hosttype == BCMA_HOSTTYPE_PCI)
1734 -               bcma_core_pci_extend_L1timer(&sii->icbus->drv_pci[0], false);
1735 -}
1736 -
1737  /* Enable BT-COEX & Ex-PA for 4313 */
1738  void ai_epa_4313war(struct si_pub *sih)
1739  {
1740 --- a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h
1741 +++ b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h
1742 @@ -183,9 +183,6 @@ extern u16 ai_clkctl_fast_pwrup_delay(st
1743  extern bool ai_clkctl_cc(struct si_pub *sih, enum bcma_clkmode mode);
1744  extern bool ai_deviceremoved(struct si_pub *sih);
1745  
1746 -extern void ai_pci_down(struct si_pub *sih);
1747 -extern void ai_pci_up(struct si_pub *sih);
1748 -
1749  /* Enable Ex-PA for 4313 */
1750  extern void ai_epa_4313war(struct si_pub *sih);
1751  
1752 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
1753 +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
1754 @@ -4667,7 +4667,7 @@ static int brcms_b_attach(struct brcms_c
1755         brcms_c_coredisable(wlc_hw);
1756  
1757         /* Match driver "down" state */
1758 -       ai_pci_down(wlc_hw->sih);
1759 +       bcma_core_pci_down(wlc_hw->d11core->bus);
1760  
1761         /* turn off pll and xtal to match driver "down" state */
1762         brcms_b_xtal(wlc_hw, OFF);
1763 @@ -5010,12 +5010,12 @@ static int brcms_b_up_prep(struct brcms_
1764          */
1765         if (brcms_b_radio_read_hwdisabled(wlc_hw)) {
1766                 /* put SB PCI in down state again */
1767 -               ai_pci_down(wlc_hw->sih);
1768 +               bcma_core_pci_down(wlc_hw->d11core->bus);
1769                 brcms_b_xtal(wlc_hw, OFF);
1770                 return -ENOMEDIUM;
1771         }
1772  
1773 -       ai_pci_up(wlc_hw->sih);
1774 +       bcma_core_pci_up(wlc_hw->d11core->bus);
1775  
1776         /* reset the d11 core */
1777         brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS);
1778 @@ -5212,7 +5212,7 @@ static int brcms_b_down_finish(struct br
1779  
1780                 /* turn off primary xtal and pll */
1781                 if (!wlc_hw->noreset) {
1782 -                       ai_pci_down(wlc_hw->sih);
1783 +                       bcma_core_pci_down(wlc_hw->d11core->bus);
1784                         brcms_b_xtal(wlc_hw, OFF);
1785                 }
1786         }
1787 --- a/drivers/bcma/driver_mips.c
1788 +++ b/drivers/bcma/driver_mips.c
1789 @@ -21,6 +21,14 @@
1790  #include <linux/serial_reg.h>
1791  #include <linux/time.h>
1792  
1793 +enum bcma_boot_dev {
1794 +       BCMA_BOOT_DEV_UNK = 0,
1795 +       BCMA_BOOT_DEV_ROM,
1796 +       BCMA_BOOT_DEV_PARALLEL,
1797 +       BCMA_BOOT_DEV_SERIAL,
1798 +       BCMA_BOOT_DEV_NAND,
1799 +};
1800 +
1801  static const char * const part_probes[] = { "bcm47xxpart", NULL };
1802  
1803  static struct physmap_flash_data bcma_pflash_data = {
1804 @@ -229,11 +237,51 @@ u32 bcma_cpu_clock(struct bcma_drv_mips
1805  }
1806  EXPORT_SYMBOL(bcma_cpu_clock);
1807  
1808 +static enum bcma_boot_dev bcma_boot_dev(struct bcma_bus *bus)
1809 +{
1810 +       struct bcma_drv_cc *cc = &bus->drv_cc;
1811 +       u8 cc_rev = cc->core->id.rev;
1812 +
1813 +       if (cc_rev == 42) {
1814 +               struct bcma_device *core;
1815 +
1816 +               core = bcma_find_core(bus, BCMA_CORE_NS_ROM);
1817 +               if (core) {
1818 +                       switch (bcma_aread32(core, BCMA_IOST) &
1819 +                               BCMA_NS_ROM_IOST_BOOT_DEV_MASK) {
1820 +                       case BCMA_NS_ROM_IOST_BOOT_DEV_NOR:
1821 +                               return BCMA_BOOT_DEV_SERIAL;
1822 +                       case BCMA_NS_ROM_IOST_BOOT_DEV_NAND:
1823 +                               return BCMA_BOOT_DEV_NAND;
1824 +                       case BCMA_NS_ROM_IOST_BOOT_DEV_ROM:
1825 +                       default:
1826 +                               return BCMA_BOOT_DEV_ROM;
1827 +                       }
1828 +               }
1829 +       } else {
1830 +               if (cc_rev == 38) {
1831 +                       if (cc->status & BCMA_CC_CHIPST_5357_NAND_BOOT)
1832 +                               return BCMA_BOOT_DEV_NAND;
1833 +                       else if (cc->status & BIT(5))
1834 +                               return BCMA_BOOT_DEV_ROM;
1835 +               }
1836 +
1837 +               if ((cc->capabilities & BCMA_CC_CAP_FLASHT) ==
1838 +                   BCMA_CC_FLASHT_PARA)
1839 +                       return BCMA_BOOT_DEV_PARALLEL;
1840 +               else
1841 +                       return BCMA_BOOT_DEV_SERIAL;
1842 +       }
1843 +
1844 +       return BCMA_BOOT_DEV_SERIAL;
1845 +}
1846 +
1847  static void bcma_core_mips_flash_detect(struct bcma_drv_mips *mcore)
1848  {
1849         struct bcma_bus *bus = mcore->core->bus;
1850         struct bcma_drv_cc *cc = &bus->drv_cc;
1851         struct bcma_pflash *pflash = &cc->pflash;
1852 +       enum bcma_boot_dev boot_dev;
1853  
1854         switch (cc->capabilities & BCMA_CC_CAP_FLASHT) {
1855         case BCMA_CC_FLASHT_STSER:
1856 @@ -269,6 +317,20 @@ static void bcma_core_mips_flash_detect(
1857                         bcma_nflash_init(cc);
1858                 }
1859         }
1860 +
1861 +       /* Determine flash type this SoC boots from */
1862 +       boot_dev = bcma_boot_dev(bus);
1863 +       switch (boot_dev) {
1864 +       case BCMA_BOOT_DEV_PARALLEL:
1865 +       case BCMA_BOOT_DEV_SERIAL:
1866 +               /* TODO: Init NVRAM using BCMA_SOC_FLASH2 window */
1867 +               break;
1868 +       case BCMA_BOOT_DEV_NAND:
1869 +               /* TODO: Init NVRAM using BCMA_SOC_FLASH1 window */
1870 +               break;
1871 +       default:
1872 +               break;
1873 +       }
1874  }
1875  
1876  void bcma_core_mips_early_init(struct bcma_drv_mips *mcore)
1877 --- a/drivers/bcma/host_soc.c
1878 +++ b/drivers/bcma/host_soc.c
1879 @@ -134,12 +134,16 @@ static void bcma_host_soc_block_write(st
1880  
1881  static u32 bcma_host_soc_aread32(struct bcma_device *core, u16 offset)
1882  {
1883 +       if (WARN_ONCE(!core->io_wrap, "Accessed core has no wrapper/agent\n"))
1884 +               return ~0;
1885         return readl(core->io_wrap + offset);
1886  }
1887  
1888  static void bcma_host_soc_awrite32(struct bcma_device *core, u16 offset,
1889                                   u32 value)
1890  {
1891 +       if (WARN_ONCE(!core->io_wrap, "Accessed core has no wrapper/agent\n"))
1892 +               return;
1893         writel(value, core->io_wrap + offset);
1894  }
1895  
1896 --- a/include/linux/bcma/bcma_regs.h
1897 +++ b/include/linux/bcma/bcma_regs.h
1898 @@ -39,6 +39,11 @@
1899  #define  BCMA_RESET_CTL_RESET          0x0001
1900  #define BCMA_RESET_ST                  0x0804
1901  
1902 +#define BCMA_NS_ROM_IOST_BOOT_DEV_MASK 0x0003
1903 +#define BCMA_NS_ROM_IOST_BOOT_DEV_NOR  0x0000
1904 +#define BCMA_NS_ROM_IOST_BOOT_DEV_NAND 0x0001
1905 +#define BCMA_NS_ROM_IOST_BOOT_DEV_ROM  0x0002
1906 +
1907  /* BCMA PCI config space registers. */
1908  #define BCMA_PCI_PMCSR                 0x44
1909  #define  BCMA_PCI_PE                   0x100