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

1--- a/drivers/bcma/Kconfig
2+++ b/drivers/bcma/Kconfig
3@@ -33,6 +33,19 @@ config BCMA_DRIVER_PCI_HOSTMODE
4     help
5       PCI core hostmode operation (external PCI bus).
6 
7+config BCMA_HOST_SOC
8+ bool
9+ depends on BCMA_DRIVER_MIPS
10+
11+config BCMA_DRIVER_MIPS
12+ bool "BCMA Broadcom MIPS core driver"
13+ depends on BCMA && MIPS
14+ help
15+ Driver for the Broadcom MIPS core attached to Broadcom specific
16+ Advanced Microcontroller Bus.
17+
18+ If unsure, say N
19+
20 config BCMA_DEBUG
21     bool "BCMA debugging"
22     depends on BCMA
23--- a/drivers/bcma/Makefile
24+++ b/drivers/bcma/Makefile
25@@ -2,7 +2,9 @@ bcma-y += main.o scan.o core.o sprom
26 bcma-y += driver_chipcommon.o driver_chipcommon_pmu.o
27 bcma-y += driver_pci.o
28 bcma-$(CONFIG_BCMA_DRIVER_PCI_HOSTMODE) += driver_pci_host.o
29+bcma-$(CONFIG_BCMA_DRIVER_MIPS) += driver_mips.o
30 bcma-$(CONFIG_BCMA_HOST_PCI) += host_pci.o
31+bcma-$(CONFIG_BCMA_HOST_SOC) += host_soc.o
32 obj-$(CONFIG_BCMA) += bcma.o
33 
34 ccflags-$(CONFIG_BCMA_DEBUG) := -DDEBUG
35--- a/drivers/bcma/bcma_private.h
36+++ b/drivers/bcma/bcma_private.h
37@@ -15,13 +15,32 @@ struct bcma_bus;
38 /* main.c */
39 int bcma_bus_register(struct bcma_bus *bus);
40 void bcma_bus_unregister(struct bcma_bus *bus);
41+int __init bcma_bus_early_register(struct bcma_bus *bus,
42+ struct bcma_device *core_cc,
43+ struct bcma_device *core_mips);
44+#ifdef CONFIG_PM
45+int bcma_bus_resume(struct bcma_bus *bus);
46+#endif
47 
48 /* scan.c */
49 int bcma_bus_scan(struct bcma_bus *bus);
50+int __init bcma_bus_scan_early(struct bcma_bus *bus,
51+ struct bcma_device_id *match,
52+ struct bcma_device *core);
53+void bcma_init_bus(struct bcma_bus *bus);
54 
55 /* sprom.c */
56 int bcma_sprom_get(struct bcma_bus *bus);
57 
58+/* driver_chipcommon.c */
59+#ifdef CONFIG_BCMA_DRIVER_MIPS
60+void bcma_chipco_serial_init(struct bcma_drv_cc *cc);
61+#endif /* CONFIG_BCMA_DRIVER_MIPS */
62+
63+/* driver_chipcommon_pmu.c */
64+u32 bcma_pmu_alp_clock(struct bcma_drv_cc *cc);
65+u32 bcma_pmu_get_clockcpu(struct bcma_drv_cc *cc);
66+
67 #ifdef CONFIG_BCMA_HOST_PCI
68 /* host_pci.c */
69 extern int __init bcma_host_pci_init(void);
70--- a/drivers/bcma/core.c
71+++ b/drivers/bcma/core.c
72@@ -110,6 +110,8 @@ EXPORT_SYMBOL_GPL(bcma_core_pll_ctl);
73 u32 bcma_core_dma_translation(struct bcma_device *core)
74 {
75     switch (core->bus->hosttype) {
76+ case BCMA_HOSTTYPE_SOC:
77+ return 0;
78     case BCMA_HOSTTYPE_PCI:
79         if (bcma_aread32(core, BCMA_IOST) & BCMA_IOST_DMA64)
80             return BCMA_DMA_TRANSLATION_DMA64_CMT;
81--- a/drivers/bcma/driver_chipcommon.c
82+++ b/drivers/bcma/driver_chipcommon.c
83@@ -26,6 +26,9 @@ void bcma_core_chipcommon_init(struct bc
84     u32 leddc_on = 10;
85     u32 leddc_off = 90;
86 
87+ if (cc->setup_done)
88+ return;
89+
90     if (cc->core->id.rev >= 11)
91         cc->status = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
92     cc->capabilities = bcma_cc_read32(cc, BCMA_CC_CAP);
93@@ -52,6 +55,8 @@ void bcma_core_chipcommon_init(struct bc
94             ((leddc_on << BCMA_CC_GPIOTIMER_ONTIME_SHIFT) |
95              (leddc_off << BCMA_CC_GPIOTIMER_OFFTIME_SHIFT)));
96     }
97+
98+ cc->setup_done = true;
99 }
100 
101 /* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */
102@@ -101,3 +106,51 @@ u32 bcma_chipco_gpio_polarity(struct bcm
103 {
104     return bcma_cc_write32_masked(cc, BCMA_CC_GPIOPOL, mask, value);
105 }
106+
107+#ifdef CONFIG_BCMA_DRIVER_MIPS
108+void bcma_chipco_serial_init(struct bcma_drv_cc *cc)
109+{
110+ unsigned int irq;
111+ u32 baud_base;
112+ u32 i;
113+ unsigned int ccrev = cc->core->id.rev;
114+ struct bcma_serial_port *ports = cc->serial_ports;
115+
116+ if (ccrev >= 11 && ccrev != 15) {
117+ /* Fixed ALP clock */
118+ baud_base = bcma_pmu_alp_clock(cc);
119+ if (ccrev >= 21) {
120+ /* Turn off UART clock before switching clocksource. */
121+ bcma_cc_write32(cc, BCMA_CC_CORECTL,
122+ bcma_cc_read32(cc, BCMA_CC_CORECTL)
123+ & ~BCMA_CC_CORECTL_UARTCLKEN);
124+ }
125+ /* Set the override bit so we don't divide it */
126+ bcma_cc_write32(cc, BCMA_CC_CORECTL,
127+ bcma_cc_read32(cc, BCMA_CC_CORECTL)
128+ | BCMA_CC_CORECTL_UARTCLK0);
129+ if (ccrev >= 21) {
130+ /* Re-enable the UART clock. */
131+ bcma_cc_write32(cc, BCMA_CC_CORECTL,
132+ bcma_cc_read32(cc, BCMA_CC_CORECTL)
133+ | BCMA_CC_CORECTL_UARTCLKEN);
134+ }
135+ } else {
136+ pr_err("serial not supported on this device ccrev: 0x%x\n",
137+ ccrev);
138+ return;
139+ }
140+
141+ irq = bcma_core_mips_irq(cc->core);
142+
143+ /* Determine the registers of the UARTs */
144+ cc->nr_serial_ports = (cc->capabilities & BCMA_CC_CAP_NRUART);
145+ for (i = 0; i < cc->nr_serial_ports; i++) {
146+ ports[i].regs = cc->core->io_addr + BCMA_CC_UART0_DATA +
147+ (i * 256);
148+ ports[i].irq = irq;
149+ ports[i].baud_base = baud_base;
150+ ports[i].reg_shift = 0;
151+ }
152+}
153+#endif /* CONFIG_BCMA_DRIVER_MIPS */
154--- a/drivers/bcma/driver_chipcommon_pmu.c
155+++ b/drivers/bcma/driver_chipcommon_pmu.c
156@@ -11,20 +11,47 @@
157 #include "bcma_private.h"
158 #include <linux/bcma/bcma.h>
159 
160-static void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc,
161- u32 offset, u32 mask, u32 set)
162+static u32 bcma_chipco_pll_read(struct bcma_drv_cc *cc, u32 offset)
163 {
164- u32 value;
165+ bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
166+ bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
167+ return bcma_cc_read32(cc, BCMA_CC_PLLCTL_DATA);
168+}
169 
170- bcma_cc_read32(cc, BCMA_CC_CHIPCTL_ADDR);
171+void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset, u32 value)
172+{
173+ bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
174+ bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
175+ bcma_cc_write32(cc, BCMA_CC_PLLCTL_DATA, value);
176+}
177+EXPORT_SYMBOL_GPL(bcma_chipco_pll_write);
178+
179+void bcma_chipco_pll_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask,
180+ u32 set)
181+{
182+ bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
183+ bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
184+ bcma_cc_maskset32(cc, BCMA_CC_PLLCTL_DATA, mask, set);
185+}
186+EXPORT_SYMBOL_GPL(bcma_chipco_pll_maskset);
187+
188+void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc,
189+ u32 offset, u32 mask, u32 set)
190+{
191     bcma_cc_write32(cc, BCMA_CC_CHIPCTL_ADDR, offset);
192     bcma_cc_read32(cc, BCMA_CC_CHIPCTL_ADDR);
193- value = bcma_cc_read32(cc, BCMA_CC_CHIPCTL_DATA);
194- value &= mask;
195- value |= set;
196- bcma_cc_write32(cc, BCMA_CC_CHIPCTL_DATA, value);
197- bcma_cc_read32(cc, BCMA_CC_CHIPCTL_DATA);
198+ bcma_cc_maskset32(cc, BCMA_CC_CHIPCTL_DATA, mask, set);
199 }
200+EXPORT_SYMBOL_GPL(bcma_chipco_chipctl_maskset);
201+
202+void bcma_chipco_regctl_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask,
203+ u32 set)
204+{
205+ bcma_cc_write32(cc, BCMA_CC_REGCTL_ADDR, offset);
206+ bcma_cc_read32(cc, BCMA_CC_REGCTL_ADDR);
207+ bcma_cc_maskset32(cc, BCMA_CC_REGCTL_DATA, mask, set);
208+}
209+EXPORT_SYMBOL_GPL(bcma_chipco_regctl_maskset);
210 
211 static void bcma_pmu_pll_init(struct bcma_drv_cc *cc)
212 {
213@@ -83,6 +110,24 @@ void bcma_pmu_swreg_init(struct bcma_drv
214     }
215 }
216 
217+/* Disable to allow reading SPROM. Don't know the adventages of enabling it. */
218+void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable)
219+{
220+ struct bcma_bus *bus = cc->core->bus;
221+ u32 val;
222+
223+ val = bcma_cc_read32(cc, BCMA_CC_CHIPCTL);
224+ if (enable) {
225+ val |= BCMA_CHIPCTL_4331_EXTPA_EN;
226+ if (bus->chipinfo.pkg == 9 || bus->chipinfo.pkg == 11)
227+ val |= BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5;
228+ } else {
229+ val &= ~BCMA_CHIPCTL_4331_EXTPA_EN;
230+ val &= ~BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5;
231+ }
232+ bcma_cc_write32(cc, BCMA_CC_CHIPCTL, val);
233+}
234+
235 void bcma_pmu_workarounds(struct bcma_drv_cc *cc)
236 {
237     struct bcma_bus *bus = cc->core->bus;
238@@ -92,7 +137,7 @@ void bcma_pmu_workarounds(struct bcma_dr
239         bcma_chipco_chipctl_maskset(cc, 0, ~0, 0x7);
240         break;
241     case 0x4331:
242- pr_err("Enabling Ext PA lines not implemented\n");
243+ /* BCM4331 workaround is SPROM-related, we put it in sprom.c */
244         break;
245     case 43224:
246         if (bus->chipinfo.rev == 0) {
247@@ -136,3 +181,129 @@ void bcma_pmu_init(struct bcma_drv_cc *c
248     bcma_pmu_swreg_init(cc);
249     bcma_pmu_workarounds(cc);
250 }
251+
252+u32 bcma_pmu_alp_clock(struct bcma_drv_cc *cc)
253+{
254+ struct bcma_bus *bus = cc->core->bus;
255+
256+ switch (bus->chipinfo.id) {
257+ case 0x4716:
258+ case 0x4748:
259+ case 47162:
260+ case 0x4313:
261+ case 0x5357:
262+ case 0x4749:
263+ case 53572:
264+ /* always 20Mhz */
265+ return 20000 * 1000;
266+ case 0x5356:
267+ case 0x5300:
268+ /* always 25Mhz */
269+ return 25000 * 1000;
270+ default:
271+ pr_warn("No ALP clock specified for %04X device, "
272+ "pmu rev. %d, using default %d Hz\n",
273+ bus->chipinfo.id, cc->pmu.rev, BCMA_CC_PMU_ALP_CLOCK);
274+ }
275+ return BCMA_CC_PMU_ALP_CLOCK;
276+}
277+
278+/* Find the output of the "m" pll divider given pll controls that start with
279+ * pllreg "pll0" i.e. 12 for main 6 for phy, 0 for misc.
280+ */
281+static u32 bcma_pmu_clock(struct bcma_drv_cc *cc, u32 pll0, u32 m)
282+{
283+ u32 tmp, div, ndiv, p1, p2, fc;
284+ struct bcma_bus *bus = cc->core->bus;
285+
286+ BUG_ON((pll0 & 3) || (pll0 > BCMA_CC_PMU4716_MAINPLL_PLL0));
287+
288+ BUG_ON(!m || m > 4);
289+
290+ if (bus->chipinfo.id == 0x5357 || bus->chipinfo.id == 0x4749) {
291+ /* Detect failure in clock setting */
292+ tmp = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
293+ if (tmp & 0x40000)
294+ return 133 * 1000000;
295+ }
296+
297+ tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_P1P2_OFF);
298+ p1 = (tmp & BCMA_CC_PPL_P1_MASK) >> BCMA_CC_PPL_P1_SHIFT;
299+ p2 = (tmp & BCMA_CC_PPL_P2_MASK) >> BCMA_CC_PPL_P2_SHIFT;
300+
301+ tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_M14_OFF);
302+ div = (tmp >> ((m - 1) * BCMA_CC_PPL_MDIV_WIDTH)) &
303+ BCMA_CC_PPL_MDIV_MASK;
304+
305+ tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_NM5_OFF);
306+ ndiv = (tmp & BCMA_CC_PPL_NDIV_MASK) >> BCMA_CC_PPL_NDIV_SHIFT;
307+
308+ /* Do calculation in Mhz */
309+ fc = bcma_pmu_alp_clock(cc) / 1000000;
310+ fc = (p1 * ndiv * fc) / p2;
311+
312+ /* Return clock in Hertz */
313+ return (fc / div) * 1000000;
314+}
315+
316+/* query bus clock frequency for PMU-enabled chipcommon */
317+u32 bcma_pmu_get_clockcontrol(struct bcma_drv_cc *cc)
318+{
319+ struct bcma_bus *bus = cc->core->bus;
320+
321+ switch (bus->chipinfo.id) {
322+ case 0x4716:
323+ case 0x4748:
324+ case 47162:
325+ return bcma_pmu_clock(cc, BCMA_CC_PMU4716_MAINPLL_PLL0,
326+ BCMA_CC_PMU5_MAINPLL_SSB);
327+ case 0x5356:
328+ return bcma_pmu_clock(cc, BCMA_CC_PMU5356_MAINPLL_PLL0,
329+ BCMA_CC_PMU5_MAINPLL_SSB);
330+ case 0x5357:
331+ case 0x4749:
332+ return bcma_pmu_clock(cc, BCMA_CC_PMU5357_MAINPLL_PLL0,
333+ BCMA_CC_PMU5_MAINPLL_SSB);
334+ case 0x5300:
335+ return bcma_pmu_clock(cc, BCMA_CC_PMU4706_MAINPLL_PLL0,
336+ BCMA_CC_PMU5_MAINPLL_SSB);
337+ case 53572:
338+ return 75000000;
339+ default:
340+ pr_warn("No backplane clock specified for %04X device, "
341+ "pmu rev. %d, using default %d Hz\n",
342+ bus->chipinfo.id, cc->pmu.rev, BCMA_CC_PMU_HT_CLOCK);
343+ }
344+ return BCMA_CC_PMU_HT_CLOCK;
345+}
346+
347+/* query cpu clock frequency for PMU-enabled chipcommon */
348+u32 bcma_pmu_get_clockcpu(struct bcma_drv_cc *cc)
349+{
350+ struct bcma_bus *bus = cc->core->bus;
351+
352+ if (bus->chipinfo.id == 53572)
353+ return 300000000;
354+
355+ if (cc->pmu.rev >= 5) {
356+ u32 pll;
357+ switch (bus->chipinfo.id) {
358+ case 0x5356:
359+ pll = BCMA_CC_PMU5356_MAINPLL_PLL0;
360+ break;
361+ case 0x5357:
362+ case 0x4749:
363+ pll = BCMA_CC_PMU5357_MAINPLL_PLL0;
364+ break;
365+ default:
366+ pll = BCMA_CC_PMU4716_MAINPLL_PLL0;
367+ break;
368+ }
369+
370+ /* TODO: if (bus->chipinfo.id == 0x5300)
371+ return si_4706_pmu_clock(sih, osh, cc, PMU4706_MAINPLL_PLL0, PMU5_MAINPLL_CPU); */
372+ return bcma_pmu_clock(cc, pll, BCMA_CC_PMU5_MAINPLL_CPU);
373+ }
374+
375+ return bcma_pmu_get_clockcontrol(cc);
376+}
377--- /dev/null
378+++ b/drivers/bcma/driver_mips.c
379@@ -0,0 +1,256 @@
380+/*
381+ * Broadcom specific AMBA
382+ * Broadcom MIPS32 74K core driver
383+ *
384+ * Copyright 2009, Broadcom Corporation
385+ * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
386+ * Copyright 2010, Bernhard Loos <bernhardloos@googlemail.com>
387+ * Copyright 2011, Hauke Mehrtens <hauke@hauke-m.de>
388+ *
389+ * Licensed under the GNU/GPL. See COPYING for details.
390+ */
391+
392+#include "bcma_private.h"
393+
394+#include <linux/bcma/bcma.h>
395+
396+#include <linux/serial.h>
397+#include <linux/serial_core.h>
398+#include <linux/serial_reg.h>
399+#include <linux/time.h>
400+
401+/* The 47162a0 hangs when reading MIPS DMP registers registers */
402+static inline bool bcma_core_mips_bcm47162a0_quirk(struct bcma_device *dev)
403+{
404+ return dev->bus->chipinfo.id == 47162 && dev->bus->chipinfo.rev == 0 &&
405+ dev->id.id == BCMA_CORE_MIPS_74K;
406+}
407+
408+/* The 5357b0 hangs when reading USB20H DMP registers */
409+static inline bool bcma_core_mips_bcm5357b0_quirk(struct bcma_device *dev)
410+{
411+ return (dev->bus->chipinfo.id == 0x5357 ||
412+ dev->bus->chipinfo.id == 0x4749) &&
413+ dev->bus->chipinfo.pkg == 11 &&
414+ dev->id.id == BCMA_CORE_USB20_HOST;
415+}
416+
417+static inline u32 mips_read32(struct bcma_drv_mips *mcore,
418+ u16 offset)
419+{
420+ return bcma_read32(mcore->core, offset);
421+}
422+
423+static inline void mips_write32(struct bcma_drv_mips *mcore,
424+ u16 offset,
425+ u32 value)
426+{
427+ bcma_write32(mcore->core, offset, value);
428+}
429+
430+static const u32 ipsflag_irq_mask[] = {
431+ 0,
432+ BCMA_MIPS_IPSFLAG_IRQ1,
433+ BCMA_MIPS_IPSFLAG_IRQ2,
434+ BCMA_MIPS_IPSFLAG_IRQ3,
435+ BCMA_MIPS_IPSFLAG_IRQ4,
436+};
437+
438+static const u32 ipsflag_irq_shift[] = {
439+ 0,
440+ BCMA_MIPS_IPSFLAG_IRQ1_SHIFT,
441+ BCMA_MIPS_IPSFLAG_IRQ2_SHIFT,
442+ BCMA_MIPS_IPSFLAG_IRQ3_SHIFT,
443+ BCMA_MIPS_IPSFLAG_IRQ4_SHIFT,
444+};
445+
446+static u32 bcma_core_mips_irqflag(struct bcma_device *dev)
447+{
448+ u32 flag;
449+
450+ if (bcma_core_mips_bcm47162a0_quirk(dev))
451+ return dev->core_index;
452+ if (bcma_core_mips_bcm5357b0_quirk(dev))
453+ return dev->core_index;
454+ flag = bcma_aread32(dev, BCMA_MIPS_OOBSELOUTA30);
455+
456+ return flag & 0x1F;
457+}
458+
459+/* Get the MIPS IRQ assignment for a specified device.
460+ * If unassigned, 0 is returned.
461+ */
462+unsigned int bcma_core_mips_irq(struct bcma_device *dev)
463+{
464+ struct bcma_device *mdev = dev->bus->drv_mips.core;
465+ u32 irqflag;
466+ unsigned int irq;
467+
468+ irqflag = bcma_core_mips_irqflag(dev);
469+
470+ for (irq = 1; irq <= 4; irq++)
471+ if (bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq)) &
472+ (1 << irqflag))
473+ return irq;
474+
475+ return 0;
476+}
477+EXPORT_SYMBOL(bcma_core_mips_irq);
478+
479+static void bcma_core_mips_set_irq(struct bcma_device *dev, unsigned int irq)
480+{
481+ unsigned int oldirq = bcma_core_mips_irq(dev);
482+ struct bcma_bus *bus = dev->bus;
483+ struct bcma_device *mdev = bus->drv_mips.core;
484+ u32 irqflag;
485+
486+ irqflag = bcma_core_mips_irqflag(dev);
487+ BUG_ON(oldirq == 6);
488+
489+ dev->irq = irq + 2;
490+
491+ /* clear the old irq */
492+ if (oldirq == 0)
493+ bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0),
494+ bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) &
495+ ~(1 << irqflag));
496+ else
497+ bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq), 0);
498+
499+ /* assign the new one */
500+ if (irq == 0) {
501+ bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0),
502+ bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) |
503+ (1 << irqflag));
504+ } else {
505+ u32 oldirqflag = bcma_read32(mdev,
506+ BCMA_MIPS_MIPS74K_INTMASK(irq));
507+ if (oldirqflag) {
508+ struct bcma_device *core;
509+
510+ /* backplane irq line is in use, find out who uses
511+ * it and set user to irq 0
512+ */
513+ list_for_each_entry_reverse(core, &bus->cores, list) {
514+ if ((1 << bcma_core_mips_irqflag(core)) ==
515+ oldirqflag) {
516+ bcma_core_mips_set_irq(core, 0);
517+ break;
518+ }
519+ }
520+ }
521+ bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq),
522+ 1 << irqflag);
523+ }
524+
525+ pr_info("set_irq: core 0x%04x, irq %d => %d\n",
526+ dev->id.id, oldirq + 2, irq + 2);
527+}
528+
529+static void bcma_core_mips_print_irq(struct bcma_device *dev, unsigned int irq)
530+{
531+ int i;
532+ static const char *irq_name[] = {"2(S)", "3", "4", "5", "6", "D", "I"};
533+ printk(KERN_INFO KBUILD_MODNAME ": core 0x%04x, irq :", dev->id.id);
534+ for (i = 0; i <= 6; i++)
535+ printk(" %s%s", irq_name[i], i == irq ? "*" : " ");
536+ printk("\n");
537+}
538+
539+static void bcma_core_mips_dump_irq(struct bcma_bus *bus)
540+{
541+ struct bcma_device *core;
542+
543+ list_for_each_entry_reverse(core, &bus->cores, list) {
544+ bcma_core_mips_print_irq(core, bcma_core_mips_irq(core));
545+ }
546+}
547+
548+u32 bcma_cpu_clock(struct bcma_drv_mips *mcore)
549+{
550+ struct bcma_bus *bus = mcore->core->bus;
551+
552+ if (bus->drv_cc.capabilities & BCMA_CC_CAP_PMU)
553+ return bcma_pmu_get_clockcpu(&bus->drv_cc);
554+
555+ pr_err("No PMU available, need this to get the cpu clock\n");
556+ return 0;
557+}
558+EXPORT_SYMBOL(bcma_cpu_clock);
559+
560+static void bcma_core_mips_flash_detect(struct bcma_drv_mips *mcore)
561+{
562+ struct bcma_bus *bus = mcore->core->bus;
563+
564+ switch (bus->drv_cc.capabilities & BCMA_CC_CAP_FLASHT) {
565+ case BCMA_CC_FLASHT_STSER:
566+ case BCMA_CC_FLASHT_ATSER:
567+ pr_err("Serial flash not supported.\n");
568+ break;
569+ case BCMA_CC_FLASHT_PARA:
570+ pr_info("found parallel flash.\n");
571+ bus->drv_cc.pflash.window = 0x1c000000;
572+ bus->drv_cc.pflash.window_size = 0x02000000;
573+
574+ if ((bcma_read32(bus->drv_cc.core, BCMA_CC_FLASH_CFG) &
575+ BCMA_CC_FLASH_CFG_DS) == 0)
576+ bus->drv_cc.pflash.buswidth = 1;
577+ else
578+ bus->drv_cc.pflash.buswidth = 2;
579+ break;
580+ default:
581+ pr_err("flash not supported.\n");
582+ }
583+}
584+
585+void bcma_core_mips_init(struct bcma_drv_mips *mcore)
586+{
587+ struct bcma_bus *bus;
588+ struct bcma_device *core;
589+ bus = mcore->core->bus;
590+
591+ pr_info("Initializing MIPS core...\n");
592+
593+ if (!mcore->setup_done)
594+ mcore->assigned_irqs = 1;
595+
596+ /* Assign IRQs to all cores on the bus */
597+ list_for_each_entry_reverse(core, &bus->cores, list) {
598+ int mips_irq;
599+ if (core->irq)
600+ continue;
601+
602+ mips_irq = bcma_core_mips_irq(core);
603+ if (mips_irq > 4)
604+ core->irq = 0;
605+ else
606+ core->irq = mips_irq + 2;
607+ if (core->irq > 5)
608+ continue;
609+ switch (core->id.id) {
610+ case BCMA_CORE_PCI:
611+ case BCMA_CORE_PCIE:
612+ case BCMA_CORE_ETHERNET:
613+ case BCMA_CORE_ETHERNET_GBIT:
614+ case BCMA_CORE_MAC_GBIT:
615+ case BCMA_CORE_80211:
616+ case BCMA_CORE_USB20_HOST:
617+ /* These devices get their own IRQ line if available,
618+ * the rest goes on IRQ0
619+ */
620+ if (mcore->assigned_irqs <= 4)
621+ bcma_core_mips_set_irq(core,
622+ mcore->assigned_irqs++);
623+ break;
624+ }
625+ }
626+ pr_info("IRQ reconfiguration done\n");
627+ bcma_core_mips_dump_irq(bus);
628+
629+ if (mcore->setup_done)
630+ return;
631+
632+ bcma_chipco_serial_init(&bus->drv_cc);
633+ bcma_core_mips_flash_detect(mcore);
634+ mcore->setup_done = true;
635+}
636--- a/drivers/bcma/driver_pci.c
637+++ b/drivers/bcma/driver_pci.c
638@@ -173,7 +173,7 @@ static bool bcma_core_pci_is_in_hostmode
639         return false;
640 
641 #ifdef CONFIG_SSB_DRIVER_PCICORE
642- if (bus->sprom.boardflags_lo & SSB_PCICORE_BFL_NOPCI)
643+ if (bus->sprom.boardflags_lo & SSB_BFL_NOPCI)
644         return false;
645 #endif /* CONFIG_SSB_DRIVER_PCICORE */
646 
647@@ -189,6 +189,9 @@ static bool bcma_core_pci_is_in_hostmode
648 
649 void bcma_core_pci_init(struct bcma_drv_pci *pc)
650 {
651+ if (pc->setup_done)
652+ return;
653+
654     if (bcma_core_pci_is_in_hostmode(pc)) {
655 #ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
656         bcma_core_pci_hostmode_init(pc);
657@@ -198,6 +201,8 @@ void bcma_core_pci_init(struct bcma_drv_
658     } else {
659         bcma_core_pci_clientmode_init(pc);
660     }
661+
662+ pc->setup_done = true;
663 }
664 
665 int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core,
666@@ -205,7 +210,14 @@ int bcma_core_pci_irq_ctl(struct bcma_dr
667 {
668     struct pci_dev *pdev = pc->core->bus->host_pci;
669     u32 coremask, tmp;
670- int err;
671+ int err = 0;
672+
673+ if (core->bus->hosttype != BCMA_HOSTTYPE_PCI) {
674+ /* This bcma device is not on a PCI host-bus. So the IRQs are
675+ * not routed through the PCI core.
676+ * So we must not enable routing through the PCI core. */
677+ goto out;
678+ }
679 
680     err = pci_read_config_dword(pdev, BCMA_PCI_IRQMASK, &tmp);
681     if (err)
682--- a/drivers/bcma/host_pci.c
683+++ b/drivers/bcma/host_pci.c
684@@ -9,6 +9,7 @@
685 #include <linux/slab.h>
686 #include <linux/bcma/bcma.h>
687 #include <linux/pci.h>
688+#include <linux/module.h>
689 
690 static void bcma_host_pci_switch_core(struct bcma_device *core)
691 {
692@@ -20,48 +21,58 @@ static void bcma_host_pci_switch_core(st
693     pr_debug("Switched to core: 0x%X\n", core->id.id);
694 }
695 
696-static u8 bcma_host_pci_read8(struct bcma_device *core, u16 offset)
697-{
698+/* Provides access to the requested core. Returns base offset that has to be
699+ * used. It makes use of fixed windows when possible. */
700+static u16 bcma_host_pci_provide_access_to_core(struct bcma_device *core)
701+{
702+ switch (core->id.id) {
703+ case BCMA_CORE_CHIPCOMMON:
704+ return 3 * BCMA_CORE_SIZE;
705+ case BCMA_CORE_PCIE:
706+ return 2 * BCMA_CORE_SIZE;
707+ }
708+
709     if (core->bus->mapped_core != core)
710         bcma_host_pci_switch_core(core);
711+ return 0;
712+}
713+
714+static u8 bcma_host_pci_read8(struct bcma_device *core, u16 offset)
715+{
716+ offset += bcma_host_pci_provide_access_to_core(core);
717     return ioread8(core->bus->mmio + offset);
718 }
719 
720 static u16 bcma_host_pci_read16(struct bcma_device *core, u16 offset)
721 {
722- if (core->bus->mapped_core != core)
723- bcma_host_pci_switch_core(core);
724+ offset += bcma_host_pci_provide_access_to_core(core);
725     return ioread16(core->bus->mmio + offset);
726 }
727 
728 static u32 bcma_host_pci_read32(struct bcma_device *core, u16 offset)
729 {
730- if (core->bus->mapped_core != core)
731- bcma_host_pci_switch_core(core);
732+ offset += bcma_host_pci_provide_access_to_core(core);
733     return ioread32(core->bus->mmio + offset);
734 }
735 
736 static void bcma_host_pci_write8(struct bcma_device *core, u16 offset,
737                  u8 value)
738 {
739- if (core->bus->mapped_core != core)
740- bcma_host_pci_switch_core(core);
741+ offset += bcma_host_pci_provide_access_to_core(core);
742     iowrite8(value, core->bus->mmio + offset);
743 }
744 
745 static void bcma_host_pci_write16(struct bcma_device *core, u16 offset,
746                  u16 value)
747 {
748- if (core->bus->mapped_core != core)
749- bcma_host_pci_switch_core(core);
750+ offset += bcma_host_pci_provide_access_to_core(core);
751     iowrite16(value, core->bus->mmio + offset);
752 }
753 
754 static void bcma_host_pci_write32(struct bcma_device *core, u16 offset,
755                  u32 value)
756 {
757- if (core->bus->mapped_core != core)
758- bcma_host_pci_switch_core(core);
759+ offset += bcma_host_pci_provide_access_to_core(core);
760     iowrite32(value, core->bus->mmio + offset);
761 }
762 
763@@ -223,6 +234,41 @@ static void bcma_host_pci_remove(struct
764     pci_set_drvdata(dev, NULL);
765 }
766 
767+#ifdef CONFIG_PM
768+static int bcma_host_pci_suspend(struct pci_dev *dev, pm_message_t state)
769+{
770+ /* Host specific */
771+ pci_save_state(dev);
772+ pci_disable_device(dev);
773+ pci_set_power_state(dev, pci_choose_state(dev, state));
774+
775+ return 0;
776+}
777+
778+static int bcma_host_pci_resume(struct pci_dev *dev)
779+{
780+ struct bcma_bus *bus = pci_get_drvdata(dev);
781+ int err;
782+
783+ /* Host specific */
784+ pci_set_power_state(dev, 0);
785+ err = pci_enable_device(dev);
786+ if (err)
787+ return err;
788+ pci_restore_state(dev);
789+
790+ /* Bus specific */
791+ err = bcma_bus_resume(bus);
792+ if (err)
793+ return err;
794+
795+ return 0;
796+}
797+#else /* CONFIG_PM */
798+# define bcma_host_pci_suspend NULL
799+# define bcma_host_pci_resume NULL
800+#endif /* CONFIG_PM */
801+
802 static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = {
803     { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) },
804     { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) },
805@@ -238,6 +284,8 @@ static struct pci_driver bcma_pci_bridge
806     .id_table = bcma_pci_bridge_tbl,
807     .probe = bcma_host_pci_probe,
808     .remove = bcma_host_pci_remove,
809+ .suspend = bcma_host_pci_suspend,
810+ .resume = bcma_host_pci_resume,
811 };
812 
813 int __init bcma_host_pci_init(void)
814--- /dev/null
815+++ b/drivers/bcma/host_soc.c
816@@ -0,0 +1,183 @@
817+/*
818+ * Broadcom specific AMBA
819+ * System on Chip (SoC) Host
820+ *
821+ * Licensed under the GNU/GPL. See COPYING for details.
822+ */
823+
824+#include "bcma_private.h"
825+#include "scan.h"
826+#include <linux/bcma/bcma.h>
827+#include <linux/bcma/bcma_soc.h>
828+
829+static u8 bcma_host_soc_read8(struct bcma_device *core, u16 offset)
830+{
831+ return readb(core->io_addr + offset);
832+}
833+
834+static u16 bcma_host_soc_read16(struct bcma_device *core, u16 offset)
835+{
836+ return readw(core->io_addr + offset);
837+}
838+
839+static u32 bcma_host_soc_read32(struct bcma_device *core, u16 offset)
840+{
841+ return readl(core->io_addr + offset);
842+}
843+
844+static void bcma_host_soc_write8(struct bcma_device *core, u16 offset,
845+ u8 value)
846+{
847+ writeb(value, core->io_addr + offset);
848+}
849+
850+static void bcma_host_soc_write16(struct bcma_device *core, u16 offset,
851+ u16 value)
852+{
853+ writew(value, core->io_addr + offset);
854+}
855+
856+static void bcma_host_soc_write32(struct bcma_device *core, u16 offset,
857+ u32 value)
858+{
859+ writel(value, core->io_addr + offset);
860+}
861+
862+#ifdef CONFIG_BCMA_BLOCKIO
863+static void bcma_host_soc_block_read(struct bcma_device *core, void *buffer,
864+ size_t count, u16 offset, u8 reg_width)
865+{
866+ void __iomem *addr = core->io_addr + offset;
867+
868+ switch (reg_width) {
869+ case sizeof(u8): {
870+ u8 *buf = buffer;
871+
872+ while (count) {
873+ *buf = __raw_readb(addr);
874+ buf++;
875+ count--;
876+ }
877+ break;
878+ }
879+ case sizeof(u16): {
880+ __le16 *buf = buffer;
881+
882+ WARN_ON(count & 1);
883+ while (count) {
884+ *buf = (__force __le16)__raw_readw(addr);
885+ buf++;
886+ count -= 2;
887+ }
888+ break;
889+ }
890+ case sizeof(u32): {
891+ __le32 *buf = buffer;
892+
893+ WARN_ON(count & 3);
894+ while (count) {
895+ *buf = (__force __le32)__raw_readl(addr);
896+ buf++;
897+ count -= 4;
898+ }
899+ break;
900+ }
901+ default:
902+ WARN_ON(1);
903+ }
904+}
905+
906+static void bcma_host_soc_block_write(struct bcma_device *core,
907+ const void *buffer,
908+ size_t count, u16 offset, u8 reg_width)
909+{
910+ void __iomem *addr = core->io_addr + offset;
911+
912+ switch (reg_width) {
913+ case sizeof(u8): {
914+ const u8 *buf = buffer;
915+
916+ while (count) {
917+ __raw_writeb(*buf, addr);
918+ buf++;
919+ count--;
920+ }
921+ break;
922+ }
923+ case sizeof(u16): {
924+ const __le16 *buf = buffer;
925+
926+ WARN_ON(count & 1);
927+ while (count) {
928+ __raw_writew((__force u16)(*buf), addr);
929+ buf++;
930+ count -= 2;
931+ }
932+ break;
933+ }
934+ case sizeof(u32): {
935+ const __le32 *buf = buffer;
936+
937+ WARN_ON(count & 3);
938+ while (count) {
939+ __raw_writel((__force u32)(*buf), addr);
940+ buf++;
941+ count -= 4;
942+ }
943+ break;
944+ }
945+ default:
946+ WARN_ON(1);
947+ }
948+}
949+#endif /* CONFIG_BCMA_BLOCKIO */
950+
951+static u32 bcma_host_soc_aread32(struct bcma_device *core, u16 offset)
952+{
953+ return readl(core->io_wrap + offset);
954+}
955+
956+static void bcma_host_soc_awrite32(struct bcma_device *core, u16 offset,
957+ u32 value)
958+{
959+ writel(value, core->io_wrap + offset);
960+}
961+
962+const struct bcma_host_ops bcma_host_soc_ops = {
963+ .read8 = bcma_host_soc_read8,
964+ .read16 = bcma_host_soc_read16,
965+ .read32 = bcma_host_soc_read32,
966+ .write8 = bcma_host_soc_write8,
967+ .write16 = bcma_host_soc_write16,
968+ .write32 = bcma_host_soc_write32,
969+#ifdef CONFIG_BCMA_BLOCKIO
970+ .block_read = bcma_host_soc_block_read,
971+ .block_write = bcma_host_soc_block_write,
972+#endif
973+ .aread32 = bcma_host_soc_aread32,
974+ .awrite32 = bcma_host_soc_awrite32,
975+};
976+
977+int __init bcma_host_soc_register(struct bcma_soc *soc)
978+{
979+ struct bcma_bus *bus = &soc->bus;
980+ int err;
981+
982+ /* iomap only first core. We have to read some register on this core
983+ * to scan the bus.
984+ */
985+ bus->mmio = ioremap_nocache(BCMA_ADDR_BASE, BCMA_CORE_SIZE * 1);
986+ if (!bus->mmio)
987+ return -ENOMEM;
988+
989+ /* Host specific */
990+ bus->hosttype = BCMA_HOSTTYPE_SOC;
991+ bus->ops = &bcma_host_soc_ops;
992+
993+ /* Register */
994+ err = bcma_bus_early_register(bus, &soc->core_cc, &soc->core_mips);
995+ if (err)
996+ iounmap(bus->mmio);
997+
998+ return err;
999+}
1000--- a/drivers/bcma/main.c
1001+++ b/drivers/bcma/main.c
1002@@ -6,6 +6,7 @@
1003  */
1004 
1005 #include "bcma_private.h"
1006+#include <linux/module.h>
1007 #include <linux/bcma/bcma.h>
1008 #include <linux/slab.h>
1009 
1010@@ -68,6 +69,10 @@ static struct bcma_device *bcma_find_cor
1011 static void bcma_release_core_dev(struct device *dev)
1012 {
1013     struct bcma_device *core = container_of(dev, struct bcma_device, dev);
1014+ if (core->io_addr)
1015+ iounmap(core->io_addr);
1016+ if (core->io_wrap)
1017+ iounmap(core->io_wrap);
1018     kfree(core);
1019 }
1020 
1021@@ -82,6 +87,7 @@ static int bcma_register_cores(struct bc
1022         case BCMA_CORE_CHIPCOMMON:
1023         case BCMA_CORE_PCI:
1024         case BCMA_CORE_PCIE:
1025+ case BCMA_CORE_MIPS_74K:
1026             continue;
1027         }
1028 
1029@@ -95,7 +101,10 @@ static int bcma_register_cores(struct bc
1030             core->dma_dev = &bus->host_pci->dev;
1031             core->irq = bus->host_pci->irq;
1032             break;
1033- case BCMA_HOSTTYPE_NONE:
1034+ case BCMA_HOSTTYPE_SOC:
1035+ core->dev.dma_mask = &core->dev.coherent_dma_mask;
1036+ core->dma_dev = &core->dev;
1037+ break;
1038         case BCMA_HOSTTYPE_SDIO:
1039             break;
1040         }
1041@@ -142,6 +151,13 @@ int bcma_bus_register(struct bcma_bus *b
1042         bcma_core_chipcommon_init(&bus->drv_cc);
1043     }
1044 
1045+ /* Init MIPS core */
1046+ core = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
1047+ if (core) {
1048+ bus->drv_mips.core = core;
1049+ bcma_core_mips_init(&bus->drv_mips);
1050+ }
1051+
1052     /* Init PCIE core */
1053     core = bcma_find_core(bus, BCMA_CORE_PCIE);
1054     if (core) {
1055@@ -171,6 +187,75 @@ void bcma_bus_unregister(struct bcma_bus
1056     bcma_unregister_cores(bus);
1057 }
1058 
1059+int __init bcma_bus_early_register(struct bcma_bus *bus,
1060+ struct bcma_device *core_cc,
1061+ struct bcma_device *core_mips)
1062+{
1063+ int err;
1064+ struct bcma_device *core;
1065+ struct bcma_device_id match;
1066+
1067+ bcma_init_bus(bus);
1068+
1069+ match.manuf = BCMA_MANUF_BCM;
1070+ match.id = BCMA_CORE_CHIPCOMMON;
1071+ match.class = BCMA_CL_SIM;
1072+ match.rev = BCMA_ANY_REV;
1073+
1074+ /* Scan for chip common core */
1075+ err = bcma_bus_scan_early(bus, &match, core_cc);
1076+ if (err) {
1077+ pr_err("Failed to scan for common core: %d\n", err);
1078+ return -1;
1079+ }
1080+
1081+ match.manuf = BCMA_MANUF_MIPS;
1082+ match.id = BCMA_CORE_MIPS_74K;
1083+ match.class = BCMA_CL_SIM;
1084+ match.rev = BCMA_ANY_REV;
1085+
1086+ /* Scan for mips core */
1087+ err = bcma_bus_scan_early(bus, &match, core_mips);
1088+ if (err) {
1089+ pr_err("Failed to scan for mips core: %d\n", err);
1090+ return -1;
1091+ }
1092+
1093+ /* Init CC core */
1094+ core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON);
1095+ if (core) {
1096+ bus->drv_cc.core = core;
1097+ bcma_core_chipcommon_init(&bus->drv_cc);
1098+ }
1099+
1100+ /* Init MIPS core */
1101+ core = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
1102+ if (core) {
1103+ bus->drv_mips.core = core;
1104+ bcma_core_mips_init(&bus->drv_mips);
1105+ }
1106+
1107+ pr_info("Early bus registered\n");
1108+
1109+ return 0;
1110+}
1111+
1112+#ifdef CONFIG_PM
1113+int bcma_bus_resume(struct bcma_bus *bus)
1114+{
1115+ struct bcma_device *core;
1116+
1117+ /* Init CC core */
1118+ core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON);
1119+ if (core) {
1120+ bus->drv_cc.setup_done = false;
1121+ bcma_core_chipcommon_init(&bus->drv_cc);
1122+ }
1123+
1124+ return 0;
1125+}
1126+#endif
1127+
1128 int __bcma_driver_register(struct bcma_driver *drv, struct module *owner)
1129 {
1130     drv->drv.name = drv->name;
1131--- a/drivers/bcma/scan.c
1132+++ b/drivers/bcma/scan.c
1133@@ -200,18 +200,162 @@ static s32 bcma_erom_get_addr_desc(struc
1134     return addrl;
1135 }
1136 
1137-int bcma_bus_scan(struct bcma_bus *bus)
1138+static struct bcma_device *bcma_find_core_by_index(struct bcma_bus *bus,
1139+ u16 index)
1140 {
1141- u32 erombase;
1142- u32 __iomem *eromptr, *eromend;
1143+ struct bcma_device *core;
1144 
1145+ list_for_each_entry(core, &bus->cores, list) {
1146+ if (core->core_index == index)
1147+ return core;
1148+ }
1149+ return NULL;
1150+}
1151+
1152+static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
1153+ struct bcma_device_id *match, int core_num,
1154+ struct bcma_device *core)
1155+{
1156+ s32 tmp;
1157+ u8 i, j;
1158     s32 cia, cib;
1159     u8 ports[2], wrappers[2];
1160 
1161+ /* get CIs */
1162+ cia = bcma_erom_get_ci(bus, eromptr);
1163+ if (cia < 0) {
1164+ bcma_erom_push_ent(eromptr);
1165+ if (bcma_erom_is_end(bus, eromptr))
1166+ return -ESPIPE;
1167+ return -EILSEQ;
1168+ }
1169+ cib = bcma_erom_get_ci(bus, eromptr);
1170+ if (cib < 0)
1171+ return -EILSEQ;
1172+
1173+ /* parse CIs */
1174+ core->id.class = (cia & SCAN_CIA_CLASS) >> SCAN_CIA_CLASS_SHIFT;
1175+ core->id.id = (cia & SCAN_CIA_ID) >> SCAN_CIA_ID_SHIFT;
1176+ core->id.manuf = (cia & SCAN_CIA_MANUF) >> SCAN_CIA_MANUF_SHIFT;
1177+ ports[0] = (cib & SCAN_CIB_NMP) >> SCAN_CIB_NMP_SHIFT;
1178+ ports[1] = (cib & SCAN_CIB_NSP) >> SCAN_CIB_NSP_SHIFT;
1179+ wrappers[0] = (cib & SCAN_CIB_NMW) >> SCAN_CIB_NMW_SHIFT;
1180+ wrappers[1] = (cib & SCAN_CIB_NSW) >> SCAN_CIB_NSW_SHIFT;
1181+ core->id.rev = (cib & SCAN_CIB_REV) >> SCAN_CIB_REV_SHIFT;
1182+
1183+ if (((core->id.manuf == BCMA_MANUF_ARM) &&
1184+ (core->id.id == 0xFFF)) ||
1185+ (ports[1] == 0)) {
1186+ bcma_erom_skip_component(bus, eromptr);
1187+ return -ENXIO;
1188+ }
1189+
1190+ /* check if component is a core at all */
1191+ if (wrappers[0] + wrappers[1] == 0) {
1192+ /* we could save addrl of the router
1193+ if (cid == BCMA_CORE_OOB_ROUTER)
1194+ */
1195+ bcma_erom_skip_component(bus, eromptr);
1196+ return -ENXIO;
1197+ }
1198+
1199+ if (bcma_erom_is_bridge(bus, eromptr)) {
1200+ bcma_erom_skip_component(bus, eromptr);
1201+ return -ENXIO;
1202+ }
1203+
1204+ if (bcma_find_core_by_index(bus, core_num)) {
1205+ bcma_erom_skip_component(bus, eromptr);
1206+ return -ENODEV;
1207+ }
1208+
1209+ if (match && ((match->manuf != BCMA_ANY_MANUF &&
1210+ match->manuf != core->id.manuf) ||
1211+ (match->id != BCMA_ANY_ID && match->id != core->id.id) ||
1212+ (match->rev != BCMA_ANY_REV && match->rev != core->id.rev) ||
1213+ (match->class != BCMA_ANY_CLASS && match->class != core->id.class)
1214+ )) {
1215+ bcma_erom_skip_component(bus, eromptr);
1216+ return -ENODEV;
1217+ }
1218+
1219+ /* get & parse master ports */
1220+ for (i = 0; i < ports[0]; i++) {
1221+ s32 mst_port_d = bcma_erom_get_mst_port(bus, eromptr);
1222+ if (mst_port_d < 0)
1223+ return -EILSEQ;
1224+ }
1225+
1226+ /* get & parse slave ports */
1227+ for (i = 0; i < ports[1]; i++) {
1228+ for (j = 0; ; j++) {
1229+ tmp = bcma_erom_get_addr_desc(bus, eromptr,
1230+ SCAN_ADDR_TYPE_SLAVE, i);
1231+ if (tmp < 0) {
1232+ /* no more entries for port _i_ */
1233+ /* pr_debug("erom: slave port %d "
1234+ * "has %d descriptors\n", i, j); */
1235+ break;
1236+ } else {
1237+ if (i == 0 && j == 0)
1238+ core->addr = tmp;
1239+ }
1240+ }
1241+ }
1242+
1243+ /* get & parse master wrappers */
1244+ for (i = 0; i < wrappers[0]; i++) {
1245+ for (j = 0; ; j++) {
1246+ tmp = bcma_erom_get_addr_desc(bus, eromptr,
1247+ SCAN_ADDR_TYPE_MWRAP, i);
1248+ if (tmp < 0) {
1249+ /* no more entries for port _i_ */
1250+ /* pr_debug("erom: master wrapper %d "
1251+ * "has %d descriptors\n", i, j); */
1252+ break;
1253+ } else {
1254+ if (i == 0 && j == 0)
1255+ core->wrap = tmp;
1256+ }
1257+ }
1258+ }
1259+
1260+ /* get & parse slave wrappers */
1261+ for (i = 0; i < wrappers[1]; i++) {
1262+ u8 hack = (ports[1] == 1) ? 0 : 1;
1263+ for (j = 0; ; j++) {
1264+ tmp = bcma_erom_get_addr_desc(bus, eromptr,
1265+ SCAN_ADDR_TYPE_SWRAP, i + hack);
1266+ if (tmp < 0) {
1267+ /* no more entries for port _i_ */
1268+ /* pr_debug("erom: master wrapper %d "
1269+ * has %d descriptors\n", i, j); */
1270+ break;
1271+ } else {
1272+ if (wrappers[0] == 0 && !i && !j)
1273+ core->wrap = tmp;
1274+ }
1275+ }
1276+ }
1277+ if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
1278+ core->io_addr = ioremap_nocache(core->addr, BCMA_CORE_SIZE);
1279+ if (!core->io_addr)
1280+ return -ENOMEM;
1281+ core->io_wrap = ioremap_nocache(core->wrap, BCMA_CORE_SIZE);
1282+ if (!core->io_wrap) {
1283+ iounmap(core->io_addr);
1284+ return -ENOMEM;
1285+ }
1286+ }
1287+ return 0;
1288+}
1289+
1290+void bcma_init_bus(struct bcma_bus *bus)
1291+{
1292     s32 tmp;
1293- u8 i, j;
1294 
1295- int err;
1296+ if (bus->init_done)
1297+ return;
1298 
1299     INIT_LIST_HEAD(&bus->cores);
1300     bus->nr_cores = 0;
1301@@ -222,9 +366,27 @@ int bcma_bus_scan(struct bcma_bus *bus)
1302     bus->chipinfo.id = (tmp & BCMA_CC_ID_ID) >> BCMA_CC_ID_ID_SHIFT;
1303     bus->chipinfo.rev = (tmp & BCMA_CC_ID_REV) >> BCMA_CC_ID_REV_SHIFT;
1304     bus->chipinfo.pkg = (tmp & BCMA_CC_ID_PKG) >> BCMA_CC_ID_PKG_SHIFT;
1305+ bus->init_done = true;
1306+}
1307+
1308+int bcma_bus_scan(struct bcma_bus *bus)
1309+{
1310+ u32 erombase;
1311+ u32 __iomem *eromptr, *eromend;
1312+
1313+ int err, core_num = 0;
1314+
1315+ bcma_init_bus(bus);
1316 
1317     erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM);
1318- eromptr = bus->mmio;
1319+ if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
1320+ eromptr = ioremap_nocache(erombase, BCMA_CORE_SIZE);
1321+ if (!eromptr)
1322+ return -ENOMEM;
1323+ } else {
1324+ eromptr = bus->mmio;
1325+ }
1326+
1327     eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32);
1328 
1329     bcma_scan_switch_core(bus, erombase);
1330@@ -236,125 +398,89 @@ int bcma_bus_scan(struct bcma_bus *bus)
1331         INIT_LIST_HEAD(&core->list);
1332         core->bus = bus;
1333 
1334- /* get CIs */
1335- cia = bcma_erom_get_ci(bus, &eromptr);
1336- if (cia < 0) {
1337- bcma_erom_push_ent(&eromptr);
1338- if (bcma_erom_is_end(bus, &eromptr))
1339- break;
1340- err= -EILSEQ;
1341- goto out;
1342- }
1343- cib = bcma_erom_get_ci(bus, &eromptr);
1344- if (cib < 0) {
1345- err= -EILSEQ;
1346- goto out;
1347- }
1348-
1349- /* parse CIs */
1350- core->id.class = (cia & SCAN_CIA_CLASS) >> SCAN_CIA_CLASS_SHIFT;
1351- core->id.id = (cia & SCAN_CIA_ID) >> SCAN_CIA_ID_SHIFT;
1352- core->id.manuf = (cia & SCAN_CIA_MANUF) >> SCAN_CIA_MANUF_SHIFT;
1353- ports[0] = (cib & SCAN_CIB_NMP) >> SCAN_CIB_NMP_SHIFT;
1354- ports[1] = (cib & SCAN_CIB_NSP) >> SCAN_CIB_NSP_SHIFT;
1355- wrappers[0] = (cib & SCAN_CIB_NMW) >> SCAN_CIB_NMW_SHIFT;
1356- wrappers[1] = (cib & SCAN_CIB_NSW) >> SCAN_CIB_NSW_SHIFT;
1357- core->id.rev = (cib & SCAN_CIB_REV) >> SCAN_CIB_REV_SHIFT;
1358-
1359- if (((core->id.manuf == BCMA_MANUF_ARM) &&
1360- (core->id.id == 0xFFF)) ||
1361- (ports[1] == 0)) {
1362- bcma_erom_skip_component(bus, &eromptr);
1363+ err = bcma_get_next_core(bus, &eromptr, NULL, core_num, core);
1364+ if (err == -ENODEV) {
1365+ core_num++;
1366             continue;
1367- }
1368-
1369- /* check if component is a core at all */
1370- if (wrappers[0] + wrappers[1] == 0) {
1371- /* we could save addrl of the router
1372- if (cid == BCMA_CORE_OOB_ROUTER)
1373- */
1374- bcma_erom_skip_component(bus, &eromptr);
1375+ } else if (err == -ENXIO)
1376             continue;
1377- }
1378+ else if (err == -ESPIPE)
1379+ break;
1380+ else if (err < 0)
1381+ return err;
1382 
1383- if (bcma_erom_is_bridge(bus, &eromptr)) {
1384- bcma_erom_skip_component(bus, &eromptr);
1385- continue;
1386- }
1387+ core->core_index = core_num++;
1388+ bus->nr_cores++;
1389 
1390- /* get & parse master ports */
1391- for (i = 0; i < ports[0]; i++) {
1392- u32 mst_port_d = bcma_erom_get_mst_port(bus, &eromptr);
1393- if (mst_port_d < 0) {
1394- err= -EILSEQ;
1395- goto out;
1396- }
1397- }
1398+ pr_info("Core %d found: %s "
1399+ "(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
1400+ core->core_index, bcma_device_name(&core->id),
1401+ core->id.manuf, core->id.id, core->id.rev,
1402+ core->id.class);
1403 
1404- /* get & parse slave ports */
1405- for (i = 0; i < ports[1]; i++) {
1406- for (j = 0; ; j++) {
1407- tmp = bcma_erom_get_addr_desc(bus, &eromptr,
1408- SCAN_ADDR_TYPE_SLAVE, i);
1409- if (tmp < 0) {
1410- /* no more entries for port _i_ */
1411- /* pr_debug("erom: slave port %d "
1412- * "has %d descriptors\n", i, j); */
1413- break;
1414- } else {
1415- if (i == 0 && j == 0)
1416- core->addr = tmp;
1417- }
1418- }
1419- }
1420+ list_add(&core->list, &bus->cores);
1421+ }
1422 
1423- /* get & parse master wrappers */
1424- for (i = 0; i < wrappers[0]; i++) {
1425- for (j = 0; ; j++) {
1426- tmp = bcma_erom_get_addr_desc(bus, &eromptr,
1427- SCAN_ADDR_TYPE_MWRAP, i);
1428- if (tmp < 0) {
1429- /* no more entries for port _i_ */
1430- /* pr_debug("erom: master wrapper %d "
1431- * "has %d descriptors\n", i, j); */
1432- break;
1433- } else {
1434- if (i == 0 && j == 0)
1435- core->wrap = tmp;
1436- }
1437- }
1438- }
1439+ if (bus->hosttype == BCMA_HOSTTYPE_SOC)
1440+ iounmap(eromptr);
1441 
1442- /* get & parse slave wrappers */
1443- for (i = 0; i < wrappers[1]; i++) {
1444- u8 hack = (ports[1] == 1) ? 0 : 1;
1445- for (j = 0; ; j++) {
1446- tmp = bcma_erom_get_addr_desc(bus, &eromptr,
1447- SCAN_ADDR_TYPE_SWRAP, i + hack);
1448- if (tmp < 0) {
1449- /* no more entries for port _i_ */
1450- /* pr_debug("erom: master wrapper %d "
1451- * has %d descriptors\n", i, j); */
1452- break;
1453- } else {
1454- if (wrappers[0] == 0 && !i && !j)
1455- core->wrap = tmp;
1456- }
1457- }
1458- }
1459+ return 0;
1460+}
1461+
1462+int __init bcma_bus_scan_early(struct bcma_bus *bus,
1463+ struct bcma_device_id *match,
1464+ struct bcma_device *core)
1465+{
1466+ u32 erombase;
1467+ u32 __iomem *eromptr, *eromend;
1468 
1469+ int err = -ENODEV;
1470+ int core_num = 0;
1471+
1472+ erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM);
1473+ if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
1474+ eromptr = ioremap_nocache(erombase, BCMA_CORE_SIZE);
1475+ if (!eromptr)
1476+ return -ENOMEM;
1477+ } else {
1478+ eromptr = bus->mmio;
1479+ }
1480+
1481+ eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32);
1482+
1483+ bcma_scan_switch_core(bus, erombase);
1484+
1485+ while (eromptr < eromend) {
1486+ memset(core, 0, sizeof(*core));
1487+ INIT_LIST_HEAD(&core->list);
1488+ core->bus = bus;
1489+
1490+ err = bcma_get_next_core(bus, &eromptr, match, core_num, core);
1491+ if (err == -ENODEV) {
1492+ core_num++;
1493+ continue;
1494+ } else if (err == -ENXIO)
1495+ continue;
1496+ else if (err == -ESPIPE)
1497+ break;
1498+ else if (err < 0)
1499+ return err;
1500+
1501+ core->core_index = core_num++;
1502+ bus->nr_cores++;
1503         pr_info("Core %d found: %s "
1504             "(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
1505- bus->nr_cores, bcma_device_name(&core->id),
1506+ core->core_index, bcma_device_name(&core->id),
1507             core->id.manuf, core->id.id, core->id.rev,
1508             core->id.class);
1509 
1510- core->core_index = bus->nr_cores++;
1511         list_add(&core->list, &bus->cores);
1512- continue;
1513-out:
1514- return err;
1515+ err = 0;
1516+ break;
1517     }
1518 
1519- return 0;
1520+ if (bus->hosttype == BCMA_HOSTTYPE_SOC)
1521+ iounmap(eromptr);
1522+
1523+ return err;
1524 }
1525--- a/drivers/bcma/sprom.c
1526+++ b/drivers/bcma/sprom.c
1527@@ -129,10 +129,80 @@ static void bcma_sprom_extract_r8(struct
1528     u16 v;
1529     int i;
1530 
1531+ bus->sprom.revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] &
1532+ SSB_SPROM_REVISION_REV;
1533+
1534     for (i = 0; i < 3; i++) {
1535         v = sprom[SPOFF(SSB_SPROM8_IL0MAC) + i];
1536         *(((__be16 *)bus->sprom.il0mac) + i) = cpu_to_be16(v);
1537     }
1538+
1539+ bus->sprom.board_rev = sprom[SPOFF(SSB_SPROM8_BOARDREV)];
1540+
1541+ bus->sprom.txpid2g[0] = (sprom[SPOFF(SSB_SPROM4_TXPID2G01)] &
1542+ SSB_SPROM4_TXPID2G0) >> SSB_SPROM4_TXPID2G0_SHIFT;
1543+ bus->sprom.txpid2g[1] = (sprom[SPOFF(SSB_SPROM4_TXPID2G01)] &
1544+ SSB_SPROM4_TXPID2G1) >> SSB_SPROM4_TXPID2G1_SHIFT;
1545+ bus->sprom.txpid2g[2] = (sprom[SPOFF(SSB_SPROM4_TXPID2G23)] &
1546+ SSB_SPROM4_TXPID2G2) >> SSB_SPROM4_TXPID2G2_SHIFT;
1547+ bus->sprom.txpid2g[3] = (sprom[SPOFF(SSB_SPROM4_TXPID2G23)] &
1548+ SSB_SPROM4_TXPID2G3) >> SSB_SPROM4_TXPID2G3_SHIFT;
1549+
1550+ bus->sprom.txpid5gl[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL01)] &
1551+ SSB_SPROM4_TXPID5GL0) >> SSB_SPROM4_TXPID5GL0_SHIFT;
1552+ bus->sprom.txpid5gl[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL01)] &
1553+ SSB_SPROM4_TXPID5GL1) >> SSB_SPROM4_TXPID5GL1_SHIFT;
1554+ bus->sprom.txpid5gl[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL23)] &
1555+ SSB_SPROM4_TXPID5GL2) >> SSB_SPROM4_TXPID5GL2_SHIFT;
1556+ bus->sprom.txpid5gl[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL23)] &
1557+ SSB_SPROM4_TXPID5GL3) >> SSB_SPROM4_TXPID5GL3_SHIFT;
1558+
1559+ bus->sprom.txpid5g[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5G01)] &
1560+ SSB_SPROM4_TXPID5G0) >> SSB_SPROM4_TXPID5G0_SHIFT;
1561+ bus->sprom.txpid5g[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5G01)] &
1562+ SSB_SPROM4_TXPID5G1) >> SSB_SPROM4_TXPID5G1_SHIFT;
1563+ bus->sprom.txpid5g[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5G23)] &
1564+ SSB_SPROM4_TXPID5G2) >> SSB_SPROM4_TXPID5G2_SHIFT;
1565+ bus->sprom.txpid5g[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5G23)] &
1566+ SSB_SPROM4_TXPID5G3) >> SSB_SPROM4_TXPID5G3_SHIFT;
1567+
1568+ bus->sprom.txpid5gh[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH01)] &
1569+ SSB_SPROM4_TXPID5GH0) >> SSB_SPROM4_TXPID5GH0_SHIFT;
1570+ bus->sprom.txpid5gh[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH01)] &
1571+ SSB_SPROM4_TXPID5GH1) >> SSB_SPROM4_TXPID5GH1_SHIFT;
1572+ bus->sprom.txpid5gh[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH23)] &
1573+ SSB_SPROM4_TXPID5GH2) >> SSB_SPROM4_TXPID5GH2_SHIFT;
1574+ bus->sprom.txpid5gh[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH23)] &
1575+ SSB_SPROM4_TXPID5GH3) >> SSB_SPROM4_TXPID5GH3_SHIFT;
1576+
1577+ bus->sprom.boardflags_lo = sprom[SPOFF(SSB_SPROM8_BFLLO)];
1578+ bus->sprom.boardflags_hi = sprom[SPOFF(SSB_SPROM8_BFLHI)];
1579+ bus->sprom.boardflags2_lo = sprom[SPOFF(SSB_SPROM8_BFL2LO)];
1580+ bus->sprom.boardflags2_hi = sprom[SPOFF(SSB_SPROM8_BFL2HI)];
1581+
1582+ bus->sprom.country_code = sprom[SPOFF(SSB_SPROM8_CCODE)];
1583+
1584+ bus->sprom.fem.ghz2.tssipos = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
1585+ SSB_SROM8_FEM_TSSIPOS) >> SSB_SROM8_FEM_TSSIPOS_SHIFT;
1586+ bus->sprom.fem.ghz2.extpa_gain = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
1587+ SSB_SROM8_FEM_EXTPA_GAIN) >> SSB_SROM8_FEM_EXTPA_GAIN_SHIFT;
1588+ bus->sprom.fem.ghz2.pdet_range = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
1589+ SSB_SROM8_FEM_PDET_RANGE) >> SSB_SROM8_FEM_PDET_RANGE_SHIFT;
1590+ bus->sprom.fem.ghz2.tr_iso = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
1591+ SSB_SROM8_FEM_TR_ISO) >> SSB_SROM8_FEM_TR_ISO_SHIFT;
1592+ bus->sprom.fem.ghz2.antswlut = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
1593+ SSB_SROM8_FEM_ANTSWLUT) >> SSB_SROM8_FEM_ANTSWLUT_SHIFT;
1594+
1595+ bus->sprom.fem.ghz5.tssipos = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
1596+ SSB_SROM8_FEM_TSSIPOS) >> SSB_SROM8_FEM_TSSIPOS_SHIFT;
1597+ bus->sprom.fem.ghz5.extpa_gain = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
1598+ SSB_SROM8_FEM_EXTPA_GAIN) >> SSB_SROM8_FEM_EXTPA_GAIN_SHIFT;
1599+ bus->sprom.fem.ghz5.pdet_range = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
1600+ SSB_SROM8_FEM_PDET_RANGE) >> SSB_SROM8_FEM_PDET_RANGE_SHIFT;
1601+ bus->sprom.fem.ghz5.tr_iso = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
1602+ SSB_SROM8_FEM_TR_ISO) >> SSB_SROM8_FEM_TR_ISO_SHIFT;
1603+ bus->sprom.fem.ghz5.antswlut = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
1604+ SSB_SROM8_FEM_ANTSWLUT) >> SSB_SROM8_FEM_ANTSWLUT_SHIFT;
1605 }
1606 
1607 int bcma_sprom_get(struct bcma_bus *bus)
1608@@ -152,6 +222,9 @@ int bcma_sprom_get(struct bcma_bus *bus)
1609     if (!sprom)
1610         return -ENOMEM;
1611 
1612+ if (bus->chipinfo.id == 0x4331)
1613+ bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, false);
1614+
1615     /* Most cards have SPROM moved by additional offset 0x30 (48 dwords).
1616      * According to brcm80211 this applies to cards with PCIe rev >= 6
1617      * TODO: understand this condition and use it */
1618@@ -159,6 +232,9 @@ int bcma_sprom_get(struct bcma_bus *bus)
1619         BCMA_CC_SPROM_PCIE6;
1620     bcma_sprom_read(bus, offset, sprom);
1621 
1622+ if (bus->chipinfo.id == 0x4331)
1623+ bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, true);
1624+
1625     err = bcma_sprom_valid(sprom);
1626     if (err)
1627         goto out;
1628--- a/include/linux/bcma/bcma.h
1629+++ b/include/linux/bcma/bcma.h
1630@@ -6,6 +6,7 @@
1631 
1632 #include <linux/bcma/bcma_driver_chipcommon.h>
1633 #include <linux/bcma/bcma_driver_pci.h>
1634+#include <linux/bcma/bcma_driver_mips.h>
1635 #include <linux/ssb/ssb.h> /* SPROM sharing */
1636 
1637 #include "bcma_regs.h"
1638@@ -14,9 +15,9 @@ struct bcma_device;
1639 struct bcma_bus;
1640 
1641 enum bcma_hosttype {
1642- BCMA_HOSTTYPE_NONE,
1643     BCMA_HOSTTYPE_PCI,
1644     BCMA_HOSTTYPE_SDIO,
1645+ BCMA_HOSTTYPE_SOC,
1646 };
1647 
1648 struct bcma_chipinfo {
1649@@ -130,6 +131,7 @@ struct bcma_device {
1650 
1651     struct device dev;
1652     struct device *dma_dev;
1653+
1654     unsigned int irq;
1655     bool dev_registered;
1656 
1657@@ -138,6 +140,9 @@ struct bcma_device {
1658     u32 addr;
1659     u32 wrap;
1660 
1661+ void __iomem *io_addr;
1662+ void __iomem *io_wrap;
1663+
1664     void *drvdata;
1665     struct list_head list;
1666 };
1667@@ -165,10 +170,9 @@ struct bcma_driver {
1668 };
1669 extern
1670 int __bcma_driver_register(struct bcma_driver *drv, struct module *owner);
1671-static inline int bcma_driver_register(struct bcma_driver *drv)
1672-{
1673- return __bcma_driver_register(drv, THIS_MODULE);
1674-}
1675+#define bcma_driver_register(drv) \
1676+ __bcma_driver_register(drv, THIS_MODULE)
1677+
1678 extern void bcma_driver_unregister(struct bcma_driver *drv);
1679 
1680 struct bcma_bus {
1681@@ -190,70 +194,93 @@ struct bcma_bus {
1682     struct bcma_device *mapped_core;
1683     struct list_head cores;
1684     u8 nr_cores;
1685+ u8 init_done:1;
1686 
1687     struct bcma_drv_cc drv_cc;
1688     struct bcma_drv_pci drv_pci;
1689+ struct bcma_drv_mips drv_mips;
1690 
1691     /* We decided to share SPROM struct with SSB as long as we do not need
1692      * any hacks for BCMA. This simplifies drivers code. */
1693     struct ssb_sprom sprom;
1694 };
1695 
1696-extern inline u32 bcma_read8(struct bcma_device *core, u16 offset)
1697+static inline u32 bcma_read8(struct bcma_device *core, u16 offset)
1698 {
1699     return core->bus->ops->read8(core, offset);
1700 }
1701-extern inline u32 bcma_read16(struct bcma_device *core, u16 offset)
1702+static inline u32 bcma_read16(struct bcma_device *core, u16 offset)
1703 {
1704     return core->bus->ops->read16(core, offset);
1705 }
1706-extern inline u32 bcma_read32(struct bcma_device *core, u16 offset)
1707+static inline u32 bcma_read32(struct bcma_device *core, u16 offset)
1708 {
1709     return core->bus->ops->read32(core, offset);
1710 }
1711-extern inline
1712+static inline
1713 void bcma_write8(struct bcma_device *core, u16 offset, u32 value)
1714 {
1715     core->bus->ops->write8(core, offset, value);
1716 }
1717-extern inline
1718+static inline
1719 void bcma_write16(struct bcma_device *core, u16 offset, u32 value)
1720 {
1721     core->bus->ops->write16(core, offset, value);
1722 }
1723-extern inline
1724+static inline
1725 void bcma_write32(struct bcma_device *core, u16 offset, u32 value)
1726 {
1727     core->bus->ops->write32(core, offset, value);
1728 }
1729 #ifdef CONFIG_BCMA_BLOCKIO
1730-extern inline void bcma_block_read(struct bcma_device *core, void *buffer,
1731+static inline void bcma_block_read(struct bcma_device *core, void *buffer,
1732                    size_t count, u16 offset, u8 reg_width)
1733 {
1734     core->bus->ops->block_read(core, buffer, count, offset, reg_width);
1735 }
1736-extern inline void bcma_block_write(struct bcma_device *core, const void *buffer,
1737- size_t count, u16 offset, u8 reg_width)
1738+static inline void bcma_block_write(struct bcma_device *core,
1739+ const void *buffer, size_t count,
1740+ u16 offset, u8 reg_width)
1741 {
1742     core->bus->ops->block_write(core, buffer, count, offset, reg_width);
1743 }
1744 #endif
1745-extern inline u32 bcma_aread32(struct bcma_device *core, u16 offset)
1746+static inline u32 bcma_aread32(struct bcma_device *core, u16 offset)
1747 {
1748     return core->bus->ops->aread32(core, offset);
1749 }
1750-extern inline
1751+static inline
1752 void bcma_awrite32(struct bcma_device *core, u16 offset, u32 value)
1753 {
1754     core->bus->ops->awrite32(core, offset, value);
1755 }
1756 
1757-#define bcma_mask32(cc, offset, mask) \
1758- bcma_write32(cc, offset, bcma_read32(cc, offset) & (mask))
1759-#define bcma_set32(cc, offset, set) \
1760- bcma_write32(cc, offset, bcma_read32(cc, offset) | (set))
1761-#define bcma_maskset32(cc, offset, mask, set) \
1762- bcma_write32(cc, offset, (bcma_read32(cc, offset) & (mask)) | (set))
1763+static inline void bcma_mask32(struct bcma_device *cc, u16 offset, u32 mask)
1764+{
1765+ bcma_write32(cc, offset, bcma_read32(cc, offset) & mask);
1766+}
1767+static inline void bcma_set32(struct bcma_device *cc, u16 offset, u32 set)
1768+{
1769+ bcma_write32(cc, offset, bcma_read32(cc, offset) | set);
1770+}
1771+static inline void bcma_maskset32(struct bcma_device *cc,
1772+ u16 offset, u32 mask, u32 set)
1773+{
1774+ bcma_write32(cc, offset, (bcma_read32(cc, offset) & mask) | set);
1775+}
1776+static inline void bcma_mask16(struct bcma_device *cc, u16 offset, u16 mask)
1777+{
1778+ bcma_write16(cc, offset, bcma_read16(cc, offset) & mask);
1779+}
1780+static inline void bcma_set16(struct bcma_device *cc, u16 offset, u16 set)
1781+{
1782+ bcma_write16(cc, offset, bcma_read16(cc, offset) | set);
1783+}
1784+static inline void bcma_maskset16(struct bcma_device *cc,
1785+ u16 offset, u16 mask, u16 set)
1786+{
1787+ bcma_write16(cc, offset, (bcma_read16(cc, offset) & mask) | set);
1788+}
1789 
1790 extern bool bcma_core_is_enabled(struct bcma_device *core);
1791 extern void bcma_core_disable(struct bcma_device *core, u32 flags);
1792--- a/include/linux/bcma/bcma_driver_chipcommon.h
1793+++ b/include/linux/bcma/bcma_driver_chipcommon.h
1794@@ -24,6 +24,7 @@
1795 #define BCMA_CC_FLASHT_NONE 0x00000000 /* No flash */
1796 #define BCMA_CC_FLASHT_STSER 0x00000100 /* ST serial flash */
1797 #define BCMA_CC_FLASHT_ATSER 0x00000200 /* Atmel serial flash */
1798+#define BCMA_CC_FLASHT_NFLASH 0x00000200
1799 #define BCMA_CC_FLASHT_PARA 0x00000700 /* Parallel flash */
1800 #define BCMA_CC_CAP_PLLT 0x00038000 /* PLL Type */
1801 #define BCMA_PLLTYPE_NONE 0x00000000
1802@@ -178,6 +179,7 @@
1803 #define BCMA_CC_PROG_CFG 0x0120
1804 #define BCMA_CC_PROG_WAITCNT 0x0124
1805 #define BCMA_CC_FLASH_CFG 0x0128
1806+#define BCMA_CC_FLASH_CFG_DS 0x0010 /* Data size, 0=8bit, 1=16bit */
1807 #define BCMA_CC_FLASH_WAITCNT 0x012C
1808 /* 0x1E0 is defined as shared BCMA_CLKCTLST */
1809 #define BCMA_CC_HW_WORKAROUND 0x01E4 /* Hardware workaround (rev >= 20) */
1810@@ -201,6 +203,7 @@
1811 #define BCMA_CC_PMU_CTL 0x0600 /* PMU control */
1812 #define BCMA_CC_PMU_CTL_ILP_DIV 0xFFFF0000 /* ILP div mask */
1813 #define BCMA_CC_PMU_CTL_ILP_DIV_SHIFT 16
1814+#define BCMA_CC_PMU_CTL_PLL_UPD 0x00000400
1815 #define BCMA_CC_PMU_CTL_NOILPONW 0x00000200 /* No ILP on wait */
1816 #define BCMA_CC_PMU_CTL_HTREQEN 0x00000100 /* HT req enable */
1817 #define BCMA_CC_PMU_CTL_ALPREQEN 0x00000080 /* ALP req enable */
1818@@ -239,6 +242,64 @@
1819 #define BCMA_CC_SPROM 0x0800 /* SPROM beginning */
1820 #define BCMA_CC_SPROM_PCIE6 0x0830 /* SPROM beginning on PCIe rev >= 6 */
1821 
1822+/* Divider allocation in 4716/47162/5356 */
1823+#define BCMA_CC_PMU5_MAINPLL_CPU 1
1824+#define BCMA_CC_PMU5_MAINPLL_MEM 2
1825+#define BCMA_CC_PMU5_MAINPLL_SSB 3
1826+
1827+/* PLL usage in 4716/47162 */
1828+#define BCMA_CC_PMU4716_MAINPLL_PLL0 12
1829+
1830+/* PLL usage in 5356/5357 */
1831+#define BCMA_CC_PMU5356_MAINPLL_PLL0 0
1832+#define BCMA_CC_PMU5357_MAINPLL_PLL0 0
1833+
1834+/* 4706 PMU */
1835+#define BCMA_CC_PMU4706_MAINPLL_PLL0 0
1836+
1837+/* ALP clock on pre-PMU chips */
1838+#define BCMA_CC_PMU_ALP_CLOCK 20000000
1839+/* HT clock for systems with PMU-enabled chipcommon */
1840+#define BCMA_CC_PMU_HT_CLOCK 80000000
1841+
1842+/* PMU rev 5 (& 6) */
1843+#define BCMA_CC_PPL_P1P2_OFF 0
1844+#define BCMA_CC_PPL_P1_MASK 0x0f000000
1845+#define BCMA_CC_PPL_P1_SHIFT 24
1846+#define BCMA_CC_PPL_P2_MASK 0x00f00000
1847+#define BCMA_CC_PPL_P2_SHIFT 20
1848+#define BCMA_CC_PPL_M14_OFF 1
1849+#define BCMA_CC_PPL_MDIV_MASK 0x000000ff
1850+#define BCMA_CC_PPL_MDIV_WIDTH 8
1851+#define BCMA_CC_PPL_NM5_OFF 2
1852+#define BCMA_CC_PPL_NDIV_MASK 0xfff00000
1853+#define BCMA_CC_PPL_NDIV_SHIFT 20
1854+#define BCMA_CC_PPL_FMAB_OFF 3
1855+#define BCMA_CC_PPL_MRAT_MASK 0xf0000000
1856+#define BCMA_CC_PPL_MRAT_SHIFT 28
1857+#define BCMA_CC_PPL_ABRAT_MASK 0x08000000
1858+#define BCMA_CC_PPL_ABRAT_SHIFT 27
1859+#define BCMA_CC_PPL_FDIV_MASK 0x07ffffff
1860+#define BCMA_CC_PPL_PLLCTL_OFF 4
1861+#define BCMA_CC_PPL_PCHI_OFF 5
1862+#define BCMA_CC_PPL_PCHI_MASK 0x0000003f
1863+
1864+/* BCM4331 ChipControl numbers. */
1865+#define BCMA_CHIPCTL_4331_BT_COEXIST BIT(0) /* 0 disable */
1866+#define BCMA_CHIPCTL_4331_SECI BIT(1) /* 0 SECI is disabled (JATG functional) */
1867+#define BCMA_CHIPCTL_4331_EXT_LNA BIT(2) /* 0 disable */
1868+#define BCMA_CHIPCTL_4331_SPROM_GPIO13_15 BIT(3) /* sprom/gpio13-15 mux */
1869+#define BCMA_CHIPCTL_4331_EXTPA_EN BIT(4) /* 0 ext pa disable, 1 ext pa enabled */
1870+#define BCMA_CHIPCTL_4331_GPIOCLK_ON_SPROMCS BIT(5) /* set drive out GPIO_CLK on sprom_cs pin */
1871+#define BCMA_CHIPCTL_4331_PCIE_MDIO_ON_SPROMCS BIT(6) /* use sprom_cs pin as PCIE mdio interface */
1872+#define BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5 BIT(7) /* aband extpa will be at gpio2/5 and sprom_dout */
1873+#define BCMA_CHIPCTL_4331_OVR_PIPEAUXCLKEN BIT(8) /* override core control on pipe_AuxClkEnable */
1874+#define BCMA_CHIPCTL_4331_OVR_PIPEAUXPWRDOWN BIT(9) /* override core control on pipe_AuxPowerDown */
1875+#define BCMA_CHIPCTL_4331_PCIE_AUXCLKEN BIT(10) /* pcie_auxclkenable */
1876+#define BCMA_CHIPCTL_4331_PCIE_PIPE_PLLDOWN BIT(11) /* pcie_pipe_pllpowerdown */
1877+#define BCMA_CHIPCTL_4331_BT_SHD0_ON_GPIO4 BIT(16) /* enable bt_shd0 at gpio4 */
1878+#define BCMA_CHIPCTL_4331_BT_SHD1_ON_GPIO5 BIT(17) /* enable bt_shd1 at gpio5 */
1879+
1880 /* Data for the PMU, if available.
1881  * Check availability with ((struct bcma_chipcommon)->capabilities & BCMA_CC_CAP_PMU)
1882  */
1883@@ -247,14 +308,37 @@ struct bcma_chipcommon_pmu {
1884     u32 crystalfreq; /* The active crystal frequency (in kHz) */
1885 };
1886 
1887+#ifdef CONFIG_BCMA_DRIVER_MIPS
1888+struct bcma_pflash {
1889+ u8 buswidth;
1890+ u32 window;
1891+ u32 window_size;
1892+};
1893+
1894+struct bcma_serial_port {
1895+ void *regs;
1896+ unsigned long clockspeed;
1897+ unsigned int irq;
1898+ unsigned int baud_base;
1899+ unsigned int reg_shift;
1900+};
1901+#endif /* CONFIG_BCMA_DRIVER_MIPS */
1902+
1903 struct bcma_drv_cc {
1904     struct bcma_device *core;
1905     u32 status;
1906     u32 capabilities;
1907     u32 capabilities_ext;
1908+ u8 setup_done:1;
1909     /* Fast Powerup Delay constant */
1910     u16 fast_pwrup_delay;
1911     struct bcma_chipcommon_pmu pmu;
1912+#ifdef CONFIG_BCMA_DRIVER_MIPS
1913+ struct bcma_pflash pflash;
1914+
1915+ int nr_serial_ports;
1916+ struct bcma_serial_port serial_ports[4];
1917+#endif /* CONFIG_BCMA_DRIVER_MIPS */
1918 };
1919 
1920 /* Register access */
1921@@ -275,6 +359,8 @@ extern void bcma_core_chipcommon_init(st
1922 extern void bcma_chipco_suspend(struct bcma_drv_cc *cc);
1923 extern void bcma_chipco_resume(struct bcma_drv_cc *cc);
1924 
1925+void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable);
1926+
1927 extern void bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc,
1928                       u32 ticks);
1929 
1930@@ -293,4 +379,13 @@ u32 bcma_chipco_gpio_polarity(struct bcm
1931 /* PMU support */
1932 extern void bcma_pmu_init(struct bcma_drv_cc *cc);
1933 
1934+extern void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset,
1935+ u32 value);
1936+extern void bcma_chipco_pll_maskset(struct bcma_drv_cc *cc, u32 offset,
1937+ u32 mask, u32 set);
1938+extern void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc,
1939+ u32 offset, u32 mask, u32 set);
1940+extern void bcma_chipco_regctl_maskset(struct bcma_drv_cc *cc,
1941+ u32 offset, u32 mask, u32 set);
1942+
1943 #endif /* LINUX_BCMA_DRIVER_CC_H_ */
1944--- /dev/null
1945+++ b/include/linux/bcma/bcma_driver_mips.h
1946@@ -0,0 +1,51 @@
1947+#ifndef LINUX_BCMA_DRIVER_MIPS_H_
1948+#define LINUX_BCMA_DRIVER_MIPS_H_
1949+
1950+#define BCMA_MIPS_IPSFLAG 0x0F08
1951+/* which sbflags get routed to mips interrupt 1 */
1952+#define BCMA_MIPS_IPSFLAG_IRQ1 0x0000003F
1953+#define BCMA_MIPS_IPSFLAG_IRQ1_SHIFT 0
1954+/* which sbflags get routed to mips interrupt 2 */
1955+#define BCMA_MIPS_IPSFLAG_IRQ2 0x00003F00
1956+#define BCMA_MIPS_IPSFLAG_IRQ2_SHIFT 8
1957+/* which sbflags get routed to mips interrupt 3 */
1958+#define BCMA_MIPS_IPSFLAG_IRQ3 0x003F0000
1959+#define BCMA_MIPS_IPSFLAG_IRQ3_SHIFT 16
1960+/* which sbflags get routed to mips interrupt 4 */
1961+#define BCMA_MIPS_IPSFLAG_IRQ4 0x3F000000
1962+#define BCMA_MIPS_IPSFLAG_IRQ4_SHIFT 24
1963+
1964+/* MIPS 74K core registers */
1965+#define BCMA_MIPS_MIPS74K_CORECTL 0x0000
1966+#define BCMA_MIPS_MIPS74K_EXCEPTBASE 0x0004
1967+#define BCMA_MIPS_MIPS74K_BIST 0x000C
1968+#define BCMA_MIPS_MIPS74K_INTMASK_INT0 0x0014
1969+#define BCMA_MIPS_MIPS74K_INTMASK(int) \
1970+ ((int) * 4 + BCMA_MIPS_MIPS74K_INTMASK_INT0)
1971+#define BCMA_MIPS_MIPS74K_NMIMASK 0x002C
1972+#define BCMA_MIPS_MIPS74K_GPIOSEL 0x0040
1973+#define BCMA_MIPS_MIPS74K_GPIOOUT 0x0044
1974+#define BCMA_MIPS_MIPS74K_GPIOEN 0x0048
1975+#define BCMA_MIPS_MIPS74K_CLKCTLST 0x01E0
1976+
1977+#define BCMA_MIPS_OOBSELOUTA30 0x100
1978+
1979+struct bcma_device;
1980+
1981+struct bcma_drv_mips {
1982+ struct bcma_device *core;
1983+ u8 setup_done:1;
1984+ unsigned int assigned_irqs;
1985+};
1986+
1987+#ifdef CONFIG_BCMA_DRIVER_MIPS
1988+extern void bcma_core_mips_init(struct bcma_drv_mips *mcore);
1989+#else
1990+static inline void bcma_core_mips_init(struct bcma_drv_mips *mcore) { }
1991+#endif
1992+
1993+extern u32 bcma_cpu_clock(struct bcma_drv_mips *mcore);
1994+
1995+extern unsigned int bcma_core_mips_irq(struct bcma_device *dev);
1996+
1997+#endif /* LINUX_BCMA_DRIVER_MIPS_H_ */
1998--- /dev/null
1999+++ b/include/linux/bcma/bcma_soc.h
2000@@ -0,0 +1,16 @@
2001+#ifndef LINUX_BCMA_SOC_H_
2002+#define LINUX_BCMA_SOC_H_
2003+
2004+#include <linux/bcma/bcma.h>
2005+
2006+struct bcma_soc {
2007+ struct bcma_bus bus;
2008+ struct bcma_device core_cc;
2009+ struct bcma_device core_mips;
2010+};
2011+
2012+int __init bcma_host_soc_register(struct bcma_soc *soc);
2013+
2014+int bcma_bus_register(struct bcma_bus *bus);
2015+
2016+#endif /* LINUX_BCMA_SOC_H_ */
2017

Archive Download this file



interactive