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