kernel: ssb/bcma: update to version from wireless-testing tag master-2012-05-16-2
[openwrt.git] / target / linux / generic / patches-3.2 / 025-bcma_backport.patch
1 --- a/drivers/bcma/Kconfig
2 +++ b/drivers/bcma/Kconfig
3 @@ -29,7 +29,7 @@ config BCMA_HOST_PCI
4  
5  config BCMA_DRIVER_PCI_HOSTMODE
6         bool "Driver for PCI core working in hostmode"
7 -       depends on BCMA && MIPS
8 +       depends on BCMA && MIPS && BCMA_HOST_PCI
9         help
10           PCI core hostmode operation (external PCI bus).
11  
12 --- a/drivers/bcma/bcma_private.h
13 +++ b/drivers/bcma/bcma_private.h
14 @@ -13,12 +13,13 @@
15  struct bcma_bus;
16  
17  /* main.c */
18 -int bcma_bus_register(struct bcma_bus *bus);
19 +int __devinit bcma_bus_register(struct bcma_bus *bus);
20  void bcma_bus_unregister(struct bcma_bus *bus);
21  int __init bcma_bus_early_register(struct bcma_bus *bus,
22                                    struct bcma_device *core_cc,
23                                    struct bcma_device *core_mips);
24  #ifdef CONFIG_PM
25 +int bcma_bus_suspend(struct bcma_bus *bus);
26  int bcma_bus_resume(struct bcma_bus *bus);
27  #endif
28  
29 @@ -47,8 +48,12 @@ extern int __init bcma_host_pci_init(voi
30  extern void __exit bcma_host_pci_exit(void);
31  #endif /* CONFIG_BCMA_HOST_PCI */
32  
33 +/* driver_pci.c */
34 +u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address);
35 +
36  #ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
37 -void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc);
38 +bool __devinit bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc);
39 +void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc);
40  #endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */
41  
42  #endif
43 --- a/drivers/bcma/core.c
44 +++ b/drivers/bcma/core.c
45 @@ -30,6 +30,7 @@ void bcma_core_disable(struct bcma_devic
46         udelay(10);
47  
48         bcma_awrite32(core, BCMA_RESET_CTL, BCMA_RESET_CTL_RESET);
49 +       bcma_aread32(core, BCMA_RESET_CTL);
50         udelay(1);
51  }
52  EXPORT_SYMBOL_GPL(bcma_core_disable);
53 @@ -77,7 +78,7 @@ void bcma_core_set_clockmode(struct bcma
54                         pr_err("HT force timeout\n");
55                 break;
56         case BCMA_CLKMODE_DYNAMIC:
57 -               pr_warn("Dynamic clockmode not supported yet!\n");
58 +               bcma_set32(core, BCMA_CLKCTLST, ~BCMA_CLKCTLST_FORCEHT);
59                 break;
60         }
61  }
62 --- a/drivers/bcma/driver_chipcommon_pmu.c
63 +++ b/drivers/bcma/driver_chipcommon_pmu.c
64 @@ -80,6 +80,7 @@ static void bcma_pmu_resources_init(stru
65                 min_msk = 0x200D;
66                 max_msk = 0xFFFF;
67                 break;
68 +       case 0x4331:
69         case 43224:
70         case 43225:
71                 break;
72 --- a/drivers/bcma/driver_pci.c
73 +++ b/drivers/bcma/driver_pci.c
74 @@ -2,8 +2,9 @@
75   * Broadcom specific AMBA
76   * PCI Core
77   *
78 - * Copyright 2005, Broadcom Corporation
79 + * Copyright 2005, 2011, Broadcom Corporation
80   * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
81 + * Copyright 2011, 2012, Hauke Mehrtens <hauke@hauke-m.de>
82   *
83   * Licensed under the GNU/GPL. See COPYING for details.
84   */
85 @@ -16,40 +17,39 @@
86   * R/W ops.
87   **************************************************/
88  
89 -static u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address)
90 +u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address)
91  {
92 -       pcicore_write32(pc, 0x130, address);
93 -       pcicore_read32(pc, 0x130);
94 -       return pcicore_read32(pc, 0x134);
95 +       pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_ADDR, address);
96 +       pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_ADDR);
97 +       return pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_DATA);
98  }
99  
100 -#if 0
101  static void bcma_pcie_write(struct bcma_drv_pci *pc, u32 address, u32 data)
102  {
103 -       pcicore_write32(pc, 0x130, address);
104 -       pcicore_read32(pc, 0x130);
105 -       pcicore_write32(pc, 0x134, data);
106 +       pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_ADDR, address);
107 +       pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_ADDR);
108 +       pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_DATA, data);
109  }
110 -#endif
111  
112  static void bcma_pcie_mdio_set_phy(struct bcma_drv_pci *pc, u8 phy)
113  {
114 -       const u16 mdio_control = 0x128;
115 -       const u16 mdio_data = 0x12C;
116         u32 v;
117         int i;
118  
119 -       v = (1 << 30); /* Start of Transaction */
120 -       v |= (1 << 28); /* Write Transaction */
121 -       v |= (1 << 17); /* Turnaround */
122 -       v |= (0x1F << 18);
123 +       v = BCMA_CORE_PCI_MDIODATA_START;
124 +       v |= BCMA_CORE_PCI_MDIODATA_WRITE;
125 +       v |= (BCMA_CORE_PCI_MDIODATA_DEV_ADDR <<
126 +             BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF);
127 +       v |= (BCMA_CORE_PCI_MDIODATA_BLK_ADDR <<
128 +             BCMA_CORE_PCI_MDIODATA_REGADDR_SHF);
129 +       v |= BCMA_CORE_PCI_MDIODATA_TA;
130         v |= (phy << 4);
131 -       pcicore_write32(pc, mdio_data, v);
132 +       pcicore_write32(pc, BCMA_CORE_PCI_MDIO_DATA, v);
133  
134         udelay(10);
135         for (i = 0; i < 200; i++) {
136 -               v = pcicore_read32(pc, mdio_control);
137 -               if (v & 0x100 /* Trans complete */)
138 +               v = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_CONTROL);
139 +               if (v & BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE)
140                         break;
141                 msleep(1);
142         }
143 @@ -57,79 +57,84 @@ static void bcma_pcie_mdio_set_phy(struc
144  
145  static u16 bcma_pcie_mdio_read(struct bcma_drv_pci *pc, u8 device, u8 address)
146  {
147 -       const u16 mdio_control = 0x128;
148 -       const u16 mdio_data = 0x12C;
149         int max_retries = 10;
150         u16 ret = 0;
151         u32 v;
152         int i;
153  
154 -       v = 0x80; /* Enable Preamble Sequence */
155 -       v |= 0x2; /* MDIO Clock Divisor */
156 -       pcicore_write32(pc, mdio_control, v);
157 +       /* enable mdio access to SERDES */
158 +       v = BCMA_CORE_PCI_MDIOCTL_PREAM_EN;
159 +       v |= BCMA_CORE_PCI_MDIOCTL_DIVISOR_VAL;
160 +       pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, v);
161  
162         if (pc->core->id.rev >= 10) {
163                 max_retries = 200;
164                 bcma_pcie_mdio_set_phy(pc, device);
165 +               v = (BCMA_CORE_PCI_MDIODATA_DEV_ADDR <<
166 +                    BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF);
167 +               v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF);
168 +       } else {
169 +               v = (device << BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF_OLD);
170 +               v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF_OLD);
171         }
172  
173 -       v = (1 << 30); /* Start of Transaction */
174 -       v |= (1 << 29); /* Read Transaction */
175 -       v |= (1 << 17); /* Turnaround */
176 -       if (pc->core->id.rev < 10)
177 -               v |= (u32)device << 22;
178 -       v |= (u32)address << 18;
179 -       pcicore_write32(pc, mdio_data, v);
180 +       v = BCMA_CORE_PCI_MDIODATA_START;
181 +       v |= BCMA_CORE_PCI_MDIODATA_READ;
182 +       v |= BCMA_CORE_PCI_MDIODATA_TA;
183 +
184 +       pcicore_write32(pc, BCMA_CORE_PCI_MDIO_DATA, v);
185         /* Wait for the device to complete the transaction */
186         udelay(10);
187         for (i = 0; i < max_retries; i++) {
188 -               v = pcicore_read32(pc, mdio_control);
189 -               if (v & 0x100 /* Trans complete */) {
190 +               v = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_CONTROL);
191 +               if (v & BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE) {
192                         udelay(10);
193 -                       ret = pcicore_read32(pc, mdio_data);
194 +                       ret = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_DATA);
195                         break;
196                 }
197                 msleep(1);
198         }
199 -       pcicore_write32(pc, mdio_control, 0);
200 +       pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, 0);
201         return ret;
202  }
203  
204  static void bcma_pcie_mdio_write(struct bcma_drv_pci *pc, u8 device,
205                                 u8 address, u16 data)
206  {
207 -       const u16 mdio_control = 0x128;
208 -       const u16 mdio_data = 0x12C;
209         int max_retries = 10;
210         u32 v;
211         int i;
212  
213 -       v = 0x80; /* Enable Preamble Sequence */
214 -       v |= 0x2; /* MDIO Clock Divisor */
215 -       pcicore_write32(pc, mdio_control, v);
216 +       /* enable mdio access to SERDES */
217 +       v = BCMA_CORE_PCI_MDIOCTL_PREAM_EN;
218 +       v |= BCMA_CORE_PCI_MDIOCTL_DIVISOR_VAL;
219 +       pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, v);
220  
221         if (pc->core->id.rev >= 10) {
222                 max_retries = 200;
223                 bcma_pcie_mdio_set_phy(pc, device);
224 +               v = (BCMA_CORE_PCI_MDIODATA_DEV_ADDR <<
225 +                    BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF);
226 +               v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF);
227 +       } else {
228 +               v = (device << BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF_OLD);
229 +               v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF_OLD);
230         }
231  
232 -       v = (1 << 30); /* Start of Transaction */
233 -       v |= (1 << 28); /* Write Transaction */
234 -       v |= (1 << 17); /* Turnaround */
235 -       if (pc->core->id.rev < 10)
236 -               v |= (u32)device << 22;
237 -       v |= (u32)address << 18;
238 +       v = BCMA_CORE_PCI_MDIODATA_START;
239 +       v |= BCMA_CORE_PCI_MDIODATA_WRITE;
240 +       v |= BCMA_CORE_PCI_MDIODATA_TA;
241         v |= data;
242 -       pcicore_write32(pc, mdio_data, v);
243 +       pcicore_write32(pc, BCMA_CORE_PCI_MDIO_DATA, v);
244         /* Wait for the device to complete the transaction */
245         udelay(10);
246         for (i = 0; i < max_retries; i++) {
247 -               v = pcicore_read32(pc, mdio_control);
248 -               if (v & 0x100 /* Trans complete */)
249 +               v = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_CONTROL);
250 +               if (v & BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE)
251                         break;
252                 msleep(1);
253         }
254 -       pcicore_write32(pc, mdio_control, 0);
255 +       pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, 0);
256  }
257  
258  /**************************************************
259 @@ -138,72 +143,90 @@ static void bcma_pcie_mdio_write(struct
260  
261  static u8 bcma_pcicore_polarity_workaround(struct bcma_drv_pci *pc)
262  {
263 -       return (bcma_pcie_read(pc, 0x204) & 0x10) ? 0xC0 : 0x80;
264 +       u32 tmp;
265 +
266 +       tmp = bcma_pcie_read(pc, BCMA_CORE_PCI_PLP_STATUSREG);
267 +       if (tmp & BCMA_CORE_PCI_PLP_POLARITYINV_STAT)
268 +               return BCMA_CORE_PCI_SERDES_RX_CTRL_FORCE |
269 +                      BCMA_CORE_PCI_SERDES_RX_CTRL_POLARITY;
270 +       else
271 +               return BCMA_CORE_PCI_SERDES_RX_CTRL_FORCE;
272  }
273  
274  static void bcma_pcicore_serdes_workaround(struct bcma_drv_pci *pc)
275  {
276 -       const u8 serdes_pll_device = 0x1D;
277 -       const u8 serdes_rx_device = 0x1F;
278         u16 tmp;
279  
280 -       bcma_pcie_mdio_write(pc, serdes_rx_device, 1 /* Control */,
281 -                             bcma_pcicore_polarity_workaround(pc));
282 -       tmp = bcma_pcie_mdio_read(pc, serdes_pll_device, 1 /* Control */);
283 -       if (tmp & 0x4000)
284 -               bcma_pcie_mdio_write(pc, serdes_pll_device, 1, tmp & ~0x4000);
285 +       bcma_pcie_mdio_write(pc, BCMA_CORE_PCI_MDIODATA_DEV_RX,
286 +                            BCMA_CORE_PCI_SERDES_RX_CTRL,
287 +                            bcma_pcicore_polarity_workaround(pc));
288 +       tmp = bcma_pcie_mdio_read(pc, BCMA_CORE_PCI_MDIODATA_DEV_PLL,
289 +                                 BCMA_CORE_PCI_SERDES_PLL_CTRL);
290 +       if (tmp & BCMA_CORE_PCI_PLL_CTRL_FREQDET_EN)
291 +               bcma_pcie_mdio_write(pc, BCMA_CORE_PCI_MDIODATA_DEV_PLL,
292 +                                    BCMA_CORE_PCI_SERDES_PLL_CTRL,
293 +                                    tmp & ~BCMA_CORE_PCI_PLL_CTRL_FREQDET_EN);
294 +}
295 +
296 +static void bcma_core_pci_fixcfg(struct bcma_drv_pci *pc)
297 +{
298 +       struct bcma_device *core = pc->core;
299 +       u16 val16, core_index;
300 +       uint regoff;
301 +
302 +       regoff = BCMA_CORE_PCI_SPROM(BCMA_CORE_PCI_SPROM_PI_OFFSET);
303 +       core_index = (u16)core->core_index;
304 +
305 +       val16 = pcicore_read16(pc, regoff);
306 +       if (((val16 & BCMA_CORE_PCI_SPROM_PI_MASK) >> BCMA_CORE_PCI_SPROM_PI_SHIFT)
307 +            != core_index) {
308 +               val16 = (core_index << BCMA_CORE_PCI_SPROM_PI_SHIFT) |
309 +                       (val16 & ~BCMA_CORE_PCI_SPROM_PI_MASK);
310 +               pcicore_write16(pc, regoff, val16);
311 +       }
312 +}
313 +
314 +/* Fix MISC config to allow coming out of L2/L3-Ready state w/o PRST */
315 +/* Needs to happen when coming out of 'standby'/'hibernate' */
316 +static void bcma_core_pci_config_fixup(struct bcma_drv_pci *pc)
317 +{
318 +       u16 val16;
319 +       uint regoff;
320 +
321 +       regoff = BCMA_CORE_PCI_SPROM(BCMA_CORE_PCI_SPROM_MISC_CONFIG);
322 +
323 +       val16 = pcicore_read16(pc, regoff);
324 +
325 +       if (!(val16 & BCMA_CORE_PCI_SPROM_L23READY_EXIT_NOPERST)) {
326 +               val16 |= BCMA_CORE_PCI_SPROM_L23READY_EXIT_NOPERST;
327 +               pcicore_write16(pc, regoff, val16);
328 +       }
329  }
330  
331  /**************************************************
332   * Init.
333   **************************************************/
334  
335 -static void bcma_core_pci_clientmode_init(struct bcma_drv_pci *pc)
336 +static void __devinit bcma_core_pci_clientmode_init(struct bcma_drv_pci *pc)
337  {
338 +       bcma_core_pci_fixcfg(pc);
339         bcma_pcicore_serdes_workaround(pc);
340 +       bcma_core_pci_config_fixup(pc);
341  }
342  
343 -static bool bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc)
344 -{
345 -       struct bcma_bus *bus = pc->core->bus;
346 -       u16 chipid_top;
347 -
348 -       chipid_top = (bus->chipinfo.id & 0xFF00);
349 -       if (chipid_top != 0x4700 &&
350 -           chipid_top != 0x5300)
351 -               return false;
352 -
353 -#ifdef CONFIG_SSB_DRIVER_PCICORE
354 -       if (bus->sprom.boardflags_lo & SSB_BFL_NOPCI)
355 -               return false;
356 -#endif /* CONFIG_SSB_DRIVER_PCICORE */
357 -
358 -#if 0
359 -       /* TODO: on BCMA we use address from EROM instead of magic formula */
360 -       u32 tmp;
361 -       return !mips_busprobe32(tmp, (bus->mmio +
362 -               (pc->core->core_index * BCMA_CORE_SIZE)));
363 -#endif
364 -
365 -       return true;
366 -}
367 -
368 -void bcma_core_pci_init(struct bcma_drv_pci *pc)
369 +void __devinit bcma_core_pci_init(struct bcma_drv_pci *pc)
370  {
371         if (pc->setup_done)
372                 return;
373  
374 -       if (bcma_core_pci_is_in_hostmode(pc)) {
375  #ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
376 +       pc->hostmode = bcma_core_pci_is_in_hostmode(pc);
377 +       if (pc->hostmode)
378                 bcma_core_pci_hostmode_init(pc);
379 -#else
380 -               pr_err("Driver compiled without support for hostmode PCI\n");
381  #endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */
382 -       } else {
383 -               bcma_core_pci_clientmode_init(pc);
384 -       }
385  
386 -       pc->setup_done = true;
387 +       if (!pc->hostmode)
388 +               bcma_core_pci_clientmode_init(pc);
389  }
390  
391  int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core,
392 @@ -236,3 +259,17 @@ out:
393         return err;
394  }
395  EXPORT_SYMBOL_GPL(bcma_core_pci_irq_ctl);
396 +
397 +void bcma_core_pci_extend_L1timer(struct bcma_drv_pci *pc, bool extend)
398 +{
399 +       u32 w;
400 +
401 +       w = bcma_pcie_read(pc, BCMA_CORE_PCI_DLLP_PMTHRESHREG);
402 +       if (extend)
403 +               w |= BCMA_CORE_PCI_ASPMTIMER_EXTEND;
404 +       else
405 +               w &= ~BCMA_CORE_PCI_ASPMTIMER_EXTEND;
406 +       bcma_pcie_write(pc, BCMA_CORE_PCI_DLLP_PMTHRESHREG, w);
407 +       bcma_pcie_read(pc, BCMA_CORE_PCI_DLLP_PMTHRESHREG);
408 +}
409 +EXPORT_SYMBOL_GPL(bcma_core_pci_extend_L1timer);
410 --- a/drivers/bcma/driver_pci_host.c
411 +++ b/drivers/bcma/driver_pci_host.c
412 @@ -2,13 +2,588 @@
413   * Broadcom specific AMBA
414   * PCI Core in hostmode
415   *
416 + * Copyright 2005 - 2011, Broadcom Corporation
417 + * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
418 + * Copyright 2011, 2012, Hauke Mehrtens <hauke@hauke-m.de>
419 + *
420   * Licensed under the GNU/GPL. See COPYING for details.
421   */
422  
423  #include "bcma_private.h"
424 +#include <linux/pci.h>
425 +#include <linux/export.h>
426  #include <linux/bcma/bcma.h>
427 +#include <asm/paccess.h>
428 +
429 +/* Probe a 32bit value on the bus and catch bus exceptions.
430 + * Returns nonzero on a bus exception.
431 + * This is MIPS specific */
432 +#define mips_busprobe32(val, addr)     get_dbe((val), ((u32 *)(addr)))
433 +
434 +/* Assume one-hot slot wiring */
435 +#define BCMA_PCI_SLOT_MAX      16
436 +#define        PCI_CONFIG_SPACE_SIZE   256
437 +
438 +bool __devinit bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc)
439 +{
440 +       struct bcma_bus *bus = pc->core->bus;
441 +       u16 chipid_top;
442 +       u32 tmp;
443 +
444 +       chipid_top = (bus->chipinfo.id & 0xFF00);
445 +       if (chipid_top != 0x4700 &&
446 +           chipid_top != 0x5300)
447 +               return false;
448 +
449 +       if (bus->sprom.boardflags_lo & BCMA_CORE_PCI_BFL_NOPCI) {
450 +               pr_info("This PCI core is disabled and not working\n");
451 +               return false;
452 +       }
453 +
454 +       bcma_core_enable(pc->core, 0);
455 +
456 +       return !mips_busprobe32(tmp, pc->core->io_addr);
457 +}
458 +
459 +static u32 bcma_pcie_read_config(struct bcma_drv_pci *pc, u32 address)
460 +{
461 +       pcicore_write32(pc, BCMA_CORE_PCI_CONFIG_ADDR, address);
462 +       pcicore_read32(pc, BCMA_CORE_PCI_CONFIG_ADDR);
463 +       return pcicore_read32(pc, BCMA_CORE_PCI_CONFIG_DATA);
464 +}
465 +
466 +static void bcma_pcie_write_config(struct bcma_drv_pci *pc, u32 address,
467 +                                  u32 data)
468 +{
469 +       pcicore_write32(pc, BCMA_CORE_PCI_CONFIG_ADDR, address);
470 +       pcicore_read32(pc, BCMA_CORE_PCI_CONFIG_ADDR);
471 +       pcicore_write32(pc, BCMA_CORE_PCI_CONFIG_DATA, data);
472 +}
473 +
474 +static u32 bcma_get_cfgspace_addr(struct bcma_drv_pci *pc, unsigned int dev,
475 +                            unsigned int func, unsigned int off)
476 +{
477 +       u32 addr = 0;
478 +
479 +       /* Issue config commands only when the data link is up (atleast
480 +        * one external pcie device is present).
481 +        */
482 +       if (dev >= 2 || !(bcma_pcie_read(pc, BCMA_CORE_PCI_DLLP_LSREG)
483 +                         & BCMA_CORE_PCI_DLLP_LSREG_LINKUP))
484 +               goto out;
485 +
486 +       /* Type 0 transaction */
487 +       /* Slide the PCI window to the appropriate slot */
488 +       pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI1, BCMA_CORE_PCI_SBTOPCI_CFG0);
489 +       /* Calculate the address */
490 +       addr = pc->host_controller->host_cfg_addr;
491 +       addr |= (dev << BCMA_CORE_PCI_CFG_SLOT_SHIFT);
492 +       addr |= (func << BCMA_CORE_PCI_CFG_FUN_SHIFT);
493 +       addr |= (off & ~3);
494 +
495 +out:
496 +       return addr;
497 +}
498  
499 -void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc)
500 +static int bcma_extpci_read_config(struct bcma_drv_pci *pc, unsigned int dev,
501 +                                 unsigned int func, unsigned int off,
502 +                                 void *buf, int len)
503  {
504 -       pr_err("No support for PCI core in hostmode yet\n");
505 +       int err = -EINVAL;
506 +       u32 addr, val;
507 +       void __iomem *mmio = 0;
508 +
509 +       WARN_ON(!pc->hostmode);
510 +       if (unlikely(len != 1 && len != 2 && len != 4))
511 +               goto out;
512 +       if (dev == 0) {
513 +               /* we support only two functions on device 0 */
514 +               if (func > 1)
515 +                       return -EINVAL;
516 +
517 +               /* accesses to config registers with offsets >= 256
518 +                * requires indirect access.
519 +                */
520 +               if (off >= PCI_CONFIG_SPACE_SIZE) {
521 +                       addr = (func << 12);
522 +                       addr |= (off & 0x0FFF);
523 +                       val = bcma_pcie_read_config(pc, addr);
524 +               } else {
525 +                       addr = BCMA_CORE_PCI_PCICFG0;
526 +                       addr |= (func << 8);
527 +                       addr |= (off & 0xfc);
528 +                       val = pcicore_read32(pc, addr);
529 +               }
530 +       } else {
531 +               addr = bcma_get_cfgspace_addr(pc, dev, func, off);
532 +               if (unlikely(!addr))
533 +                       goto out;
534 +               err = -ENOMEM;
535 +               mmio = ioremap_nocache(addr, sizeof(val));
536 +               if (!mmio)
537 +                       goto out;
538 +
539 +               if (mips_busprobe32(val, mmio)) {
540 +                       val = 0xffffffff;
541 +                       goto unmap;
542 +               }
543 +
544 +               val = readl(mmio);
545 +       }
546 +       val >>= (8 * (off & 3));
547 +
548 +       switch (len) {
549 +       case 1:
550 +               *((u8 *)buf) = (u8)val;
551 +               break;
552 +       case 2:
553 +               *((u16 *)buf) = (u16)val;
554 +               break;
555 +       case 4:
556 +               *((u32 *)buf) = (u32)val;
557 +               break;
558 +       }
559 +       err = 0;
560 +unmap:
561 +       if (mmio)
562 +               iounmap(mmio);
563 +out:
564 +       return err;
565 +}
566 +
567 +static int bcma_extpci_write_config(struct bcma_drv_pci *pc, unsigned int dev,
568 +                                  unsigned int func, unsigned int off,
569 +                                  const void *buf, int len)
570 +{
571 +       int err = -EINVAL;
572 +       u32 addr = 0, val = 0;
573 +       void __iomem *mmio = 0;
574 +       u16 chipid = pc->core->bus->chipinfo.id;
575 +
576 +       WARN_ON(!pc->hostmode);
577 +       if (unlikely(len != 1 && len != 2 && len != 4))
578 +               goto out;
579 +       if (dev == 0) {
580 +               /* accesses to config registers with offsets >= 256
581 +                * requires indirect access.
582 +                */
583 +               if (off < PCI_CONFIG_SPACE_SIZE) {
584 +                       addr = pc->core->addr + BCMA_CORE_PCI_PCICFG0;
585 +                       addr |= (func << 8);
586 +                       addr |= (off & 0xfc);
587 +                       mmio = ioremap_nocache(addr, sizeof(val));
588 +                       if (!mmio)
589 +                               goto out;
590 +               }
591 +       } else {
592 +               addr = bcma_get_cfgspace_addr(pc, dev, func, off);
593 +               if (unlikely(!addr))
594 +                       goto out;
595 +               err = -ENOMEM;
596 +               mmio = ioremap_nocache(addr, sizeof(val));
597 +               if (!mmio)
598 +                       goto out;
599 +
600 +               if (mips_busprobe32(val, mmio)) {
601 +                       val = 0xffffffff;
602 +                       goto unmap;
603 +               }
604 +       }
605 +
606 +       switch (len) {
607 +       case 1:
608 +               val = readl(mmio);
609 +               val &= ~(0xFF << (8 * (off & 3)));
610 +               val |= *((const u8 *)buf) << (8 * (off & 3));
611 +               break;
612 +       case 2:
613 +               val = readl(mmio);
614 +               val &= ~(0xFFFF << (8 * (off & 3)));
615 +               val |= *((const u16 *)buf) << (8 * (off & 3));
616 +               break;
617 +       case 4:
618 +               val = *((const u32 *)buf);
619 +               break;
620 +       }
621 +       if (dev == 0 && !addr) {
622 +               /* accesses to config registers with offsets >= 256
623 +                * requires indirect access.
624 +                */
625 +               addr = (func << 12);
626 +               addr |= (off & 0x0FFF);
627 +               bcma_pcie_write_config(pc, addr, val);
628 +       } else {
629 +               writel(val, mmio);
630 +
631 +               if (chipid == 0x4716 || chipid == 0x4748)
632 +                       readl(mmio);
633 +       }
634 +
635 +       err = 0;
636 +unmap:
637 +       if (mmio)
638 +               iounmap(mmio);
639 +out:
640 +       return err;
641 +}
642 +
643 +static int bcma_core_pci_hostmode_read_config(struct pci_bus *bus,
644 +                                             unsigned int devfn,
645 +                                             int reg, int size, u32 *val)
646 +{
647 +       unsigned long flags;
648 +       int err;
649 +       struct bcma_drv_pci *pc;
650 +       struct bcma_drv_pci_host *pc_host;
651 +
652 +       pc_host = container_of(bus->ops, struct bcma_drv_pci_host, pci_ops);
653 +       pc = pc_host->pdev;
654 +
655 +       spin_lock_irqsave(&pc_host->cfgspace_lock, flags);
656 +       err = bcma_extpci_read_config(pc, PCI_SLOT(devfn),
657 +                                    PCI_FUNC(devfn), reg, val, size);
658 +       spin_unlock_irqrestore(&pc_host->cfgspace_lock, flags);
659 +
660 +       return err ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
661 +}
662 +
663 +static int bcma_core_pci_hostmode_write_config(struct pci_bus *bus,
664 +                                              unsigned int devfn,
665 +                                              int reg, int size, u32 val)
666 +{
667 +       unsigned long flags;
668 +       int err;
669 +       struct bcma_drv_pci *pc;
670 +       struct bcma_drv_pci_host *pc_host;
671 +
672 +       pc_host = container_of(bus->ops, struct bcma_drv_pci_host, pci_ops);
673 +       pc = pc_host->pdev;
674 +
675 +       spin_lock_irqsave(&pc_host->cfgspace_lock, flags);
676 +       err = bcma_extpci_write_config(pc, PCI_SLOT(devfn),
677 +                                     PCI_FUNC(devfn), reg, &val, size);
678 +       spin_unlock_irqrestore(&pc_host->cfgspace_lock, flags);
679 +
680 +       return err ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
681 +}
682 +
683 +/* return cap_offset if requested capability exists in the PCI config space */
684 +static u8 __devinit bcma_find_pci_capability(struct bcma_drv_pci *pc,
685 +                                            unsigned int dev,
686 +                                            unsigned int func, u8 req_cap_id,
687 +                                            unsigned char *buf, u32 *buflen)
688 +{
689 +       u8 cap_id;
690 +       u8 cap_ptr = 0;
691 +       u32 bufsize;
692 +       u8 byte_val;
693 +
694 +       /* check for Header type 0 */
695 +       bcma_extpci_read_config(pc, dev, func, PCI_HEADER_TYPE, &byte_val,
696 +                               sizeof(u8));
697 +       if ((byte_val & 0x7f) != PCI_HEADER_TYPE_NORMAL)
698 +               return cap_ptr;
699 +
700 +       /* check if the capability pointer field exists */
701 +       bcma_extpci_read_config(pc, dev, func, PCI_STATUS, &byte_val,
702 +                               sizeof(u8));
703 +       if (!(byte_val & PCI_STATUS_CAP_LIST))
704 +               return cap_ptr;
705 +
706 +       /* check if the capability pointer is 0x00 */
707 +       bcma_extpci_read_config(pc, dev, func, PCI_CAPABILITY_LIST, &cap_ptr,
708 +                               sizeof(u8));
709 +       if (cap_ptr == 0x00)
710 +               return cap_ptr;
711 +
712 +       /* loop thr'u the capability list and see if the requested capabilty
713 +        * exists */
714 +       bcma_extpci_read_config(pc, dev, func, cap_ptr, &cap_id, sizeof(u8));
715 +       while (cap_id != req_cap_id) {
716 +               bcma_extpci_read_config(pc, dev, func, cap_ptr + 1, &cap_ptr,
717 +                                       sizeof(u8));
718 +               if (cap_ptr == 0x00)
719 +                       return cap_ptr;
720 +               bcma_extpci_read_config(pc, dev, func, cap_ptr, &cap_id,
721 +                                       sizeof(u8));
722 +       }
723 +
724 +       /* found the caller requested capability */
725 +       if ((buf != NULL) && (buflen != NULL)) {
726 +               u8 cap_data;
727 +
728 +               bufsize = *buflen;
729 +               if (!bufsize)
730 +                       return cap_ptr;
731 +
732 +               *buflen = 0;
733 +
734 +               /* copy the cpability data excluding cap ID and next ptr */
735 +               cap_data = cap_ptr + 2;
736 +               if ((bufsize + cap_data)  > PCI_CONFIG_SPACE_SIZE)
737 +                       bufsize = PCI_CONFIG_SPACE_SIZE - cap_data;
738 +               *buflen = bufsize;
739 +               while (bufsize--) {
740 +                       bcma_extpci_read_config(pc, dev, func, cap_data, buf,
741 +                                               sizeof(u8));
742 +                       cap_data++;
743 +                       buf++;
744 +               }
745 +       }
746 +
747 +       return cap_ptr;
748 +}
749 +
750 +/* If the root port is capable of returning Config Request
751 + * Retry Status (CRS) Completion Status to software then
752 + * enable the feature.
753 + */
754 +static void __devinit bcma_core_pci_enable_crs(struct bcma_drv_pci *pc)
755 +{
756 +       u8 cap_ptr, root_ctrl, root_cap, dev;
757 +       u16 val16;
758 +       int i;
759 +
760 +       cap_ptr = bcma_find_pci_capability(pc, 0, 0, PCI_CAP_ID_EXP, NULL,
761 +                                          NULL);
762 +       root_cap = cap_ptr + PCI_EXP_RTCAP;
763 +       bcma_extpci_read_config(pc, 0, 0, root_cap, &val16, sizeof(u16));
764 +       if (val16 & BCMA_CORE_PCI_RC_CRS_VISIBILITY) {
765 +               /* Enable CRS software visibility */
766 +               root_ctrl = cap_ptr + PCI_EXP_RTCTL;
767 +               val16 = PCI_EXP_RTCTL_CRSSVE;
768 +               bcma_extpci_read_config(pc, 0, 0, root_ctrl, &val16,
769 +                                       sizeof(u16));
770 +
771 +               /* Initiate a configuration request to read the vendor id
772 +                * field of the device function's config space header after
773 +                * 100 ms wait time from the end of Reset. If the device is
774 +                * not done with its internal initialization, it must at
775 +                * least return a completion TLP, with a completion status
776 +                * of "Configuration Request Retry Status (CRS)". The root
777 +                * complex must complete the request to the host by returning
778 +                * a read-data value of 0001h for the Vendor ID field and
779 +                * all 1s for any additional bytes included in the request.
780 +                * Poll using the config reads for max wait time of 1 sec or
781 +                * until we receive the successful completion status. Repeat
782 +                * the procedure for all the devices.
783 +                */
784 +               for (dev = 1; dev < BCMA_PCI_SLOT_MAX; dev++) {
785 +                       for (i = 0; i < 100000; i++) {
786 +                               bcma_extpci_read_config(pc, dev, 0,
787 +                                                       PCI_VENDOR_ID, &val16,
788 +                                                       sizeof(val16));
789 +                               if (val16 != 0x1)
790 +                                       break;
791 +                               udelay(10);
792 +                       }
793 +                       if (val16 == 0x1)
794 +                               pr_err("PCI: Broken device in slot %d\n", dev);
795 +               }
796 +       }
797 +}
798 +
799 +void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc)
800 +{
801 +       struct bcma_bus *bus = pc->core->bus;
802 +       struct bcma_drv_pci_host *pc_host;
803 +       u32 tmp;
804 +       u32 pci_membase_1G;
805 +       unsigned long io_map_base;
806 +
807 +       pr_info("PCIEcore in host mode found\n");
808 +
809 +       pc_host = kzalloc(sizeof(*pc_host), GFP_KERNEL);
810 +       if (!pc_host)  {
811 +               pr_err("can not allocate memory");
812 +               return;
813 +       }
814 +
815 +       pc->host_controller = pc_host;
816 +       pc_host->pci_controller.io_resource = &pc_host->io_resource;
817 +       pc_host->pci_controller.mem_resource = &pc_host->mem_resource;
818 +       pc_host->pci_controller.pci_ops = &pc_host->pci_ops;
819 +       pc_host->pdev = pc;
820 +
821 +       pci_membase_1G = BCMA_SOC_PCI_DMA;
822 +       pc_host->host_cfg_addr = BCMA_SOC_PCI_CFG;
823 +
824 +       pc_host->pci_ops.read = bcma_core_pci_hostmode_read_config;
825 +       pc_host->pci_ops.write = bcma_core_pci_hostmode_write_config;
826 +
827 +       pc_host->mem_resource.name = "BCMA PCIcore external memory",
828 +       pc_host->mem_resource.start = BCMA_SOC_PCI_DMA;
829 +       pc_host->mem_resource.end = BCMA_SOC_PCI_DMA + BCMA_SOC_PCI_DMA_SZ - 1;
830 +       pc_host->mem_resource.flags = IORESOURCE_MEM | IORESOURCE_PCI_FIXED;
831 +
832 +       pc_host->io_resource.name = "BCMA PCIcore external I/O",
833 +       pc_host->io_resource.start = 0x100;
834 +       pc_host->io_resource.end = 0x7FF;
835 +       pc_host->io_resource.flags = IORESOURCE_IO | IORESOURCE_PCI_FIXED;
836 +
837 +       /* Reset RC */
838 +       udelay(3000);
839 +       pcicore_write32(pc, BCMA_CORE_PCI_CTL, BCMA_CORE_PCI_CTL_RST_OE);
840 +       udelay(1000);
841 +       pcicore_write32(pc, BCMA_CORE_PCI_CTL, BCMA_CORE_PCI_CTL_RST |
842 +                       BCMA_CORE_PCI_CTL_RST_OE);
843 +
844 +       /* 64 MB I/O access window. On 4716, use
845 +        * sbtopcie0 to access the device registers. We
846 +        * can't use address match 2 (1 GB window) region
847 +        * as mips can't generate 64-bit address on the
848 +        * backplane.
849 +        */
850 +       if (bus->chipinfo.id == 0x4716 || bus->chipinfo.id == 0x4748) {
851 +               pc_host->mem_resource.start = BCMA_SOC_PCI_MEM;
852 +               pc_host->mem_resource.end = BCMA_SOC_PCI_MEM +
853 +                                           BCMA_SOC_PCI_MEM_SZ - 1;
854 +               pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0,
855 +                               BCMA_CORE_PCI_SBTOPCI_MEM | BCMA_SOC_PCI_MEM);
856 +       } else if (bus->chipinfo.id == 0x5300) {
857 +               tmp = BCMA_CORE_PCI_SBTOPCI_MEM;
858 +               tmp |= BCMA_CORE_PCI_SBTOPCI_PREF;
859 +               tmp |= BCMA_CORE_PCI_SBTOPCI_BURST;
860 +               if (pc->core->core_unit == 0) {
861 +                       pc_host->mem_resource.start = BCMA_SOC_PCI_MEM;
862 +                       pc_host->mem_resource.end = BCMA_SOC_PCI_MEM +
863 +                                                   BCMA_SOC_PCI_MEM_SZ - 1;
864 +                       pci_membase_1G = BCMA_SOC_PCIE_DMA_H32;
865 +                       pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0,
866 +                                       tmp | BCMA_SOC_PCI_MEM);
867 +               } else if (pc->core->core_unit == 1) {
868 +                       pc_host->mem_resource.start = BCMA_SOC_PCI1_MEM;
869 +                       pc_host->mem_resource.end = BCMA_SOC_PCI1_MEM +
870 +                                                   BCMA_SOC_PCI_MEM_SZ - 1;
871 +                       pci_membase_1G = BCMA_SOC_PCIE1_DMA_H32;
872 +                       pc_host->host_cfg_addr = BCMA_SOC_PCI1_CFG;
873 +                       pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0,
874 +                                       tmp | BCMA_SOC_PCI1_MEM);
875 +               }
876 +       } else
877 +               pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0,
878 +                               BCMA_CORE_PCI_SBTOPCI_IO);
879 +
880 +       /* 64 MB configuration access window */
881 +       pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI1, BCMA_CORE_PCI_SBTOPCI_CFG0);
882 +
883 +       /* 1 GB memory access window */
884 +       pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI2,
885 +                       BCMA_CORE_PCI_SBTOPCI_MEM | pci_membase_1G);
886 +
887 +
888 +       /* As per PCI Express Base Spec 1.1 we need to wait for
889 +        * at least 100 ms from the end of a reset (cold/warm/hot)
890 +        * before issuing configuration requests to PCI Express
891 +        * devices.
892 +        */
893 +       udelay(100000);
894 +
895 +       bcma_core_pci_enable_crs(pc);
896 +
897 +       /* Enable PCI bridge BAR0 memory & master access */
898 +       tmp = PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
899 +       bcma_extpci_write_config(pc, 0, 0, PCI_COMMAND, &tmp, sizeof(tmp));
900 +
901 +       /* Enable PCI interrupts */
902 +       pcicore_write32(pc, BCMA_CORE_PCI_IMASK, BCMA_CORE_PCI_IMASK_INTA);
903 +
904 +       /* Ok, ready to run, register it to the system.
905 +        * The following needs change, if we want to port hostmode
906 +        * to non-MIPS platform. */
907 +       io_map_base = (unsigned long)ioremap_nocache(pc_host->mem_resource.start,
908 +                                                    resource_size(&pc_host->mem_resource));
909 +       pc_host->pci_controller.io_map_base = io_map_base;
910 +       set_io_port_base(pc_host->pci_controller.io_map_base);
911 +       /* Give some time to the PCI controller to configure itself with the new
912 +        * values. Not waiting at this point causes crashes of the machine. */
913 +       mdelay(10);
914 +       register_pci_controller(&pc_host->pci_controller);
915 +       return;
916 +}
917 +
918 +/* Early PCI fixup for a device on the PCI-core bridge. */
919 +static void bcma_core_pci_fixup_pcibridge(struct pci_dev *dev)
920 +{
921 +       if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) {
922 +               /* This is not a device on the PCI-core bridge. */
923 +               return;
924 +       }
925 +       if (PCI_SLOT(dev->devfn) != 0)
926 +               return;
927 +
928 +       pr_info("PCI: Fixing up bridge %s\n", pci_name(dev));
929 +
930 +       /* Enable PCI bridge bus mastering and memory space */
931 +       pci_set_master(dev);
932 +       if (pcibios_enable_device(dev, ~0) < 0) {
933 +               pr_err("PCI: BCMA bridge enable failed\n");
934 +               return;
935 +       }
936 +
937 +       /* Enable PCI bridge BAR1 prefetch and burst */
938 +       pci_write_config_dword(dev, BCMA_PCI_BAR1_CONTROL, 3);
939 +}
940 +DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, bcma_core_pci_fixup_pcibridge);
941 +
942 +/* Early PCI fixup for all PCI-cores to set the correct memory address. */
943 +static void bcma_core_pci_fixup_addresses(struct pci_dev *dev)
944 +{
945 +       struct resource *res;
946 +       int pos;
947 +
948 +       if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) {
949 +               /* This is not a device on the PCI-core bridge. */
950 +               return;
951 +       }
952 +       if (PCI_SLOT(dev->devfn) == 0)
953 +               return;
954 +
955 +       pr_info("PCI: Fixing up addresses %s\n", pci_name(dev));
956 +
957 +       for (pos = 0; pos < 6; pos++) {
958 +               res = &dev->resource[pos];
959 +               if (res->flags & (IORESOURCE_IO | IORESOURCE_MEM))
960 +                       pci_assign_resource(dev, pos);
961 +       }
962 +}
963 +DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, bcma_core_pci_fixup_addresses);
964 +
965 +/* This function is called when doing a pci_enable_device().
966 + * We must first check if the device is a device on the PCI-core bridge. */
967 +int bcma_core_pci_plat_dev_init(struct pci_dev *dev)
968 +{
969 +       struct bcma_drv_pci_host *pc_host;
970 +
971 +       if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) {
972 +               /* This is not a device on the PCI-core bridge. */
973 +               return -ENODEV;
974 +       }
975 +       pc_host = container_of(dev->bus->ops, struct bcma_drv_pci_host,
976 +                              pci_ops);
977 +
978 +       pr_info("PCI: Fixing up device %s\n", pci_name(dev));
979 +
980 +       /* Fix up interrupt lines */
981 +       dev->irq = bcma_core_mips_irq(pc_host->pdev->core) + 2;
982 +       pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
983 +
984 +       return 0;
985 +}
986 +EXPORT_SYMBOL(bcma_core_pci_plat_dev_init);
987 +
988 +/* PCI device IRQ mapping. */
989 +int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev)
990 +{
991 +       struct bcma_drv_pci_host *pc_host;
992 +
993 +       if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) {
994 +               /* This is not a device on the PCI-core bridge. */
995 +               return -ENODEV;
996 +       }
997 +
998 +       pc_host = container_of(dev->bus->ops, struct bcma_drv_pci_host,
999 +                              pci_ops);
1000 +       return bcma_core_mips_irq(pc_host->pdev->core) + 2;
1001  }
1002 +EXPORT_SYMBOL(bcma_core_pci_pcibios_map_irq);
1003 --- a/drivers/bcma/host_pci.c
1004 +++ b/drivers/bcma/host_pci.c
1005 @@ -21,48 +21,58 @@ static void bcma_host_pci_switch_core(st
1006         pr_debug("Switched to core: 0x%X\n", core->id.id);
1007  }
1008  
1009 -static u8 bcma_host_pci_read8(struct bcma_device *core, u16 offset)
1010 -{
1011 +/* Provides access to the requested core. Returns base offset that has to be
1012 + * used. It makes use of fixed windows when possible. */
1013 +static u16 bcma_host_pci_provide_access_to_core(struct bcma_device *core)
1014 +{
1015 +       switch (core->id.id) {
1016 +       case BCMA_CORE_CHIPCOMMON:
1017 +               return 3 * BCMA_CORE_SIZE;
1018 +       case BCMA_CORE_PCIE:
1019 +               return 2 * BCMA_CORE_SIZE;
1020 +       }
1021 +
1022         if (core->bus->mapped_core != core)
1023                 bcma_host_pci_switch_core(core);
1024 +       return 0;
1025 +}
1026 +
1027 +static u8 bcma_host_pci_read8(struct bcma_device *core, u16 offset)
1028 +{
1029 +       offset += bcma_host_pci_provide_access_to_core(core);
1030         return ioread8(core->bus->mmio + offset);
1031  }
1032  
1033  static u16 bcma_host_pci_read16(struct bcma_device *core, u16 offset)
1034  {
1035 -       if (core->bus->mapped_core != core)
1036 -               bcma_host_pci_switch_core(core);
1037 +       offset += bcma_host_pci_provide_access_to_core(core);
1038         return ioread16(core->bus->mmio + offset);
1039  }
1040  
1041  static u32 bcma_host_pci_read32(struct bcma_device *core, u16 offset)
1042  {
1043 -       if (core->bus->mapped_core != core)
1044 -               bcma_host_pci_switch_core(core);
1045 +       offset += bcma_host_pci_provide_access_to_core(core);
1046         return ioread32(core->bus->mmio + offset);
1047  }
1048  
1049  static void bcma_host_pci_write8(struct bcma_device *core, u16 offset,
1050                                  u8 value)
1051  {
1052 -       if (core->bus->mapped_core != core)
1053 -               bcma_host_pci_switch_core(core);
1054 +       offset += bcma_host_pci_provide_access_to_core(core);
1055         iowrite8(value, core->bus->mmio + offset);
1056  }
1057  
1058  static void bcma_host_pci_write16(struct bcma_device *core, u16 offset,
1059                                  u16 value)
1060  {
1061 -       if (core->bus->mapped_core != core)
1062 -               bcma_host_pci_switch_core(core);
1063 +       offset += bcma_host_pci_provide_access_to_core(core);
1064         iowrite16(value, core->bus->mmio + offset);
1065  }
1066  
1067  static void bcma_host_pci_write32(struct bcma_device *core, u16 offset,
1068                                  u32 value)
1069  {
1070 -       if (core->bus->mapped_core != core)
1071 -               bcma_host_pci_switch_core(core);
1072 +       offset += bcma_host_pci_provide_access_to_core(core);
1073         iowrite32(value, core->bus->mmio + offset);
1074  }
1075  
1076 @@ -144,8 +154,8 @@ const struct bcma_host_ops bcma_host_pci
1077         .awrite32       = bcma_host_pci_awrite32,
1078  };
1079  
1080 -static int bcma_host_pci_probe(struct pci_dev *dev,
1081 -                            const struct pci_device_id *id)
1082 +static int __devinit bcma_host_pci_probe(struct pci_dev *dev,
1083 +                                        const struct pci_device_id *id)
1084  {
1085         struct bcma_bus *bus;
1086         int err = -ENOMEM;
1087 @@ -191,6 +201,9 @@ static int bcma_host_pci_probe(struct pc
1088         bus->hosttype = BCMA_HOSTTYPE_PCI;
1089         bus->ops = &bcma_host_pci_ops;
1090  
1091 +       bus->boardinfo.vendor = bus->host_pci->subsystem_vendor;
1092 +       bus->boardinfo.type = bus->host_pci->subsystem_device;
1093 +
1094         /* Register */
1095         err = bcma_bus_register(bus);
1096         if (err)
1097 @@ -212,7 +225,7 @@ err_kfree_bus:
1098         return err;
1099  }
1100  
1101 -static void bcma_host_pci_remove(struct pci_dev *dev)
1102 +static void __devexit bcma_host_pci_remove(struct pci_dev *dev)
1103  {
1104         struct bcma_bus *bus = pci_get_drvdata(dev);
1105  
1106 @@ -225,41 +238,32 @@ static void bcma_host_pci_remove(struct
1107  }
1108  
1109  #ifdef CONFIG_PM
1110 -static int bcma_host_pci_suspend(struct pci_dev *dev, pm_message_t state)
1111 +static int bcma_host_pci_suspend(struct device *dev)
1112  {
1113 -       struct bcma_bus *bus = pci_get_drvdata(dev);
1114 -
1115 -       /* Host specific */
1116 -       pci_save_state(dev);
1117 -       pci_disable_device(dev);
1118 -       pci_set_power_state(dev, pci_choose_state(dev, state));
1119 +       struct pci_dev *pdev = to_pci_dev(dev);
1120 +       struct bcma_bus *bus = pci_get_drvdata(pdev);
1121  
1122         bus->mapped_core = NULL;
1123 -       return 0;
1124 +
1125 +       return bcma_bus_suspend(bus);
1126  }
1127  
1128 -static int bcma_host_pci_resume(struct pci_dev *dev)
1129 +static int bcma_host_pci_resume(struct device *dev)
1130  {
1131 -       struct bcma_bus *bus = pci_get_drvdata(dev);
1132 -       int err;
1133 +       struct pci_dev *pdev = to_pci_dev(dev);
1134 +       struct bcma_bus *bus = pci_get_drvdata(pdev);
1135  
1136 -       /* Host specific */
1137 -       pci_set_power_state(dev, 0);
1138 -       err = pci_enable_device(dev);
1139 -       if (err)
1140 -               return err;
1141 -       pci_restore_state(dev);
1142 +       return bcma_bus_resume(bus);
1143 +}
1144  
1145 -       /* Bus specific */
1146 -       err = bcma_bus_resume(bus);
1147 -       if (err)
1148 -               return err;
1149 +static SIMPLE_DEV_PM_OPS(bcma_pm_ops, bcma_host_pci_suspend,
1150 +                        bcma_host_pci_resume);
1151 +#define BCMA_PM_OPS    (&bcma_pm_ops)
1152  
1153 -       return 0;
1154 -}
1155  #else /* CONFIG_PM */
1156 -# define bcma_host_pci_suspend NULL
1157 -# define bcma_host_pci_resume  NULL
1158 +
1159 +#define BCMA_PM_OPS     NULL
1160 +
1161  #endif /* CONFIG_PM */
1162  
1163  static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = {
1164 @@ -276,9 +280,8 @@ static struct pci_driver bcma_pci_bridge
1165         .name = "bcma-pci-bridge",
1166         .id_table = bcma_pci_bridge_tbl,
1167         .probe = bcma_host_pci_probe,
1168 -       .remove = bcma_host_pci_remove,
1169 -       .suspend = bcma_host_pci_suspend,
1170 -       .resume = bcma_host_pci_resume,
1171 +       .remove = __devexit_p(bcma_host_pci_remove),
1172 +       .driver.pm = BCMA_PM_OPS,
1173  };
1174  
1175  int __init bcma_host_pci_init(void)
1176 --- a/drivers/bcma/main.c
1177 +++ b/drivers/bcma/main.c
1178 @@ -13,6 +13,12 @@
1179  MODULE_DESCRIPTION("Broadcom's specific AMBA driver");
1180  MODULE_LICENSE("GPL");
1181  
1182 +/* contains the number the next bus should get. */
1183 +static unsigned int bcma_bus_next_num = 0;
1184 +
1185 +/* bcma_buses_mutex locks the bcma_bus_next_num */
1186 +static DEFINE_MUTEX(bcma_buses_mutex);
1187 +
1188  static int bcma_bus_match(struct device *dev, struct device_driver *drv);
1189  static int bcma_device_probe(struct device *dev);
1190  static int bcma_device_remove(struct device *dev);
1191 @@ -55,7 +61,7 @@ static struct bus_type bcma_bus_type = {
1192         .dev_attrs      = bcma_device_attrs,
1193  };
1194  
1195 -static struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid)
1196 +struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid)
1197  {
1198         struct bcma_device *core;
1199  
1200 @@ -65,6 +71,7 @@ static struct bcma_device *bcma_find_cor
1201         }
1202         return NULL;
1203  }
1204 +EXPORT_SYMBOL_GPL(bcma_find_core);
1205  
1206  static void bcma_release_core_dev(struct device *dev)
1207  {
1208 @@ -93,7 +100,7 @@ static int bcma_register_cores(struct bc
1209  
1210                 core->dev.release = bcma_release_core_dev;
1211                 core->dev.bus = &bcma_bus_type;
1212 -               dev_set_name(&core->dev, "bcma%d:%d", 0/*bus->num*/, dev_id);
1213 +               dev_set_name(&core->dev, "bcma%d:%d", bus->num, dev_id);
1214  
1215                 switch (bus->hosttype) {
1216                 case BCMA_HOSTTYPE_PCI:
1217 @@ -132,11 +139,15 @@ static void bcma_unregister_cores(struct
1218         }
1219  }
1220  
1221 -int bcma_bus_register(struct bcma_bus *bus)
1222 +int __devinit bcma_bus_register(struct bcma_bus *bus)
1223  {
1224         int err;
1225         struct bcma_device *core;
1226  
1227 +       mutex_lock(&bcma_buses_mutex);
1228 +       bus->num = bcma_bus_next_num++;
1229 +       mutex_unlock(&bcma_buses_mutex);
1230 +
1231         /* Scan for devices (cores) */
1232         err = bcma_bus_scan(bus);
1233         if (err) {
1234 @@ -169,10 +180,8 @@ int bcma_bus_register(struct bcma_bus *b
1235         err = bcma_sprom_get(bus);
1236         if (err == -ENOENT) {
1237                 pr_err("No SPROM available\n");
1238 -       } else if (err) {
1239 +       } else if (err)
1240                 pr_err("Failed to get SPROM: %d\n", err);
1241 -               return -ENOENT;
1242 -       }
1243  
1244         /* Register found cores */
1245         bcma_register_cores(bus);
1246 @@ -241,6 +250,21 @@ int __init bcma_bus_early_register(struc
1247  }
1248  
1249  #ifdef CONFIG_PM
1250 +int bcma_bus_suspend(struct bcma_bus *bus)
1251 +{
1252 +       struct bcma_device *core;
1253 +
1254 +       list_for_each_entry(core, &bus->cores, list) {
1255 +               struct device_driver *drv = core->dev.driver;
1256 +               if (drv) {
1257 +                       struct bcma_driver *adrv = container_of(drv, struct bcma_driver, drv);
1258 +                       if (adrv->suspend)
1259 +                               adrv->suspend(core);
1260 +               }
1261 +       }
1262 +       return 0;
1263 +}
1264 +
1265  int bcma_bus_resume(struct bcma_bus *bus)
1266  {
1267         struct bcma_device *core;
1268 @@ -252,6 +276,15 @@ int bcma_bus_resume(struct bcma_bus *bus
1269                 bcma_core_chipcommon_init(&bus->drv_cc);
1270         }
1271  
1272 +       list_for_each_entry(core, &bus->cores, list) {
1273 +               struct device_driver *drv = core->dev.driver;
1274 +               if (drv) {
1275 +                       struct bcma_driver *adrv = container_of(drv, struct bcma_driver, drv);
1276 +                       if (adrv->resume)
1277 +                               adrv->resume(core);
1278 +               }
1279 +       }
1280 +
1281         return 0;
1282  }
1283  #endif
1284 --- a/drivers/bcma/scan.c
1285 +++ b/drivers/bcma/scan.c
1286 @@ -19,7 +19,14 @@ struct bcma_device_id_name {
1287         u16 id;
1288         const char *name;
1289  };
1290 -struct bcma_device_id_name bcma_device_names[] = {
1291 +
1292 +static const struct bcma_device_id_name bcma_arm_device_names[] = {
1293 +       { BCMA_CORE_ARM_1176, "ARM 1176" },
1294 +       { BCMA_CORE_ARM_7TDMI, "ARM 7TDMI" },
1295 +       { BCMA_CORE_ARM_CM3, "ARM CM3" },
1296 +};
1297 +
1298 +static const struct bcma_device_id_name bcma_bcm_device_names[] = {
1299         { BCMA_CORE_OOB_ROUTER, "OOB Router" },
1300         { BCMA_CORE_INVALID, "Invalid" },
1301         { BCMA_CORE_CHIPCOMMON, "ChipCommon" },
1302 @@ -27,7 +34,6 @@ struct bcma_device_id_name bcma_device_n
1303         { BCMA_CORE_SRAM, "SRAM" },
1304         { BCMA_CORE_SDRAM, "SDRAM" },
1305         { BCMA_CORE_PCI, "PCI" },
1306 -       { BCMA_CORE_MIPS, "MIPS" },
1307         { BCMA_CORE_ETHERNET, "Fast Ethernet" },
1308         { BCMA_CORE_V90, "V90" },
1309         { BCMA_CORE_USB11_HOSTDEV, "USB 1.1 Hostdev" },
1310 @@ -44,7 +50,6 @@ struct bcma_device_id_name bcma_device_n
1311         { BCMA_CORE_PHY_A, "PHY A" },
1312         { BCMA_CORE_PHY_B, "PHY B" },
1313         { BCMA_CORE_PHY_G, "PHY G" },
1314 -       { BCMA_CORE_MIPS_3302, "MIPS 3302" },
1315         { BCMA_CORE_USB11_HOST, "USB 1.1 Host" },
1316         { BCMA_CORE_USB11_DEV, "USB 1.1 Device" },
1317         { BCMA_CORE_USB20_HOST, "USB 2.0 Host" },
1318 @@ -58,15 +63,11 @@ struct bcma_device_id_name bcma_device_n
1319         { BCMA_CORE_PHY_N, "PHY N" },
1320         { BCMA_CORE_SRAM_CTL, "SRAM Controller" },
1321         { BCMA_CORE_MINI_MACPHY, "Mini MACPHY" },
1322 -       { BCMA_CORE_ARM_1176, "ARM 1176" },
1323 -       { BCMA_CORE_ARM_7TDMI, "ARM 7TDMI" },
1324         { BCMA_CORE_PHY_LP, "PHY LP" },
1325         { BCMA_CORE_PMU, "PMU" },
1326         { BCMA_CORE_PHY_SSN, "PHY SSN" },
1327         { BCMA_CORE_SDIO_DEV, "SDIO Device" },
1328 -       { BCMA_CORE_ARM_CM3, "ARM CM3" },
1329         { BCMA_CORE_PHY_HT, "PHY HT" },
1330 -       { BCMA_CORE_MIPS_74K, "MIPS 74K" },
1331         { BCMA_CORE_MAC_GBIT, "GBit MAC" },
1332         { BCMA_CORE_DDR12_MEM_CTL, "DDR1/DDR2 Memory Controller" },
1333         { BCMA_CORE_PCIE_RC, "PCIe Root Complex" },
1334 @@ -79,16 +80,41 @@ struct bcma_device_id_name bcma_device_n
1335         { BCMA_CORE_SHIM, "SHIM" },
1336         { BCMA_CORE_DEFAULT, "Default" },
1337  };
1338 -const char *bcma_device_name(struct bcma_device_id *id)
1339 +
1340 +static const struct bcma_device_id_name bcma_mips_device_names[] = {
1341 +       { BCMA_CORE_MIPS, "MIPS" },
1342 +       { BCMA_CORE_MIPS_3302, "MIPS 3302" },
1343 +       { BCMA_CORE_MIPS_74K, "MIPS 74K" },
1344 +};
1345 +
1346 +static const char *bcma_device_name(const struct bcma_device_id *id)
1347  {
1348 -       int i;
1349 +       const struct bcma_device_id_name *names;
1350 +       int size, i;
1351  
1352 -       if (id->manuf == BCMA_MANUF_BCM) {
1353 -               for (i = 0; i < ARRAY_SIZE(bcma_device_names); i++) {
1354 -                       if (bcma_device_names[i].id == id->id)
1355 -                               return bcma_device_names[i].name;
1356 -               }
1357 +       /* search manufacturer specific names */
1358 +       switch (id->manuf) {
1359 +       case BCMA_MANUF_ARM:
1360 +               names = bcma_arm_device_names;
1361 +               size = ARRAY_SIZE(bcma_arm_device_names);
1362 +               break;
1363 +       case BCMA_MANUF_BCM:
1364 +               names = bcma_bcm_device_names;
1365 +               size = ARRAY_SIZE(bcma_bcm_device_names);
1366 +               break;
1367 +       case BCMA_MANUF_MIPS:
1368 +               names = bcma_mips_device_names;
1369 +               size = ARRAY_SIZE(bcma_mips_device_names);
1370 +               break;
1371 +       default:
1372 +               return "UNKNOWN";
1373 +       }
1374 +
1375 +       for (i = 0; i < size; i++) {
1376 +               if (names[i].id == id->id)
1377 +                       return names[i].name;
1378         }
1379 +
1380         return "UNKNOWN";
1381  }
1382  
1383 @@ -212,6 +238,17 @@ static struct bcma_device *bcma_find_cor
1384         return NULL;
1385  }
1386  
1387 +static struct bcma_device *bcma_find_core_reverse(struct bcma_bus *bus, u16 coreid)
1388 +{
1389 +       struct bcma_device *core;
1390 +
1391 +       list_for_each_entry_reverse(core, &bus->cores, list) {
1392 +               if (core->id.id == coreid)
1393 +                       return core;
1394 +       }
1395 +       return NULL;
1396 +}
1397 +
1398  static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
1399                               struct bcma_device_id *match, int core_num,
1400                               struct bcma_device *core)
1401 @@ -353,6 +390,7 @@ static int bcma_get_next_core(struct bcm
1402  void bcma_init_bus(struct bcma_bus *bus)
1403  {
1404         s32 tmp;
1405 +       struct bcma_chipinfo *chipinfo = &(bus->chipinfo);
1406  
1407         if (bus->init_done)
1408                 return;
1409 @@ -363,9 +401,12 @@ void bcma_init_bus(struct bcma_bus *bus)
1410         bcma_scan_switch_core(bus, BCMA_ADDR_BASE);
1411  
1412         tmp = bcma_scan_read32(bus, 0, BCMA_CC_ID);
1413 -       bus->chipinfo.id = (tmp & BCMA_CC_ID_ID) >> BCMA_CC_ID_ID_SHIFT;
1414 -       bus->chipinfo.rev = (tmp & BCMA_CC_ID_REV) >> BCMA_CC_ID_REV_SHIFT;
1415 -       bus->chipinfo.pkg = (tmp & BCMA_CC_ID_PKG) >> BCMA_CC_ID_PKG_SHIFT;
1416 +       chipinfo->id = (tmp & BCMA_CC_ID_ID) >> BCMA_CC_ID_ID_SHIFT;
1417 +       chipinfo->rev = (tmp & BCMA_CC_ID_REV) >> BCMA_CC_ID_REV_SHIFT;
1418 +       chipinfo->pkg = (tmp & BCMA_CC_ID_PKG) >> BCMA_CC_ID_PKG_SHIFT;
1419 +       pr_info("Found chip with id 0x%04X, rev 0x%02X and package 0x%02X\n",
1420 +               chipinfo->id, chipinfo->rev, chipinfo->pkg);
1421 +
1422         bus->init_done = true;
1423  }
1424  
1425 @@ -392,6 +433,7 @@ int bcma_bus_scan(struct bcma_bus *bus)
1426         bcma_scan_switch_core(bus, erombase);
1427  
1428         while (eromptr < eromend) {
1429 +               struct bcma_device *other_core;
1430                 struct bcma_device *core = kzalloc(sizeof(*core), GFP_KERNEL);
1431                 if (!core)
1432                         return -ENOMEM;
1433 @@ -399,18 +441,23 @@ int bcma_bus_scan(struct bcma_bus *bus)
1434                 core->bus = bus;
1435  
1436                 err = bcma_get_next_core(bus, &eromptr, NULL, core_num, core);
1437 -               if (err == -ENODEV) {
1438 -                       core_num++;
1439 -                       continue;
1440 -               } else if (err == -ENXIO)
1441 -                       continue;
1442 -               else if (err == -ESPIPE)
1443 -                       break;
1444 -               else if (err < 0)
1445 +               if (err < 0) {
1446 +                       kfree(core);
1447 +                       if (err == -ENODEV) {
1448 +                               core_num++;
1449 +                               continue;
1450 +                       } else if (err == -ENXIO) {
1451 +                               continue;
1452 +                       } else if (err == -ESPIPE) {
1453 +                               break;
1454 +                       }
1455                         return err;
1456 +               }
1457  
1458                 core->core_index = core_num++;
1459                 bus->nr_cores++;
1460 +               other_core = bcma_find_core_reverse(bus, core->id.id);
1461 +               core->core_unit = (other_core == NULL) ? 0 : other_core->core_unit + 1;
1462  
1463                 pr_info("Core %d found: %s "
1464                         "(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
1465 --- a/drivers/bcma/sprom.c
1466 +++ b/drivers/bcma/sprom.c
1467 @@ -2,6 +2,8 @@
1468   * Broadcom specific AMBA
1469   * SPROM reading
1470   *
1471 + * Copyright 2011, 2012, Hauke Mehrtens <hauke@hauke-m.de>
1472 + *
1473   * Licensed under the GNU/GPL. See COPYING for details.
1474   */
1475  
1476 @@ -14,7 +16,57 @@
1477  #include <linux/dma-mapping.h>
1478  #include <linux/slab.h>
1479  
1480 -#define SPOFF(offset)  ((offset) / sizeof(u16))
1481 +static int(*get_fallback_sprom)(struct bcma_bus *dev, struct ssb_sprom *out);
1482 +
1483 +/**
1484 + * bcma_arch_register_fallback_sprom - Registers a method providing a
1485 + * fallback SPROM if no SPROM is found.
1486 + *
1487 + * @sprom_callback: The callback function.
1488 + *
1489 + * With this function the architecture implementation may register a
1490 + * callback handler which fills the SPROM data structure. The fallback is
1491 + * used for PCI based BCMA devices, where no valid SPROM can be found
1492 + * in the shadow registers and to provide the SPROM for SoCs where BCMA is
1493 + * to controll the system bus.
1494 + *
1495 + * This function is useful for weird architectures that have a half-assed
1496 + * BCMA device hardwired to their PCI bus.
1497 + *
1498 + * This function is available for architecture code, only. So it is not
1499 + * exported.
1500 + */
1501 +int bcma_arch_register_fallback_sprom(int (*sprom_callback)(struct bcma_bus *bus,
1502 +                                    struct ssb_sprom *out))
1503 +{
1504 +       if (get_fallback_sprom)
1505 +               return -EEXIST;
1506 +       get_fallback_sprom = sprom_callback;
1507 +
1508 +       return 0;
1509 +}
1510 +
1511 +static int bcma_fill_sprom_with_fallback(struct bcma_bus *bus,
1512 +                                        struct ssb_sprom *out)
1513 +{
1514 +       int err;
1515 +
1516 +       if (!get_fallback_sprom) {
1517 +               err = -ENOENT;
1518 +               goto fail;
1519 +       }
1520 +
1521 +       err = get_fallback_sprom(bus, out);
1522 +       if (err)
1523 +               goto fail;
1524 +
1525 +       pr_debug("Using SPROM revision %d provided by"
1526 +                " platform.\n", bus->sprom.revision);
1527 +       return 0;
1528 +fail:
1529 +       pr_warn("Using fallback SPROM failed (err %d)\n", err);
1530 +       return err;
1531 +}
1532  
1533  /**************************************************
1534   * R/W ops.
1535 @@ -124,37 +176,403 @@ static int bcma_sprom_valid(const u16 *s
1536   * SPROM extraction.
1537   **************************************************/
1538  
1539 +#define SPOFF(offset)  ((offset) / sizeof(u16))
1540 +
1541 +#define SPEX(_field, _offset, _mask, _shift)   \
1542 +       bus->sprom._field = ((sprom[SPOFF(_offset)] & (_mask)) >> (_shift))
1543 +
1544 +#define SPEX32(_field, _offset, _mask, _shift) \
1545 +       bus->sprom._field = ((((u32)sprom[SPOFF((_offset)+2)] << 16 | \
1546 +                               sprom[SPOFF(_offset)]) & (_mask)) >> (_shift))
1547 +
1548 +#define SPEX_ARRAY8(_field, _offset, _mask, _shift)    \
1549 +       do {    \
1550 +               SPEX(_field[0], _offset +  0, _mask, _shift);   \
1551 +               SPEX(_field[1], _offset +  2, _mask, _shift);   \
1552 +               SPEX(_field[2], _offset +  4, _mask, _shift);   \
1553 +               SPEX(_field[3], _offset +  6, _mask, _shift);   \
1554 +               SPEX(_field[4], _offset +  8, _mask, _shift);   \
1555 +               SPEX(_field[5], _offset + 10, _mask, _shift);   \
1556 +               SPEX(_field[6], _offset + 12, _mask, _shift);   \
1557 +               SPEX(_field[7], _offset + 14, _mask, _shift);   \
1558 +       } while (0)
1559 +
1560  static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
1561  {
1562 -       u16 v;
1563 +       u16 v, o;
1564         int i;
1565 +       u16 pwr_info_offset[] = {
1566 +               SSB_SROM8_PWR_INFO_CORE0, SSB_SROM8_PWR_INFO_CORE1,
1567 +               SSB_SROM8_PWR_INFO_CORE2, SSB_SROM8_PWR_INFO_CORE3
1568 +       };
1569 +       BUILD_BUG_ON(ARRAY_SIZE(pwr_info_offset) !=
1570 +                       ARRAY_SIZE(bus->sprom.core_pwr_info));
1571 +
1572 +       bus->sprom.revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] &
1573 +               SSB_SPROM_REVISION_REV;
1574  
1575         for (i = 0; i < 3; i++) {
1576                 v = sprom[SPOFF(SSB_SPROM8_IL0MAC) + i];
1577                 *(((__be16 *)bus->sprom.il0mac) + i) = cpu_to_be16(v);
1578         }
1579  
1580 -       bus->sprom.board_rev = sprom[SPOFF(SSB_SPROM8_BOARDREV)];
1581 +       SPEX(board_rev, SSB_SPROM8_BOARDREV, ~0, 0);
1582  
1583 -       bus->sprom.boardflags_lo = sprom[SPOFF(SSB_SPROM8_BFLLO)];
1584 -       bus->sprom.boardflags_hi = sprom[SPOFF(SSB_SPROM8_BFLHI)];
1585 -       bus->sprom.boardflags2_lo = sprom[SPOFF(SSB_SPROM8_BFL2LO)];
1586 -       bus->sprom.boardflags2_hi = sprom[SPOFF(SSB_SPROM8_BFL2HI)];
1587 +       SPEX(txpid2g[0], SSB_SPROM4_TXPID2G01, SSB_SPROM4_TXPID2G0,
1588 +            SSB_SPROM4_TXPID2G0_SHIFT);
1589 +       SPEX(txpid2g[1], SSB_SPROM4_TXPID2G01, SSB_SPROM4_TXPID2G1,
1590 +            SSB_SPROM4_TXPID2G1_SHIFT);
1591 +       SPEX(txpid2g[2], SSB_SPROM4_TXPID2G23, SSB_SPROM4_TXPID2G2,
1592 +            SSB_SPROM4_TXPID2G2_SHIFT);
1593 +       SPEX(txpid2g[3], SSB_SPROM4_TXPID2G23, SSB_SPROM4_TXPID2G3,
1594 +            SSB_SPROM4_TXPID2G3_SHIFT);
1595 +
1596 +       SPEX(txpid5gl[0], SSB_SPROM4_TXPID5GL01, SSB_SPROM4_TXPID5GL0,
1597 +            SSB_SPROM4_TXPID5GL0_SHIFT);
1598 +       SPEX(txpid5gl[1], SSB_SPROM4_TXPID5GL01, SSB_SPROM4_TXPID5GL1,
1599 +            SSB_SPROM4_TXPID5GL1_SHIFT);
1600 +       SPEX(txpid5gl[2], SSB_SPROM4_TXPID5GL23, SSB_SPROM4_TXPID5GL2,
1601 +            SSB_SPROM4_TXPID5GL2_SHIFT);
1602 +       SPEX(txpid5gl[3], SSB_SPROM4_TXPID5GL23, SSB_SPROM4_TXPID5GL3,
1603 +            SSB_SPROM4_TXPID5GL3_SHIFT);
1604 +
1605 +       SPEX(txpid5g[0], SSB_SPROM4_TXPID5G01, SSB_SPROM4_TXPID5G0,
1606 +            SSB_SPROM4_TXPID5G0_SHIFT);
1607 +       SPEX(txpid5g[1], SSB_SPROM4_TXPID5G01, SSB_SPROM4_TXPID5G1,
1608 +            SSB_SPROM4_TXPID5G1_SHIFT);
1609 +       SPEX(txpid5g[2], SSB_SPROM4_TXPID5G23, SSB_SPROM4_TXPID5G2,
1610 +            SSB_SPROM4_TXPID5G2_SHIFT);
1611 +       SPEX(txpid5g[3], SSB_SPROM4_TXPID5G23, SSB_SPROM4_TXPID5G3,
1612 +            SSB_SPROM4_TXPID5G3_SHIFT);
1613 +
1614 +       SPEX(txpid5gh[0], SSB_SPROM4_TXPID5GH01, SSB_SPROM4_TXPID5GH0,
1615 +            SSB_SPROM4_TXPID5GH0_SHIFT);
1616 +       SPEX(txpid5gh[1], SSB_SPROM4_TXPID5GH01, SSB_SPROM4_TXPID5GH1,
1617 +            SSB_SPROM4_TXPID5GH1_SHIFT);
1618 +       SPEX(txpid5gh[2], SSB_SPROM4_TXPID5GH23, SSB_SPROM4_TXPID5GH2,
1619 +            SSB_SPROM4_TXPID5GH2_SHIFT);
1620 +       SPEX(txpid5gh[3], SSB_SPROM4_TXPID5GH23, SSB_SPROM4_TXPID5GH3,
1621 +            SSB_SPROM4_TXPID5GH3_SHIFT);
1622 +
1623 +       SPEX(boardflags_lo, SSB_SPROM8_BFLLO, ~0, 0);
1624 +       SPEX(boardflags_hi, SSB_SPROM8_BFLHI, ~0, 0);
1625 +       SPEX(boardflags2_lo, SSB_SPROM8_BFL2LO, ~0, 0);
1626 +       SPEX(boardflags2_hi, SSB_SPROM8_BFL2HI, ~0, 0);
1627 +
1628 +       SPEX(alpha2[0], SSB_SPROM8_CCODE, 0xff00, 8);
1629 +       SPEX(alpha2[1], SSB_SPROM8_CCODE, 0x00ff, 0);
1630 +
1631 +       /* Extract cores power info info */
1632 +       for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) {
1633 +               o = pwr_info_offset[i];
1634 +               SPEX(core_pwr_info[i].itssi_2g, o + SSB_SROM8_2G_MAXP_ITSSI,
1635 +                       SSB_SPROM8_2G_ITSSI, SSB_SPROM8_2G_ITSSI_SHIFT);
1636 +               SPEX(core_pwr_info[i].maxpwr_2g, o + SSB_SROM8_2G_MAXP_ITSSI,
1637 +                       SSB_SPROM8_2G_MAXP, 0);
1638 +
1639 +               SPEX(core_pwr_info[i].pa_2g[0], o + SSB_SROM8_2G_PA_0, ~0, 0);
1640 +               SPEX(core_pwr_info[i].pa_2g[1], o + SSB_SROM8_2G_PA_1, ~0, 0);
1641 +               SPEX(core_pwr_info[i].pa_2g[2], o + SSB_SROM8_2G_PA_2, ~0, 0);
1642 +
1643 +               SPEX(core_pwr_info[i].itssi_5g, o + SSB_SROM8_5G_MAXP_ITSSI,
1644 +                       SSB_SPROM8_5G_ITSSI, SSB_SPROM8_5G_ITSSI_SHIFT);
1645 +               SPEX(core_pwr_info[i].maxpwr_5g, o + SSB_SROM8_5G_MAXP_ITSSI,
1646 +                       SSB_SPROM8_5G_MAXP, 0);
1647 +               SPEX(core_pwr_info[i].maxpwr_5gh, o + SSB_SPROM8_5GHL_MAXP,
1648 +                       SSB_SPROM8_5GH_MAXP, 0);
1649 +               SPEX(core_pwr_info[i].maxpwr_5gl, o + SSB_SPROM8_5GHL_MAXP,
1650 +                       SSB_SPROM8_5GL_MAXP, SSB_SPROM8_5GL_MAXP_SHIFT);
1651 +
1652 +               SPEX(core_pwr_info[i].pa_5gl[0], o + SSB_SROM8_5GL_PA_0, ~0, 0);
1653 +               SPEX(core_pwr_info[i].pa_5gl[1], o + SSB_SROM8_5GL_PA_1, ~0, 0);
1654 +               SPEX(core_pwr_info[i].pa_5gl[2], o + SSB_SROM8_5GL_PA_2, ~0, 0);
1655 +               SPEX(core_pwr_info[i].pa_5g[0], o + SSB_SROM8_5G_PA_0, ~0, 0);
1656 +               SPEX(core_pwr_info[i].pa_5g[1], o + SSB_SROM8_5G_PA_1, ~0, 0);
1657 +               SPEX(core_pwr_info[i].pa_5g[2], o + SSB_SROM8_5G_PA_2, ~0, 0);
1658 +               SPEX(core_pwr_info[i].pa_5gh[0], o + SSB_SROM8_5GH_PA_0, ~0, 0);
1659 +               SPEX(core_pwr_info[i].pa_5gh[1], o + SSB_SROM8_5GH_PA_1, ~0, 0);
1660 +               SPEX(core_pwr_info[i].pa_5gh[2], o + SSB_SROM8_5GH_PA_2, ~0, 0);
1661 +       }
1662 +
1663 +       SPEX(fem.ghz2.tssipos, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_TSSIPOS,
1664 +            SSB_SROM8_FEM_TSSIPOS_SHIFT);
1665 +       SPEX(fem.ghz2.extpa_gain, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_EXTPA_GAIN,
1666 +            SSB_SROM8_FEM_EXTPA_GAIN_SHIFT);
1667 +       SPEX(fem.ghz2.pdet_range, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_PDET_RANGE,
1668 +            SSB_SROM8_FEM_PDET_RANGE_SHIFT);
1669 +       SPEX(fem.ghz2.tr_iso, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_TR_ISO,
1670 +            SSB_SROM8_FEM_TR_ISO_SHIFT);
1671 +       SPEX(fem.ghz2.antswlut, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_ANTSWLUT,
1672 +            SSB_SROM8_FEM_ANTSWLUT_SHIFT);
1673 +
1674 +       SPEX(fem.ghz5.tssipos, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_TSSIPOS,
1675 +            SSB_SROM8_FEM_TSSIPOS_SHIFT);
1676 +       SPEX(fem.ghz5.extpa_gain, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_EXTPA_GAIN,
1677 +            SSB_SROM8_FEM_EXTPA_GAIN_SHIFT);
1678 +       SPEX(fem.ghz5.pdet_range, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_PDET_RANGE,
1679 +            SSB_SROM8_FEM_PDET_RANGE_SHIFT);
1680 +       SPEX(fem.ghz5.tr_iso, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_TR_ISO,
1681 +            SSB_SROM8_FEM_TR_ISO_SHIFT);
1682 +       SPEX(fem.ghz5.antswlut, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_ANTSWLUT,
1683 +            SSB_SROM8_FEM_ANTSWLUT_SHIFT);
1684 +
1685 +       SPEX(ant_available_a, SSB_SPROM8_ANTAVAIL, SSB_SPROM8_ANTAVAIL_A,
1686 +            SSB_SPROM8_ANTAVAIL_A_SHIFT);
1687 +       SPEX(ant_available_bg, SSB_SPROM8_ANTAVAIL, SSB_SPROM8_ANTAVAIL_BG,
1688 +            SSB_SPROM8_ANTAVAIL_BG_SHIFT);
1689 +       SPEX(maxpwr_bg, SSB_SPROM8_MAXP_BG, SSB_SPROM8_MAXP_BG_MASK, 0);
1690 +       SPEX(itssi_bg, SSB_SPROM8_MAXP_BG, SSB_SPROM8_ITSSI_BG,
1691 +            SSB_SPROM8_ITSSI_BG_SHIFT);
1692 +       SPEX(maxpwr_a, SSB_SPROM8_MAXP_A, SSB_SPROM8_MAXP_A_MASK, 0);
1693 +       SPEX(itssi_a, SSB_SPROM8_MAXP_A, SSB_SPROM8_ITSSI_A,
1694 +            SSB_SPROM8_ITSSI_A_SHIFT);
1695 +       SPEX(maxpwr_ah, SSB_SPROM8_MAXP_AHL, SSB_SPROM8_MAXP_AH_MASK, 0);
1696 +       SPEX(maxpwr_al, SSB_SPROM8_MAXP_AHL, SSB_SPROM8_MAXP_AL_MASK,
1697 +            SSB_SPROM8_MAXP_AL_SHIFT);
1698 +       SPEX(gpio0, SSB_SPROM8_GPIOA, SSB_SPROM8_GPIOA_P0, 0);
1699 +       SPEX(gpio1, SSB_SPROM8_GPIOA, SSB_SPROM8_GPIOA_P1,
1700 +            SSB_SPROM8_GPIOA_P1_SHIFT);
1701 +       SPEX(gpio2, SSB_SPROM8_GPIOB, SSB_SPROM8_GPIOB_P2, 0);
1702 +       SPEX(gpio3, SSB_SPROM8_GPIOB, SSB_SPROM8_GPIOB_P3,
1703 +            SSB_SPROM8_GPIOB_P3_SHIFT);
1704 +       SPEX(tri2g, SSB_SPROM8_TRI25G, SSB_SPROM8_TRI2G, 0);
1705 +       SPEX(tri5g, SSB_SPROM8_TRI25G, SSB_SPROM8_TRI5G,
1706 +            SSB_SPROM8_TRI5G_SHIFT);
1707 +       SPEX(tri5gl, SSB_SPROM8_TRI5GHL, SSB_SPROM8_TRI5GL, 0);
1708 +       SPEX(tri5gh, SSB_SPROM8_TRI5GHL, SSB_SPROM8_TRI5GH,
1709 +            SSB_SPROM8_TRI5GH_SHIFT);
1710 +       SPEX(rxpo2g, SSB_SPROM8_RXPO, SSB_SPROM8_RXPO2G,
1711 +            SSB_SPROM8_RXPO2G_SHIFT);
1712 +       SPEX(rxpo5g, SSB_SPROM8_RXPO, SSB_SPROM8_RXPO5G,
1713 +            SSB_SPROM8_RXPO5G_SHIFT);
1714 +       SPEX(rssismf2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISMF2G, 0);
1715 +       SPEX(rssismc2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISMC2G,
1716 +            SSB_SPROM8_RSSISMC2G_SHIFT);
1717 +       SPEX(rssisav2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISAV2G,
1718 +            SSB_SPROM8_RSSISAV2G_SHIFT);
1719 +       SPEX(bxa2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_BXA2G,
1720 +            SSB_SPROM8_BXA2G_SHIFT);
1721 +       SPEX(rssismf5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISMF5G, 0);
1722 +       SPEX(rssismc5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISMC5G,
1723 +            SSB_SPROM8_RSSISMC5G_SHIFT);
1724 +       SPEX(rssisav5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISAV5G,
1725 +            SSB_SPROM8_RSSISAV5G_SHIFT);
1726 +       SPEX(bxa5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_BXA5G,
1727 +            SSB_SPROM8_BXA5G_SHIFT);
1728 +
1729 +       SPEX(pa0b0, SSB_SPROM8_PA0B0, ~0, 0);
1730 +       SPEX(pa0b1, SSB_SPROM8_PA0B1, ~0, 0);
1731 +       SPEX(pa0b2, SSB_SPROM8_PA0B2, ~0, 0);
1732 +       SPEX(pa1b0, SSB_SPROM8_PA1B0, ~0, 0);
1733 +       SPEX(pa1b1, SSB_SPROM8_PA1B1, ~0, 0);
1734 +       SPEX(pa1b2, SSB_SPROM8_PA1B2, ~0, 0);
1735 +       SPEX(pa1lob0, SSB_SPROM8_PA1LOB0, ~0, 0);
1736 +       SPEX(pa1lob1, SSB_SPROM8_PA1LOB1, ~0, 0);
1737 +       SPEX(pa1lob2, SSB_SPROM8_PA1LOB2, ~0, 0);
1738 +       SPEX(pa1hib0, SSB_SPROM8_PA1HIB0, ~0, 0);
1739 +       SPEX(pa1hib1, SSB_SPROM8_PA1HIB1, ~0, 0);
1740 +       SPEX(pa1hib2, SSB_SPROM8_PA1HIB2, ~0, 0);
1741 +       SPEX(cck2gpo, SSB_SPROM8_CCK2GPO, ~0, 0);
1742 +       SPEX32(ofdm2gpo, SSB_SPROM8_OFDM2GPO, ~0, 0);
1743 +       SPEX32(ofdm5glpo, SSB_SPROM8_OFDM5GLPO, ~0, 0);
1744 +       SPEX32(ofdm5gpo, SSB_SPROM8_OFDM5GPO, ~0, 0);
1745 +       SPEX32(ofdm5ghpo, SSB_SPROM8_OFDM5GHPO, ~0, 0);
1746 +
1747 +       /* Extract the antenna gain values. */
1748 +       SPEX(antenna_gain.a0, SSB_SPROM8_AGAIN01,
1749 +            SSB_SPROM8_AGAIN0, SSB_SPROM8_AGAIN0_SHIFT);
1750 +       SPEX(antenna_gain.a1, SSB_SPROM8_AGAIN01,
1751 +            SSB_SPROM8_AGAIN1, SSB_SPROM8_AGAIN1_SHIFT);
1752 +       SPEX(antenna_gain.a2, SSB_SPROM8_AGAIN23,
1753 +            SSB_SPROM8_AGAIN2, SSB_SPROM8_AGAIN2_SHIFT);
1754 +       SPEX(antenna_gain.a3, SSB_SPROM8_AGAIN23,
1755 +            SSB_SPROM8_AGAIN3, SSB_SPROM8_AGAIN3_SHIFT);
1756 +
1757 +       SPEX(leddc_on_time, SSB_SPROM8_LEDDC, SSB_SPROM8_LEDDC_ON,
1758 +            SSB_SPROM8_LEDDC_ON_SHIFT);
1759 +       SPEX(leddc_off_time, SSB_SPROM8_LEDDC, SSB_SPROM8_LEDDC_OFF,
1760 +            SSB_SPROM8_LEDDC_OFF_SHIFT);
1761 +
1762 +       SPEX(txchain, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_TXCHAIN,
1763 +            SSB_SPROM8_TXRXC_TXCHAIN_SHIFT);
1764 +       SPEX(rxchain, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_RXCHAIN,
1765 +            SSB_SPROM8_TXRXC_RXCHAIN_SHIFT);
1766 +       SPEX(antswitch, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_SWITCH,
1767 +            SSB_SPROM8_TXRXC_SWITCH_SHIFT);
1768 +
1769 +       SPEX(opo, SSB_SPROM8_OFDM2GPO, 0x00ff, 0);
1770 +
1771 +       SPEX_ARRAY8(mcs2gpo, SSB_SPROM8_2G_MCSPO, ~0, 0);
1772 +       SPEX_ARRAY8(mcs5gpo, SSB_SPROM8_5G_MCSPO, ~0, 0);
1773 +       SPEX_ARRAY8(mcs5glpo, SSB_SPROM8_5GL_MCSPO, ~0, 0);
1774 +       SPEX_ARRAY8(mcs5ghpo, SSB_SPROM8_5GH_MCSPO, ~0, 0);
1775 +
1776 +       SPEX(rawtempsense, SSB_SPROM8_RAWTS, SSB_SPROM8_RAWTS_RAWTEMP,
1777 +            SSB_SPROM8_RAWTS_RAWTEMP_SHIFT);
1778 +       SPEX(measpower, SSB_SPROM8_RAWTS, SSB_SPROM8_RAWTS_MEASPOWER,
1779 +            SSB_SPROM8_RAWTS_MEASPOWER_SHIFT);
1780 +       SPEX(tempsense_slope, SSB_SPROM8_OPT_CORRX,
1781 +            SSB_SPROM8_OPT_CORRX_TEMP_SLOPE,
1782 +            SSB_SPROM8_OPT_CORRX_TEMP_SLOPE_SHIFT);
1783 +       SPEX(tempcorrx, SSB_SPROM8_OPT_CORRX, SSB_SPROM8_OPT_CORRX_TEMPCORRX,
1784 +            SSB_SPROM8_OPT_CORRX_TEMPCORRX_SHIFT);
1785 +       SPEX(tempsense_option, SSB_SPROM8_OPT_CORRX,
1786 +            SSB_SPROM8_OPT_CORRX_TEMP_OPTION,
1787 +            SSB_SPROM8_OPT_CORRX_TEMP_OPTION_SHIFT);
1788 +       SPEX(freqoffset_corr, SSB_SPROM8_HWIQ_IQSWP,
1789 +            SSB_SPROM8_HWIQ_IQSWP_FREQ_CORR,
1790 +            SSB_SPROM8_HWIQ_IQSWP_FREQ_CORR_SHIFT);
1791 +       SPEX(iqcal_swp_dis, SSB_SPROM8_HWIQ_IQSWP,
1792 +            SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP,
1793 +            SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP_SHIFT);
1794 +       SPEX(hw_iqcal_en, SSB_SPROM8_HWIQ_IQSWP, SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL,
1795 +            SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL_SHIFT);
1796 +
1797 +       SPEX(bw40po, SSB_SPROM8_BW40PO, ~0, 0);
1798 +       SPEX(cddpo, SSB_SPROM8_CDDPO, ~0, 0);
1799 +       SPEX(stbcpo, SSB_SPROM8_STBCPO, ~0, 0);
1800 +       SPEX(bwduppo, SSB_SPROM8_BWDUPPO, ~0, 0);
1801 +
1802 +       SPEX(tempthresh, SSB_SPROM8_THERMAL, SSB_SPROM8_THERMAL_TRESH,
1803 +            SSB_SPROM8_THERMAL_TRESH_SHIFT);
1804 +       SPEX(tempoffset, SSB_SPROM8_THERMAL, SSB_SPROM8_THERMAL_OFFSET,
1805 +            SSB_SPROM8_THERMAL_OFFSET_SHIFT);
1806 +       SPEX(phycal_tempdelta, SSB_SPROM8_TEMPDELTA,
1807 +            SSB_SPROM8_TEMPDELTA_PHYCAL,
1808 +            SSB_SPROM8_TEMPDELTA_PHYCAL_SHIFT);
1809 +       SPEX(temps_period, SSB_SPROM8_TEMPDELTA, SSB_SPROM8_TEMPDELTA_PERIOD,
1810 +            SSB_SPROM8_TEMPDELTA_PERIOD_SHIFT);
1811 +       SPEX(temps_hysteresis, SSB_SPROM8_TEMPDELTA,
1812 +            SSB_SPROM8_TEMPDELTA_HYSTERESIS,
1813 +            SSB_SPROM8_TEMPDELTA_HYSTERESIS_SHIFT);
1814 +}
1815 +
1816 +/*
1817 + * Indicates the presence of external SPROM.
1818 + */
1819 +static bool bcma_sprom_ext_available(struct bcma_bus *bus)
1820 +{
1821 +       u32 chip_status;
1822 +       u32 srom_control;
1823 +       u32 present_mask;
1824 +
1825 +       if (bus->drv_cc.core->id.rev >= 31) {
1826 +               if (!(bus->drv_cc.capabilities & BCMA_CC_CAP_SPROM))
1827 +                       return false;
1828 +
1829 +               srom_control = bcma_read32(bus->drv_cc.core,
1830 +                                          BCMA_CC_SROM_CONTROL);
1831 +               return srom_control & BCMA_CC_SROM_CONTROL_PRESENT;
1832 +       }
1833  
1834 -       bus->sprom.country_code = sprom[SPOFF(SSB_SPROM8_CCODE)];
1835 +       /* older chipcommon revisions use chip status register */
1836 +       chip_status = bcma_read32(bus->drv_cc.core, BCMA_CC_CHIPSTAT);
1837 +       switch (bus->chipinfo.id) {
1838 +       case 0x4313:
1839 +               present_mask = BCMA_CC_CHIPST_4313_SPROM_PRESENT;
1840 +               break;
1841 +
1842 +       case 0x4331:
1843 +               present_mask = BCMA_CC_CHIPST_4331_SPROM_PRESENT;
1844 +               break;
1845 +
1846 +       default:
1847 +               return true;
1848 +       }
1849 +
1850 +       return chip_status & present_mask;
1851 +}
1852 +
1853 +/*
1854 + * Indicates that on-chip OTP memory is present and enabled.
1855 + */
1856 +static bool bcma_sprom_onchip_available(struct bcma_bus *bus)
1857 +{
1858 +       u32 chip_status;
1859 +       u32 otpsize = 0;
1860 +       bool present;
1861 +
1862 +       chip_status = bcma_read32(bus->drv_cc.core, BCMA_CC_CHIPSTAT);
1863 +       switch (bus->chipinfo.id) {
1864 +       case 0x4313:
1865 +               present = chip_status & BCMA_CC_CHIPST_4313_OTP_PRESENT;
1866 +               break;
1867 +
1868 +       case 0x4331:
1869 +               present = chip_status & BCMA_CC_CHIPST_4331_OTP_PRESENT;
1870 +               break;
1871 +
1872 +       case 43224:
1873 +       case 43225:
1874 +               /* for these chips OTP is always available */
1875 +               present = true;
1876 +               break;
1877 +
1878 +       default:
1879 +               present = false;
1880 +               break;
1881 +       }
1882 +
1883 +       if (present) {
1884 +               otpsize = bus->drv_cc.capabilities & BCMA_CC_CAP_OTPS;
1885 +               otpsize >>= BCMA_CC_CAP_OTPS_SHIFT;
1886 +       }
1887 +
1888 +       return otpsize != 0;
1889 +}
1890 +
1891 +/*
1892 + * Verify OTP is filled and determine the byte
1893 + * offset where SPROM data is located.
1894 + *
1895 + * On error, returns 0; byte offset otherwise.
1896 + */
1897 +static int bcma_sprom_onchip_offset(struct bcma_bus *bus)
1898 +{
1899 +       struct bcma_device *cc = bus->drv_cc.core;
1900 +       u32 offset;
1901 +
1902 +       /* verify OTP status */
1903 +       if ((bcma_read32(cc, BCMA_CC_OTPS) & BCMA_CC_OTPS_GU_PROG_HW) == 0)
1904 +               return 0;
1905 +
1906 +       /* obtain bit offset from otplayout register */
1907 +       offset = (bcma_read32(cc, BCMA_CC_OTPL) & BCMA_CC_OTPL_GURGN_OFFSET);
1908 +       return BCMA_CC_SPROM + (offset >> 3);
1909  }
1910  
1911  int bcma_sprom_get(struct bcma_bus *bus)
1912  {
1913 -       u16 offset;
1914 +       u16 offset = BCMA_CC_SPROM;
1915         u16 *sprom;
1916         int err = 0;
1917  
1918         if (!bus->drv_cc.core)
1919                 return -EOPNOTSUPP;
1920  
1921 -       if (!(bus->drv_cc.capabilities & BCMA_CC_CAP_SPROM))
1922 -               return -ENOENT;
1923 +       if (!bcma_sprom_ext_available(bus)) {
1924 +               bool sprom_onchip;
1925 +
1926 +               /*
1927 +                * External SPROM takes precedence so check
1928 +                * on-chip OTP only when no external SPROM
1929 +                * is present.
1930 +                */
1931 +               sprom_onchip = bcma_sprom_onchip_available(bus);
1932 +               if (sprom_onchip) {
1933 +                       /* determine offset */
1934 +                       offset = bcma_sprom_onchip_offset(bus);
1935 +               }
1936 +               if (!offset || !sprom_onchip) {
1937 +                       /*
1938 +                        * Maybe there is no SPROM on the device?
1939 +                        * Now we ask the arch code if there is some sprom
1940 +                        * available for this device in some other storage.
1941 +                        */
1942 +                       err = bcma_fill_sprom_with_fallback(bus, &bus->sprom);
1943 +                       return err;
1944 +               }
1945 +       }
1946  
1947         sprom = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16),
1948                         GFP_KERNEL);
1949 @@ -164,11 +582,7 @@ int bcma_sprom_get(struct bcma_bus *bus)
1950         if (bus->chipinfo.id == 0x4331)
1951                 bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, false);
1952  
1953 -       /* Most cards have SPROM moved by additional offset 0x30 (48 dwords).
1954 -        * According to brcm80211 this applies to cards with PCIe rev >= 6
1955 -        * TODO: understand this condition and use it */
1956 -       offset = (bus->chipinfo.id == 0x4331) ? BCMA_CC_SPROM :
1957 -               BCMA_CC_SPROM_PCIE6;
1958 +       pr_debug("SPROM offset 0x%x\n", offset);
1959         bcma_sprom_read(bus, offset, sprom);
1960  
1961         if (bus->chipinfo.id == 0x4331)
1962 --- a/include/linux/bcma/bcma.h
1963 +++ b/include/linux/bcma/bcma.h
1964 @@ -26,6 +26,11 @@ struct bcma_chipinfo {
1965         u8 pkg;
1966  };
1967  
1968 +struct bcma_boardinfo {
1969 +       u16 vendor;
1970 +       u16 type;
1971 +};
1972 +
1973  enum bcma_clkmode {
1974         BCMA_CLKMODE_FAST,
1975         BCMA_CLKMODE_DYNAMIC,
1976 @@ -136,6 +141,7 @@ struct bcma_device {
1977         bool dev_registered;
1978  
1979         u8 core_index;
1980 +       u8 core_unit;
1981  
1982         u32 addr;
1983         u32 wrap;
1984 @@ -162,7 +168,7 @@ struct bcma_driver {
1985  
1986         int (*probe)(struct bcma_device *dev);
1987         void (*remove)(struct bcma_device *dev);
1988 -       int (*suspend)(struct bcma_device *dev, pm_message_t state);
1989 +       int (*suspend)(struct bcma_device *dev);
1990         int (*resume)(struct bcma_device *dev);
1991         void (*shutdown)(struct bcma_device *dev);
1992  
1993 @@ -175,6 +181,12 @@ int __bcma_driver_register(struct bcma_d
1994  
1995  extern void bcma_driver_unregister(struct bcma_driver *drv);
1996  
1997 +/* Set a fallback SPROM.
1998 + * See kdoc at the function definition for complete documentation. */
1999 +extern int bcma_arch_register_fallback_sprom(
2000 +               int (*sprom_callback)(struct bcma_bus *bus,
2001 +               struct ssb_sprom *out));
2002 +
2003  struct bcma_bus {
2004         /* The MMIO area. */
2005         void __iomem *mmio;
2006 @@ -191,10 +203,13 @@ struct bcma_bus {
2007  
2008         struct bcma_chipinfo chipinfo;
2009  
2010 +       struct bcma_boardinfo boardinfo;
2011 +
2012         struct bcma_device *mapped_core;
2013         struct list_head cores;
2014         u8 nr_cores;
2015         u8 init_done:1;
2016 +       u8 num;
2017  
2018         struct bcma_drv_cc drv_cc;
2019         struct bcma_drv_pci drv_pci;
2020 @@ -205,62 +220,84 @@ struct bcma_bus {
2021         struct ssb_sprom sprom;
2022  };
2023  
2024 -extern inline u32 bcma_read8(struct bcma_device *core, u16 offset)
2025 +static inline u32 bcma_read8(struct bcma_device *core, u16 offset)
2026  {
2027         return core->bus->ops->read8(core, offset);
2028  }
2029 -extern inline u32 bcma_read16(struct bcma_device *core, u16 offset)
2030 +static inline u32 bcma_read16(struct bcma_device *core, u16 offset)
2031  {
2032         return core->bus->ops->read16(core, offset);
2033  }
2034 -extern inline u32 bcma_read32(struct bcma_device *core, u16 offset)
2035 +static inline u32 bcma_read32(struct bcma_device *core, u16 offset)
2036  {
2037         return core->bus->ops->read32(core, offset);
2038  }
2039 -extern inline
2040 +static inline
2041  void bcma_write8(struct bcma_device *core, u16 offset, u32 value)
2042  {
2043         core->bus->ops->write8(core, offset, value);
2044  }
2045 -extern inline
2046 +static inline
2047  void bcma_write16(struct bcma_device *core, u16 offset, u32 value)
2048  {
2049         core->bus->ops->write16(core, offset, value);
2050  }
2051 -extern inline
2052 +static inline
2053  void bcma_write32(struct bcma_device *core, u16 offset, u32 value)
2054  {
2055         core->bus->ops->write32(core, offset, value);
2056  }
2057  #ifdef CONFIG_BCMA_BLOCKIO
2058 -extern inline void bcma_block_read(struct bcma_device *core, void *buffer,
2059 +static inline void bcma_block_read(struct bcma_device *core, void *buffer,
2060                                    size_t count, u16 offset, u8 reg_width)
2061  {
2062         core->bus->ops->block_read(core, buffer, count, offset, reg_width);
2063  }
2064 -extern inline void bcma_block_write(struct bcma_device *core, const void *buffer,
2065 -                                   size_t count, u16 offset, u8 reg_width)
2066 +static inline void bcma_block_write(struct bcma_device *core,
2067 +                                   const void *buffer, size_t count,
2068 +                                   u16 offset, u8 reg_width)
2069  {
2070         core->bus->ops->block_write(core, buffer, count, offset, reg_width);
2071  }
2072  #endif
2073 -extern inline u32 bcma_aread32(struct bcma_device *core, u16 offset)
2074 +static inline u32 bcma_aread32(struct bcma_device *core, u16 offset)
2075  {
2076         return core->bus->ops->aread32(core, offset);
2077  }
2078 -extern inline
2079 +static inline
2080  void bcma_awrite32(struct bcma_device *core, u16 offset, u32 value)
2081  {
2082         core->bus->ops->awrite32(core, offset, value);
2083  }
2084  
2085 -#define bcma_mask32(cc, offset, mask) \
2086 -       bcma_write32(cc, offset, bcma_read32(cc, offset) & (mask))
2087 -#define bcma_set32(cc, offset, set) \
2088 -       bcma_write32(cc, offset, bcma_read32(cc, offset) | (set))
2089 -#define bcma_maskset32(cc, offset, mask, set) \
2090 -       bcma_write32(cc, offset, (bcma_read32(cc, offset) & (mask)) | (set))
2091 +static inline void bcma_mask32(struct bcma_device *cc, u16 offset, u32 mask)
2092 +{
2093 +       bcma_write32(cc, offset, bcma_read32(cc, offset) & mask);
2094 +}
2095 +static inline void bcma_set32(struct bcma_device *cc, u16 offset, u32 set)
2096 +{
2097 +       bcma_write32(cc, offset, bcma_read32(cc, offset) | set);
2098 +}
2099 +static inline void bcma_maskset32(struct bcma_device *cc,
2100 +                                 u16 offset, u32 mask, u32 set)
2101 +{
2102 +       bcma_write32(cc, offset, (bcma_read32(cc, offset) & mask) | set);
2103 +}
2104 +static inline void bcma_mask16(struct bcma_device *cc, u16 offset, u16 mask)
2105 +{
2106 +       bcma_write16(cc, offset, bcma_read16(cc, offset) & mask);
2107 +}
2108 +static inline void bcma_set16(struct bcma_device *cc, u16 offset, u16 set)
2109 +{
2110 +       bcma_write16(cc, offset, bcma_read16(cc, offset) | set);
2111 +}
2112 +static inline void bcma_maskset16(struct bcma_device *cc,
2113 +                                 u16 offset, u16 mask, u16 set)
2114 +{
2115 +       bcma_write16(cc, offset, (bcma_read16(cc, offset) & mask) | set);
2116 +}
2117  
2118 +extern struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid);
2119  extern bool bcma_core_is_enabled(struct bcma_device *core);
2120  extern void bcma_core_disable(struct bcma_device *core, u32 flags);
2121  extern int bcma_core_enable(struct bcma_device *core, u32 flags);
2122 --- a/include/linux/bcma/bcma_driver_chipcommon.h
2123 +++ b/include/linux/bcma/bcma_driver_chipcommon.h
2124 @@ -56,6 +56,9 @@
2125  #define         BCMA_CC_OTPS_HW_PROTECT        0x00000001
2126  #define         BCMA_CC_OTPS_SW_PROTECT        0x00000002
2127  #define         BCMA_CC_OTPS_CID_PROTECT       0x00000004
2128 +#define  BCMA_CC_OTPS_GU_PROG_IND      0x00000F00      /* General Use programmed indication */
2129 +#define  BCMA_CC_OTPS_GU_PROG_IND_SHIFT        8
2130 +#define  BCMA_CC_OTPS_GU_PROG_HW       0x00000100      /* HW region programmed */
2131  #define BCMA_CC_OTPC                   0x0014          /* OTP control */
2132  #define         BCMA_CC_OTPC_RECWAIT           0xFF000000
2133  #define         BCMA_CC_OTPC_PROGWAIT          0x00FFFF00
2134 @@ -72,6 +75,8 @@
2135  #define         BCMA_CC_OTPP_READ              0x40000000
2136  #define         BCMA_CC_OTPP_START             0x80000000
2137  #define         BCMA_CC_OTPP_BUSY              0x80000000
2138 +#define BCMA_CC_OTPL                   0x001C          /* OTP layout */
2139 +#define  BCMA_CC_OTPL_GURGN_OFFSET     0x00000FFF      /* offset of general use region */
2140  #define BCMA_CC_IRQSTAT                        0x0020
2141  #define BCMA_CC_IRQMASK                        0x0024
2142  #define         BCMA_CC_IRQ_GPIO               0x00000001      /* gpio intr */
2143 @@ -79,6 +84,10 @@
2144  #define         BCMA_CC_IRQ_WDRESET            0x80000000      /* watchdog reset occurred */
2145  #define BCMA_CC_CHIPCTL                        0x0028          /* Rev >= 11 only */
2146  #define BCMA_CC_CHIPSTAT               0x002C          /* Rev >= 11 only */
2147 +#define  BCMA_CC_CHIPST_4313_SPROM_PRESENT     1
2148 +#define  BCMA_CC_CHIPST_4313_OTP_PRESENT       2
2149 +#define  BCMA_CC_CHIPST_4331_SPROM_PRESENT     2
2150 +#define  BCMA_CC_CHIPST_4331_OTP_PRESENT       4
2151  #define BCMA_CC_JCMD                   0x0030          /* Rev >= 10 only */
2152  #define  BCMA_CC_JCMD_START            0x80000000
2153  #define  BCMA_CC_JCMD_BUSY             0x80000000
2154 @@ -181,6 +190,22 @@
2155  #define BCMA_CC_FLASH_CFG              0x0128
2156  #define  BCMA_CC_FLASH_CFG_DS          0x0010  /* Data size, 0=8bit, 1=16bit */
2157  #define BCMA_CC_FLASH_WAITCNT          0x012C
2158 +#define BCMA_CC_SROM_CONTROL           0x0190
2159 +#define  BCMA_CC_SROM_CONTROL_START    0x80000000
2160 +#define  BCMA_CC_SROM_CONTROL_BUSY     0x80000000
2161 +#define  BCMA_CC_SROM_CONTROL_OPCODE   0x60000000
2162 +#define  BCMA_CC_SROM_CONTROL_OP_READ  0x00000000
2163 +#define  BCMA_CC_SROM_CONTROL_OP_WRITE 0x20000000
2164 +#define  BCMA_CC_SROM_CONTROL_OP_WRDIS 0x40000000
2165 +#define  BCMA_CC_SROM_CONTROL_OP_WREN  0x60000000
2166 +#define  BCMA_CC_SROM_CONTROL_OTPSEL   0x00000010
2167 +#define  BCMA_CC_SROM_CONTROL_LOCK     0x00000008
2168 +#define  BCMA_CC_SROM_CONTROL_SIZE_MASK        0x00000006
2169 +#define  BCMA_CC_SROM_CONTROL_SIZE_1K  0x00000000
2170 +#define  BCMA_CC_SROM_CONTROL_SIZE_4K  0x00000002
2171 +#define  BCMA_CC_SROM_CONTROL_SIZE_16K 0x00000004
2172 +#define  BCMA_CC_SROM_CONTROL_SIZE_SHIFT       1
2173 +#define  BCMA_CC_SROM_CONTROL_PRESENT  0x00000001
2174  /* 0x1E0 is defined as shared BCMA_CLKCTLST */
2175  #define BCMA_CC_HW_WORKAROUND          0x01E4 /* Hardware workaround (rev >= 20) */
2176  #define BCMA_CC_UART0_DATA             0x0300
2177 @@ -203,6 +228,7 @@
2178  #define BCMA_CC_PMU_CTL                        0x0600 /* PMU control */
2179  #define  BCMA_CC_PMU_CTL_ILP_DIV       0xFFFF0000 /* ILP div mask */
2180  #define  BCMA_CC_PMU_CTL_ILP_DIV_SHIFT 16
2181 +#define  BCMA_CC_PMU_CTL_PLL_UPD       0x00000400
2182  #define  BCMA_CC_PMU_CTL_NOILPONW      0x00000200 /* No ILP on wait */
2183  #define  BCMA_CC_PMU_CTL_HTREQEN       0x00000100 /* HT req enable */
2184  #define  BCMA_CC_PMU_CTL_ALPREQEN      0x00000080 /* ALP req enable */
2185 @@ -239,7 +265,6 @@
2186  #define BCMA_CC_PLLCTL_ADDR            0x0660
2187  #define BCMA_CC_PLLCTL_DATA            0x0664
2188  #define BCMA_CC_SPROM                  0x0800 /* SPROM beginning */
2189 -#define BCMA_CC_SPROM_PCIE6            0x0830 /* SPROM beginning on PCIe rev >= 6 */
2190  
2191  /* Divider allocation in 4716/47162/5356 */
2192  #define BCMA_CC_PMU5_MAINPLL_CPU       1
2193 --- a/include/linux/bcma/bcma_driver_pci.h
2194 +++ b/include/linux/bcma/bcma_driver_pci.h
2195 @@ -53,11 +53,47 @@ struct pci_dev;
2196  #define  BCMA_CORE_PCI_SBTOPCI1_MASK           0xFC000000
2197  #define BCMA_CORE_PCI_SBTOPCI2                 0x0108  /* Backplane to PCI translation 2 (sbtopci2) */
2198  #define  BCMA_CORE_PCI_SBTOPCI2_MASK           0xC0000000
2199 +#define BCMA_CORE_PCI_CONFIG_ADDR              0x0120  /* pcie config space access */
2200 +#define BCMA_CORE_PCI_CONFIG_DATA              0x0124  /* pcie config space access */
2201 +#define BCMA_CORE_PCI_MDIO_CONTROL             0x0128  /* controls the mdio access */
2202 +#define  BCMA_CORE_PCI_MDIOCTL_DIVISOR_MASK    0x7f    /* clock to be used on MDIO */
2203 +#define  BCMA_CORE_PCI_MDIOCTL_DIVISOR_VAL     0x2
2204 +#define  BCMA_CORE_PCI_MDIOCTL_PREAM_EN                0x80    /* Enable preamble sequnce */
2205 +#define  BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE     0x100   /* Tranaction complete */
2206 +#define BCMA_CORE_PCI_MDIO_DATA                        0x012c  /* Data to the mdio access */
2207 +#define  BCMA_CORE_PCI_MDIODATA_MASK           0x0000ffff /* data 2 bytes */
2208 +#define  BCMA_CORE_PCI_MDIODATA_TA             0x00020000 /* Turnaround */
2209 +#define  BCMA_CORE_PCI_MDIODATA_REGADDR_SHF_OLD        18      /* Regaddr shift (rev < 10) */
2210 +#define  BCMA_CORE_PCI_MDIODATA_REGADDR_MASK_OLD       0x003c0000 /* Regaddr Mask (rev < 10) */
2211 +#define  BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF_OLD        22      /* Physmedia devaddr shift (rev < 10) */
2212 +#define  BCMA_CORE_PCI_MDIODATA_DEVADDR_MASK_OLD       0x0fc00000 /* Physmedia devaddr Mask (rev < 10) */
2213 +#define  BCMA_CORE_PCI_MDIODATA_REGADDR_SHF    18      /* Regaddr shift */
2214 +#define  BCMA_CORE_PCI_MDIODATA_REGADDR_MASK   0x007c0000 /* Regaddr Mask */
2215 +#define  BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF    23      /* Physmedia devaddr shift */
2216 +#define  BCMA_CORE_PCI_MDIODATA_DEVADDR_MASK   0x0f800000 /* Physmedia devaddr Mask */
2217 +#define  BCMA_CORE_PCI_MDIODATA_WRITE          0x10000000 /* write Transaction */
2218 +#define  BCMA_CORE_PCI_MDIODATA_READ           0x20000000 /* Read Transaction */
2219 +#define  BCMA_CORE_PCI_MDIODATA_START          0x40000000 /* start of Transaction */
2220 +#define  BCMA_CORE_PCI_MDIODATA_DEV_ADDR       0x0     /* dev address for serdes */
2221 +#define  BCMA_CORE_PCI_MDIODATA_BLK_ADDR       0x1F    /* blk address for serdes */
2222 +#define  BCMA_CORE_PCI_MDIODATA_DEV_PLL                0x1d    /* SERDES PLL Dev */
2223 +#define  BCMA_CORE_PCI_MDIODATA_DEV_TX         0x1e    /* SERDES TX Dev */
2224 +#define  BCMA_CORE_PCI_MDIODATA_DEV_RX         0x1f    /* SERDES RX Dev */
2225 +#define BCMA_CORE_PCI_PCIEIND_ADDR             0x0130  /* indirect access to the internal register */
2226 +#define BCMA_CORE_PCI_PCIEIND_DATA             0x0134  /* Data to/from the internal regsiter */
2227 +#define BCMA_CORE_PCI_CLKREQENCTRL             0x0138  /*  >= rev 6, Clkreq rdma control */
2228  #define BCMA_CORE_PCI_PCICFG0                  0x0400  /* PCI config space 0 (rev >= 8) */
2229  #define BCMA_CORE_PCI_PCICFG1                  0x0500  /* PCI config space 1 (rev >= 8) */
2230  #define BCMA_CORE_PCI_PCICFG2                  0x0600  /* PCI config space 2 (rev >= 8) */
2231  #define BCMA_CORE_PCI_PCICFG3                  0x0700  /* PCI config space 3 (rev >= 8) */
2232  #define BCMA_CORE_PCI_SPROM(wordoffset)                (0x0800 + ((wordoffset) * 2)) /* SPROM shadow area (72 bytes) */
2233 +#define  BCMA_CORE_PCI_SPROM_PI_OFFSET         0       /* first word */
2234 +#define   BCMA_CORE_PCI_SPROM_PI_MASK          0xf000  /* bit 15:12 */
2235 +#define   BCMA_CORE_PCI_SPROM_PI_SHIFT         12      /* bit 15:12 */
2236 +#define  BCMA_CORE_PCI_SPROM_MISC_CONFIG       5       /* word 5 */
2237 +#define   BCMA_CORE_PCI_SPROM_L23READY_EXIT_NOPERST    0x8000  /* bit 15 */
2238 +#define   BCMA_CORE_PCI_SPROM_CLKREQ_OFFSET_REV5       20      /* word 20 for srom rev <= 5 */
2239 +#define   BCMA_CORE_PCI_SPROM_CLKREQ_ENB       0x0800  /* bit 11 */
2240  
2241  /* SBtoPCIx */
2242  #define BCMA_CORE_PCI_SBTOPCI_MEM              0x00000000
2243 @@ -72,20 +108,118 @@ struct pci_dev;
2244  #define  BCMA_CORE_PCI_SBTOPCI_RC_READL                0x00000010 /* Memory read line */
2245  #define  BCMA_CORE_PCI_SBTOPCI_RC_READM                0x00000020 /* Memory read multiple */
2246  
2247 +/* PCIE protocol PHY diagnostic registers */
2248 +#define BCMA_CORE_PCI_PLP_MODEREG              0x200   /* Mode */
2249 +#define BCMA_CORE_PCI_PLP_STATUSREG            0x204   /* Status */
2250 +#define  BCMA_CORE_PCI_PLP_POLARITYINV_STAT    0x10    /* Status reg PCIE_PLP_STATUSREG */
2251 +#define BCMA_CORE_PCI_PLP_LTSSMCTRLREG         0x208   /* LTSSM control */
2252 +#define BCMA_CORE_PCI_PLP_LTLINKNUMREG         0x20c   /* Link Training Link number */
2253 +#define BCMA_CORE_PCI_PLP_LTLANENUMREG         0x210   /* Link Training Lane number */
2254 +#define BCMA_CORE_PCI_PLP_LTNFTSREG            0x214   /* Link Training N_FTS */
2255 +#define BCMA_CORE_PCI_PLP_ATTNREG              0x218   /* Attention */
2256 +#define BCMA_CORE_PCI_PLP_ATTNMASKREG          0x21C   /* Attention Mask */
2257 +#define BCMA_CORE_PCI_PLP_RXERRCTR             0x220   /* Rx Error */
2258 +#define BCMA_CORE_PCI_PLP_RXFRMERRCTR          0x224   /* Rx Framing Error */
2259 +#define BCMA_CORE_PCI_PLP_RXERRTHRESHREG       0x228   /* Rx Error threshold */
2260 +#define BCMA_CORE_PCI_PLP_TESTCTRLREG          0x22C   /* Test Control reg */
2261 +#define BCMA_CORE_PCI_PLP_SERDESCTRLOVRDREG    0x230   /* SERDES Control Override */
2262 +#define BCMA_CORE_PCI_PLP_TIMINGOVRDREG                0x234   /* Timing param override */
2263 +#define BCMA_CORE_PCI_PLP_RXTXSMDIAGREG                0x238   /* RXTX State Machine Diag */
2264 +#define BCMA_CORE_PCI_PLP_LTSSMDIAGREG         0x23C   /* LTSSM State Machine Diag */
2265 +
2266 +/* PCIE protocol DLLP diagnostic registers */
2267 +#define BCMA_CORE_PCI_DLLP_LCREG               0x100   /* Link Control */
2268 +#define BCMA_CORE_PCI_DLLP_LSREG               0x104   /* Link Status */
2269 +#define BCMA_CORE_PCI_DLLP_LAREG               0x108   /* Link Attention */
2270 +#define  BCMA_CORE_PCI_DLLP_LSREG_LINKUP       (1 << 16)
2271 +#define BCMA_CORE_PCI_DLLP_LAMASKREG           0x10C   /* Link Attention Mask */
2272 +#define BCMA_CORE_PCI_DLLP_NEXTTXSEQNUMREG     0x110   /* Next Tx Seq Num */
2273 +#define BCMA_CORE_PCI_DLLP_ACKEDTXSEQNUMREG    0x114   /* Acked Tx Seq Num */
2274 +#define BCMA_CORE_PCI_DLLP_PURGEDTXSEQNUMREG   0x118   /* Purged Tx Seq Num */
2275 +#define BCMA_CORE_PCI_DLLP_RXSEQNUMREG         0x11C   /* Rx Sequence Number */
2276 +#define BCMA_CORE_PCI_DLLP_LRREG               0x120   /* Link Replay */
2277 +#define BCMA_CORE_PCI_DLLP_LACKTOREG           0x124   /* Link Ack Timeout */
2278 +#define BCMA_CORE_PCI_DLLP_PMTHRESHREG         0x128   /* Power Management Threshold */
2279 +#define  BCMA_CORE_PCI_ASPMTIMER_EXTEND                0x01000000 /* > rev7: enable extend ASPM timer */
2280 +#define BCMA_CORE_PCI_DLLP_RTRYWPREG           0x12C   /* Retry buffer write ptr */
2281 +#define BCMA_CORE_PCI_DLLP_RTRYRPREG           0x130   /* Retry buffer Read ptr */
2282 +#define BCMA_CORE_PCI_DLLP_RTRYPPREG           0x134   /* Retry buffer Purged ptr */
2283 +#define BCMA_CORE_PCI_DLLP_RTRRWREG            0x138   /* Retry buffer Read/Write */
2284 +#define BCMA_CORE_PCI_DLLP_ECTHRESHREG         0x13C   /* Error Count Threshold */
2285 +#define BCMA_CORE_PCI_DLLP_TLPERRCTRREG                0x140   /* TLP Error Counter */
2286 +#define BCMA_CORE_PCI_DLLP_ERRCTRREG           0x144   /* Error Counter */
2287 +#define BCMA_CORE_PCI_DLLP_NAKRXCTRREG         0x148   /* NAK Received Counter */
2288 +#define BCMA_CORE_PCI_DLLP_TESTREG             0x14C   /* Test */
2289 +#define BCMA_CORE_PCI_DLLP_PKTBIST             0x150   /* Packet BIST */
2290 +#define BCMA_CORE_PCI_DLLP_PCIE11              0x154   /* DLLP PCIE 1.1 reg */
2291 +
2292 +/* SERDES RX registers */
2293 +#define BCMA_CORE_PCI_SERDES_RX_CTRL           1       /* Rx cntrl */
2294 +#define  BCMA_CORE_PCI_SERDES_RX_CTRL_FORCE    0x80    /* rxpolarity_force */
2295 +#define  BCMA_CORE_PCI_SERDES_RX_CTRL_POLARITY 0x40    /* rxpolarity_value */
2296 +#define BCMA_CORE_PCI_SERDES_RX_TIMER1         2       /* Rx Timer1 */
2297 +#define BCMA_CORE_PCI_SERDES_RX_CDR            6       /* CDR */
2298 +#define BCMA_CORE_PCI_SERDES_RX_CDRBW          7       /* CDR BW */
2299 +
2300 +/* SERDES PLL registers */
2301 +#define BCMA_CORE_PCI_SERDES_PLL_CTRL          1       /* PLL control reg */
2302 +#define BCMA_CORE_PCI_PLL_CTRL_FREQDET_EN      0x4000  /* bit 14 is FREQDET on */
2303 +
2304  /* PCIcore specific boardflags */
2305  #define BCMA_CORE_PCI_BFL_NOPCI                        0x00000400 /* Board leaves PCI floating */
2306  
2307 +/* PCIE Config space accessing MACROS */
2308 +#define BCMA_CORE_PCI_CFG_BUS_SHIFT            24      /* Bus shift */
2309 +#define BCMA_CORE_PCI_CFG_SLOT_SHIFT           19      /* Slot/Device shift */
2310 +#define BCMA_CORE_PCI_CFG_FUN_SHIFT            16      /* Function shift */
2311 +#define BCMA_CORE_PCI_CFG_OFF_SHIFT            0       /* Register shift */
2312 +
2313 +#define BCMA_CORE_PCI_CFG_BUS_MASK             0xff    /* Bus mask */
2314 +#define BCMA_CORE_PCI_CFG_SLOT_MASK            0x1f    /* Slot/Device mask */
2315 +#define BCMA_CORE_PCI_CFG_FUN_MASK             7       /* Function mask */
2316 +#define BCMA_CORE_PCI_CFG_OFF_MASK             0xfff   /* Register mask */
2317 +
2318 +/* PCIE Root Capability Register bits (Host mode only) */
2319 +#define BCMA_CORE_PCI_RC_CRS_VISIBILITY                0x0001
2320 +
2321 +struct bcma_drv_pci;
2322 +
2323 +#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
2324 +struct bcma_drv_pci_host {
2325 +       struct bcma_drv_pci *pdev;
2326 +
2327 +       u32 host_cfg_addr;
2328 +       spinlock_t cfgspace_lock;
2329 +
2330 +       struct pci_controller pci_controller;
2331 +       struct pci_ops pci_ops;
2332 +       struct resource mem_resource;
2333 +       struct resource io_resource;
2334 +};
2335 +#endif
2336 +
2337  struct bcma_drv_pci {
2338         struct bcma_device *core;
2339         u8 setup_done:1;
2340 +       u8 hostmode:1;
2341 +
2342 +#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
2343 +       struct bcma_drv_pci_host *host_controller;
2344 +#endif
2345  };
2346  
2347  /* Register access */
2348 +#define pcicore_read16(pc, offset)             bcma_read16((pc)->core, offset)
2349  #define pcicore_read32(pc, offset)             bcma_read32((pc)->core, offset)
2350 +#define pcicore_write16(pc, offset, val)       bcma_write16((pc)->core, offset, val)
2351  #define pcicore_write32(pc, offset, val)       bcma_write32((pc)->core, offset, val)
2352  
2353 -extern void bcma_core_pci_init(struct bcma_drv_pci *pc);
2354 +extern void __devinit bcma_core_pci_init(struct bcma_drv_pci *pc);
2355  extern int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc,
2356                                  struct bcma_device *core, bool enable);
2357 +extern void bcma_core_pci_extend_L1timer(struct bcma_drv_pci *pc, bool extend);
2358 +
2359 +extern int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev);
2360 +extern int bcma_core_pci_plat_dev_init(struct pci_dev *dev);
2361  
2362  #endif /* LINUX_BCMA_DRIVER_PCI_H_ */
2363 --- a/include/linux/bcma/bcma_regs.h
2364 +++ b/include/linux/bcma/bcma_regs.h
2365 @@ -56,4 +56,31 @@
2366  #define  BCMA_PCI_GPIO_XTAL            0x40    /* PCI config space GPIO 14 for Xtal powerup */
2367  #define  BCMA_PCI_GPIO_PLL             0x80    /* PCI config space GPIO 15 for PLL powerdown */
2368  
2369 +/* SiliconBackplane Address Map.
2370 + * All regions may not exist on all chips.
2371 + */
2372 +#define BCMA_SOC_SDRAM_BASE            0x00000000U     /* Physical SDRAM */
2373 +#define BCMA_SOC_PCI_MEM               0x08000000U     /* Host Mode sb2pcitranslation0 (64 MB) */
2374 +#define BCMA_SOC_PCI_MEM_SZ            (64 * 1024 * 1024)
2375 +#define BCMA_SOC_PCI_CFG               0x0c000000U     /* Host Mode sb2pcitranslation1 (64 MB) */
2376 +#define BCMA_SOC_SDRAM_SWAPPED         0x10000000U     /* Byteswapped Physical SDRAM */
2377 +#define BCMA_SOC_SDRAM_R2              0x80000000U     /* Region 2 for sdram (512 MB) */
2378 +
2379 +
2380 +#define BCMA_SOC_PCI_DMA               0x40000000U     /* Client Mode sb2pcitranslation2 (1 GB) */
2381 +#define BCMA_SOC_PCI_DMA2              0x80000000U     /* Client Mode sb2pcitranslation2 (1 GB) */
2382 +#define BCMA_SOC_PCI_DMA_SZ            0x40000000U     /* Client Mode sb2pcitranslation2 size in bytes */
2383 +#define BCMA_SOC_PCIE_DMA_L32          0x00000000U     /* PCIE Client Mode sb2pcitranslation2
2384 +                                                        * (2 ZettaBytes), low 32 bits
2385 +                                                        */
2386 +#define BCMA_SOC_PCIE_DMA_H32          0x80000000U     /* PCIE Client Mode sb2pcitranslation2
2387 +                                                        * (2 ZettaBytes), high 32 bits
2388 +                                                        */
2389 +
2390 +#define BCMA_SOC_PCI1_MEM              0x40000000U     /* Host Mode sb2pcitranslation0 (64 MB) */
2391 +#define BCMA_SOC_PCI1_CFG              0x44000000U     /* Host Mode sb2pcitranslation1 (64 MB) */
2392 +#define BCMA_SOC_PCIE1_DMA_H32         0xc0000000U     /* PCIE Client Mode sb2pcitranslation2
2393 +                                                        * (2 ZettaBytes), high 32 bits
2394 +                                                        */
2395 +
2396  #endif /* LINUX_BCMA_REGS_H_ */