Root/target/linux/generic/patches-3.3/025-bcma_backport.patch

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

Archive Download this file



interactive