kernel: rewrite the phy packet hook, put it in the network stack to avoid having...
[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/driver_chipcommon_pmu.c
38 +++ b/drivers/bcma/driver_chipcommon_pmu.c
39 @@ -80,6 +80,7 @@ static void bcma_pmu_resources_init(stru
40                 min_msk = 0x200D;
41                 max_msk = 0xFFFF;
42                 break;
43 +       case 0x4331:
44         case 43224:
45         case 43225:
46                 break;
47 --- a/drivers/bcma/driver_pci.c
48 +++ b/drivers/bcma/driver_pci.c
49 @@ -2,8 +2,9 @@
50   * Broadcom specific AMBA
51   * PCI Core
52   *
53 - * Copyright 2005, Broadcom Corporation
54 + * Copyright 2005, 2011, Broadcom Corporation
55   * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
56 + * Copyright 2011, 2012, Hauke Mehrtens <hauke@hauke-m.de>
57   *
58   * Licensed under the GNU/GPL. See COPYING for details.
59   */
60 @@ -16,40 +17,41 @@
61   * R/W ops.
62   **************************************************/
63  
64 -static u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address)
65 +u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address)
66  {
67 -       pcicore_write32(pc, 0x130, address);
68 -       pcicore_read32(pc, 0x130);
69 -       return pcicore_read32(pc, 0x134);
70 +       pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_ADDR, address);
71 +       pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_ADDR);
72 +       return pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_DATA);
73  }
74  
75  #if 0
76  static void bcma_pcie_write(struct bcma_drv_pci *pc, u32 address, u32 data)
77  {
78 -       pcicore_write32(pc, 0x130, address);
79 -       pcicore_read32(pc, 0x130);
80 -       pcicore_write32(pc, 0x134, data);
81 +       pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_ADDR, address);
82 +       pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_ADDR);
83 +       pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_DATA, data);
84  }
85  #endif
86  
87  static void bcma_pcie_mdio_set_phy(struct bcma_drv_pci *pc, u8 phy)
88  {
89 -       const u16 mdio_control = 0x128;
90 -       const u16 mdio_data = 0x12C;
91         u32 v;
92         int i;
93  
94 -       v = (1 << 30); /* Start of Transaction */
95 -       v |= (1 << 28); /* Write Transaction */
96 -       v |= (1 << 17); /* Turnaround */
97 -       v |= (0x1F << 18);
98 +       v = BCMA_CORE_PCI_MDIODATA_START;
99 +       v |= BCMA_CORE_PCI_MDIODATA_WRITE;
100 +       v |= (BCMA_CORE_PCI_MDIODATA_DEV_ADDR <<
101 +             BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF);
102 +       v |= (BCMA_CORE_PCI_MDIODATA_BLK_ADDR <<
103 +             BCMA_CORE_PCI_MDIODATA_REGADDR_SHF);
104 +       v |= BCMA_CORE_PCI_MDIODATA_TA;
105         v |= (phy << 4);
106 -       pcicore_write32(pc, mdio_data, v);
107 +       pcicore_write32(pc, BCMA_CORE_PCI_MDIO_DATA, v);
108  
109         udelay(10);
110         for (i = 0; i < 200; i++) {
111 -               v = pcicore_read32(pc, mdio_control);
112 -               if (v & 0x100 /* Trans complete */)
113 +               v = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_CONTROL);
114 +               if (v & BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE)
115                         break;
116                 msleep(1);
117         }
118 @@ -57,79 +59,84 @@ static void bcma_pcie_mdio_set_phy(struc
119  
120  static u16 bcma_pcie_mdio_read(struct bcma_drv_pci *pc, u8 device, u8 address)
121  {
122 -       const u16 mdio_control = 0x128;
123 -       const u16 mdio_data = 0x12C;
124         int max_retries = 10;
125         u16 ret = 0;
126         u32 v;
127         int i;
128  
129 -       v = 0x80; /* Enable Preamble Sequence */
130 -       v |= 0x2; /* MDIO Clock Divisor */
131 -       pcicore_write32(pc, mdio_control, v);
132 +       /* enable mdio access to SERDES */
133 +       v = BCMA_CORE_PCI_MDIOCTL_PREAM_EN;
134 +       v |= BCMA_CORE_PCI_MDIOCTL_DIVISOR_VAL;
135 +       pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, v);
136  
137         if (pc->core->id.rev >= 10) {
138                 max_retries = 200;
139                 bcma_pcie_mdio_set_phy(pc, device);
140 +               v = (BCMA_CORE_PCI_MDIODATA_DEV_ADDR <<
141 +                    BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF);
142 +               v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF);
143 +       } else {
144 +               v = (device << BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF_OLD);
145 +               v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF_OLD);
146         }
147  
148 -       v = (1 << 30); /* Start of Transaction */
149 -       v |= (1 << 29); /* Read Transaction */
150 -       v |= (1 << 17); /* Turnaround */
151 -       if (pc->core->id.rev < 10)
152 -               v |= (u32)device << 22;
153 -       v |= (u32)address << 18;
154 -       pcicore_write32(pc, mdio_data, v);
155 +       v = BCMA_CORE_PCI_MDIODATA_START;
156 +       v |= BCMA_CORE_PCI_MDIODATA_READ;
157 +       v |= BCMA_CORE_PCI_MDIODATA_TA;
158 +
159 +       pcicore_write32(pc, BCMA_CORE_PCI_MDIO_DATA, v);
160         /* Wait for the device to complete the transaction */
161         udelay(10);
162         for (i = 0; i < max_retries; i++) {
163 -               v = pcicore_read32(pc, mdio_control);
164 -               if (v & 0x100 /* Trans complete */) {
165 +               v = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_CONTROL);
166 +               if (v & BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE) {
167                         udelay(10);
168 -                       ret = pcicore_read32(pc, mdio_data);
169 +                       ret = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_DATA);
170                         break;
171                 }
172                 msleep(1);
173         }
174 -       pcicore_write32(pc, mdio_control, 0);
175 +       pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, 0);
176         return ret;
177  }
178  
179  static void bcma_pcie_mdio_write(struct bcma_drv_pci *pc, u8 device,
180                                 u8 address, u16 data)
181  {
182 -       const u16 mdio_control = 0x128;
183 -       const u16 mdio_data = 0x12C;
184         int max_retries = 10;
185         u32 v;
186         int i;
187  
188 -       v = 0x80; /* Enable Preamble Sequence */
189 -       v |= 0x2; /* MDIO Clock Divisor */
190 -       pcicore_write32(pc, mdio_control, v);
191 +       /* enable mdio access to SERDES */
192 +       v = BCMA_CORE_PCI_MDIOCTL_PREAM_EN;
193 +       v |= BCMA_CORE_PCI_MDIOCTL_DIVISOR_VAL;
194 +       pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, v);
195  
196         if (pc->core->id.rev >= 10) {
197                 max_retries = 200;
198                 bcma_pcie_mdio_set_phy(pc, device);
199 +               v = (BCMA_CORE_PCI_MDIODATA_DEV_ADDR <<
200 +                    BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF);
201 +               v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF);
202 +       } else {
203 +               v = (device << BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF_OLD);
204 +               v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF_OLD);
205         }
206  
207 -       v = (1 << 30); /* Start of Transaction */
208 -       v |= (1 << 28); /* Write Transaction */
209 -       v |= (1 << 17); /* Turnaround */
210 -       if (pc->core->id.rev < 10)
211 -               v |= (u32)device << 22;
212 -       v |= (u32)address << 18;
213 +       v = BCMA_CORE_PCI_MDIODATA_START;
214 +       v |= BCMA_CORE_PCI_MDIODATA_WRITE;
215 +       v |= BCMA_CORE_PCI_MDIODATA_TA;
216         v |= data;
217 -       pcicore_write32(pc, mdio_data, v);
218 +       pcicore_write32(pc, BCMA_CORE_PCI_MDIO_DATA, v);
219         /* Wait for the device to complete the transaction */
220         udelay(10);
221         for (i = 0; i < max_retries; i++) {
222 -               v = pcicore_read32(pc, mdio_control);
223 -               if (v & 0x100 /* Trans complete */)
224 +               v = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_CONTROL);
225 +               if (v & BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE)
226                         break;
227                 msleep(1);
228         }
229 -       pcicore_write32(pc, mdio_control, 0);
230 +       pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, 0);
231  }
232  
233  /**************************************************
234 @@ -138,72 +145,53 @@ static void bcma_pcie_mdio_write(struct
235  
236  static u8 bcma_pcicore_polarity_workaround(struct bcma_drv_pci *pc)
237  {
238 -       return (bcma_pcie_read(pc, 0x204) & 0x10) ? 0xC0 : 0x80;
239 +       u32 tmp;
240 +
241 +       tmp = bcma_pcie_read(pc, BCMA_CORE_PCI_PLP_STATUSREG);
242 +       if (tmp & BCMA_CORE_PCI_PLP_POLARITYINV_STAT)
243 +               return BCMA_CORE_PCI_SERDES_RX_CTRL_FORCE |
244 +                      BCMA_CORE_PCI_SERDES_RX_CTRL_POLARITY;
245 +       else
246 +               return BCMA_CORE_PCI_SERDES_RX_CTRL_FORCE;
247  }
248  
249  static void bcma_pcicore_serdes_workaround(struct bcma_drv_pci *pc)
250  {
251 -       const u8 serdes_pll_device = 0x1D;
252 -       const u8 serdes_rx_device = 0x1F;
253         u16 tmp;
254  
255 -       bcma_pcie_mdio_write(pc, serdes_rx_device, 1 /* Control */,
256 -                             bcma_pcicore_polarity_workaround(pc));
257 -       tmp = bcma_pcie_mdio_read(pc, serdes_pll_device, 1 /* Control */);
258 -       if (tmp & 0x4000)
259 -               bcma_pcie_mdio_write(pc, serdes_pll_device, 1, tmp & ~0x4000);
260 +       bcma_pcie_mdio_write(pc, BCMA_CORE_PCI_MDIODATA_DEV_RX,
261 +                            BCMA_CORE_PCI_SERDES_RX_CTRL,
262 +                            bcma_pcicore_polarity_workaround(pc));
263 +       tmp = bcma_pcie_mdio_read(pc, BCMA_CORE_PCI_MDIODATA_DEV_PLL,
264 +                                 BCMA_CORE_PCI_SERDES_PLL_CTRL);
265 +       if (tmp & BCMA_CORE_PCI_PLL_CTRL_FREQDET_EN)
266 +               bcma_pcie_mdio_write(pc, BCMA_CORE_PCI_MDIODATA_DEV_PLL,
267 +                                    BCMA_CORE_PCI_SERDES_PLL_CTRL,
268 +                                    tmp & ~BCMA_CORE_PCI_PLL_CTRL_FREQDET_EN);
269  }
270  
271  /**************************************************
272   * Init.
273   **************************************************/
274  
275 -static void bcma_core_pci_clientmode_init(struct bcma_drv_pci *pc)
276 +static void __devinit bcma_core_pci_clientmode_init(struct bcma_drv_pci *pc)
277  {
278         bcma_pcicore_serdes_workaround(pc);
279  }
280  
281 -static bool bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc)
282 -{
283 -       struct bcma_bus *bus = pc->core->bus;
284 -       u16 chipid_top;
285 -
286 -       chipid_top = (bus->chipinfo.id & 0xFF00);
287 -       if (chipid_top != 0x4700 &&
288 -           chipid_top != 0x5300)
289 -               return false;
290 -
291 -#ifdef CONFIG_SSB_DRIVER_PCICORE
292 -       if (bus->sprom.boardflags_lo & SSB_BFL_NOPCI)
293 -               return false;
294 -#endif /* CONFIG_SSB_DRIVER_PCICORE */
295 -
296 -#if 0
297 -       /* TODO: on BCMA we use address from EROM instead of magic formula */
298 -       u32 tmp;
299 -       return !mips_busprobe32(tmp, (bus->mmio +
300 -               (pc->core->core_index * BCMA_CORE_SIZE)));
301 -#endif
302 -
303 -       return true;
304 -}
305 -
306 -void bcma_core_pci_init(struct bcma_drv_pci *pc)
307 +void __devinit bcma_core_pci_init(struct bcma_drv_pci *pc)
308  {
309         if (pc->setup_done)
310                 return;
311  
312 -       if (bcma_core_pci_is_in_hostmode(pc)) {
313  #ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
314 +       pc->hostmode = bcma_core_pci_is_in_hostmode(pc);
315 +       if (pc->hostmode)
316                 bcma_core_pci_hostmode_init(pc);
317 -#else
318 -               pr_err("Driver compiled without support for hostmode PCI\n");
319  #endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */
320 -       } else {
321 -               bcma_core_pci_clientmode_init(pc);
322 -       }
323  
324 -       pc->setup_done = true;
325 +       if (!pc->hostmode)
326 +               bcma_core_pci_clientmode_init(pc);
327  }
328  
329  int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core,
330 --- a/drivers/bcma/driver_pci_host.c
331 +++ b/drivers/bcma/driver_pci_host.c
332 @@ -2,13 +2,588 @@
333   * Broadcom specific AMBA
334   * PCI Core in hostmode
335   *
336 + * Copyright 2005 - 2011, Broadcom Corporation
337 + * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
338 + * Copyright 2011, 2012, Hauke Mehrtens <hauke@hauke-m.de>
339 + *
340   * Licensed under the GNU/GPL. See COPYING for details.
341   */
342  
343  #include "bcma_private.h"
344 +#include <linux/pci.h>
345 +#include <linux/export.h>
346  #include <linux/bcma/bcma.h>
347 +#include <asm/paccess.h>
348 +
349 +/* Probe a 32bit value on the bus and catch bus exceptions.
350 + * Returns nonzero on a bus exception.
351 + * This is MIPS specific */
352 +#define mips_busprobe32(val, addr)     get_dbe((val), ((u32 *)(addr)))
353 +
354 +/* Assume one-hot slot wiring */
355 +#define BCMA_PCI_SLOT_MAX      16
356 +#define        PCI_CONFIG_SPACE_SIZE   256
357 +
358 +bool __devinit bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc)
359 +{
360 +       struct bcma_bus *bus = pc->core->bus;
361 +       u16 chipid_top;
362 +       u32 tmp;
363 +
364 +       chipid_top = (bus->chipinfo.id & 0xFF00);
365 +       if (chipid_top != 0x4700 &&
366 +           chipid_top != 0x5300)
367 +               return false;
368 +
369 +       if (bus->sprom.boardflags_lo & BCMA_CORE_PCI_BFL_NOPCI) {
370 +               pr_info("This PCI core is disabled and not working\n");
371 +               return false;
372 +       }
373 +
374 +       bcma_core_enable(pc->core, 0);
375 +
376 +       return !mips_busprobe32(tmp, pc->core->io_addr);
377 +}
378 +
379 +static u32 bcma_pcie_read_config(struct bcma_drv_pci *pc, u32 address)
380 +{
381 +       pcicore_write32(pc, BCMA_CORE_PCI_CONFIG_ADDR, address);
382 +       pcicore_read32(pc, BCMA_CORE_PCI_CONFIG_ADDR);
383 +       return pcicore_read32(pc, BCMA_CORE_PCI_CONFIG_DATA);
384 +}
385 +
386 +static void bcma_pcie_write_config(struct bcma_drv_pci *pc, u32 address,
387 +                                  u32 data)
388 +{
389 +       pcicore_write32(pc, BCMA_CORE_PCI_CONFIG_ADDR, address);
390 +       pcicore_read32(pc, BCMA_CORE_PCI_CONFIG_ADDR);
391 +       pcicore_write32(pc, BCMA_CORE_PCI_CONFIG_DATA, data);
392 +}
393 +
394 +static u32 bcma_get_cfgspace_addr(struct bcma_drv_pci *pc, unsigned int dev,
395 +                            unsigned int func, unsigned int off)
396 +{
397 +       u32 addr = 0;
398 +
399 +       /* Issue config commands only when the data link is up (atleast
400 +        * one external pcie device is present).
401 +        */
402 +       if (dev >= 2 || !(bcma_pcie_read(pc, BCMA_CORE_PCI_DLLP_LSREG)
403 +                         & BCMA_CORE_PCI_DLLP_LSREG_LINKUP))
404 +               goto out;
405 +
406 +       /* Type 0 transaction */
407 +       /* Slide the PCI window to the appropriate slot */
408 +       pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI1, BCMA_CORE_PCI_SBTOPCI_CFG0);
409 +       /* Calculate the address */
410 +       addr = pc->host_controller->host_cfg_addr;
411 +       addr |= (dev << BCMA_CORE_PCI_CFG_SLOT_SHIFT);
412 +       addr |= (func << BCMA_CORE_PCI_CFG_FUN_SHIFT);
413 +       addr |= (off & ~3);
414 +
415 +out:
416 +       return addr;
417 +}
418  
419 -void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc)
420 +static int bcma_extpci_read_config(struct bcma_drv_pci *pc, unsigned int dev,
421 +                                 unsigned int func, unsigned int off,
422 +                                 void *buf, int len)
423  {
424 -       pr_err("No support for PCI core in hostmode yet\n");
425 +       int err = -EINVAL;
426 +       u32 addr, val;
427 +       void __iomem *mmio = 0;
428 +
429 +       WARN_ON(!pc->hostmode);
430 +       if (unlikely(len != 1 && len != 2 && len != 4))
431 +               goto out;
432 +       if (dev == 0) {
433 +               /* we support only two functions on device 0 */
434 +               if (func > 1)
435 +                       return -EINVAL;
436 +
437 +               /* accesses to config registers with offsets >= 256
438 +                * requires indirect access.
439 +                */
440 +               if (off >= PCI_CONFIG_SPACE_SIZE) {
441 +                       addr = (func << 12);
442 +                       addr |= (off & 0x0FFF);
443 +                       val = bcma_pcie_read_config(pc, addr);
444 +               } else {
445 +                       addr = BCMA_CORE_PCI_PCICFG0;
446 +                       addr |= (func << 8);
447 +                       addr |= (off & 0xfc);
448 +                       val = pcicore_read32(pc, addr);
449 +               }
450 +       } else {
451 +               addr = bcma_get_cfgspace_addr(pc, dev, func, off);
452 +               if (unlikely(!addr))
453 +                       goto out;
454 +               err = -ENOMEM;
455 +               mmio = ioremap_nocache(addr, len);
456 +               if (!mmio)
457 +                       goto out;
458 +
459 +               if (mips_busprobe32(val, mmio)) {
460 +                       val = 0xffffffff;
461 +                       goto unmap;
462 +               }
463 +
464 +               val = readl(mmio);
465 +       }
466 +       val >>= (8 * (off & 3));
467 +
468 +       switch (len) {
469 +       case 1:
470 +               *((u8 *)buf) = (u8)val;
471 +               break;
472 +       case 2:
473 +               *((u16 *)buf) = (u16)val;
474 +               break;
475 +       case 4:
476 +               *((u32 *)buf) = (u32)val;
477 +               break;
478 +       }
479 +       err = 0;
480 +unmap:
481 +       if (mmio)
482 +               iounmap(mmio);
483 +out:
484 +       return err;
485 +}
486 +
487 +static int bcma_extpci_write_config(struct bcma_drv_pci *pc, unsigned int dev,
488 +                                  unsigned int func, unsigned int off,
489 +                                  const void *buf, int len)
490 +{
491 +       int err = -EINVAL;
492 +       u32 addr = 0, val = 0;
493 +       void __iomem *mmio = 0;
494 +       u16 chipid = pc->core->bus->chipinfo.id;
495 +
496 +       WARN_ON(!pc->hostmode);
497 +       if (unlikely(len != 1 && len != 2 && len != 4))
498 +               goto out;
499 +       if (dev == 0) {
500 +               /* accesses to config registers with offsets >= 256
501 +                * requires indirect access.
502 +                */
503 +               if (off < PCI_CONFIG_SPACE_SIZE) {
504 +                       addr = pc->core->addr + BCMA_CORE_PCI_PCICFG0;
505 +                       addr |= (func << 8);
506 +                       addr |= (off & 0xfc);
507 +                       mmio = ioremap_nocache(addr, len);
508 +                       if (!mmio)
509 +                               goto out;
510 +               }
511 +       } else {
512 +               addr = bcma_get_cfgspace_addr(pc, dev, func, off);
513 +               if (unlikely(!addr))
514 +                       goto out;
515 +               err = -ENOMEM;
516 +               mmio = ioremap_nocache(addr, len);
517 +               if (!mmio)
518 +                       goto out;
519 +
520 +               if (mips_busprobe32(val, mmio)) {
521 +                       val = 0xffffffff;
522 +                       goto unmap;
523 +               }
524 +       }
525 +
526 +       switch (len) {
527 +       case 1:
528 +               val = readl(mmio);
529 +               val &= ~(0xFF << (8 * (off & 3)));
530 +               val |= *((const u8 *)buf) << (8 * (off & 3));
531 +               break;
532 +       case 2:
533 +               val = readl(mmio);
534 +               val &= ~(0xFFFF << (8 * (off & 3)));
535 +               val |= *((const u16 *)buf) << (8 * (off & 3));
536 +               break;
537 +       case 4:
538 +               val = *((const u32 *)buf);
539 +               break;
540 +       }
541 +       if (dev == 0 && !addr) {
542 +               /* accesses to config registers with offsets >= 256
543 +                * requires indirect access.
544 +                */
545 +               addr = (func << 12);
546 +               addr |= (off & 0x0FFF);
547 +               bcma_pcie_write_config(pc, addr, val);
548 +       } else {
549 +               writel(val, mmio);
550 +
551 +               if (chipid == 0x4716 || chipid == 0x4748)
552 +                       readl(mmio);
553 +       }
554 +
555 +       err = 0;
556 +unmap:
557 +       if (mmio)
558 +               iounmap(mmio);
559 +out:
560 +       return err;
561 +}
562 +
563 +static int bcma_core_pci_hostmode_read_config(struct pci_bus *bus,
564 +                                             unsigned int devfn,
565 +                                             int reg, int size, u32 *val)
566 +{
567 +       unsigned long flags;
568 +       int err;
569 +       struct bcma_drv_pci *pc;
570 +       struct bcma_drv_pci_host *pc_host;
571 +
572 +       pc_host = container_of(bus->ops, struct bcma_drv_pci_host, pci_ops);
573 +       pc = pc_host->pdev;
574 +
575 +       spin_lock_irqsave(&pc_host->cfgspace_lock, flags);
576 +       err = bcma_extpci_read_config(pc, PCI_SLOT(devfn),
577 +                                    PCI_FUNC(devfn), reg, val, size);
578 +       spin_unlock_irqrestore(&pc_host->cfgspace_lock, flags);
579 +
580 +       return err ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
581 +}
582 +
583 +static int bcma_core_pci_hostmode_write_config(struct pci_bus *bus,
584 +                                              unsigned int devfn,
585 +                                              int reg, int size, u32 val)
586 +{
587 +       unsigned long flags;
588 +       int err;
589 +       struct bcma_drv_pci *pc;
590 +       struct bcma_drv_pci_host *pc_host;
591 +
592 +       pc_host = container_of(bus->ops, struct bcma_drv_pci_host, pci_ops);
593 +       pc = pc_host->pdev;
594 +
595 +       spin_lock_irqsave(&pc_host->cfgspace_lock, flags);
596 +       err = bcma_extpci_write_config(pc, PCI_SLOT(devfn),
597 +                                     PCI_FUNC(devfn), reg, &val, size);
598 +       spin_unlock_irqrestore(&pc_host->cfgspace_lock, flags);
599 +
600 +       return err ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
601 +}
602 +
603 +/* return cap_offset if requested capability exists in the PCI config space */
604 +static u8 __devinit bcma_find_pci_capability(struct bcma_drv_pci *pc,
605 +                                            unsigned int dev,
606 +                                            unsigned int func, u8 req_cap_id,
607 +                                            unsigned char *buf, u32 *buflen)
608 +{
609 +       u8 cap_id;
610 +       u8 cap_ptr = 0;
611 +       u32 bufsize;
612 +       u8 byte_val;
613 +
614 +       /* check for Header type 0 */
615 +       bcma_extpci_read_config(pc, dev, func, PCI_HEADER_TYPE, &byte_val,
616 +                               sizeof(u8));
617 +       if ((byte_val & 0x7f) != PCI_HEADER_TYPE_NORMAL)
618 +               return cap_ptr;
619 +
620 +       /* check if the capability pointer field exists */
621 +       bcma_extpci_read_config(pc, dev, func, PCI_STATUS, &byte_val,
622 +                               sizeof(u8));
623 +       if (!(byte_val & PCI_STATUS_CAP_LIST))
624 +               return cap_ptr;
625 +
626 +       /* check if the capability pointer is 0x00 */
627 +       bcma_extpci_read_config(pc, dev, func, PCI_CAPABILITY_LIST, &cap_ptr,
628 +                               sizeof(u8));
629 +       if (cap_ptr == 0x00)
630 +               return cap_ptr;
631 +
632 +       /* loop thr'u the capability list and see if the requested capabilty
633 +        * exists */
634 +       bcma_extpci_read_config(pc, dev, func, cap_ptr, &cap_id, sizeof(u8));
635 +       while (cap_id != req_cap_id) {
636 +               bcma_extpci_read_config(pc, dev, func, cap_ptr + 1, &cap_ptr,
637 +                                       sizeof(u8));
638 +               if (cap_ptr == 0x00)
639 +                       return cap_ptr;
640 +               bcma_extpci_read_config(pc, dev, func, cap_ptr, &cap_id,
641 +                                       sizeof(u8));
642 +       }
643 +
644 +       /* found the caller requested capability */
645 +       if ((buf != NULL) && (buflen != NULL)) {
646 +               u8 cap_data;
647 +
648 +               bufsize = *buflen;
649 +               if (!bufsize)
650 +                       return cap_ptr;
651 +
652 +               *buflen = 0;
653 +
654 +               /* copy the cpability data excluding cap ID and next ptr */
655 +               cap_data = cap_ptr + 2;
656 +               if ((bufsize + cap_data)  > PCI_CONFIG_SPACE_SIZE)
657 +                       bufsize = PCI_CONFIG_SPACE_SIZE - cap_data;
658 +               *buflen = bufsize;
659 +               while (bufsize--) {
660 +                       bcma_extpci_read_config(pc, dev, func, cap_data, buf,
661 +                                               sizeof(u8));
662 +                       cap_data++;
663 +                       buf++;
664 +               }
665 +       }
666 +
667 +       return cap_ptr;
668 +}
669 +
670 +/* If the root port is capable of returning Config Request
671 + * Retry Status (CRS) Completion Status to software then
672 + * enable the feature.
673 + */
674 +static void __devinit bcma_core_pci_enable_crs(struct bcma_drv_pci *pc)
675 +{
676 +       u8 cap_ptr, root_ctrl, root_cap, dev;
677 +       u16 val16;
678 +       int i;
679 +
680 +       cap_ptr = bcma_find_pci_capability(pc, 0, 0, PCI_CAP_ID_EXP, NULL,
681 +                                          NULL);
682 +       root_cap = cap_ptr + PCI_EXP_RTCAP;
683 +       bcma_extpci_read_config(pc, 0, 0, root_cap, &val16, sizeof(u16));
684 +       if (val16 & BCMA_CORE_PCI_RC_CRS_VISIBILITY) {
685 +               /* Enable CRS software visibility */
686 +               root_ctrl = cap_ptr + PCI_EXP_RTCTL;
687 +               val16 = PCI_EXP_RTCTL_CRSSVE;
688 +               bcma_extpci_read_config(pc, 0, 0, root_ctrl, &val16,
689 +                                       sizeof(u16));
690 +
691 +               /* Initiate a configuration request to read the vendor id
692 +                * field of the device function's config space header after
693 +                * 100 ms wait time from the end of Reset. If the device is
694 +                * not done with its internal initialization, it must at
695 +                * least return a completion TLP, with a completion status
696 +                * of "Configuration Request Retry Status (CRS)". The root
697 +                * complex must complete the request to the host by returning
698 +                * a read-data value of 0001h for the Vendor ID field and
699 +                * all 1s for any additional bytes included in the request.
700 +                * Poll using the config reads for max wait time of 1 sec or
701 +                * until we receive the successful completion status. Repeat
702 +                * the procedure for all the devices.
703 +                */
704 +               for (dev = 1; dev < BCMA_PCI_SLOT_MAX; dev++) {
705 +                       for (i = 0; i < 100000; i++) {
706 +                               bcma_extpci_read_config(pc, dev, 0,
707 +                                                       PCI_VENDOR_ID, &val16,
708 +                                                       sizeof(val16));
709 +                               if (val16 != 0x1)
710 +                                       break;
711 +                               udelay(10);
712 +                       }
713 +                       if (val16 == 0x1)
714 +                               pr_err("PCI: Broken device in slot %d\n", dev);
715 +               }
716 +       }
717 +}
718 +
719 +void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc)
720 +{
721 +       struct bcma_bus *bus = pc->core->bus;
722 +       struct bcma_drv_pci_host *pc_host;
723 +       u32 tmp;
724 +       u32 pci_membase_1G;
725 +       unsigned long io_map_base;
726 +
727 +       pr_info("PCIEcore in host mode found\n");
728 +
729 +       pc_host = kzalloc(sizeof(*pc_host), GFP_KERNEL);
730 +       if (!pc_host)  {
731 +               pr_err("can not allocate memory");
732 +               return;
733 +       }
734 +
735 +       pc->host_controller = pc_host;
736 +       pc_host->pci_controller.io_resource = &pc_host->io_resource;
737 +       pc_host->pci_controller.mem_resource = &pc_host->mem_resource;
738 +       pc_host->pci_controller.pci_ops = &pc_host->pci_ops;
739 +       pc_host->pdev = pc;
740 +
741 +       pci_membase_1G = BCMA_SOC_PCI_DMA;
742 +       pc_host->host_cfg_addr = BCMA_SOC_PCI_CFG;
743 +
744 +       pc_host->pci_ops.read = bcma_core_pci_hostmode_read_config;
745 +       pc_host->pci_ops.write = bcma_core_pci_hostmode_write_config;
746 +
747 +       pc_host->mem_resource.name = "BCMA PCIcore external memory",
748 +       pc_host->mem_resource.start = BCMA_SOC_PCI_DMA;
749 +       pc_host->mem_resource.end = BCMA_SOC_PCI_DMA + BCMA_SOC_PCI_DMA_SZ - 1;
750 +       pc_host->mem_resource.flags = IORESOURCE_MEM | IORESOURCE_PCI_FIXED;
751 +
752 +       pc_host->io_resource.name = "BCMA PCIcore external I/O",
753 +       pc_host->io_resource.start = 0x100;
754 +       pc_host->io_resource.end = 0x7FF;
755 +       pc_host->io_resource.flags = IORESOURCE_IO | IORESOURCE_PCI_FIXED;
756 +
757 +       /* Reset RC */
758 +       udelay(3000);
759 +       pcicore_write32(pc, BCMA_CORE_PCI_CTL, BCMA_CORE_PCI_CTL_RST_OE);
760 +       udelay(1000);
761 +       pcicore_write32(pc, BCMA_CORE_PCI_CTL, BCMA_CORE_PCI_CTL_RST |
762 +                       BCMA_CORE_PCI_CTL_RST_OE);
763 +
764 +       /* 64 MB I/O access window. On 4716, use
765 +        * sbtopcie0 to access the device registers. We
766 +        * can't use address match 2 (1 GB window) region
767 +        * as mips can't generate 64-bit address on the
768 +        * backplane.
769 +        */
770 +       if (bus->chipinfo.id == 0x4716 || bus->chipinfo.id == 0x4748) {
771 +               pc_host->mem_resource.start = BCMA_SOC_PCI_MEM;
772 +               pc_host->mem_resource.end = BCMA_SOC_PCI_MEM +
773 +                                           BCMA_SOC_PCI_MEM_SZ - 1;
774 +               pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0,
775 +                               BCMA_CORE_PCI_SBTOPCI_MEM | BCMA_SOC_PCI_MEM);
776 +       } else if (bus->chipinfo.id == 0x5300) {
777 +               tmp = BCMA_CORE_PCI_SBTOPCI_MEM;
778 +               tmp |= BCMA_CORE_PCI_SBTOPCI_PREF;
779 +               tmp |= BCMA_CORE_PCI_SBTOPCI_BURST;
780 +               if (pc->core->core_unit == 0) {
781 +                       pc_host->mem_resource.start = BCMA_SOC_PCI_MEM;
782 +                       pc_host->mem_resource.end = BCMA_SOC_PCI_MEM +
783 +                                                   BCMA_SOC_PCI_MEM_SZ - 1;
784 +                       pci_membase_1G = BCMA_SOC_PCIE_DMA_H32;
785 +                       pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0,
786 +                                       tmp | BCMA_SOC_PCI_MEM);
787 +               } else if (pc->core->core_unit == 1) {
788 +                       pc_host->mem_resource.start = BCMA_SOC_PCI1_MEM;
789 +                       pc_host->mem_resource.end = BCMA_SOC_PCI1_MEM +
790 +                                                   BCMA_SOC_PCI_MEM_SZ - 1;
791 +                       pci_membase_1G = BCMA_SOC_PCIE1_DMA_H32;
792 +                       pc_host->host_cfg_addr = BCMA_SOC_PCI1_CFG;
793 +                       pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0,
794 +                                       tmp | BCMA_SOC_PCI1_MEM);
795 +               }
796 +       } else
797 +               pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0,
798 +                               BCMA_CORE_PCI_SBTOPCI_IO);
799 +
800 +       /* 64 MB configuration access window */
801 +       pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI1, BCMA_CORE_PCI_SBTOPCI_CFG0);
802 +
803 +       /* 1 GB memory access window */
804 +       pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI2,
805 +                       BCMA_CORE_PCI_SBTOPCI_MEM | pci_membase_1G);
806 +
807 +
808 +       /* As per PCI Express Base Spec 1.1 we need to wait for
809 +        * at least 100 ms from the end of a reset (cold/warm/hot)
810 +        * before issuing configuration requests to PCI Express
811 +        * devices.
812 +        */
813 +       udelay(100000);
814 +
815 +       bcma_core_pci_enable_crs(pc);
816 +
817 +       /* Enable PCI bridge BAR0 memory & master access */
818 +       tmp = PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
819 +       bcma_extpci_write_config(pc, 0, 0, PCI_COMMAND, &tmp, sizeof(tmp));
820 +
821 +       /* Enable PCI interrupts */
822 +       pcicore_write32(pc, BCMA_CORE_PCI_IMASK, BCMA_CORE_PCI_IMASK_INTA);
823 +
824 +       /* Ok, ready to run, register it to the system.
825 +        * The following needs change, if we want to port hostmode
826 +        * to non-MIPS platform. */
827 +       io_map_base = (unsigned long)ioremap_nocache(BCMA_SOC_PCI_MEM,
828 +                                                    0x04000000);
829 +       pc_host->pci_controller.io_map_base = io_map_base;
830 +       set_io_port_base(pc_host->pci_controller.io_map_base);
831 +       /* Give some time to the PCI controller to configure itself with the new
832 +        * values. Not waiting at this point causes crashes of the machine. */
833 +       mdelay(10);
834 +       register_pci_controller(&pc_host->pci_controller);
835 +       return;
836 +}
837 +
838 +/* Early PCI fixup for a device on the PCI-core bridge. */
839 +static void bcma_core_pci_fixup_pcibridge(struct pci_dev *dev)
840 +{
841 +       if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) {
842 +               /* This is not a device on the PCI-core bridge. */
843 +               return;
844 +       }
845 +       if (PCI_SLOT(dev->devfn) != 0)
846 +               return;
847 +
848 +       pr_info("PCI: Fixing up bridge %s\n", pci_name(dev));
849 +
850 +       /* Enable PCI bridge bus mastering and memory space */
851 +       pci_set_master(dev);
852 +       if (pcibios_enable_device(dev, ~0) < 0) {
853 +               pr_err("PCI: BCMA bridge enable failed\n");
854 +               return;
855 +       }
856 +
857 +       /* Enable PCI bridge BAR1 prefetch and burst */
858 +       pci_write_config_dword(dev, BCMA_PCI_BAR1_CONTROL, 3);
859 +}
860 +DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, bcma_core_pci_fixup_pcibridge);
861 +
862 +/* Early PCI fixup for all PCI-cores to set the correct memory address. */
863 +static void bcma_core_pci_fixup_addresses(struct pci_dev *dev)
864 +{
865 +       struct resource *res;
866 +       int pos;
867 +
868 +       if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) {
869 +               /* This is not a device on the PCI-core bridge. */
870 +               return;
871 +       }
872 +       if (PCI_SLOT(dev->devfn) == 0)
873 +               return;
874 +
875 +       pr_info("PCI: Fixing up addresses %s\n", pci_name(dev));
876 +
877 +       for (pos = 0; pos < 6; pos++) {
878 +               res = &dev->resource[pos];
879 +               if (res->flags & (IORESOURCE_IO | IORESOURCE_MEM))
880 +                       pci_assign_resource(dev, pos);
881 +       }
882 +}
883 +DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, bcma_core_pci_fixup_addresses);
884 +
885 +/* This function is called when doing a pci_enable_device().
886 + * We must first check if the device is a device on the PCI-core bridge. */
887 +int bcma_core_pci_plat_dev_init(struct pci_dev *dev)
888 +{
889 +       struct bcma_drv_pci_host *pc_host;
890 +
891 +       if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) {
892 +               /* This is not a device on the PCI-core bridge. */
893 +               return -ENODEV;
894 +       }
895 +       pc_host = container_of(dev->bus->ops, struct bcma_drv_pci_host,
896 +                              pci_ops);
897 +
898 +       pr_info("PCI: Fixing up device %s\n", pci_name(dev));
899 +
900 +       /* Fix up interrupt lines */
901 +       dev->irq = bcma_core_mips_irq(pc_host->pdev->core) + 2;
902 +       pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
903 +
904 +       return 0;
905 +}
906 +EXPORT_SYMBOL(bcma_core_pci_plat_dev_init);
907 +
908 +/* PCI device IRQ mapping. */
909 +int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev)
910 +{
911 +       struct bcma_drv_pci_host *pc_host;
912 +
913 +       if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) {
914 +               /* This is not a device on the PCI-core bridge. */
915 +               return -ENODEV;
916 +       }
917 +
918 +       pc_host = container_of(dev->bus->ops, struct bcma_drv_pci_host,
919 +                              pci_ops);
920 +       return bcma_core_mips_irq(pc_host->pdev->core) + 2;
921  }
922 +EXPORT_SYMBOL(bcma_core_pci_pcibios_map_irq);
923 --- a/drivers/bcma/host_pci.c
924 +++ b/drivers/bcma/host_pci.c
925 @@ -154,8 +154,8 @@ const struct bcma_host_ops bcma_host_pci
926         .awrite32       = bcma_host_pci_awrite32,
927  };
928  
929 -static int bcma_host_pci_probe(struct pci_dev *dev,
930 -                            const struct pci_device_id *id)
931 +static int __devinit bcma_host_pci_probe(struct pci_dev *dev,
932 +                                        const struct pci_device_id *id)
933  {
934         struct bcma_bus *bus;
935         int err = -ENOMEM;
936 --- a/drivers/bcma/main.c
937 +++ b/drivers/bcma/main.c
938 @@ -13,6 +13,12 @@
939  MODULE_DESCRIPTION("Broadcom's specific AMBA driver");
940  MODULE_LICENSE("GPL");
941  
942 +/* contains the number the next bus should get. */
943 +static unsigned int bcma_bus_next_num = 0;
944 +
945 +/* bcma_buses_mutex locks the bcma_bus_next_num */
946 +static DEFINE_MUTEX(bcma_buses_mutex);
947 +
948  static int bcma_bus_match(struct device *dev, struct device_driver *drv);
949  static int bcma_device_probe(struct device *dev);
950  static int bcma_device_remove(struct device *dev);
951 @@ -55,7 +61,7 @@ static struct bus_type bcma_bus_type = {
952         .dev_attrs      = bcma_device_attrs,
953  };
954  
955 -static struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid)
956 +struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid)
957  {
958         struct bcma_device *core;
959  
960 @@ -65,6 +71,7 @@ static struct bcma_device *bcma_find_cor
961         }
962         return NULL;
963  }
964 +EXPORT_SYMBOL_GPL(bcma_find_core);
965  
966  static void bcma_release_core_dev(struct device *dev)
967  {
968 @@ -93,7 +100,7 @@ static int bcma_register_cores(struct bc
969  
970                 core->dev.release = bcma_release_core_dev;
971                 core->dev.bus = &bcma_bus_type;
972 -               dev_set_name(&core->dev, "bcma%d:%d", 0/*bus->num*/, dev_id);
973 +               dev_set_name(&core->dev, "bcma%d:%d", bus->num, dev_id);
974  
975                 switch (bus->hosttype) {
976                 case BCMA_HOSTTYPE_PCI:
977 @@ -132,11 +139,15 @@ static void bcma_unregister_cores(struct
978         }
979  }
980  
981 -int bcma_bus_register(struct bcma_bus *bus)
982 +int __devinit bcma_bus_register(struct bcma_bus *bus)
983  {
984         int err;
985         struct bcma_device *core;
986  
987 +       mutex_lock(&bcma_buses_mutex);
988 +       bus->num = bcma_bus_next_num++;
989 +       mutex_unlock(&bcma_buses_mutex);
990 +
991         /* Scan for devices (cores) */
992         err = bcma_bus_scan(bus);
993         if (err) {
994 --- a/drivers/bcma/scan.c
995 +++ b/drivers/bcma/scan.c
996 @@ -212,6 +212,17 @@ static struct bcma_device *bcma_find_cor
997         return NULL;
998  }
999  
1000 +static struct bcma_device *bcma_find_core_reverse(struct bcma_bus *bus, u16 coreid)
1001 +{
1002 +       struct bcma_device *core;
1003 +
1004 +       list_for_each_entry_reverse(core, &bus->cores, list) {
1005 +               if (core->id.id == coreid)
1006 +                       return core;
1007 +       }
1008 +       return NULL;
1009 +}
1010 +
1011  static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
1012                               struct bcma_device_id *match, int core_num,
1013                               struct bcma_device *core)
1014 @@ -353,6 +364,7 @@ static int bcma_get_next_core(struct bcm
1015  void bcma_init_bus(struct bcma_bus *bus)
1016  {
1017         s32 tmp;
1018 +       struct bcma_chipinfo *chipinfo = &(bus->chipinfo);
1019  
1020         if (bus->init_done)
1021                 return;
1022 @@ -363,9 +375,12 @@ void bcma_init_bus(struct bcma_bus *bus)
1023         bcma_scan_switch_core(bus, BCMA_ADDR_BASE);
1024  
1025         tmp = bcma_scan_read32(bus, 0, BCMA_CC_ID);
1026 -       bus->chipinfo.id = (tmp & BCMA_CC_ID_ID) >> BCMA_CC_ID_ID_SHIFT;
1027 -       bus->chipinfo.rev = (tmp & BCMA_CC_ID_REV) >> BCMA_CC_ID_REV_SHIFT;
1028 -       bus->chipinfo.pkg = (tmp & BCMA_CC_ID_PKG) >> BCMA_CC_ID_PKG_SHIFT;
1029 +       chipinfo->id = (tmp & BCMA_CC_ID_ID) >> BCMA_CC_ID_ID_SHIFT;
1030 +       chipinfo->rev = (tmp & BCMA_CC_ID_REV) >> BCMA_CC_ID_REV_SHIFT;
1031 +       chipinfo->pkg = (tmp & BCMA_CC_ID_PKG) >> BCMA_CC_ID_PKG_SHIFT;
1032 +       pr_info("Found chip with id 0x%04X, rev 0x%02X and package 0x%02X\n",
1033 +               chipinfo->id, chipinfo->rev, chipinfo->pkg);
1034 +
1035         bus->init_done = true;
1036  }
1037  
1038 @@ -392,6 +407,7 @@ int bcma_bus_scan(struct bcma_bus *bus)
1039         bcma_scan_switch_core(bus, erombase);
1040  
1041         while (eromptr < eromend) {
1042 +               struct bcma_device *other_core;
1043                 struct bcma_device *core = kzalloc(sizeof(*core), GFP_KERNEL);
1044                 if (!core)
1045                         return -ENOMEM;
1046 @@ -414,6 +430,8 @@ int bcma_bus_scan(struct bcma_bus *bus)
1047  
1048                 core->core_index = core_num++;
1049                 bus->nr_cores++;
1050 +               other_core = bcma_find_core_reverse(bus, core->id.id);
1051 +               core->core_unit = (other_core == NULL) ? 0 : other_core->core_unit + 1;
1052  
1053                 pr_info("Core %d found: %s "
1054                         "(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
1055 --- a/drivers/bcma/sprom.c
1056 +++ b/drivers/bcma/sprom.c
1057 @@ -2,6 +2,8 @@
1058   * Broadcom specific AMBA
1059   * SPROM reading
1060   *
1061 + * Copyright 2011, 2012, Hauke Mehrtens <hauke@hauke-m.de>
1062 + *
1063   * Licensed under the GNU/GPL. See COPYING for details.
1064   */
1065  
1066 @@ -14,7 +16,57 @@
1067  #include <linux/dma-mapping.h>
1068  #include <linux/slab.h>
1069  
1070 -#define SPOFF(offset)  ((offset) / sizeof(u16))
1071 +static int(*get_fallback_sprom)(struct bcma_bus *dev, struct ssb_sprom *out);
1072 +
1073 +/**
1074 + * bcma_arch_register_fallback_sprom - Registers a method providing a
1075 + * fallback SPROM if no SPROM is found.
1076 + *
1077 + * @sprom_callback: The callback function.
1078 + *
1079 + * With this function the architecture implementation may register a
1080 + * callback handler which fills the SPROM data structure. The fallback is
1081 + * used for PCI based BCMA devices, where no valid SPROM can be found
1082 + * in the shadow registers and to provide the SPROM for SoCs where BCMA is
1083 + * to controll the system bus.
1084 + *
1085 + * This function is useful for weird architectures that have a half-assed
1086 + * BCMA device hardwired to their PCI bus.
1087 + *
1088 + * This function is available for architecture code, only. So it is not
1089 + * exported.
1090 + */
1091 +int bcma_arch_register_fallback_sprom(int (*sprom_callback)(struct bcma_bus *bus,
1092 +                                    struct ssb_sprom *out))
1093 +{
1094 +       if (get_fallback_sprom)
1095 +               return -EEXIST;
1096 +       get_fallback_sprom = sprom_callback;
1097 +
1098 +       return 0;
1099 +}
1100 +
1101 +static int bcma_fill_sprom_with_fallback(struct bcma_bus *bus,
1102 +                                        struct ssb_sprom *out)
1103 +{
1104 +       int err;
1105 +
1106 +       if (!get_fallback_sprom) {
1107 +               err = -ENOENT;
1108 +               goto fail;
1109 +       }
1110 +
1111 +       err = get_fallback_sprom(bus, out);
1112 +       if (err)
1113 +               goto fail;
1114 +
1115 +       pr_debug("Using SPROM revision %d provided by"
1116 +                " platform.\n", bus->sprom.revision);
1117 +       return 0;
1118 +fail:
1119 +       pr_warn("Using fallback SPROM failed (err %d)\n", err);
1120 +       return err;
1121 +}
1122  
1123  /**************************************************
1124   * R/W ops.
1125 @@ -124,10 +176,21 @@ static int bcma_sprom_valid(const u16 *s
1126   * SPROM extraction.
1127   **************************************************/
1128  
1129 +#define SPOFF(offset)  ((offset) / sizeof(u16))
1130 +
1131 +#define SPEX(_field, _offset, _mask, _shift)   \
1132 +       bus->sprom._field = ((sprom[SPOFF(_offset)] & (_mask)) >> (_shift))
1133 +
1134  static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
1135  {
1136 -       u16 v;
1137 +       u16 v, o;
1138         int i;
1139 +       u16 pwr_info_offset[] = {
1140 +               SSB_SROM8_PWR_INFO_CORE0, SSB_SROM8_PWR_INFO_CORE1,
1141 +               SSB_SROM8_PWR_INFO_CORE2, SSB_SROM8_PWR_INFO_CORE3
1142 +       };
1143 +       BUILD_BUG_ON(ARRAY_SIZE(pwr_info_offset) !=
1144 +                       ARRAY_SIZE(bus->sprom.core_pwr_info));
1145  
1146         bus->sprom.revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] &
1147                 SSB_SPROM_REVISION_REV;
1148 @@ -137,85 +200,229 @@ static void bcma_sprom_extract_r8(struct
1149                 *(((__be16 *)bus->sprom.il0mac) + i) = cpu_to_be16(v);
1150         }
1151  
1152 -       bus->sprom.board_rev = sprom[SPOFF(SSB_SPROM8_BOARDREV)];
1153 +       SPEX(board_rev, SSB_SPROM8_BOARDREV, ~0, 0);
1154  
1155 -       bus->sprom.txpid2g[0] = (sprom[SPOFF(SSB_SPROM4_TXPID2G01)] &
1156 -            SSB_SPROM4_TXPID2G0) >> SSB_SPROM4_TXPID2G0_SHIFT;
1157 -       bus->sprom.txpid2g[1] = (sprom[SPOFF(SSB_SPROM4_TXPID2G01)] &
1158 -            SSB_SPROM4_TXPID2G1) >> SSB_SPROM4_TXPID2G1_SHIFT;
1159 -       bus->sprom.txpid2g[2] = (sprom[SPOFF(SSB_SPROM4_TXPID2G23)] &
1160 -            SSB_SPROM4_TXPID2G2) >> SSB_SPROM4_TXPID2G2_SHIFT;
1161 -       bus->sprom.txpid2g[3] = (sprom[SPOFF(SSB_SPROM4_TXPID2G23)] &
1162 -            SSB_SPROM4_TXPID2G3) >> SSB_SPROM4_TXPID2G3_SHIFT;
1163 -
1164 -       bus->sprom.txpid5gl[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL01)] &
1165 -            SSB_SPROM4_TXPID5GL0) >> SSB_SPROM4_TXPID5GL0_SHIFT;
1166 -       bus->sprom.txpid5gl[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL01)] &
1167 -            SSB_SPROM4_TXPID5GL1) >> SSB_SPROM4_TXPID5GL1_SHIFT;
1168 -       bus->sprom.txpid5gl[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL23)] &
1169 -            SSB_SPROM4_TXPID5GL2) >> SSB_SPROM4_TXPID5GL2_SHIFT;
1170 -       bus->sprom.txpid5gl[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL23)] &
1171 -            SSB_SPROM4_TXPID5GL3) >> SSB_SPROM4_TXPID5GL3_SHIFT;
1172 -
1173 -       bus->sprom.txpid5g[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5G01)] &
1174 -            SSB_SPROM4_TXPID5G0) >> SSB_SPROM4_TXPID5G0_SHIFT;
1175 -       bus->sprom.txpid5g[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5G01)] &
1176 -            SSB_SPROM4_TXPID5G1) >> SSB_SPROM4_TXPID5G1_SHIFT;
1177 -       bus->sprom.txpid5g[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5G23)] &
1178 -            SSB_SPROM4_TXPID5G2) >> SSB_SPROM4_TXPID5G2_SHIFT;
1179 -       bus->sprom.txpid5g[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5G23)] &
1180 -            SSB_SPROM4_TXPID5G3) >> SSB_SPROM4_TXPID5G3_SHIFT;
1181 -
1182 -       bus->sprom.txpid5gh[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH01)] &
1183 -            SSB_SPROM4_TXPID5GH0) >> SSB_SPROM4_TXPID5GH0_SHIFT;
1184 -       bus->sprom.txpid5gh[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH01)] &
1185 -            SSB_SPROM4_TXPID5GH1) >> SSB_SPROM4_TXPID5GH1_SHIFT;
1186 -       bus->sprom.txpid5gh[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH23)] &
1187 -            SSB_SPROM4_TXPID5GH2) >> SSB_SPROM4_TXPID5GH2_SHIFT;
1188 -       bus->sprom.txpid5gh[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH23)] &
1189 -            SSB_SPROM4_TXPID5GH3) >> SSB_SPROM4_TXPID5GH3_SHIFT;
1190 -
1191 -       bus->sprom.boardflags_lo = sprom[SPOFF(SSB_SPROM8_BFLLO)];
1192 -       bus->sprom.boardflags_hi = sprom[SPOFF(SSB_SPROM8_BFLHI)];
1193 -       bus->sprom.boardflags2_lo = sprom[SPOFF(SSB_SPROM8_BFL2LO)];
1194 -       bus->sprom.boardflags2_hi = sprom[SPOFF(SSB_SPROM8_BFL2HI)];
1195 -
1196 -       bus->sprom.country_code = sprom[SPOFF(SSB_SPROM8_CCODE)];
1197 -
1198 -       bus->sprom.fem.ghz2.tssipos = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
1199 -               SSB_SROM8_FEM_TSSIPOS) >> SSB_SROM8_FEM_TSSIPOS_SHIFT;
1200 -       bus->sprom.fem.ghz2.extpa_gain = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
1201 -               SSB_SROM8_FEM_EXTPA_GAIN) >> SSB_SROM8_FEM_EXTPA_GAIN_SHIFT;
1202 -       bus->sprom.fem.ghz2.pdet_range = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
1203 -               SSB_SROM8_FEM_PDET_RANGE) >> SSB_SROM8_FEM_PDET_RANGE_SHIFT;
1204 -       bus->sprom.fem.ghz2.tr_iso = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
1205 -               SSB_SROM8_FEM_TR_ISO) >> SSB_SROM8_FEM_TR_ISO_SHIFT;
1206 -       bus->sprom.fem.ghz2.antswlut = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
1207 -               SSB_SROM8_FEM_ANTSWLUT) >> SSB_SROM8_FEM_ANTSWLUT_SHIFT;
1208 -
1209 -       bus->sprom.fem.ghz5.tssipos = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
1210 -               SSB_SROM8_FEM_TSSIPOS) >> SSB_SROM8_FEM_TSSIPOS_SHIFT;
1211 -       bus->sprom.fem.ghz5.extpa_gain = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
1212 -               SSB_SROM8_FEM_EXTPA_GAIN) >> SSB_SROM8_FEM_EXTPA_GAIN_SHIFT;
1213 -       bus->sprom.fem.ghz5.pdet_range = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
1214 -               SSB_SROM8_FEM_PDET_RANGE) >> SSB_SROM8_FEM_PDET_RANGE_SHIFT;
1215 -       bus->sprom.fem.ghz5.tr_iso = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
1216 -               SSB_SROM8_FEM_TR_ISO) >> SSB_SROM8_FEM_TR_ISO_SHIFT;
1217 -       bus->sprom.fem.ghz5.antswlut = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
1218 -               SSB_SROM8_FEM_ANTSWLUT) >> SSB_SROM8_FEM_ANTSWLUT_SHIFT;
1219 +       SPEX(txpid2g[0], SSB_SPROM4_TXPID2G01, SSB_SPROM4_TXPID2G0,
1220 +            SSB_SPROM4_TXPID2G0_SHIFT);
1221 +       SPEX(txpid2g[1], SSB_SPROM4_TXPID2G01, SSB_SPROM4_TXPID2G1,
1222 +            SSB_SPROM4_TXPID2G1_SHIFT);
1223 +       SPEX(txpid2g[2], SSB_SPROM4_TXPID2G23, SSB_SPROM4_TXPID2G2,
1224 +            SSB_SPROM4_TXPID2G2_SHIFT);
1225 +       SPEX(txpid2g[3], SSB_SPROM4_TXPID2G23, SSB_SPROM4_TXPID2G3,
1226 +            SSB_SPROM4_TXPID2G3_SHIFT);
1227 +
1228 +       SPEX(txpid5gl[0], SSB_SPROM4_TXPID5GL01, SSB_SPROM4_TXPID5GL0,
1229 +            SSB_SPROM4_TXPID5GL0_SHIFT);
1230 +       SPEX(txpid5gl[1], SSB_SPROM4_TXPID5GL01, SSB_SPROM4_TXPID5GL1,
1231 +            SSB_SPROM4_TXPID5GL1_SHIFT);
1232 +       SPEX(txpid5gl[2], SSB_SPROM4_TXPID5GL23, SSB_SPROM4_TXPID5GL2,
1233 +            SSB_SPROM4_TXPID5GL2_SHIFT);
1234 +       SPEX(txpid5gl[3], SSB_SPROM4_TXPID5GL23, SSB_SPROM4_TXPID5GL3,
1235 +            SSB_SPROM4_TXPID5GL3_SHIFT);
1236 +
1237 +       SPEX(txpid5g[0], SSB_SPROM4_TXPID5G01, SSB_SPROM4_TXPID5G0,
1238 +            SSB_SPROM4_TXPID5G0_SHIFT);
1239 +       SPEX(txpid5g[1], SSB_SPROM4_TXPID5G01, SSB_SPROM4_TXPID5G1,
1240 +            SSB_SPROM4_TXPID5G1_SHIFT);
1241 +       SPEX(txpid5g[2], SSB_SPROM4_TXPID5G23, SSB_SPROM4_TXPID5G2,
1242 +            SSB_SPROM4_TXPID5G2_SHIFT);
1243 +       SPEX(txpid5g[3], SSB_SPROM4_TXPID5G23, SSB_SPROM4_TXPID5G3,
1244 +            SSB_SPROM4_TXPID5G3_SHIFT);
1245 +
1246 +       SPEX(txpid5gh[0], SSB_SPROM4_TXPID5GH01, SSB_SPROM4_TXPID5GH0,
1247 +            SSB_SPROM4_TXPID5GH0_SHIFT);
1248 +       SPEX(txpid5gh[1], SSB_SPROM4_TXPID5GH01, SSB_SPROM4_TXPID5GH1,
1249 +            SSB_SPROM4_TXPID5GH1_SHIFT);
1250 +       SPEX(txpid5gh[2], SSB_SPROM4_TXPID5GH23, SSB_SPROM4_TXPID5GH2,
1251 +            SSB_SPROM4_TXPID5GH2_SHIFT);
1252 +       SPEX(txpid5gh[3], SSB_SPROM4_TXPID5GH23, SSB_SPROM4_TXPID5GH3,
1253 +            SSB_SPROM4_TXPID5GH3_SHIFT);
1254 +
1255 +       SPEX(boardflags_lo, SSB_SPROM8_BFLLO, ~0, 0);
1256 +       SPEX(boardflags_hi, SSB_SPROM8_BFLHI, ~0, 0);
1257 +       SPEX(boardflags2_lo, SSB_SPROM8_BFL2LO, ~0, 0);
1258 +       SPEX(boardflags2_hi, SSB_SPROM8_BFL2HI, ~0, 0);
1259 +
1260 +       SPEX(country_code, SSB_SPROM8_CCODE, ~0, 0);
1261 +
1262 +       /* Extract cores power info info */
1263 +       for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) {
1264 +               o = pwr_info_offset[i];
1265 +               SPEX(core_pwr_info[i].itssi_2g, o + SSB_SROM8_2G_MAXP_ITSSI,
1266 +                       SSB_SPROM8_2G_ITSSI, SSB_SPROM8_2G_ITSSI_SHIFT);
1267 +               SPEX(core_pwr_info[i].maxpwr_2g, o + SSB_SROM8_2G_MAXP_ITSSI,
1268 +                       SSB_SPROM8_2G_MAXP, 0);
1269 +
1270 +               SPEX(core_pwr_info[i].pa_2g[0], o + SSB_SROM8_2G_PA_0, ~0, 0);
1271 +               SPEX(core_pwr_info[i].pa_2g[1], o + SSB_SROM8_2G_PA_1, ~0, 0);
1272 +               SPEX(core_pwr_info[i].pa_2g[2], o + SSB_SROM8_2G_PA_2, ~0, 0);
1273 +
1274 +               SPEX(core_pwr_info[i].itssi_5g, o + SSB_SROM8_5G_MAXP_ITSSI,
1275 +                       SSB_SPROM8_5G_ITSSI, SSB_SPROM8_5G_ITSSI_SHIFT);
1276 +               SPEX(core_pwr_info[i].maxpwr_5g, o + SSB_SROM8_5G_MAXP_ITSSI,
1277 +                       SSB_SPROM8_5G_MAXP, 0);
1278 +               SPEX(core_pwr_info[i].maxpwr_5gh, o + SSB_SPROM8_5GHL_MAXP,
1279 +                       SSB_SPROM8_5GH_MAXP, 0);
1280 +               SPEX(core_pwr_info[i].maxpwr_5gl, o + SSB_SPROM8_5GHL_MAXP,
1281 +                       SSB_SPROM8_5GL_MAXP, SSB_SPROM8_5GL_MAXP_SHIFT);
1282 +
1283 +               SPEX(core_pwr_info[i].pa_5gl[0], o + SSB_SROM8_5GL_PA_0, ~0, 0);
1284 +               SPEX(core_pwr_info[i].pa_5gl[1], o + SSB_SROM8_5GL_PA_1, ~0, 0);
1285 +               SPEX(core_pwr_info[i].pa_5gl[2], o + SSB_SROM8_5GL_PA_2, ~0, 0);
1286 +               SPEX(core_pwr_info[i].pa_5g[0], o + SSB_SROM8_5G_PA_0, ~0, 0);
1287 +               SPEX(core_pwr_info[i].pa_5g[1], o + SSB_SROM8_5G_PA_1, ~0, 0);
1288 +               SPEX(core_pwr_info[i].pa_5g[2], o + SSB_SROM8_5G_PA_2, ~0, 0);
1289 +               SPEX(core_pwr_info[i].pa_5gh[0], o + SSB_SROM8_5GH_PA_0, ~0, 0);
1290 +               SPEX(core_pwr_info[i].pa_5gh[1], o + SSB_SROM8_5GH_PA_1, ~0, 0);
1291 +               SPEX(core_pwr_info[i].pa_5gh[2], o + SSB_SROM8_5GH_PA_2, ~0, 0);
1292 +       }
1293 +
1294 +       SPEX(fem.ghz2.tssipos, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_TSSIPOS,
1295 +            SSB_SROM8_FEM_TSSIPOS_SHIFT);
1296 +       SPEX(fem.ghz2.extpa_gain, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_EXTPA_GAIN,
1297 +            SSB_SROM8_FEM_EXTPA_GAIN_SHIFT);
1298 +       SPEX(fem.ghz2.pdet_range, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_PDET_RANGE,
1299 +            SSB_SROM8_FEM_PDET_RANGE_SHIFT);
1300 +       SPEX(fem.ghz2.tr_iso, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_TR_ISO,
1301 +            SSB_SROM8_FEM_TR_ISO_SHIFT);
1302 +       SPEX(fem.ghz2.antswlut, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_ANTSWLUT,
1303 +            SSB_SROM8_FEM_ANTSWLUT_SHIFT);
1304 +
1305 +       SPEX(fem.ghz5.tssipos, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_TSSIPOS,
1306 +            SSB_SROM8_FEM_TSSIPOS_SHIFT);
1307 +       SPEX(fem.ghz5.extpa_gain, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_EXTPA_GAIN,
1308 +            SSB_SROM8_FEM_EXTPA_GAIN_SHIFT);
1309 +       SPEX(fem.ghz5.pdet_range, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_PDET_RANGE,
1310 +            SSB_SROM8_FEM_PDET_RANGE_SHIFT);
1311 +       SPEX(fem.ghz5.tr_iso, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_TR_ISO,
1312 +            SSB_SROM8_FEM_TR_ISO_SHIFT);
1313 +       SPEX(fem.ghz5.antswlut, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_ANTSWLUT,
1314 +            SSB_SROM8_FEM_ANTSWLUT_SHIFT);
1315 +}
1316 +
1317 +/*
1318 + * Indicates the presence of external SPROM.
1319 + */
1320 +static bool bcma_sprom_ext_available(struct bcma_bus *bus)
1321 +{
1322 +       u32 chip_status;
1323 +       u32 srom_control;
1324 +       u32 present_mask;
1325 +
1326 +       if (bus->drv_cc.core->id.rev >= 31) {
1327 +               if (!(bus->drv_cc.capabilities & BCMA_CC_CAP_SPROM))
1328 +                       return false;
1329 +
1330 +               srom_control = bcma_read32(bus->drv_cc.core,
1331 +                                          BCMA_CC_SROM_CONTROL);
1332 +               return srom_control & BCMA_CC_SROM_CONTROL_PRESENT;
1333 +       }
1334 +
1335 +       /* older chipcommon revisions use chip status register */
1336 +       chip_status = bcma_read32(bus->drv_cc.core, BCMA_CC_CHIPSTAT);
1337 +       switch (bus->chipinfo.id) {
1338 +       case 0x4313:
1339 +               present_mask = BCMA_CC_CHIPST_4313_SPROM_PRESENT;
1340 +               break;
1341 +
1342 +       case 0x4331:
1343 +               present_mask = BCMA_CC_CHIPST_4331_SPROM_PRESENT;
1344 +               break;
1345 +
1346 +       default:
1347 +               return true;
1348 +       }
1349 +
1350 +       return chip_status & present_mask;
1351 +}
1352 +
1353 +/*
1354 + * Indicates that on-chip OTP memory is present and enabled.
1355 + */
1356 +static bool bcma_sprom_onchip_available(struct bcma_bus *bus)
1357 +{
1358 +       u32 chip_status;
1359 +       u32 otpsize = 0;
1360 +       bool present;
1361 +
1362 +       chip_status = bcma_read32(bus->drv_cc.core, BCMA_CC_CHIPSTAT);
1363 +       switch (bus->chipinfo.id) {
1364 +       case 0x4313:
1365 +               present = chip_status & BCMA_CC_CHIPST_4313_OTP_PRESENT;
1366 +               break;
1367 +
1368 +       case 0x4331:
1369 +               present = chip_status & BCMA_CC_CHIPST_4331_OTP_PRESENT;
1370 +               break;
1371 +
1372 +       case 43224:
1373 +       case 43225:
1374 +               /* for these chips OTP is always available */
1375 +               present = true;
1376 +               break;
1377 +
1378 +       default:
1379 +               present = false;
1380 +               break;
1381 +       }
1382 +
1383 +       if (present) {
1384 +               otpsize = bus->drv_cc.capabilities & BCMA_CC_CAP_OTPS;
1385 +               otpsize >>= BCMA_CC_CAP_OTPS_SHIFT;
1386 +       }
1387 +
1388 +       return otpsize != 0;
1389 +}
1390 +
1391 +/*
1392 + * Verify OTP is filled and determine the byte
1393 + * offset where SPROM data is located.
1394 + *
1395 + * On error, returns 0; byte offset otherwise.
1396 + */
1397 +static int bcma_sprom_onchip_offset(struct bcma_bus *bus)
1398 +{
1399 +       struct bcma_device *cc = bus->drv_cc.core;
1400 +       u32 offset;
1401 +
1402 +       /* verify OTP status */
1403 +       if ((bcma_read32(cc, BCMA_CC_OTPS) & BCMA_CC_OTPS_GU_PROG_HW) == 0)
1404 +               return 0;
1405 +
1406 +       /* obtain bit offset from otplayout register */
1407 +       offset = (bcma_read32(cc, BCMA_CC_OTPL) & BCMA_CC_OTPL_GURGN_OFFSET);
1408 +       return BCMA_CC_SPROM + (offset >> 3);
1409  }
1410  
1411  int bcma_sprom_get(struct bcma_bus *bus)
1412  {
1413 -       u16 offset;
1414 +       u16 offset = BCMA_CC_SPROM;
1415         u16 *sprom;
1416         int err = 0;
1417  
1418         if (!bus->drv_cc.core)
1419                 return -EOPNOTSUPP;
1420  
1421 -       if (!(bus->drv_cc.capabilities & BCMA_CC_CAP_SPROM))
1422 -               return -ENOENT;
1423 +       if (!bcma_sprom_ext_available(bus)) {
1424 +               /*
1425 +                * External SPROM takes precedence so check
1426 +                * on-chip OTP only when no external SPROM
1427 +                * is present.
1428 +                */
1429 +               if (bcma_sprom_onchip_available(bus)) {
1430 +                       /* determine offset */
1431 +                       offset = bcma_sprom_onchip_offset(bus);
1432 +               }
1433 +               if (!offset) {
1434 +                       /*
1435 +                        * Maybe there is no SPROM on the device?
1436 +                        * Now we ask the arch code if there is some sprom
1437 +                        * available for this device in some other storage.
1438 +                        */
1439 +                       err = bcma_fill_sprom_with_fallback(bus, &bus->sprom);
1440 +                       return err;
1441 +               }
1442 +       }
1443  
1444         sprom = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16),
1445                         GFP_KERNEL);
1446 @@ -225,11 +432,7 @@ int bcma_sprom_get(struct bcma_bus *bus)
1447         if (bus->chipinfo.id == 0x4331)
1448                 bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, false);
1449  
1450 -       /* Most cards have SPROM moved by additional offset 0x30 (48 dwords).
1451 -        * According to brcm80211 this applies to cards with PCIe rev >= 6
1452 -        * TODO: understand this condition and use it */
1453 -       offset = (bus->chipinfo.id == 0x4331) ? BCMA_CC_SPROM :
1454 -               BCMA_CC_SPROM_PCIE6;
1455 +       pr_debug("SPROM offset 0x%x\n", offset);
1456         bcma_sprom_read(bus, offset, sprom);
1457  
1458         if (bus->chipinfo.id == 0x4331)
1459 --- a/include/linux/bcma/bcma.h
1460 +++ b/include/linux/bcma/bcma.h
1461 @@ -136,6 +136,7 @@ struct bcma_device {
1462         bool dev_registered;
1463  
1464         u8 core_index;
1465 +       u8 core_unit;
1466  
1467         u32 addr;
1468         u32 wrap;
1469 @@ -175,6 +176,12 @@ int __bcma_driver_register(struct bcma_d
1470  
1471  extern void bcma_driver_unregister(struct bcma_driver *drv);
1472  
1473 +/* Set a fallback SPROM.
1474 + * See kdoc at the function definition for complete documentation. */
1475 +extern int bcma_arch_register_fallback_sprom(
1476 +               int (*sprom_callback)(struct bcma_bus *bus,
1477 +               struct ssb_sprom *out));
1478 +
1479  struct bcma_bus {
1480         /* The MMIO area. */
1481         void __iomem *mmio;
1482 @@ -195,6 +202,7 @@ struct bcma_bus {
1483         struct list_head cores;
1484         u8 nr_cores;
1485         u8 init_done:1;
1486 +       u8 num;
1487  
1488         struct bcma_drv_cc drv_cc;
1489         struct bcma_drv_pci drv_pci;
1490 @@ -282,6 +290,7 @@ static inline void bcma_maskset16(struct
1491         bcma_write16(cc, offset, (bcma_read16(cc, offset) & mask) | set);
1492  }
1493  
1494 +extern struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid);
1495  extern bool bcma_core_is_enabled(struct bcma_device *core);
1496  extern void bcma_core_disable(struct bcma_device *core, u32 flags);
1497  extern int bcma_core_enable(struct bcma_device *core, u32 flags);
1498 --- a/include/linux/bcma/bcma_driver_chipcommon.h
1499 +++ b/include/linux/bcma/bcma_driver_chipcommon.h
1500 @@ -56,6 +56,9 @@
1501  #define         BCMA_CC_OTPS_HW_PROTECT        0x00000001
1502  #define         BCMA_CC_OTPS_SW_PROTECT        0x00000002
1503  #define         BCMA_CC_OTPS_CID_PROTECT       0x00000004
1504 +#define  BCMA_CC_OTPS_GU_PROG_IND      0x00000F00      /* General Use programmed indication */
1505 +#define  BCMA_CC_OTPS_GU_PROG_IND_SHIFT        8
1506 +#define  BCMA_CC_OTPS_GU_PROG_HW       0x00000100      /* HW region programmed */
1507  #define BCMA_CC_OTPC                   0x0014          /* OTP control */
1508  #define         BCMA_CC_OTPC_RECWAIT           0xFF000000
1509  #define         BCMA_CC_OTPC_PROGWAIT          0x00FFFF00
1510 @@ -72,6 +75,8 @@
1511  #define         BCMA_CC_OTPP_READ              0x40000000
1512  #define         BCMA_CC_OTPP_START             0x80000000
1513  #define         BCMA_CC_OTPP_BUSY              0x80000000
1514 +#define BCMA_CC_OTPL                   0x001C          /* OTP layout */
1515 +#define  BCMA_CC_OTPL_GURGN_OFFSET     0x00000FFF      /* offset of general use region */
1516  #define BCMA_CC_IRQSTAT                        0x0020
1517  #define BCMA_CC_IRQMASK                        0x0024
1518  #define         BCMA_CC_IRQ_GPIO               0x00000001      /* gpio intr */
1519 @@ -79,6 +84,10 @@
1520  #define         BCMA_CC_IRQ_WDRESET            0x80000000      /* watchdog reset occurred */
1521  #define BCMA_CC_CHIPCTL                        0x0028          /* Rev >= 11 only */
1522  #define BCMA_CC_CHIPSTAT               0x002C          /* Rev >= 11 only */
1523 +#define  BCMA_CC_CHIPST_4313_SPROM_PRESENT     1
1524 +#define  BCMA_CC_CHIPST_4313_OTP_PRESENT       2
1525 +#define  BCMA_CC_CHIPST_4331_SPROM_PRESENT     2
1526 +#define  BCMA_CC_CHIPST_4331_OTP_PRESENT       4
1527  #define BCMA_CC_JCMD                   0x0030          /* Rev >= 10 only */
1528  #define  BCMA_CC_JCMD_START            0x80000000
1529  #define  BCMA_CC_JCMD_BUSY             0x80000000
1530 @@ -181,6 +190,22 @@
1531  #define BCMA_CC_FLASH_CFG              0x0128
1532  #define  BCMA_CC_FLASH_CFG_DS          0x0010  /* Data size, 0=8bit, 1=16bit */
1533  #define BCMA_CC_FLASH_WAITCNT          0x012C
1534 +#define BCMA_CC_SROM_CONTROL           0x0190
1535 +#define  BCMA_CC_SROM_CONTROL_START    0x80000000
1536 +#define  BCMA_CC_SROM_CONTROL_BUSY     0x80000000
1537 +#define  BCMA_CC_SROM_CONTROL_OPCODE   0x60000000
1538 +#define  BCMA_CC_SROM_CONTROL_OP_READ  0x00000000
1539 +#define  BCMA_CC_SROM_CONTROL_OP_WRITE 0x20000000
1540 +#define  BCMA_CC_SROM_CONTROL_OP_WRDIS 0x40000000
1541 +#define  BCMA_CC_SROM_CONTROL_OP_WREN  0x60000000
1542 +#define  BCMA_CC_SROM_CONTROL_OTPSEL   0x00000010
1543 +#define  BCMA_CC_SROM_CONTROL_LOCK     0x00000008
1544 +#define  BCMA_CC_SROM_CONTROL_SIZE_MASK        0x00000006
1545 +#define  BCMA_CC_SROM_CONTROL_SIZE_1K  0x00000000
1546 +#define  BCMA_CC_SROM_CONTROL_SIZE_4K  0x00000002
1547 +#define  BCMA_CC_SROM_CONTROL_SIZE_16K 0x00000004
1548 +#define  BCMA_CC_SROM_CONTROL_SIZE_SHIFT       1
1549 +#define  BCMA_CC_SROM_CONTROL_PRESENT  0x00000001
1550  /* 0x1E0 is defined as shared BCMA_CLKCTLST */
1551  #define BCMA_CC_HW_WORKAROUND          0x01E4 /* Hardware workaround (rev >= 20) */
1552  #define BCMA_CC_UART0_DATA             0x0300
1553 @@ -240,7 +265,6 @@
1554  #define BCMA_CC_PLLCTL_ADDR            0x0660
1555  #define BCMA_CC_PLLCTL_DATA            0x0664
1556  #define BCMA_CC_SPROM                  0x0800 /* SPROM beginning */
1557 -#define BCMA_CC_SPROM_PCIE6            0x0830 /* SPROM beginning on PCIe rev >= 6 */
1558  
1559  /* Divider allocation in 4716/47162/5356 */
1560  #define BCMA_CC_PMU5_MAINPLL_CPU       1
1561 --- a/include/linux/bcma/bcma_driver_pci.h
1562 +++ b/include/linux/bcma/bcma_driver_pci.h
1563 @@ -53,6 +53,35 @@ struct pci_dev;
1564  #define  BCMA_CORE_PCI_SBTOPCI1_MASK           0xFC000000
1565  #define BCMA_CORE_PCI_SBTOPCI2                 0x0108  /* Backplane to PCI translation 2 (sbtopci2) */
1566  #define  BCMA_CORE_PCI_SBTOPCI2_MASK           0xC0000000
1567 +#define BCMA_CORE_PCI_CONFIG_ADDR              0x0120  /* pcie config space access */
1568 +#define BCMA_CORE_PCI_CONFIG_DATA              0x0124  /* pcie config space access */
1569 +#define BCMA_CORE_PCI_MDIO_CONTROL             0x0128  /* controls the mdio access */
1570 +#define  BCMA_CORE_PCI_MDIOCTL_DIVISOR_MASK    0x7f    /* clock to be used on MDIO */
1571 +#define  BCMA_CORE_PCI_MDIOCTL_DIVISOR_VAL     0x2
1572 +#define  BCMA_CORE_PCI_MDIOCTL_PREAM_EN                0x80    /* Enable preamble sequnce */
1573 +#define  BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE     0x100   /* Tranaction complete */
1574 +#define BCMA_CORE_PCI_MDIO_DATA                        0x012c  /* Data to the mdio access */
1575 +#define  BCMA_CORE_PCI_MDIODATA_MASK           0x0000ffff /* data 2 bytes */
1576 +#define  BCMA_CORE_PCI_MDIODATA_TA             0x00020000 /* Turnaround */
1577 +#define  BCMA_CORE_PCI_MDIODATA_REGADDR_SHF_OLD        18      /* Regaddr shift (rev < 10) */
1578 +#define  BCMA_CORE_PCI_MDIODATA_REGADDR_MASK_OLD       0x003c0000 /* Regaddr Mask (rev < 10) */
1579 +#define  BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF_OLD        22      /* Physmedia devaddr shift (rev < 10) */
1580 +#define  BCMA_CORE_PCI_MDIODATA_DEVADDR_MASK_OLD       0x0fc00000 /* Physmedia devaddr Mask (rev < 10) */
1581 +#define  BCMA_CORE_PCI_MDIODATA_REGADDR_SHF    18      /* Regaddr shift */
1582 +#define  BCMA_CORE_PCI_MDIODATA_REGADDR_MASK   0x007c0000 /* Regaddr Mask */
1583 +#define  BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF    23      /* Physmedia devaddr shift */
1584 +#define  BCMA_CORE_PCI_MDIODATA_DEVADDR_MASK   0x0f800000 /* Physmedia devaddr Mask */
1585 +#define  BCMA_CORE_PCI_MDIODATA_WRITE          0x10000000 /* write Transaction */
1586 +#define  BCMA_CORE_PCI_MDIODATA_READ           0x20000000 /* Read Transaction */
1587 +#define  BCMA_CORE_PCI_MDIODATA_START          0x40000000 /* start of Transaction */
1588 +#define  BCMA_CORE_PCI_MDIODATA_DEV_ADDR       0x0     /* dev address for serdes */
1589 +#define  BCMA_CORE_PCI_MDIODATA_BLK_ADDR       0x1F    /* blk address for serdes */
1590 +#define  BCMA_CORE_PCI_MDIODATA_DEV_PLL                0x1d    /* SERDES PLL Dev */
1591 +#define  BCMA_CORE_PCI_MDIODATA_DEV_TX         0x1e    /* SERDES TX Dev */
1592 +#define  BCMA_CORE_PCI_MDIODATA_DEV_RX         0x1f    /* SERDES RX Dev */
1593 +#define BCMA_CORE_PCI_PCIEIND_ADDR             0x0130  /* indirect access to the internal register */
1594 +#define BCMA_CORE_PCI_PCIEIND_DATA             0x0134  /* Data to/from the internal regsiter */
1595 +#define BCMA_CORE_PCI_CLKREQENCTRL             0x0138  /*  >= rev 6, Clkreq rdma control */
1596  #define BCMA_CORE_PCI_PCICFG0                  0x0400  /* PCI config space 0 (rev >= 8) */
1597  #define BCMA_CORE_PCI_PCICFG1                  0x0500  /* PCI config space 1 (rev >= 8) */
1598  #define BCMA_CORE_PCI_PCICFG2                  0x0600  /* PCI config space 2 (rev >= 8) */
1599 @@ -72,20 +101,114 @@ struct pci_dev;
1600  #define  BCMA_CORE_PCI_SBTOPCI_RC_READL                0x00000010 /* Memory read line */
1601  #define  BCMA_CORE_PCI_SBTOPCI_RC_READM                0x00000020 /* Memory read multiple */
1602  
1603 +/* PCIE protocol PHY diagnostic registers */
1604 +#define BCMA_CORE_PCI_PLP_MODEREG              0x200   /* Mode */
1605 +#define BCMA_CORE_PCI_PLP_STATUSREG            0x204   /* Status */
1606 +#define  BCMA_CORE_PCI_PLP_POLARITYINV_STAT    0x10    /* Status reg PCIE_PLP_STATUSREG */
1607 +#define BCMA_CORE_PCI_PLP_LTSSMCTRLREG         0x208   /* LTSSM control */
1608 +#define BCMA_CORE_PCI_PLP_LTLINKNUMREG         0x20c   /* Link Training Link number */
1609 +#define BCMA_CORE_PCI_PLP_LTLANENUMREG         0x210   /* Link Training Lane number */
1610 +#define BCMA_CORE_PCI_PLP_LTNFTSREG            0x214   /* Link Training N_FTS */
1611 +#define BCMA_CORE_PCI_PLP_ATTNREG              0x218   /* Attention */
1612 +#define BCMA_CORE_PCI_PLP_ATTNMASKREG          0x21C   /* Attention Mask */
1613 +#define BCMA_CORE_PCI_PLP_RXERRCTR             0x220   /* Rx Error */
1614 +#define BCMA_CORE_PCI_PLP_RXFRMERRCTR          0x224   /* Rx Framing Error */
1615 +#define BCMA_CORE_PCI_PLP_RXERRTHRESHREG       0x228   /* Rx Error threshold */
1616 +#define BCMA_CORE_PCI_PLP_TESTCTRLREG          0x22C   /* Test Control reg */
1617 +#define BCMA_CORE_PCI_PLP_SERDESCTRLOVRDREG    0x230   /* SERDES Control Override */
1618 +#define BCMA_CORE_PCI_PLP_TIMINGOVRDREG                0x234   /* Timing param override */
1619 +#define BCMA_CORE_PCI_PLP_RXTXSMDIAGREG                0x238   /* RXTX State Machine Diag */
1620 +#define BCMA_CORE_PCI_PLP_LTSSMDIAGREG         0x23C   /* LTSSM State Machine Diag */
1621 +
1622 +/* PCIE protocol DLLP diagnostic registers */
1623 +#define BCMA_CORE_PCI_DLLP_LCREG               0x100   /* Link Control */
1624 +#define BCMA_CORE_PCI_DLLP_LSREG               0x104   /* Link Status */
1625 +#define BCMA_CORE_PCI_DLLP_LAREG               0x108   /* Link Attention */
1626 +#define  BCMA_CORE_PCI_DLLP_LSREG_LINKUP       (1 << 16)
1627 +#define BCMA_CORE_PCI_DLLP_LAMASKREG           0x10C   /* Link Attention Mask */
1628 +#define BCMA_CORE_PCI_DLLP_NEXTTXSEQNUMREG     0x110   /* Next Tx Seq Num */
1629 +#define BCMA_CORE_PCI_DLLP_ACKEDTXSEQNUMREG    0x114   /* Acked Tx Seq Num */
1630 +#define BCMA_CORE_PCI_DLLP_PURGEDTXSEQNUMREG   0x118   /* Purged Tx Seq Num */
1631 +#define BCMA_CORE_PCI_DLLP_RXSEQNUMREG         0x11C   /* Rx Sequence Number */
1632 +#define BCMA_CORE_PCI_DLLP_LRREG               0x120   /* Link Replay */
1633 +#define BCMA_CORE_PCI_DLLP_LACKTOREG           0x124   /* Link Ack Timeout */
1634 +#define BCMA_CORE_PCI_DLLP_PMTHRESHREG         0x128   /* Power Management Threshold */
1635 +#define BCMA_CORE_PCI_DLLP_RTRYWPREG           0x12C   /* Retry buffer write ptr */
1636 +#define BCMA_CORE_PCI_DLLP_RTRYRPREG           0x130   /* Retry buffer Read ptr */
1637 +#define BCMA_CORE_PCI_DLLP_RTRYPPREG           0x134   /* Retry buffer Purged ptr */
1638 +#define BCMA_CORE_PCI_DLLP_RTRRWREG            0x138   /* Retry buffer Read/Write */
1639 +#define BCMA_CORE_PCI_DLLP_ECTHRESHREG         0x13C   /* Error Count Threshold */
1640 +#define BCMA_CORE_PCI_DLLP_TLPERRCTRREG                0x140   /* TLP Error Counter */
1641 +#define BCMA_CORE_PCI_DLLP_ERRCTRREG           0x144   /* Error Counter */
1642 +#define BCMA_CORE_PCI_DLLP_NAKRXCTRREG         0x148   /* NAK Received Counter */
1643 +#define BCMA_CORE_PCI_DLLP_TESTREG             0x14C   /* Test */
1644 +#define BCMA_CORE_PCI_DLLP_PKTBIST             0x150   /* Packet BIST */
1645 +#define BCMA_CORE_PCI_DLLP_PCIE11              0x154   /* DLLP PCIE 1.1 reg */
1646 +
1647 +/* SERDES RX registers */
1648 +#define BCMA_CORE_PCI_SERDES_RX_CTRL           1       /* Rx cntrl */
1649 +#define  BCMA_CORE_PCI_SERDES_RX_CTRL_FORCE    0x80    /* rxpolarity_force */
1650 +#define  BCMA_CORE_PCI_SERDES_RX_CTRL_POLARITY 0x40    /* rxpolarity_value */
1651 +#define BCMA_CORE_PCI_SERDES_RX_TIMER1         2       /* Rx Timer1 */
1652 +#define BCMA_CORE_PCI_SERDES_RX_CDR            6       /* CDR */
1653 +#define BCMA_CORE_PCI_SERDES_RX_CDRBW          7       /* CDR BW */
1654 +
1655 +/* SERDES PLL registers */
1656 +#define BCMA_CORE_PCI_SERDES_PLL_CTRL          1       /* PLL control reg */
1657 +#define BCMA_CORE_PCI_PLL_CTRL_FREQDET_EN      0x4000  /* bit 14 is FREQDET on */
1658 +
1659  /* PCIcore specific boardflags */
1660  #define BCMA_CORE_PCI_BFL_NOPCI                        0x00000400 /* Board leaves PCI floating */
1661  
1662 +/* PCIE Config space accessing MACROS */
1663 +#define BCMA_CORE_PCI_CFG_BUS_SHIFT            24      /* Bus shift */
1664 +#define BCMA_CORE_PCI_CFG_SLOT_SHIFT           19      /* Slot/Device shift */
1665 +#define BCMA_CORE_PCI_CFG_FUN_SHIFT            16      /* Function shift */
1666 +#define BCMA_CORE_PCI_CFG_OFF_SHIFT            0       /* Register shift */
1667 +
1668 +#define BCMA_CORE_PCI_CFG_BUS_MASK             0xff    /* Bus mask */
1669 +#define BCMA_CORE_PCI_CFG_SLOT_MASK            0x1f    /* Slot/Device mask */
1670 +#define BCMA_CORE_PCI_CFG_FUN_MASK             7       /* Function mask */
1671 +#define BCMA_CORE_PCI_CFG_OFF_MASK             0xfff   /* Register mask */
1672 +
1673 +/* PCIE Root Capability Register bits (Host mode only) */
1674 +#define BCMA_CORE_PCI_RC_CRS_VISIBILITY                0x0001
1675 +
1676 +struct bcma_drv_pci;
1677 +
1678 +#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
1679 +struct bcma_drv_pci_host {
1680 +       struct bcma_drv_pci *pdev;
1681 +
1682 +       u32 host_cfg_addr;
1683 +       spinlock_t cfgspace_lock;
1684 +
1685 +       struct pci_controller pci_controller;
1686 +       struct pci_ops pci_ops;
1687 +       struct resource mem_resource;
1688 +       struct resource io_resource;
1689 +};
1690 +#endif
1691 +
1692  struct bcma_drv_pci {
1693         struct bcma_device *core;
1694         u8 setup_done:1;
1695 +       u8 hostmode:1;
1696 +
1697 +#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
1698 +       struct bcma_drv_pci_host *host_controller;
1699 +#endif
1700  };
1701  
1702  /* Register access */
1703  #define pcicore_read32(pc, offset)             bcma_read32((pc)->core, offset)
1704  #define pcicore_write32(pc, offset, val)       bcma_write32((pc)->core, offset, val)
1705  
1706 -extern void bcma_core_pci_init(struct bcma_drv_pci *pc);
1707 +extern void __devinit bcma_core_pci_init(struct bcma_drv_pci *pc);
1708  extern int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc,
1709                                  struct bcma_device *core, bool enable);
1710  
1711 +extern int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev);
1712 +extern int bcma_core_pci_plat_dev_init(struct pci_dev *dev);
1713 +
1714  #endif /* LINUX_BCMA_DRIVER_PCI_H_ */
1715 --- a/include/linux/bcma/bcma_regs.h
1716 +++ b/include/linux/bcma/bcma_regs.h
1717 @@ -56,4 +56,31 @@
1718  #define  BCMA_PCI_GPIO_XTAL            0x40    /* PCI config space GPIO 14 for Xtal powerup */
1719  #define  BCMA_PCI_GPIO_PLL             0x80    /* PCI config space GPIO 15 for PLL powerdown */
1720  
1721 +/* SiliconBackplane Address Map.
1722 + * All regions may not exist on all chips.
1723 + */
1724 +#define BCMA_SOC_SDRAM_BASE            0x00000000U     /* Physical SDRAM */
1725 +#define BCMA_SOC_PCI_MEM               0x08000000U     /* Host Mode sb2pcitranslation0 (64 MB) */
1726 +#define BCMA_SOC_PCI_MEM_SZ            (64 * 1024 * 1024)
1727 +#define BCMA_SOC_PCI_CFG               0x0c000000U     /* Host Mode sb2pcitranslation1 (64 MB) */
1728 +#define BCMA_SOC_SDRAM_SWAPPED         0x10000000U     /* Byteswapped Physical SDRAM */
1729 +#define BCMA_SOC_SDRAM_R2              0x80000000U     /* Region 2 for sdram (512 MB) */
1730 +
1731 +
1732 +#define BCMA_SOC_PCI_DMA               0x40000000U     /* Client Mode sb2pcitranslation2 (1 GB) */
1733 +#define BCMA_SOC_PCI_DMA2              0x80000000U     /* Client Mode sb2pcitranslation2 (1 GB) */
1734 +#define BCMA_SOC_PCI_DMA_SZ            0x40000000U     /* Client Mode sb2pcitranslation2 size in bytes */
1735 +#define BCMA_SOC_PCIE_DMA_L32          0x00000000U     /* PCIE Client Mode sb2pcitranslation2
1736 +                                                        * (2 ZettaBytes), low 32 bits
1737 +                                                        */
1738 +#define BCMA_SOC_PCIE_DMA_H32          0x80000000U     /* PCIE Client Mode sb2pcitranslation2
1739 +                                                        * (2 ZettaBytes), high 32 bits
1740 +                                                        */
1741 +
1742 +#define BCMA_SOC_PCI1_MEM              0x40000000U     /* Host Mode sb2pcitranslation0 (64 MB) */
1743 +#define BCMA_SOC_PCI1_CFG              0x44000000U     /* Host Mode sb2pcitranslation1 (64 MB) */
1744 +#define BCMA_SOC_PCIE1_DMA_H32         0xc0000000U     /* PCIE Client Mode sb2pcitranslation2
1745 +                                                        * (2 ZettaBytes), high 32 bits
1746 +                                                        */
1747 +
1748  #endif /* LINUX_BCMA_REGS_H_ */