1 --- a/drivers/bcma/Kconfig
2 +++ b/drivers/bcma/Kconfig
3 @@ -13,6 +13,11 @@ config BCMA
4 Bus driver for Broadcom specific Advanced Microcontroller Bus
7 +# Support for Block-I/O. SELECT this from the driver that needs it.
12 config BCMA_HOST_PCI_POSSIBLE
14 depends on BCMA && PCI = y
15 @@ -22,6 +27,25 @@ config BCMA_HOST_PCI
16 bool "Support for BCMA on PCI-host bus"
17 depends on BCMA_HOST_PCI_POSSIBLE
19 +config BCMA_DRIVER_PCI_HOSTMODE
20 + bool "Driver for PCI core working in hostmode"
21 + depends on BCMA && MIPS
23 + PCI core hostmode operation (external PCI bus).
27 + depends on BCMA_DRIVER_MIPS
29 +config BCMA_DRIVER_MIPS
30 + bool "BCMA Broadcom MIPS core driver"
31 + depends on BCMA && MIPS
33 + Driver for the Broadcom MIPS core attached to Broadcom specific
34 + Advanced Microcontroller Bus.
41 --- a/drivers/bcma/Makefile
42 +++ b/drivers/bcma/Makefile
44 -bcma-y += main.o scan.o core.o
45 +bcma-y += main.o scan.o core.o sprom.o
46 bcma-y += driver_chipcommon.o driver_chipcommon_pmu.o
47 bcma-y += driver_pci.o
48 +bcma-$(CONFIG_BCMA_DRIVER_PCI_HOSTMODE) += driver_pci_host.o
49 +bcma-$(CONFIG_BCMA_DRIVER_MIPS) += driver_mips.o
50 bcma-$(CONFIG_BCMA_HOST_PCI) += host_pci.o
51 +bcma-$(CONFIG_BCMA_HOST_SOC) += host_soc.o
52 obj-$(CONFIG_BCMA) += bcma.o
54 ccflags-$(CONFIG_BCMA_DEBUG) := -DDEBUG
55 --- a/drivers/bcma/bcma_private.h
56 +++ b/drivers/bcma/bcma_private.h
61 -extern int bcma_bus_register(struct bcma_bus *bus);
62 -extern void bcma_bus_unregister(struct bcma_bus *bus);
63 +int bcma_bus_register(struct bcma_bus *bus);
64 +void bcma_bus_unregister(struct bcma_bus *bus);
65 +int __init bcma_bus_early_register(struct bcma_bus *bus,
66 + struct bcma_device *core_cc,
67 + struct bcma_device *core_mips);
69 +int bcma_bus_resume(struct bcma_bus *bus);
73 int bcma_bus_scan(struct bcma_bus *bus);
74 +int __init bcma_bus_scan_early(struct bcma_bus *bus,
75 + struct bcma_device_id *match,
76 + struct bcma_device *core);
77 +void bcma_init_bus(struct bcma_bus *bus);
80 +int bcma_sprom_get(struct bcma_bus *bus);
82 +/* driver_chipcommon.c */
83 +#ifdef CONFIG_BCMA_DRIVER_MIPS
84 +void bcma_chipco_serial_init(struct bcma_drv_cc *cc);
85 +#endif /* CONFIG_BCMA_DRIVER_MIPS */
87 +/* driver_chipcommon_pmu.c */
88 +u32 bcma_pmu_alp_clock(struct bcma_drv_cc *cc);
89 +u32 bcma_pmu_get_clockcpu(struct bcma_drv_cc *cc);
91 #ifdef CONFIG_BCMA_HOST_PCI
93 @@ -25,4 +47,8 @@ extern int __init bcma_host_pci_init(voi
94 extern void __exit bcma_host_pci_exit(void);
95 #endif /* CONFIG_BCMA_HOST_PCI */
97 +#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
98 +void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc);
99 +#endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */
102 --- a/drivers/bcma/core.c
103 +++ b/drivers/bcma/core.c
104 @@ -19,7 +19,7 @@ bool bcma_core_is_enabled(struct bcma_de
106 EXPORT_SYMBOL_GPL(bcma_core_is_enabled);
108 -static void bcma_core_disable(struct bcma_device *core, u32 flags)
109 +void bcma_core_disable(struct bcma_device *core, u32 flags)
111 if (bcma_aread32(core, BCMA_RESET_CTL) & BCMA_RESET_CTL_RESET)
113 @@ -31,6 +31,7 @@ static void bcma_core_disable(struct bcm
114 bcma_awrite32(core, BCMA_RESET_CTL, BCMA_RESET_CTL_RESET);
117 +EXPORT_SYMBOL_GPL(bcma_core_disable);
119 int bcma_core_enable(struct bcma_device *core, u32 flags)
121 @@ -49,3 +50,77 @@ int bcma_core_enable(struct bcma_device
124 EXPORT_SYMBOL_GPL(bcma_core_enable);
126 +void bcma_core_set_clockmode(struct bcma_device *core,
127 + enum bcma_clkmode clkmode)
131 + WARN_ON(core->id.id != BCMA_CORE_CHIPCOMMON &&
132 + core->id.id != BCMA_CORE_PCIE &&
133 + core->id.id != BCMA_CORE_80211);
136 + case BCMA_CLKMODE_FAST:
137 + bcma_set32(core, BCMA_CLKCTLST, BCMA_CLKCTLST_FORCEHT);
139 + for (i = 0; i < 1500; i++) {
140 + if (bcma_read32(core, BCMA_CLKCTLST) &
141 + BCMA_CLKCTLST_HAVEHT) {
148 + pr_err("HT force timeout\n");
150 + case BCMA_CLKMODE_DYNAMIC:
151 + pr_warn("Dynamic clockmode not supported yet!\n");
155 +EXPORT_SYMBOL_GPL(bcma_core_set_clockmode);
157 +void bcma_core_pll_ctl(struct bcma_device *core, u32 req, u32 status, bool on)
161 + WARN_ON(req & ~BCMA_CLKCTLST_EXTRESREQ);
162 + WARN_ON(status & ~BCMA_CLKCTLST_EXTRESST);
165 + bcma_set32(core, BCMA_CLKCTLST, req);
166 + for (i = 0; i < 10000; i++) {
167 + if ((bcma_read32(core, BCMA_CLKCTLST) & status) ==
175 + pr_err("PLL enable timeout\n");
177 + pr_warn("Disabling PLL not supported yet!\n");
180 +EXPORT_SYMBOL_GPL(bcma_core_pll_ctl);
182 +u32 bcma_core_dma_translation(struct bcma_device *core)
184 + switch (core->bus->hosttype) {
185 + case BCMA_HOSTTYPE_SOC:
187 + case BCMA_HOSTTYPE_PCI:
188 + if (bcma_aread32(core, BCMA_IOST) & BCMA_IOST_DMA64)
189 + return BCMA_DMA_TRANSLATION_DMA64_CMT;
191 + return BCMA_DMA_TRANSLATION_DMA32_CMT;
193 + pr_err("DMA translation unknown for host %d\n",
194 + core->bus->hosttype);
196 + return BCMA_DMA_TRANSLATION_NONE;
198 +EXPORT_SYMBOL(bcma_core_dma_translation);
199 --- a/drivers/bcma/driver_chipcommon.c
200 +++ b/drivers/bcma/driver_chipcommon.c
202 * ChipCommon core driver
204 * Copyright 2005, Broadcom Corporation
205 - * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
206 + * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
208 * Licensed under the GNU/GPL. See COPYING for details.
210 @@ -23,6 +23,12 @@ static inline u32 bcma_cc_write32_masked
212 void bcma_core_chipcommon_init(struct bcma_drv_cc *cc)
215 + u32 leddc_off = 90;
217 + if (cc->setup_done)
220 if (cc->core->id.rev >= 11)
221 cc->status = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
222 cc->capabilities = bcma_cc_read32(cc, BCMA_CC_CAP);
223 @@ -38,6 +44,19 @@ void bcma_core_chipcommon_init(struct bc
225 if (cc->capabilities & BCMA_CC_CAP_PCTL)
226 pr_err("Power control not implemented!\n");
228 + if (cc->core->id.rev >= 16) {
229 + if (cc->core->bus->sprom.leddc_on_time &&
230 + cc->core->bus->sprom.leddc_off_time) {
231 + leddc_on = cc->core->bus->sprom.leddc_on_time;
232 + leddc_off = cc->core->bus->sprom.leddc_off_time;
234 + bcma_cc_write32(cc, BCMA_CC_GPIOTIMER,
235 + ((leddc_on << BCMA_CC_GPIOTIMER_ONTIME_SHIFT) |
236 + (leddc_off << BCMA_CC_GPIOTIMER_OFFTIME_SHIFT)));
239 + cc->setup_done = true;
242 /* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */
243 @@ -87,3 +106,51 @@ u32 bcma_chipco_gpio_polarity(struct bcm
245 return bcma_cc_write32_masked(cc, BCMA_CC_GPIOPOL, mask, value);
248 +#ifdef CONFIG_BCMA_DRIVER_MIPS
249 +void bcma_chipco_serial_init(struct bcma_drv_cc *cc)
254 + unsigned int ccrev = cc->core->id.rev;
255 + struct bcma_serial_port *ports = cc->serial_ports;
257 + if (ccrev >= 11 && ccrev != 15) {
258 + /* Fixed ALP clock */
259 + baud_base = bcma_pmu_alp_clock(cc);
261 + /* Turn off UART clock before switching clocksource. */
262 + bcma_cc_write32(cc, BCMA_CC_CORECTL,
263 + bcma_cc_read32(cc, BCMA_CC_CORECTL)
264 + & ~BCMA_CC_CORECTL_UARTCLKEN);
266 + /* Set the override bit so we don't divide it */
267 + bcma_cc_write32(cc, BCMA_CC_CORECTL,
268 + bcma_cc_read32(cc, BCMA_CC_CORECTL)
269 + | BCMA_CC_CORECTL_UARTCLK0);
271 + /* Re-enable the UART clock. */
272 + bcma_cc_write32(cc, BCMA_CC_CORECTL,
273 + bcma_cc_read32(cc, BCMA_CC_CORECTL)
274 + | BCMA_CC_CORECTL_UARTCLKEN);
277 + pr_err("serial not supported on this device ccrev: 0x%x\n",
282 + irq = bcma_core_mips_irq(cc->core);
284 + /* Determine the registers of the UARTs */
285 + cc->nr_serial_ports = (cc->capabilities & BCMA_CC_CAP_NRUART);
286 + for (i = 0; i < cc->nr_serial_ports; i++) {
287 + ports[i].regs = cc->core->io_addr + BCMA_CC_UART0_DATA +
289 + ports[i].irq = irq;
290 + ports[i].baud_base = baud_base;
291 + ports[i].reg_shift = 0;
294 +#endif /* CONFIG_BCMA_DRIVER_MIPS */
295 --- a/drivers/bcma/driver_chipcommon_pmu.c
296 +++ b/drivers/bcma/driver_chipcommon_pmu.c
298 * Broadcom specific AMBA
299 * ChipCommon Power Management Unit driver
301 - * Copyright 2009, Michael Buesch <mb@bu3sch.de>
302 + * Copyright 2009, Michael Buesch <m@bues.ch>
303 * Copyright 2007, Broadcom Corporation
305 * Licensed under the GNU/GPL. See COPYING for details.
307 #include "bcma_private.h"
308 #include <linux/bcma/bcma.h>
310 -static void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc,
311 - u32 offset, u32 mask, u32 set)
312 +static u32 bcma_chipco_pll_read(struct bcma_drv_cc *cc, u32 offset)
315 + bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
316 + bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
317 + return bcma_cc_read32(cc, BCMA_CC_PLLCTL_DATA);
320 - bcma_cc_read32(cc, BCMA_CC_CHIPCTL_ADDR);
321 +void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset, u32 value)
323 + bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
324 + bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
325 + bcma_cc_write32(cc, BCMA_CC_PLLCTL_DATA, value);
327 +EXPORT_SYMBOL_GPL(bcma_chipco_pll_write);
329 +void bcma_chipco_pll_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask,
332 + bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
333 + bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
334 + bcma_cc_maskset32(cc, BCMA_CC_PLLCTL_DATA, mask, set);
336 +EXPORT_SYMBOL_GPL(bcma_chipco_pll_maskset);
338 +void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc,
339 + u32 offset, u32 mask, u32 set)
341 bcma_cc_write32(cc, BCMA_CC_CHIPCTL_ADDR, offset);
342 bcma_cc_read32(cc, BCMA_CC_CHIPCTL_ADDR);
343 - value = bcma_cc_read32(cc, BCMA_CC_CHIPCTL_DATA);
346 - bcma_cc_write32(cc, BCMA_CC_CHIPCTL_DATA, value);
347 - bcma_cc_read32(cc, BCMA_CC_CHIPCTL_DATA);
348 + bcma_cc_maskset32(cc, BCMA_CC_CHIPCTL_DATA, mask, set);
350 +EXPORT_SYMBOL_GPL(bcma_chipco_chipctl_maskset);
352 +void bcma_chipco_regctl_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask,
355 + bcma_cc_write32(cc, BCMA_CC_REGCTL_ADDR, offset);
356 + bcma_cc_read32(cc, BCMA_CC_REGCTL_ADDR);
357 + bcma_cc_maskset32(cc, BCMA_CC_REGCTL_DATA, mask, set);
359 +EXPORT_SYMBOL_GPL(bcma_chipco_regctl_maskset);
361 static void bcma_pmu_pll_init(struct bcma_drv_cc *cc)
363 @@ -53,6 +80,7 @@ static void bcma_pmu_resources_init(stru
370 pr_err("PMU resource config unknown for device 0x%04X\n",
371 @@ -74,6 +102,7 @@ void bcma_pmu_swreg_init(struct bcma_drv
378 pr_err("PMU switch/regulators init unknown for device "
379 @@ -81,6 +110,24 @@ void bcma_pmu_swreg_init(struct bcma_drv
383 +/* Disable to allow reading SPROM. Don't know the adventages of enabling it. */
384 +void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable)
386 + struct bcma_bus *bus = cc->core->bus;
389 + val = bcma_cc_read32(cc, BCMA_CC_CHIPCTL);
391 + val |= BCMA_CHIPCTL_4331_EXTPA_EN;
392 + if (bus->chipinfo.pkg == 9 || bus->chipinfo.pkg == 11)
393 + val |= BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5;
395 + val &= ~BCMA_CHIPCTL_4331_EXTPA_EN;
396 + val &= ~BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5;
398 + bcma_cc_write32(cc, BCMA_CC_CHIPCTL, val);
401 void bcma_pmu_workarounds(struct bcma_drv_cc *cc)
403 struct bcma_bus *bus = cc->core->bus;
404 @@ -90,17 +137,19 @@ void bcma_pmu_workarounds(struct bcma_dr
405 bcma_chipco_chipctl_maskset(cc, 0, ~0, 0x7);
408 - pr_err("Enabling Ext PA lines not implemented\n");
409 + /* BCM4331 workaround is SPROM-related, we put it in sprom.c */
412 if (bus->chipinfo.rev == 0) {
413 pr_err("Workarounds for 43224 rev 0 not fully "
415 - bcma_chipco_chipctl_maskset(cc, 0, ~0, 0xF0);
416 + bcma_chipco_chipctl_maskset(cc, 0, ~0, 0x00F000F0);
418 bcma_chipco_chipctl_maskset(cc, 0, ~0, 0xF0);
424 pr_err("Workarounds unknown for device 0x%04X\n",
426 @@ -132,3 +181,129 @@ void bcma_pmu_init(struct bcma_drv_cc *c
427 bcma_pmu_swreg_init(cc);
428 bcma_pmu_workarounds(cc);
431 +u32 bcma_pmu_alp_clock(struct bcma_drv_cc *cc)
433 + struct bcma_bus *bus = cc->core->bus;
435 + switch (bus->chipinfo.id) {
444 + return 20000 * 1000;
448 + return 25000 * 1000;
450 + pr_warn("No ALP clock specified for %04X device, "
451 + "pmu rev. %d, using default %d Hz\n",
452 + bus->chipinfo.id, cc->pmu.rev, BCMA_CC_PMU_ALP_CLOCK);
454 + return BCMA_CC_PMU_ALP_CLOCK;
457 +/* Find the output of the "m" pll divider given pll controls that start with
458 + * pllreg "pll0" i.e. 12 for main 6 for phy, 0 for misc.
460 +static u32 bcma_pmu_clock(struct bcma_drv_cc *cc, u32 pll0, u32 m)
462 + u32 tmp, div, ndiv, p1, p2, fc;
463 + struct bcma_bus *bus = cc->core->bus;
465 + BUG_ON((pll0 & 3) || (pll0 > BCMA_CC_PMU4716_MAINPLL_PLL0));
467 + BUG_ON(!m || m > 4);
469 + if (bus->chipinfo.id == 0x5357 || bus->chipinfo.id == 0x4749) {
470 + /* Detect failure in clock setting */
471 + tmp = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
473 + return 133 * 1000000;
476 + tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_P1P2_OFF);
477 + p1 = (tmp & BCMA_CC_PPL_P1_MASK) >> BCMA_CC_PPL_P1_SHIFT;
478 + p2 = (tmp & BCMA_CC_PPL_P2_MASK) >> BCMA_CC_PPL_P2_SHIFT;
480 + tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_M14_OFF);
481 + div = (tmp >> ((m - 1) * BCMA_CC_PPL_MDIV_WIDTH)) &
482 + BCMA_CC_PPL_MDIV_MASK;
484 + tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_NM5_OFF);
485 + ndiv = (tmp & BCMA_CC_PPL_NDIV_MASK) >> BCMA_CC_PPL_NDIV_SHIFT;
487 + /* Do calculation in Mhz */
488 + fc = bcma_pmu_alp_clock(cc) / 1000000;
489 + fc = (p1 * ndiv * fc) / p2;
491 + /* Return clock in Hertz */
492 + return (fc / div) * 1000000;
495 +/* query bus clock frequency for PMU-enabled chipcommon */
496 +u32 bcma_pmu_get_clockcontrol(struct bcma_drv_cc *cc)
498 + struct bcma_bus *bus = cc->core->bus;
500 + switch (bus->chipinfo.id) {
504 + return bcma_pmu_clock(cc, BCMA_CC_PMU4716_MAINPLL_PLL0,
505 + BCMA_CC_PMU5_MAINPLL_SSB);
507 + return bcma_pmu_clock(cc, BCMA_CC_PMU5356_MAINPLL_PLL0,
508 + BCMA_CC_PMU5_MAINPLL_SSB);
511 + return bcma_pmu_clock(cc, BCMA_CC_PMU5357_MAINPLL_PLL0,
512 + BCMA_CC_PMU5_MAINPLL_SSB);
514 + return bcma_pmu_clock(cc, BCMA_CC_PMU4706_MAINPLL_PLL0,
515 + BCMA_CC_PMU5_MAINPLL_SSB);
519 + pr_warn("No backplane clock specified for %04X device, "
520 + "pmu rev. %d, using default %d Hz\n",
521 + bus->chipinfo.id, cc->pmu.rev, BCMA_CC_PMU_HT_CLOCK);
523 + return BCMA_CC_PMU_HT_CLOCK;
526 +/* query cpu clock frequency for PMU-enabled chipcommon */
527 +u32 bcma_pmu_get_clockcpu(struct bcma_drv_cc *cc)
529 + struct bcma_bus *bus = cc->core->bus;
531 + if (bus->chipinfo.id == 53572)
534 + if (cc->pmu.rev >= 5) {
536 + switch (bus->chipinfo.id) {
538 + pll = BCMA_CC_PMU5356_MAINPLL_PLL0;
542 + pll = BCMA_CC_PMU5357_MAINPLL_PLL0;
545 + pll = BCMA_CC_PMU4716_MAINPLL_PLL0;
549 + /* TODO: if (bus->chipinfo.id == 0x5300)
550 + return si_4706_pmu_clock(sih, osh, cc, PMU4706_MAINPLL_PLL0, PMU5_MAINPLL_CPU); */
551 + return bcma_pmu_clock(cc, pll, BCMA_CC_PMU5_MAINPLL_CPU);
554 + return bcma_pmu_get_clockcontrol(cc);
557 +++ b/drivers/bcma/driver_mips.c
560 + * Broadcom specific AMBA
561 + * Broadcom MIPS32 74K core driver
563 + * Copyright 2009, Broadcom Corporation
564 + * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
565 + * Copyright 2010, Bernhard Loos <bernhardloos@googlemail.com>
566 + * Copyright 2011, Hauke Mehrtens <hauke@hauke-m.de>
568 + * Licensed under the GNU/GPL. See COPYING for details.
571 +#include "bcma_private.h"
573 +#include <linux/bcma/bcma.h>
575 +#include <linux/serial.h>
576 +#include <linux/serial_core.h>
577 +#include <linux/serial_reg.h>
578 +#include <linux/time.h>
580 +/* The 47162a0 hangs when reading MIPS DMP registers registers */
581 +static inline bool bcma_core_mips_bcm47162a0_quirk(struct bcma_device *dev)
583 + return dev->bus->chipinfo.id == 47162 && dev->bus->chipinfo.rev == 0 &&
584 + dev->id.id == BCMA_CORE_MIPS_74K;
587 +/* The 5357b0 hangs when reading USB20H DMP registers */
588 +static inline bool bcma_core_mips_bcm5357b0_quirk(struct bcma_device *dev)
590 + return (dev->bus->chipinfo.id == 0x5357 ||
591 + dev->bus->chipinfo.id == 0x4749) &&
592 + dev->bus->chipinfo.pkg == 11 &&
593 + dev->id.id == BCMA_CORE_USB20_HOST;
596 +static inline u32 mips_read32(struct bcma_drv_mips *mcore,
599 + return bcma_read32(mcore->core, offset);
602 +static inline void mips_write32(struct bcma_drv_mips *mcore,
606 + bcma_write32(mcore->core, offset, value);
609 +static const u32 ipsflag_irq_mask[] = {
611 + BCMA_MIPS_IPSFLAG_IRQ1,
612 + BCMA_MIPS_IPSFLAG_IRQ2,
613 + BCMA_MIPS_IPSFLAG_IRQ3,
614 + BCMA_MIPS_IPSFLAG_IRQ4,
617 +static const u32 ipsflag_irq_shift[] = {
619 + BCMA_MIPS_IPSFLAG_IRQ1_SHIFT,
620 + BCMA_MIPS_IPSFLAG_IRQ2_SHIFT,
621 + BCMA_MIPS_IPSFLAG_IRQ3_SHIFT,
622 + BCMA_MIPS_IPSFLAG_IRQ4_SHIFT,
625 +static u32 bcma_core_mips_irqflag(struct bcma_device *dev)
629 + if (bcma_core_mips_bcm47162a0_quirk(dev))
630 + return dev->core_index;
631 + if (bcma_core_mips_bcm5357b0_quirk(dev))
632 + return dev->core_index;
633 + flag = bcma_aread32(dev, BCMA_MIPS_OOBSELOUTA30);
635 + return flag & 0x1F;
638 +/* Get the MIPS IRQ assignment for a specified device.
639 + * If unassigned, 0 is returned.
641 +unsigned int bcma_core_mips_irq(struct bcma_device *dev)
643 + struct bcma_device *mdev = dev->bus->drv_mips.core;
647 + irqflag = bcma_core_mips_irqflag(dev);
649 + for (irq = 1; irq <= 4; irq++)
650 + if (bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq)) &
656 +EXPORT_SYMBOL(bcma_core_mips_irq);
658 +static void bcma_core_mips_set_irq(struct bcma_device *dev, unsigned int irq)
660 + unsigned int oldirq = bcma_core_mips_irq(dev);
661 + struct bcma_bus *bus = dev->bus;
662 + struct bcma_device *mdev = bus->drv_mips.core;
665 + irqflag = bcma_core_mips_irqflag(dev);
666 + BUG_ON(oldirq == 6);
668 + dev->irq = irq + 2;
670 + /* clear the old irq */
672 + bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0),
673 + bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) &
676 + bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq), 0);
678 + /* assign the new one */
680 + bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0),
681 + bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) |
684 + u32 oldirqflag = bcma_read32(mdev,
685 + BCMA_MIPS_MIPS74K_INTMASK(irq));
687 + struct bcma_device *core;
689 + /* backplane irq line is in use, find out who uses
690 + * it and set user to irq 0
692 + list_for_each_entry_reverse(core, &bus->cores, list) {
693 + if ((1 << bcma_core_mips_irqflag(core)) ==
695 + bcma_core_mips_set_irq(core, 0);
700 + bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq),
704 + pr_info("set_irq: core 0x%04x, irq %d => %d\n",
705 + dev->id.id, oldirq + 2, irq + 2);
708 +static void bcma_core_mips_print_irq(struct bcma_device *dev, unsigned int irq)
711 + static const char *irq_name[] = {"2(S)", "3", "4", "5", "6", "D", "I"};
712 + printk(KERN_INFO KBUILD_MODNAME ": core 0x%04x, irq :", dev->id.id);
713 + for (i = 0; i <= 6; i++)
714 + printk(" %s%s", irq_name[i], i == irq ? "*" : " ");
718 +static void bcma_core_mips_dump_irq(struct bcma_bus *bus)
720 + struct bcma_device *core;
722 + list_for_each_entry_reverse(core, &bus->cores, list) {
723 + bcma_core_mips_print_irq(core, bcma_core_mips_irq(core));
727 +u32 bcma_cpu_clock(struct bcma_drv_mips *mcore)
729 + struct bcma_bus *bus = mcore->core->bus;
731 + if (bus->drv_cc.capabilities & BCMA_CC_CAP_PMU)
732 + return bcma_pmu_get_clockcpu(&bus->drv_cc);
734 + pr_err("No PMU available, need this to get the cpu clock\n");
737 +EXPORT_SYMBOL(bcma_cpu_clock);
739 +static void bcma_core_mips_flash_detect(struct bcma_drv_mips *mcore)
741 + struct bcma_bus *bus = mcore->core->bus;
743 + switch (bus->drv_cc.capabilities & BCMA_CC_CAP_FLASHT) {
744 + case BCMA_CC_FLASHT_STSER:
745 + case BCMA_CC_FLASHT_ATSER:
746 + pr_err("Serial flash not supported.\n");
748 + case BCMA_CC_FLASHT_PARA:
749 + pr_info("found parallel flash.\n");
750 + bus->drv_cc.pflash.window = 0x1c000000;
751 + bus->drv_cc.pflash.window_size = 0x02000000;
753 + if ((bcma_read32(bus->drv_cc.core, BCMA_CC_FLASH_CFG) &
754 + BCMA_CC_FLASH_CFG_DS) == 0)
755 + bus->drv_cc.pflash.buswidth = 1;
757 + bus->drv_cc.pflash.buswidth = 2;
760 + pr_err("flash not supported.\n");
764 +void bcma_core_mips_init(struct bcma_drv_mips *mcore)
766 + struct bcma_bus *bus;
767 + struct bcma_device *core;
768 + bus = mcore->core->bus;
770 + pr_info("Initializing MIPS core...\n");
772 + if (!mcore->setup_done)
773 + mcore->assigned_irqs = 1;
775 + /* Assign IRQs to all cores on the bus */
776 + list_for_each_entry_reverse(core, &bus->cores, list) {
781 + mips_irq = bcma_core_mips_irq(core);
785 + core->irq = mips_irq + 2;
788 + switch (core->id.id) {
789 + case BCMA_CORE_PCI:
790 + case BCMA_CORE_PCIE:
791 + case BCMA_CORE_ETHERNET:
792 + case BCMA_CORE_ETHERNET_GBIT:
793 + case BCMA_CORE_MAC_GBIT:
794 + case BCMA_CORE_80211:
795 + case BCMA_CORE_USB20_HOST:
796 + /* These devices get their own IRQ line if available,
797 + * the rest goes on IRQ0
799 + if (mcore->assigned_irqs <= 4)
800 + bcma_core_mips_set_irq(core,
801 + mcore->assigned_irqs++);
805 + pr_info("IRQ reconfiguration done\n");
806 + bcma_core_mips_dump_irq(bus);
808 + if (mcore->setup_done)
811 + bcma_chipco_serial_init(&bus->drv_cc);
812 + bcma_core_mips_flash_detect(mcore);
813 + mcore->setup_done = true;
815 --- a/drivers/bcma/driver_pci.c
816 +++ b/drivers/bcma/driver_pci.c
820 * Copyright 2005, Broadcom Corporation
821 - * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
822 + * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
824 * Licensed under the GNU/GPL. See COPYING for details.
826 @@ -157,7 +157,81 @@ static void bcma_pcicore_serdes_workarou
828 **************************************************/
830 -void bcma_core_pci_init(struct bcma_drv_pci *pc)
831 +static void bcma_core_pci_clientmode_init(struct bcma_drv_pci *pc)
833 bcma_pcicore_serdes_workaround(pc);
836 +static bool bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc)
838 + struct bcma_bus *bus = pc->core->bus;
841 + chipid_top = (bus->chipinfo.id & 0xFF00);
842 + if (chipid_top != 0x4700 &&
843 + chipid_top != 0x5300)
846 +#ifdef CONFIG_SSB_DRIVER_PCICORE
847 + if (bus->sprom.boardflags_lo & SSB_BFL_NOPCI)
849 +#endif /* CONFIG_SSB_DRIVER_PCICORE */
852 + /* TODO: on BCMA we use address from EROM instead of magic formula */
854 + return !mips_busprobe32(tmp, (bus->mmio +
855 + (pc->core->core_index * BCMA_CORE_SIZE)));
861 +void bcma_core_pci_init(struct bcma_drv_pci *pc)
863 + if (pc->setup_done)
866 + if (bcma_core_pci_is_in_hostmode(pc)) {
867 +#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
868 + bcma_core_pci_hostmode_init(pc);
870 + pr_err("Driver compiled without support for hostmode PCI\n");
871 +#endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */
873 + bcma_core_pci_clientmode_init(pc);
876 + pc->setup_done = true;
879 +int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core,
882 + struct pci_dev *pdev = pc->core->bus->host_pci;
886 + if (core->bus->hosttype != BCMA_HOSTTYPE_PCI) {
887 + /* This bcma device is not on a PCI host-bus. So the IRQs are
888 + * not routed through the PCI core.
889 + * So we must not enable routing through the PCI core. */
893 + err = pci_read_config_dword(pdev, BCMA_PCI_IRQMASK, &tmp);
897 + coremask = BIT(core->core_index) << 8;
903 + err = pci_write_config_dword(pdev, BCMA_PCI_IRQMASK, tmp);
908 +EXPORT_SYMBOL_GPL(bcma_core_pci_irq_ctl);
910 +++ b/drivers/bcma/driver_pci_host.c
913 + * Broadcom specific AMBA
914 + * PCI Core in hostmode
916 + * Licensed under the GNU/GPL. See COPYING for details.
919 +#include "bcma_private.h"
920 +#include <linux/bcma/bcma.h>
922 +void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc)
924 + pr_err("No support for PCI core in hostmode yet\n");
926 --- a/drivers/bcma/host_pci.c
927 +++ b/drivers/bcma/host_pci.c
929 #include <linux/slab.h>
930 #include <linux/bcma/bcma.h>
931 #include <linux/pci.h>
932 +#include <linux/module.h>
934 static void bcma_host_pci_switch_core(struct bcma_device *core)
936 @@ -20,50 +21,108 @@ static void bcma_host_pci_switch_core(st
937 pr_debug("Switched to core: 0x%X\n", core->id.id);
940 -static u8 bcma_host_pci_read8(struct bcma_device *core, u16 offset)
942 +/* Provides access to the requested core. Returns base offset that has to be
943 + * used. It makes use of fixed windows when possible. */
944 +static u16 bcma_host_pci_provide_access_to_core(struct bcma_device *core)
946 + switch (core->id.id) {
947 + case BCMA_CORE_CHIPCOMMON:
948 + return 3 * BCMA_CORE_SIZE;
949 + case BCMA_CORE_PCIE:
950 + return 2 * BCMA_CORE_SIZE;
953 if (core->bus->mapped_core != core)
954 bcma_host_pci_switch_core(core);
958 +static u8 bcma_host_pci_read8(struct bcma_device *core, u16 offset)
960 + offset += bcma_host_pci_provide_access_to_core(core);
961 return ioread8(core->bus->mmio + offset);
964 static u16 bcma_host_pci_read16(struct bcma_device *core, u16 offset)
966 - if (core->bus->mapped_core != core)
967 - bcma_host_pci_switch_core(core);
968 + offset += bcma_host_pci_provide_access_to_core(core);
969 return ioread16(core->bus->mmio + offset);
972 static u32 bcma_host_pci_read32(struct bcma_device *core, u16 offset)
974 - if (core->bus->mapped_core != core)
975 - bcma_host_pci_switch_core(core);
976 + offset += bcma_host_pci_provide_access_to_core(core);
977 return ioread32(core->bus->mmio + offset);
980 static void bcma_host_pci_write8(struct bcma_device *core, u16 offset,
983 - if (core->bus->mapped_core != core)
984 - bcma_host_pci_switch_core(core);
985 + offset += bcma_host_pci_provide_access_to_core(core);
986 iowrite8(value, core->bus->mmio + offset);
989 static void bcma_host_pci_write16(struct bcma_device *core, u16 offset,
992 - if (core->bus->mapped_core != core)
993 - bcma_host_pci_switch_core(core);
994 + offset += bcma_host_pci_provide_access_to_core(core);
995 iowrite16(value, core->bus->mmio + offset);
998 static void bcma_host_pci_write32(struct bcma_device *core, u16 offset,
1001 + offset += bcma_host_pci_provide_access_to_core(core);
1002 + iowrite32(value, core->bus->mmio + offset);
1005 +#ifdef CONFIG_BCMA_BLOCKIO
1006 +void bcma_host_pci_block_read(struct bcma_device *core, void *buffer,
1007 + size_t count, u16 offset, u8 reg_width)
1009 + void __iomem *addr = core->bus->mmio + offset;
1010 if (core->bus->mapped_core != core)
1011 bcma_host_pci_switch_core(core);
1012 - iowrite32(value, core->bus->mmio + offset);
1013 + switch (reg_width) {
1015 + ioread8_rep(addr, buffer, count);
1018 + WARN_ON(count & 1);
1019 + ioread16_rep(addr, buffer, count >> 1);
1022 + WARN_ON(count & 3);
1023 + ioread32_rep(addr, buffer, count >> 2);
1030 +void bcma_host_pci_block_write(struct bcma_device *core, const void *buffer,
1031 + size_t count, u16 offset, u8 reg_width)
1033 + void __iomem *addr = core->bus->mmio + offset;
1034 + if (core->bus->mapped_core != core)
1035 + bcma_host_pci_switch_core(core);
1036 + switch (reg_width) {
1038 + iowrite8_rep(addr, buffer, count);
1041 + WARN_ON(count & 1);
1042 + iowrite16_rep(addr, buffer, count >> 1);
1045 + WARN_ON(count & 3);
1046 + iowrite32_rep(addr, buffer, count >> 2);
1054 static u32 bcma_host_pci_aread32(struct bcma_device *core, u16 offset)
1056 @@ -87,6 +146,10 @@ const struct bcma_host_ops bcma_host_pci
1057 .write8 = bcma_host_pci_write8,
1058 .write16 = bcma_host_pci_write16,
1059 .write32 = bcma_host_pci_write32,
1060 +#ifdef CONFIG_BCMA_BLOCKIO
1061 + .block_read = bcma_host_pci_block_read,
1062 + .block_write = bcma_host_pci_block_write,
1064 .aread32 = bcma_host_pci_aread32,
1065 .awrite32 = bcma_host_pci_awrite32,
1067 @@ -171,10 +234,46 @@ static void bcma_host_pci_remove(struct
1068 pci_set_drvdata(dev, NULL);
1072 +static int bcma_host_pci_suspend(struct pci_dev *dev, pm_message_t state)
1074 + /* Host specific */
1075 + pci_save_state(dev);
1076 + pci_disable_device(dev);
1077 + pci_set_power_state(dev, pci_choose_state(dev, state));
1082 +static int bcma_host_pci_resume(struct pci_dev *dev)
1084 + struct bcma_bus *bus = pci_get_drvdata(dev);
1087 + /* Host specific */
1088 + pci_set_power_state(dev, 0);
1089 + err = pci_enable_device(dev);
1092 + pci_restore_state(dev);
1094 + /* Bus specific */
1095 + err = bcma_bus_resume(bus);
1101 +#else /* CONFIG_PM */
1102 +# define bcma_host_pci_suspend NULL
1103 +# define bcma_host_pci_resume NULL
1104 +#endif /* CONFIG_PM */
1106 static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = {
1107 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) },
1108 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) },
1109 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4353) },
1110 + { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4357) },
1111 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) },
1114 @@ -185,6 +284,8 @@ static struct pci_driver bcma_pci_bridge
1115 .id_table = bcma_pci_bridge_tbl,
1116 .probe = bcma_host_pci_probe,
1117 .remove = bcma_host_pci_remove,
1118 + .suspend = bcma_host_pci_suspend,
1119 + .resume = bcma_host_pci_resume,
1122 int __init bcma_host_pci_init(void)
1124 +++ b/drivers/bcma/host_soc.c
1127 + * Broadcom specific AMBA
1128 + * System on Chip (SoC) Host
1130 + * Licensed under the GNU/GPL. See COPYING for details.
1133 +#include "bcma_private.h"
1135 +#include <linux/bcma/bcma.h>
1136 +#include <linux/bcma/bcma_soc.h>
1138 +static u8 bcma_host_soc_read8(struct bcma_device *core, u16 offset)
1140 + return readb(core->io_addr + offset);
1143 +static u16 bcma_host_soc_read16(struct bcma_device *core, u16 offset)
1145 + return readw(core->io_addr + offset);
1148 +static u32 bcma_host_soc_read32(struct bcma_device *core, u16 offset)
1150 + return readl(core->io_addr + offset);
1153 +static void bcma_host_soc_write8(struct bcma_device *core, u16 offset,
1156 + writeb(value, core->io_addr + offset);
1159 +static void bcma_host_soc_write16(struct bcma_device *core, u16 offset,
1162 + writew(value, core->io_addr + offset);
1165 +static void bcma_host_soc_write32(struct bcma_device *core, u16 offset,
1168 + writel(value, core->io_addr + offset);
1171 +#ifdef CONFIG_BCMA_BLOCKIO
1172 +static void bcma_host_soc_block_read(struct bcma_device *core, void *buffer,
1173 + size_t count, u16 offset, u8 reg_width)
1175 + void __iomem *addr = core->io_addr + offset;
1177 + switch (reg_width) {
1178 + case sizeof(u8): {
1182 + *buf = __raw_readb(addr);
1188 + case sizeof(u16): {
1189 + __le16 *buf = buffer;
1191 + WARN_ON(count & 1);
1193 + *buf = (__force __le16)__raw_readw(addr);
1199 + case sizeof(u32): {
1200 + __le32 *buf = buffer;
1202 + WARN_ON(count & 3);
1204 + *buf = (__force __le32)__raw_readl(addr);
1215 +static void bcma_host_soc_block_write(struct bcma_device *core,
1216 + const void *buffer,
1217 + size_t count, u16 offset, u8 reg_width)
1219 + void __iomem *addr = core->io_addr + offset;
1221 + switch (reg_width) {
1222 + case sizeof(u8): {
1223 + const u8 *buf = buffer;
1226 + __raw_writeb(*buf, addr);
1232 + case sizeof(u16): {
1233 + const __le16 *buf = buffer;
1235 + WARN_ON(count & 1);
1237 + __raw_writew((__force u16)(*buf), addr);
1243 + case sizeof(u32): {
1244 + const __le32 *buf = buffer;
1246 + WARN_ON(count & 3);
1248 + __raw_writel((__force u32)(*buf), addr);
1258 +#endif /* CONFIG_BCMA_BLOCKIO */
1260 +static u32 bcma_host_soc_aread32(struct bcma_device *core, u16 offset)
1262 + return readl(core->io_wrap + offset);
1265 +static void bcma_host_soc_awrite32(struct bcma_device *core, u16 offset,
1268 + writel(value, core->io_wrap + offset);
1271 +const struct bcma_host_ops bcma_host_soc_ops = {
1272 + .read8 = bcma_host_soc_read8,
1273 + .read16 = bcma_host_soc_read16,
1274 + .read32 = bcma_host_soc_read32,
1275 + .write8 = bcma_host_soc_write8,
1276 + .write16 = bcma_host_soc_write16,
1277 + .write32 = bcma_host_soc_write32,
1278 +#ifdef CONFIG_BCMA_BLOCKIO
1279 + .block_read = bcma_host_soc_block_read,
1280 + .block_write = bcma_host_soc_block_write,
1282 + .aread32 = bcma_host_soc_aread32,
1283 + .awrite32 = bcma_host_soc_awrite32,
1286 +int __init bcma_host_soc_register(struct bcma_soc *soc)
1288 + struct bcma_bus *bus = &soc->bus;
1291 + /* iomap only first core. We have to read some register on this core
1292 + * to scan the bus.
1294 + bus->mmio = ioremap_nocache(BCMA_ADDR_BASE, BCMA_CORE_SIZE * 1);
1298 + /* Host specific */
1299 + bus->hosttype = BCMA_HOSTTYPE_SOC;
1300 + bus->ops = &bcma_host_soc_ops;
1303 + err = bcma_bus_early_register(bus, &soc->core_cc, &soc->core_mips);
1305 + iounmap(bus->mmio);
1309 --- a/drivers/bcma/main.c
1310 +++ b/drivers/bcma/main.c
1314 #include "bcma_private.h"
1315 +#include <linux/module.h>
1316 #include <linux/bcma/bcma.h>
1317 +#include <linux/slab.h>
1319 MODULE_DESCRIPTION("Broadcom's specific AMBA driver");
1320 MODULE_LICENSE("GPL");
1321 @@ -14,6 +16,7 @@ MODULE_LICENSE("GPL");
1322 static int bcma_bus_match(struct device *dev, struct device_driver *drv);
1323 static int bcma_device_probe(struct device *dev);
1324 static int bcma_device_remove(struct device *dev);
1325 +static int bcma_device_uevent(struct device *dev, struct kobj_uevent_env *env);
1327 static ssize_t manuf_show(struct device *dev, struct device_attribute *attr, char *buf)
1329 @@ -48,6 +51,7 @@ static struct bus_type bcma_bus_type = {
1330 .match = bcma_bus_match,
1331 .probe = bcma_device_probe,
1332 .remove = bcma_device_remove,
1333 + .uevent = bcma_device_uevent,
1334 .dev_attrs = bcma_device_attrs,
1337 @@ -65,6 +69,10 @@ static struct bcma_device *bcma_find_cor
1338 static void bcma_release_core_dev(struct device *dev)
1340 struct bcma_device *core = container_of(dev, struct bcma_device, dev);
1341 + if (core->io_addr)
1342 + iounmap(core->io_addr);
1343 + if (core->io_wrap)
1344 + iounmap(core->io_wrap);
1348 @@ -79,6 +87,7 @@ static int bcma_register_cores(struct bc
1349 case BCMA_CORE_CHIPCOMMON:
1351 case BCMA_CORE_PCIE:
1352 + case BCMA_CORE_MIPS_74K:
1356 @@ -89,8 +98,13 @@ static int bcma_register_cores(struct bc
1357 switch (bus->hosttype) {
1358 case BCMA_HOSTTYPE_PCI:
1359 core->dev.parent = &bus->host_pci->dev;
1360 + core->dma_dev = &bus->host_pci->dev;
1361 + core->irq = bus->host_pci->irq;
1363 + case BCMA_HOSTTYPE_SOC:
1364 + core->dev.dma_mask = &core->dev.coherent_dma_mask;
1365 + core->dma_dev = &core->dev;
1367 - case BCMA_HOSTTYPE_NONE:
1368 case BCMA_HOSTTYPE_SDIO:
1371 @@ -137,6 +151,13 @@ int bcma_bus_register(struct bcma_bus *b
1372 bcma_core_chipcommon_init(&bus->drv_cc);
1375 + /* Init MIPS core */
1376 + core = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
1378 + bus->drv_mips.core = core;
1379 + bcma_core_mips_init(&bus->drv_mips);
1382 /* Init PCIE core */
1383 core = bcma_find_core(bus, BCMA_CORE_PCIE);
1385 @@ -144,6 +165,15 @@ int bcma_bus_register(struct bcma_bus *b
1386 bcma_core_pci_init(&bus->drv_pci);
1389 + /* Try to get SPROM */
1390 + err = bcma_sprom_get(bus);
1391 + if (err == -ENOENT) {
1392 + pr_err("No SPROM available\n");
1394 + pr_err("Failed to get SPROM: %d\n", err);
1398 /* Register found cores */
1399 bcma_register_cores(bus);
1401 @@ -151,13 +181,80 @@ int bcma_bus_register(struct bcma_bus *b
1405 -EXPORT_SYMBOL_GPL(bcma_bus_register);
1407 void bcma_bus_unregister(struct bcma_bus *bus)
1409 bcma_unregister_cores(bus);
1411 -EXPORT_SYMBOL_GPL(bcma_bus_unregister);
1413 +int __init bcma_bus_early_register(struct bcma_bus *bus,
1414 + struct bcma_device *core_cc,
1415 + struct bcma_device *core_mips)
1418 + struct bcma_device *core;
1419 + struct bcma_device_id match;
1421 + bcma_init_bus(bus);
1423 + match.manuf = BCMA_MANUF_BCM;
1424 + match.id = BCMA_CORE_CHIPCOMMON;
1425 + match.class = BCMA_CL_SIM;
1426 + match.rev = BCMA_ANY_REV;
1428 + /* Scan for chip common core */
1429 + err = bcma_bus_scan_early(bus, &match, core_cc);
1431 + pr_err("Failed to scan for common core: %d\n", err);
1435 + match.manuf = BCMA_MANUF_MIPS;
1436 + match.id = BCMA_CORE_MIPS_74K;
1437 + match.class = BCMA_CL_SIM;
1438 + match.rev = BCMA_ANY_REV;
1440 + /* Scan for mips core */
1441 + err = bcma_bus_scan_early(bus, &match, core_mips);
1443 + pr_err("Failed to scan for mips core: %d\n", err);
1447 + /* Init CC core */
1448 + core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON);
1450 + bus->drv_cc.core = core;
1451 + bcma_core_chipcommon_init(&bus->drv_cc);
1454 + /* Init MIPS core */
1455 + core = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
1457 + bus->drv_mips.core = core;
1458 + bcma_core_mips_init(&bus->drv_mips);
1461 + pr_info("Early bus registered\n");
1467 +int bcma_bus_resume(struct bcma_bus *bus)
1469 + struct bcma_device *core;
1471 + /* Init CC core */
1472 + core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON);
1474 + bus->drv_cc.setup_done = false;
1475 + bcma_core_chipcommon_init(&bus->drv_cc);
1482 int __bcma_driver_register(struct bcma_driver *drv, struct module *owner)
1484 @@ -217,6 +314,16 @@ static int bcma_device_remove(struct dev
1488 +static int bcma_device_uevent(struct device *dev, struct kobj_uevent_env *env)
1490 + struct bcma_device *core = container_of(dev, struct bcma_device, dev);
1492 + return add_uevent_var(env,
1493 + "MODALIAS=bcma:m%04Xid%04Xrev%02Xcl%02X",
1494 + core->id.manuf, core->id.id,
1495 + core->id.rev, core->id.class);
1498 static int __init bcma_modinit(void)
1501 --- a/drivers/bcma/scan.c
1502 +++ b/drivers/bcma/scan.c
1503 @@ -200,18 +200,162 @@ static s32 bcma_erom_get_addr_desc(struc
1507 -int bcma_bus_scan(struct bcma_bus *bus)
1508 +static struct bcma_device *bcma_find_core_by_index(struct bcma_bus *bus,
1512 - u32 __iomem *eromptr, *eromend;
1513 + struct bcma_device *core;
1515 + list_for_each_entry(core, &bus->cores, list) {
1516 + if (core->core_index == index)
1522 +static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
1523 + struct bcma_device_id *match, int core_num,
1524 + struct bcma_device *core)
1529 u8 ports[2], wrappers[2];
1532 + cia = bcma_erom_get_ci(bus, eromptr);
1534 + bcma_erom_push_ent(eromptr);
1535 + if (bcma_erom_is_end(bus, eromptr))
1539 + cib = bcma_erom_get_ci(bus, eromptr);
1544 + core->id.class = (cia & SCAN_CIA_CLASS) >> SCAN_CIA_CLASS_SHIFT;
1545 + core->id.id = (cia & SCAN_CIA_ID) >> SCAN_CIA_ID_SHIFT;
1546 + core->id.manuf = (cia & SCAN_CIA_MANUF) >> SCAN_CIA_MANUF_SHIFT;
1547 + ports[0] = (cib & SCAN_CIB_NMP) >> SCAN_CIB_NMP_SHIFT;
1548 + ports[1] = (cib & SCAN_CIB_NSP) >> SCAN_CIB_NSP_SHIFT;
1549 + wrappers[0] = (cib & SCAN_CIB_NMW) >> SCAN_CIB_NMW_SHIFT;
1550 + wrappers[1] = (cib & SCAN_CIB_NSW) >> SCAN_CIB_NSW_SHIFT;
1551 + core->id.rev = (cib & SCAN_CIB_REV) >> SCAN_CIB_REV_SHIFT;
1553 + if (((core->id.manuf == BCMA_MANUF_ARM) &&
1554 + (core->id.id == 0xFFF)) ||
1555 + (ports[1] == 0)) {
1556 + bcma_erom_skip_component(bus, eromptr);
1560 + /* check if component is a core at all */
1561 + if (wrappers[0] + wrappers[1] == 0) {
1562 + /* we could save addrl of the router
1563 + if (cid == BCMA_CORE_OOB_ROUTER)
1565 + bcma_erom_skip_component(bus, eromptr);
1569 + if (bcma_erom_is_bridge(bus, eromptr)) {
1570 + bcma_erom_skip_component(bus, eromptr);
1574 + if (bcma_find_core_by_index(bus, core_num)) {
1575 + bcma_erom_skip_component(bus, eromptr);
1579 + if (match && ((match->manuf != BCMA_ANY_MANUF &&
1580 + match->manuf != core->id.manuf) ||
1581 + (match->id != BCMA_ANY_ID && match->id != core->id.id) ||
1582 + (match->rev != BCMA_ANY_REV && match->rev != core->id.rev) ||
1583 + (match->class != BCMA_ANY_CLASS && match->class != core->id.class)
1585 + bcma_erom_skip_component(bus, eromptr);
1589 + /* get & parse master ports */
1590 + for (i = 0; i < ports[0]; i++) {
1591 + s32 mst_port_d = bcma_erom_get_mst_port(bus, eromptr);
1592 + if (mst_port_d < 0)
1596 + /* get & parse slave ports */
1597 + for (i = 0; i < ports[1]; i++) {
1598 + for (j = 0; ; j++) {
1599 + tmp = bcma_erom_get_addr_desc(bus, eromptr,
1600 + SCAN_ADDR_TYPE_SLAVE, i);
1602 + /* no more entries for port _i_ */
1603 + /* pr_debug("erom: slave port %d "
1604 + * "has %d descriptors\n", i, j); */
1607 + if (i == 0 && j == 0)
1613 + /* get & parse master wrappers */
1614 + for (i = 0; i < wrappers[0]; i++) {
1615 + for (j = 0; ; j++) {
1616 + tmp = bcma_erom_get_addr_desc(bus, eromptr,
1617 + SCAN_ADDR_TYPE_MWRAP, i);
1619 + /* no more entries for port _i_ */
1620 + /* pr_debug("erom: master wrapper %d "
1621 + * "has %d descriptors\n", i, j); */
1624 + if (i == 0 && j == 0)
1630 + /* get & parse slave wrappers */
1631 + for (i = 0; i < wrappers[1]; i++) {
1632 + u8 hack = (ports[1] == 1) ? 0 : 1;
1633 + for (j = 0; ; j++) {
1634 + tmp = bcma_erom_get_addr_desc(bus, eromptr,
1635 + SCAN_ADDR_TYPE_SWRAP, i + hack);
1637 + /* no more entries for port _i_ */
1638 + /* pr_debug("erom: master wrapper %d "
1639 + * has %d descriptors\n", i, j); */
1642 + if (wrappers[0] == 0 && !i && !j)
1647 + if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
1648 + core->io_addr = ioremap_nocache(core->addr, BCMA_CORE_SIZE);
1649 + if (!core->io_addr)
1651 + core->io_wrap = ioremap_nocache(core->wrap, BCMA_CORE_SIZE);
1652 + if (!core->io_wrap) {
1653 + iounmap(core->io_addr);
1660 +void bcma_init_bus(struct bcma_bus *bus)
1666 + if (bus->init_done)
1669 INIT_LIST_HEAD(&bus->cores);
1671 @@ -222,9 +366,27 @@ int bcma_bus_scan(struct bcma_bus *bus)
1672 bus->chipinfo.id = (tmp & BCMA_CC_ID_ID) >> BCMA_CC_ID_ID_SHIFT;
1673 bus->chipinfo.rev = (tmp & BCMA_CC_ID_REV) >> BCMA_CC_ID_REV_SHIFT;
1674 bus->chipinfo.pkg = (tmp & BCMA_CC_ID_PKG) >> BCMA_CC_ID_PKG_SHIFT;
1675 + bus->init_done = true;
1678 +int bcma_bus_scan(struct bcma_bus *bus)
1681 + u32 __iomem *eromptr, *eromend;
1683 + int err, core_num = 0;
1685 + bcma_init_bus(bus);
1687 erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM);
1688 - eromptr = bus->mmio;
1689 + if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
1690 + eromptr = ioremap_nocache(erombase, BCMA_CORE_SIZE);
1694 + eromptr = bus->mmio;
1697 eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32);
1699 bcma_scan_switch_core(bus, erombase);
1700 @@ -236,125 +398,89 @@ int bcma_bus_scan(struct bcma_bus *bus)
1701 INIT_LIST_HEAD(&core->list);
1705 - cia = bcma_erom_get_ci(bus, &eromptr);
1707 - bcma_erom_push_ent(&eromptr);
1708 - if (bcma_erom_is_end(bus, &eromptr))
1713 - cib = bcma_erom_get_ci(bus, &eromptr);
1720 - core->id.class = (cia & SCAN_CIA_CLASS) >> SCAN_CIA_CLASS_SHIFT;
1721 - core->id.id = (cia & SCAN_CIA_ID) >> SCAN_CIA_ID_SHIFT;
1722 - core->id.manuf = (cia & SCAN_CIA_MANUF) >> SCAN_CIA_MANUF_SHIFT;
1723 - ports[0] = (cib & SCAN_CIB_NMP) >> SCAN_CIB_NMP_SHIFT;
1724 - ports[1] = (cib & SCAN_CIB_NSP) >> SCAN_CIB_NSP_SHIFT;
1725 - wrappers[0] = (cib & SCAN_CIB_NMW) >> SCAN_CIB_NMW_SHIFT;
1726 - wrappers[1] = (cib & SCAN_CIB_NSW) >> SCAN_CIB_NSW_SHIFT;
1727 - core->id.rev = (cib & SCAN_CIB_REV) >> SCAN_CIB_REV_SHIFT;
1729 - if (((core->id.manuf == BCMA_MANUF_ARM) &&
1730 - (core->id.id == 0xFFF)) ||
1731 - (ports[1] == 0)) {
1732 - bcma_erom_skip_component(bus, &eromptr);
1733 + err = bcma_get_next_core(bus, &eromptr, NULL, core_num, core);
1734 + if (err == -ENODEV) {
1739 - /* check if component is a core at all */
1740 - if (wrappers[0] + wrappers[1] == 0) {
1741 - /* we could save addrl of the router
1742 - if (cid == BCMA_CORE_OOB_ROUTER)
1744 - bcma_erom_skip_component(bus, &eromptr);
1745 + } else if (err == -ENXIO)
1748 + else if (err == -ESPIPE)
1753 - if (bcma_erom_is_bridge(bus, &eromptr)) {
1754 - bcma_erom_skip_component(bus, &eromptr);
1757 + core->core_index = core_num++;
1760 - /* get & parse master ports */
1761 - for (i = 0; i < ports[0]; i++) {
1762 - u32 mst_port_d = bcma_erom_get_mst_port(bus, &eromptr);
1763 - if (mst_port_d < 0) {
1768 + pr_info("Core %d found: %s "
1769 + "(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
1770 + core->core_index, bcma_device_name(&core->id),
1771 + core->id.manuf, core->id.id, core->id.rev,
1774 - /* get & parse slave ports */
1775 - for (i = 0; i < ports[1]; i++) {
1776 - for (j = 0; ; j++) {
1777 - tmp = bcma_erom_get_addr_desc(bus, &eromptr,
1778 - SCAN_ADDR_TYPE_SLAVE, i);
1780 - /* no more entries for port _i_ */
1781 - /* pr_debug("erom: slave port %d "
1782 - * "has %d descriptors\n", i, j); */
1785 - if (i == 0 && j == 0)
1790 + list_add(&core->list, &bus->cores);
1793 - /* get & parse master wrappers */
1794 - for (i = 0; i < wrappers[0]; i++) {
1795 - for (j = 0; ; j++) {
1796 - tmp = bcma_erom_get_addr_desc(bus, &eromptr,
1797 - SCAN_ADDR_TYPE_MWRAP, i);
1799 - /* no more entries for port _i_ */
1800 - /* pr_debug("erom: master wrapper %d "
1801 - * "has %d descriptors\n", i, j); */
1804 - if (i == 0 && j == 0)
1809 + if (bus->hosttype == BCMA_HOSTTYPE_SOC)
1812 - /* get & parse slave wrappers */
1813 - for (i = 0; i < wrappers[1]; i++) {
1814 - u8 hack = (ports[1] == 1) ? 0 : 1;
1815 - for (j = 0; ; j++) {
1816 - tmp = bcma_erom_get_addr_desc(bus, &eromptr,
1817 - SCAN_ADDR_TYPE_SWRAP, i + hack);
1819 - /* no more entries for port _i_ */
1820 - /* pr_debug("erom: master wrapper %d "
1821 - * has %d descriptors\n", i, j); */
1824 - if (wrappers[0] == 0 && !i && !j)
1832 +int __init bcma_bus_scan_early(struct bcma_bus *bus,
1833 + struct bcma_device_id *match,
1834 + struct bcma_device *core)
1837 + u32 __iomem *eromptr, *eromend;
1839 + int err = -ENODEV;
1842 + erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM);
1843 + if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
1844 + eromptr = ioremap_nocache(erombase, BCMA_CORE_SIZE);
1848 + eromptr = bus->mmio;
1851 + eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32);
1853 + bcma_scan_switch_core(bus, erombase);
1855 + while (eromptr < eromend) {
1856 + memset(core, 0, sizeof(*core));
1857 + INIT_LIST_HEAD(&core->list);
1860 + err = bcma_get_next_core(bus, &eromptr, match, core_num, core);
1861 + if (err == -ENODEV) {
1864 + } else if (err == -ENXIO)
1866 + else if (err == -ESPIPE)
1871 + core->core_index = core_num++;
1873 pr_info("Core %d found: %s "
1874 "(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
1875 - bus->nr_cores, bcma_device_name(&core->id),
1876 + core->core_index, bcma_device_name(&core->id),
1877 core->id.manuf, core->id.id, core->id.rev,
1880 - core->core_index = bus->nr_cores++;
1881 list_add(&core->list, &bus->cores);
1890 + if (bus->hosttype == BCMA_HOSTTYPE_SOC)
1896 +++ b/drivers/bcma/sprom.c
1899 + * Broadcom specific AMBA
1902 + * Licensed under the GNU/GPL. See COPYING for details.
1905 +#include "bcma_private.h"
1907 +#include <linux/bcma/bcma.h>
1908 +#include <linux/bcma/bcma_regs.h>
1909 +#include <linux/pci.h>
1910 +#include <linux/io.h>
1911 +#include <linux/dma-mapping.h>
1912 +#include <linux/slab.h>
1914 +#define SPOFF(offset) ((offset) / sizeof(u16))
1916 +/**************************************************
1918 + **************************************************/
1920 +static void bcma_sprom_read(struct bcma_bus *bus, u16 offset, u16 *sprom)
1923 + for (i = 0; i < SSB_SPROMSIZE_WORDS_R4; i++)
1924 + sprom[i] = bcma_read16(bus->drv_cc.core,
1925 + offset + (i * 2));
1928 +/**************************************************
1930 + **************************************************/
1932 +static inline u8 bcma_crc8(u8 crc, u8 data)
1934 + /* Polynomial: x^8 + x^7 + x^6 + x^4 + x^2 + 1 */
1935 + static const u8 t[] = {
1936 + 0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B,
1937 + 0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21,
1938 + 0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF,
1939 + 0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5,
1940 + 0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14,
1941 + 0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E,
1942 + 0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80,
1943 + 0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA,
1944 + 0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95,
1945 + 0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF,
1946 + 0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01,
1947 + 0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B,
1948 + 0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA,
1949 + 0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0,
1950 + 0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E,
1951 + 0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34,
1952 + 0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0,
1953 + 0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A,
1954 + 0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54,
1955 + 0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E,
1956 + 0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF,
1957 + 0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5,
1958 + 0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B,
1959 + 0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61,
1960 + 0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E,
1961 + 0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74,
1962 + 0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA,
1963 + 0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0,
1964 + 0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41,
1965 + 0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B,
1966 + 0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5,
1967 + 0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F,
1969 + return t[crc ^ data];
1972 +static u8 bcma_sprom_crc(const u16 *sprom)
1977 + for (word = 0; word < SSB_SPROMSIZE_WORDS_R4 - 1; word++) {
1978 + crc = bcma_crc8(crc, sprom[word] & 0x00FF);
1979 + crc = bcma_crc8(crc, (sprom[word] & 0xFF00) >> 8);
1981 + crc = bcma_crc8(crc, sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & 0x00FF);
1987 +static int bcma_sprom_check_crc(const u16 *sprom)
1993 + crc = bcma_sprom_crc(sprom);
1994 + tmp = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & SSB_SPROM_REVISION_CRC;
1995 + expected_crc = tmp >> SSB_SPROM_REVISION_CRC_SHIFT;
1996 + if (crc != expected_crc)
2002 +static int bcma_sprom_valid(const u16 *sprom)
2007 + err = bcma_sprom_check_crc(sprom);
2011 + revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & SSB_SPROM_REVISION_REV;
2012 + if (revision != 8 && revision != 9) {
2013 + pr_err("Unsupported SPROM revision: %d\n", revision);
2020 +/**************************************************
2021 + * SPROM extraction.
2022 + **************************************************/
2024 +static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
2029 + bus->sprom.revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] &
2030 + SSB_SPROM_REVISION_REV;
2032 + for (i = 0; i < 3; i++) {
2033 + v = sprom[SPOFF(SSB_SPROM8_IL0MAC) + i];
2034 + *(((__be16 *)bus->sprom.il0mac) + i) = cpu_to_be16(v);
2037 + bus->sprom.board_rev = sprom[SPOFF(SSB_SPROM8_BOARDREV)];
2039 + bus->sprom.txpid2g[0] = (sprom[SPOFF(SSB_SPROM4_TXPID2G01)] &
2040 + SSB_SPROM4_TXPID2G0) >> SSB_SPROM4_TXPID2G0_SHIFT;
2041 + bus->sprom.txpid2g[1] = (sprom[SPOFF(SSB_SPROM4_TXPID2G01)] &
2042 + SSB_SPROM4_TXPID2G1) >> SSB_SPROM4_TXPID2G1_SHIFT;
2043 + bus->sprom.txpid2g[2] = (sprom[SPOFF(SSB_SPROM4_TXPID2G23)] &
2044 + SSB_SPROM4_TXPID2G2) >> SSB_SPROM4_TXPID2G2_SHIFT;
2045 + bus->sprom.txpid2g[3] = (sprom[SPOFF(SSB_SPROM4_TXPID2G23)] &
2046 + SSB_SPROM4_TXPID2G3) >> SSB_SPROM4_TXPID2G3_SHIFT;
2048 + bus->sprom.txpid5gl[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL01)] &
2049 + SSB_SPROM4_TXPID5GL0) >> SSB_SPROM4_TXPID5GL0_SHIFT;
2050 + bus->sprom.txpid5gl[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL01)] &
2051 + SSB_SPROM4_TXPID5GL1) >> SSB_SPROM4_TXPID5GL1_SHIFT;
2052 + bus->sprom.txpid5gl[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL23)] &
2053 + SSB_SPROM4_TXPID5GL2) >> SSB_SPROM4_TXPID5GL2_SHIFT;
2054 + bus->sprom.txpid5gl[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL23)] &
2055 + SSB_SPROM4_TXPID5GL3) >> SSB_SPROM4_TXPID5GL3_SHIFT;
2057 + bus->sprom.txpid5g[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5G01)] &
2058 + SSB_SPROM4_TXPID5G0) >> SSB_SPROM4_TXPID5G0_SHIFT;
2059 + bus->sprom.txpid5g[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5G01)] &
2060 + SSB_SPROM4_TXPID5G1) >> SSB_SPROM4_TXPID5G1_SHIFT;
2061 + bus->sprom.txpid5g[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5G23)] &
2062 + SSB_SPROM4_TXPID5G2) >> SSB_SPROM4_TXPID5G2_SHIFT;
2063 + bus->sprom.txpid5g[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5G23)] &
2064 + SSB_SPROM4_TXPID5G3) >> SSB_SPROM4_TXPID5G3_SHIFT;
2066 + bus->sprom.txpid5gh[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH01)] &
2067 + SSB_SPROM4_TXPID5GH0) >> SSB_SPROM4_TXPID5GH0_SHIFT;
2068 + bus->sprom.txpid5gh[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH01)] &
2069 + SSB_SPROM4_TXPID5GH1) >> SSB_SPROM4_TXPID5GH1_SHIFT;
2070 + bus->sprom.txpid5gh[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH23)] &
2071 + SSB_SPROM4_TXPID5GH2) >> SSB_SPROM4_TXPID5GH2_SHIFT;
2072 + bus->sprom.txpid5gh[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH23)] &
2073 + SSB_SPROM4_TXPID5GH3) >> SSB_SPROM4_TXPID5GH3_SHIFT;
2075 + bus->sprom.boardflags_lo = sprom[SPOFF(SSB_SPROM8_BFLLO)];
2076 + bus->sprom.boardflags_hi = sprom[SPOFF(SSB_SPROM8_BFLHI)];
2077 + bus->sprom.boardflags2_lo = sprom[SPOFF(SSB_SPROM8_BFL2LO)];
2078 + bus->sprom.boardflags2_hi = sprom[SPOFF(SSB_SPROM8_BFL2HI)];
2080 + bus->sprom.country_code = sprom[SPOFF(SSB_SPROM8_CCODE)];
2082 + bus->sprom.fem.ghz2.tssipos = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
2083 + SSB_SROM8_FEM_TSSIPOS) >> SSB_SROM8_FEM_TSSIPOS_SHIFT;
2084 + bus->sprom.fem.ghz2.extpa_gain = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
2085 + SSB_SROM8_FEM_EXTPA_GAIN) >> SSB_SROM8_FEM_EXTPA_GAIN_SHIFT;
2086 + bus->sprom.fem.ghz2.pdet_range = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
2087 + SSB_SROM8_FEM_PDET_RANGE) >> SSB_SROM8_FEM_PDET_RANGE_SHIFT;
2088 + bus->sprom.fem.ghz2.tr_iso = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
2089 + SSB_SROM8_FEM_TR_ISO) >> SSB_SROM8_FEM_TR_ISO_SHIFT;
2090 + bus->sprom.fem.ghz2.antswlut = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
2091 + SSB_SROM8_FEM_ANTSWLUT) >> SSB_SROM8_FEM_ANTSWLUT_SHIFT;
2093 + bus->sprom.fem.ghz5.tssipos = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
2094 + SSB_SROM8_FEM_TSSIPOS) >> SSB_SROM8_FEM_TSSIPOS_SHIFT;
2095 + bus->sprom.fem.ghz5.extpa_gain = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
2096 + SSB_SROM8_FEM_EXTPA_GAIN) >> SSB_SROM8_FEM_EXTPA_GAIN_SHIFT;
2097 + bus->sprom.fem.ghz5.pdet_range = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
2098 + SSB_SROM8_FEM_PDET_RANGE) >> SSB_SROM8_FEM_PDET_RANGE_SHIFT;
2099 + bus->sprom.fem.ghz5.tr_iso = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
2100 + SSB_SROM8_FEM_TR_ISO) >> SSB_SROM8_FEM_TR_ISO_SHIFT;
2101 + bus->sprom.fem.ghz5.antswlut = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
2102 + SSB_SROM8_FEM_ANTSWLUT) >> SSB_SROM8_FEM_ANTSWLUT_SHIFT;
2105 +int bcma_sprom_get(struct bcma_bus *bus)
2111 + if (!bus->drv_cc.core)
2112 + return -EOPNOTSUPP;
2114 + if (!(bus->drv_cc.capabilities & BCMA_CC_CAP_SPROM))
2117 + sprom = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16),
2122 + if (bus->chipinfo.id == 0x4331)
2123 + bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, false);
2125 + /* Most cards have SPROM moved by additional offset 0x30 (48 dwords).
2126 + * According to brcm80211 this applies to cards with PCIe rev >= 6
2127 + * TODO: understand this condition and use it */
2128 + offset = (bus->chipinfo.id == 0x4331) ? BCMA_CC_SPROM :
2129 + BCMA_CC_SPROM_PCIE6;
2130 + bcma_sprom_read(bus, offset, sprom);
2132 + if (bus->chipinfo.id == 0x4331)
2133 + bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, true);
2135 + err = bcma_sprom_valid(sprom);
2139 + bcma_sprom_extract_r8(bus, sprom);
2145 --- a/include/linux/bcma/bcma.h
2146 +++ b/include/linux/bcma/bcma.h
2149 #include <linux/bcma/bcma_driver_chipcommon.h>
2150 #include <linux/bcma/bcma_driver_pci.h>
2151 +#include <linux/bcma/bcma_driver_mips.h>
2152 +#include <linux/ssb/ssb.h> /* SPROM sharing */
2154 #include "bcma_regs.h"
2156 @@ -13,9 +15,9 @@ struct bcma_device;
2159 enum bcma_hosttype {
2160 - BCMA_HOSTTYPE_NONE,
2163 + BCMA_HOSTTYPE_SOC,
2166 struct bcma_chipinfo {
2167 @@ -24,6 +26,11 @@ struct bcma_chipinfo {
2171 +enum bcma_clkmode {
2172 + BCMA_CLKMODE_FAST,
2173 + BCMA_CLKMODE_DYNAMIC,
2176 struct bcma_host_ops {
2177 u8 (*read8)(struct bcma_device *core, u16 offset);
2178 u16 (*read16)(struct bcma_device *core, u16 offset);
2179 @@ -31,6 +38,12 @@ struct bcma_host_ops {
2180 void (*write8)(struct bcma_device *core, u16 offset, u8 value);
2181 void (*write16)(struct bcma_device *core, u16 offset, u16 value);
2182 void (*write32)(struct bcma_device *core, u16 offset, u32 value);
2183 +#ifdef CONFIG_BCMA_BLOCKIO
2184 + void (*block_read)(struct bcma_device *core, void *buffer,
2185 + size_t count, u16 offset, u8 reg_width);
2186 + void (*block_write)(struct bcma_device *core, const void *buffer,
2187 + size_t count, u16 offset, u8 reg_width);
2190 u32 (*aread32)(struct bcma_device *core, u16 offset);
2191 void (*awrite32)(struct bcma_device *core, u16 offset, u32 value);
2192 @@ -117,6 +130,9 @@ struct bcma_device {
2193 struct bcma_device_id id;
2196 + struct device *dma_dev;
2199 bool dev_registered;
2202 @@ -124,6 +140,9 @@ struct bcma_device {
2206 + void __iomem *io_addr;
2207 + void __iomem *io_wrap;
2210 struct list_head list;
2212 @@ -151,10 +170,9 @@ struct bcma_driver {
2215 int __bcma_driver_register(struct bcma_driver *drv, struct module *owner);
2216 -static inline int bcma_driver_register(struct bcma_driver *drv)
2218 - return __bcma_driver_register(drv, THIS_MODULE);
2220 +#define bcma_driver_register(drv) \
2221 + __bcma_driver_register(drv, THIS_MODULE)
2223 extern void bcma_driver_unregister(struct bcma_driver *drv);
2226 @@ -176,49 +194,105 @@ struct bcma_bus {
2227 struct bcma_device *mapped_core;
2228 struct list_head cores;
2232 struct bcma_drv_cc drv_cc;
2233 struct bcma_drv_pci drv_pci;
2234 + struct bcma_drv_mips drv_mips;
2236 + /* We decided to share SPROM struct with SSB as long as we do not need
2237 + * any hacks for BCMA. This simplifies drivers code. */
2238 + struct ssb_sprom sprom;
2241 -extern inline u32 bcma_read8(struct bcma_device *core, u16 offset)
2242 +static inline u32 bcma_read8(struct bcma_device *core, u16 offset)
2244 return core->bus->ops->read8(core, offset);
2246 -extern inline u32 bcma_read16(struct bcma_device *core, u16 offset)
2247 +static inline u32 bcma_read16(struct bcma_device *core, u16 offset)
2249 return core->bus->ops->read16(core, offset);
2251 -extern inline u32 bcma_read32(struct bcma_device *core, u16 offset)
2252 +static inline u32 bcma_read32(struct bcma_device *core, u16 offset)
2254 return core->bus->ops->read32(core, offset);
2258 void bcma_write8(struct bcma_device *core, u16 offset, u32 value)
2260 core->bus->ops->write8(core, offset, value);
2264 void bcma_write16(struct bcma_device *core, u16 offset, u32 value)
2266 core->bus->ops->write16(core, offset, value);
2270 void bcma_write32(struct bcma_device *core, u16 offset, u32 value)
2272 core->bus->ops->write32(core, offset, value);
2274 -extern inline u32 bcma_aread32(struct bcma_device *core, u16 offset)
2275 +#ifdef CONFIG_BCMA_BLOCKIO
2276 +static inline void bcma_block_read(struct bcma_device *core, void *buffer,
2277 + size_t count, u16 offset, u8 reg_width)
2279 + core->bus->ops->block_read(core, buffer, count, offset, reg_width);
2281 +static inline void bcma_block_write(struct bcma_device *core,
2282 + const void *buffer, size_t count,
2283 + u16 offset, u8 reg_width)
2285 + core->bus->ops->block_write(core, buffer, count, offset, reg_width);
2288 +static inline u32 bcma_aread32(struct bcma_device *core, u16 offset)
2290 return core->bus->ops->aread32(core, offset);
2294 void bcma_awrite32(struct bcma_device *core, u16 offset, u32 value)
2296 core->bus->ops->awrite32(core, offset, value);
2299 +static inline void bcma_mask32(struct bcma_device *cc, u16 offset, u32 mask)
2301 + bcma_write32(cc, offset, bcma_read32(cc, offset) & mask);
2303 +static inline void bcma_set32(struct bcma_device *cc, u16 offset, u32 set)
2305 + bcma_write32(cc, offset, bcma_read32(cc, offset) | set);
2307 +static inline void bcma_maskset32(struct bcma_device *cc,
2308 + u16 offset, u32 mask, u32 set)
2310 + bcma_write32(cc, offset, (bcma_read32(cc, offset) & mask) | set);
2312 +static inline void bcma_mask16(struct bcma_device *cc, u16 offset, u16 mask)
2314 + bcma_write16(cc, offset, bcma_read16(cc, offset) & mask);
2316 +static inline void bcma_set16(struct bcma_device *cc, u16 offset, u16 set)
2318 + bcma_write16(cc, offset, bcma_read16(cc, offset) | set);
2320 +static inline void bcma_maskset16(struct bcma_device *cc,
2321 + u16 offset, u16 mask, u16 set)
2323 + bcma_write16(cc, offset, (bcma_read16(cc, offset) & mask) | set);
2326 extern bool bcma_core_is_enabled(struct bcma_device *core);
2327 +extern void bcma_core_disable(struct bcma_device *core, u32 flags);
2328 extern int bcma_core_enable(struct bcma_device *core, u32 flags);
2329 +extern void bcma_core_set_clockmode(struct bcma_device *core,
2330 + enum bcma_clkmode clkmode);
2331 +extern void bcma_core_pll_ctl(struct bcma_device *core, u32 req, u32 status,
2333 +#define BCMA_DMA_TRANSLATION_MASK 0xC0000000
2334 +#define BCMA_DMA_TRANSLATION_NONE 0x00000000
2335 +#define BCMA_DMA_TRANSLATION_DMA32_CMT 0x40000000 /* Client Mode Translation for 32-bit DMA */
2336 +#define BCMA_DMA_TRANSLATION_DMA64_CMT 0x80000000 /* Client Mode Translation for 64-bit DMA */
2337 +extern u32 bcma_core_dma_translation(struct bcma_device *core);
2339 #endif /* LINUX_BCMA_H_ */
2340 --- a/include/linux/bcma/bcma_driver_chipcommon.h
2341 +++ b/include/linux/bcma/bcma_driver_chipcommon.h
2343 #define BCMA_CC_FLASHT_NONE 0x00000000 /* No flash */
2344 #define BCMA_CC_FLASHT_STSER 0x00000100 /* ST serial flash */
2345 #define BCMA_CC_FLASHT_ATSER 0x00000200 /* Atmel serial flash */
2346 +#define BCMA_CC_FLASHT_NFLASH 0x00000200
2347 #define BCMA_CC_FLASHT_PARA 0x00000700 /* Parallel flash */
2348 #define BCMA_CC_CAP_PLLT 0x00038000 /* PLL Type */
2349 #define BCMA_PLLTYPE_NONE 0x00000000
2350 @@ -178,16 +179,9 @@
2351 #define BCMA_CC_PROG_CFG 0x0120
2352 #define BCMA_CC_PROG_WAITCNT 0x0124
2353 #define BCMA_CC_FLASH_CFG 0x0128
2354 +#define BCMA_CC_FLASH_CFG_DS 0x0010 /* Data size, 0=8bit, 1=16bit */
2355 #define BCMA_CC_FLASH_WAITCNT 0x012C
2356 -#define BCMA_CC_CLKCTLST 0x01E0 /* Clock control and status (rev >= 20) */
2357 -#define BCMA_CC_CLKCTLST_FORCEALP 0x00000001 /* Force ALP request */
2358 -#define BCMA_CC_CLKCTLST_FORCEHT 0x00000002 /* Force HT request */
2359 -#define BCMA_CC_CLKCTLST_FORCEILP 0x00000004 /* Force ILP request */
2360 -#define BCMA_CC_CLKCTLST_HAVEALPREQ 0x00000008 /* ALP available request */
2361 -#define BCMA_CC_CLKCTLST_HAVEHTREQ 0x00000010 /* HT available request */
2362 -#define BCMA_CC_CLKCTLST_HWCROFF 0x00000020 /* Force HW clock request off */
2363 -#define BCMA_CC_CLKCTLST_HAVEHT 0x00010000 /* HT available */
2364 -#define BCMA_CC_CLKCTLST_HAVEALP 0x00020000 /* APL available */
2365 +/* 0x1E0 is defined as shared BCMA_CLKCTLST */
2366 #define BCMA_CC_HW_WORKAROUND 0x01E4 /* Hardware workaround (rev >= 20) */
2367 #define BCMA_CC_UART0_DATA 0x0300
2368 #define BCMA_CC_UART0_IMR 0x0304
2370 #define BCMA_CC_PMU_CTL 0x0600 /* PMU control */
2371 #define BCMA_CC_PMU_CTL_ILP_DIV 0xFFFF0000 /* ILP div mask */
2372 #define BCMA_CC_PMU_CTL_ILP_DIV_SHIFT 16
2373 +#define BCMA_CC_PMU_CTL_PLL_UPD 0x00000400
2374 #define BCMA_CC_PMU_CTL_NOILPONW 0x00000200 /* No ILP on wait */
2375 #define BCMA_CC_PMU_CTL_HTREQEN 0x00000100 /* HT req enable */
2376 #define BCMA_CC_PMU_CTL_ALPREQEN 0x00000080 /* ALP req enable */
2377 @@ -244,6 +239,66 @@
2378 #define BCMA_CC_REGCTL_DATA 0x065C
2379 #define BCMA_CC_PLLCTL_ADDR 0x0660
2380 #define BCMA_CC_PLLCTL_DATA 0x0664
2381 +#define BCMA_CC_SPROM 0x0800 /* SPROM beginning */
2382 +#define BCMA_CC_SPROM_PCIE6 0x0830 /* SPROM beginning on PCIe rev >= 6 */
2384 +/* Divider allocation in 4716/47162/5356 */
2385 +#define BCMA_CC_PMU5_MAINPLL_CPU 1
2386 +#define BCMA_CC_PMU5_MAINPLL_MEM 2
2387 +#define BCMA_CC_PMU5_MAINPLL_SSB 3
2389 +/* PLL usage in 4716/47162 */
2390 +#define BCMA_CC_PMU4716_MAINPLL_PLL0 12
2392 +/* PLL usage in 5356/5357 */
2393 +#define BCMA_CC_PMU5356_MAINPLL_PLL0 0
2394 +#define BCMA_CC_PMU5357_MAINPLL_PLL0 0
2397 +#define BCMA_CC_PMU4706_MAINPLL_PLL0 0
2399 +/* ALP clock on pre-PMU chips */
2400 +#define BCMA_CC_PMU_ALP_CLOCK 20000000
2401 +/* HT clock for systems with PMU-enabled chipcommon */
2402 +#define BCMA_CC_PMU_HT_CLOCK 80000000
2404 +/* PMU rev 5 (& 6) */
2405 +#define BCMA_CC_PPL_P1P2_OFF 0
2406 +#define BCMA_CC_PPL_P1_MASK 0x0f000000
2407 +#define BCMA_CC_PPL_P1_SHIFT 24
2408 +#define BCMA_CC_PPL_P2_MASK 0x00f00000
2409 +#define BCMA_CC_PPL_P2_SHIFT 20
2410 +#define BCMA_CC_PPL_M14_OFF 1
2411 +#define BCMA_CC_PPL_MDIV_MASK 0x000000ff
2412 +#define BCMA_CC_PPL_MDIV_WIDTH 8
2413 +#define BCMA_CC_PPL_NM5_OFF 2
2414 +#define BCMA_CC_PPL_NDIV_MASK 0xfff00000
2415 +#define BCMA_CC_PPL_NDIV_SHIFT 20
2416 +#define BCMA_CC_PPL_FMAB_OFF 3
2417 +#define BCMA_CC_PPL_MRAT_MASK 0xf0000000
2418 +#define BCMA_CC_PPL_MRAT_SHIFT 28
2419 +#define BCMA_CC_PPL_ABRAT_MASK 0x08000000
2420 +#define BCMA_CC_PPL_ABRAT_SHIFT 27
2421 +#define BCMA_CC_PPL_FDIV_MASK 0x07ffffff
2422 +#define BCMA_CC_PPL_PLLCTL_OFF 4
2423 +#define BCMA_CC_PPL_PCHI_OFF 5
2424 +#define BCMA_CC_PPL_PCHI_MASK 0x0000003f
2426 +/* BCM4331 ChipControl numbers. */
2427 +#define BCMA_CHIPCTL_4331_BT_COEXIST BIT(0) /* 0 disable */
2428 +#define BCMA_CHIPCTL_4331_SECI BIT(1) /* 0 SECI is disabled (JATG functional) */
2429 +#define BCMA_CHIPCTL_4331_EXT_LNA BIT(2) /* 0 disable */
2430 +#define BCMA_CHIPCTL_4331_SPROM_GPIO13_15 BIT(3) /* sprom/gpio13-15 mux */
2431 +#define BCMA_CHIPCTL_4331_EXTPA_EN BIT(4) /* 0 ext pa disable, 1 ext pa enabled */
2432 +#define BCMA_CHIPCTL_4331_GPIOCLK_ON_SPROMCS BIT(5) /* set drive out GPIO_CLK on sprom_cs pin */
2433 +#define BCMA_CHIPCTL_4331_PCIE_MDIO_ON_SPROMCS BIT(6) /* use sprom_cs pin as PCIE mdio interface */
2434 +#define BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5 BIT(7) /* aband extpa will be at gpio2/5 and sprom_dout */
2435 +#define BCMA_CHIPCTL_4331_OVR_PIPEAUXCLKEN BIT(8) /* override core control on pipe_AuxClkEnable */
2436 +#define BCMA_CHIPCTL_4331_OVR_PIPEAUXPWRDOWN BIT(9) /* override core control on pipe_AuxPowerDown */
2437 +#define BCMA_CHIPCTL_4331_PCIE_AUXCLKEN BIT(10) /* pcie_auxclkenable */
2438 +#define BCMA_CHIPCTL_4331_PCIE_PIPE_PLLDOWN BIT(11) /* pcie_pipe_pllpowerdown */
2439 +#define BCMA_CHIPCTL_4331_BT_SHD0_ON_GPIO4 BIT(16) /* enable bt_shd0 at gpio4 */
2440 +#define BCMA_CHIPCTL_4331_BT_SHD1_ON_GPIO5 BIT(17) /* enable bt_shd1 at gpio5 */
2442 /* Data for the PMU, if available.
2443 * Check availability with ((struct bcma_chipcommon)->capabilities & BCMA_CC_CAP_PMU)
2444 @@ -253,14 +308,37 @@ struct bcma_chipcommon_pmu {
2445 u32 crystalfreq; /* The active crystal frequency (in kHz) */
2448 +#ifdef CONFIG_BCMA_DRIVER_MIPS
2449 +struct bcma_pflash {
2455 +struct bcma_serial_port {
2457 + unsigned long clockspeed;
2459 + unsigned int baud_base;
2460 + unsigned int reg_shift;
2462 +#endif /* CONFIG_BCMA_DRIVER_MIPS */
2464 struct bcma_drv_cc {
2465 struct bcma_device *core;
2468 u32 capabilities_ext;
2470 /* Fast Powerup Delay constant */
2471 u16 fast_pwrup_delay;
2472 struct bcma_chipcommon_pmu pmu;
2473 +#ifdef CONFIG_BCMA_DRIVER_MIPS
2474 + struct bcma_pflash pflash;
2476 + int nr_serial_ports;
2477 + struct bcma_serial_port serial_ports[4];
2478 +#endif /* CONFIG_BCMA_DRIVER_MIPS */
2481 /* Register access */
2482 @@ -281,6 +359,8 @@ extern void bcma_core_chipcommon_init(st
2483 extern void bcma_chipco_suspend(struct bcma_drv_cc *cc);
2484 extern void bcma_chipco_resume(struct bcma_drv_cc *cc);
2486 +void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable);
2488 extern void bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc,
2491 @@ -299,4 +379,13 @@ u32 bcma_chipco_gpio_polarity(struct bcm
2493 extern void bcma_pmu_init(struct bcma_drv_cc *cc);
2495 +extern void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset,
2497 +extern void bcma_chipco_pll_maskset(struct bcma_drv_cc *cc, u32 offset,
2498 + u32 mask, u32 set);
2499 +extern void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc,
2500 + u32 offset, u32 mask, u32 set);
2501 +extern void bcma_chipco_regctl_maskset(struct bcma_drv_cc *cc,
2502 + u32 offset, u32 mask, u32 set);
2504 #endif /* LINUX_BCMA_DRIVER_CC_H_ */
2506 +++ b/include/linux/bcma/bcma_driver_mips.h
2508 +#ifndef LINUX_BCMA_DRIVER_MIPS_H_
2509 +#define LINUX_BCMA_DRIVER_MIPS_H_
2511 +#define BCMA_MIPS_IPSFLAG 0x0F08
2512 +/* which sbflags get routed to mips interrupt 1 */
2513 +#define BCMA_MIPS_IPSFLAG_IRQ1 0x0000003F
2514 +#define BCMA_MIPS_IPSFLAG_IRQ1_SHIFT 0
2515 +/* which sbflags get routed to mips interrupt 2 */
2516 +#define BCMA_MIPS_IPSFLAG_IRQ2 0x00003F00
2517 +#define BCMA_MIPS_IPSFLAG_IRQ2_SHIFT 8
2518 +/* which sbflags get routed to mips interrupt 3 */
2519 +#define BCMA_MIPS_IPSFLAG_IRQ3 0x003F0000
2520 +#define BCMA_MIPS_IPSFLAG_IRQ3_SHIFT 16
2521 +/* which sbflags get routed to mips interrupt 4 */
2522 +#define BCMA_MIPS_IPSFLAG_IRQ4 0x3F000000
2523 +#define BCMA_MIPS_IPSFLAG_IRQ4_SHIFT 24
2525 +/* MIPS 74K core registers */
2526 +#define BCMA_MIPS_MIPS74K_CORECTL 0x0000
2527 +#define BCMA_MIPS_MIPS74K_EXCEPTBASE 0x0004
2528 +#define BCMA_MIPS_MIPS74K_BIST 0x000C
2529 +#define BCMA_MIPS_MIPS74K_INTMASK_INT0 0x0014
2530 +#define BCMA_MIPS_MIPS74K_INTMASK(int) \
2531 + ((int) * 4 + BCMA_MIPS_MIPS74K_INTMASK_INT0)
2532 +#define BCMA_MIPS_MIPS74K_NMIMASK 0x002C
2533 +#define BCMA_MIPS_MIPS74K_GPIOSEL 0x0040
2534 +#define BCMA_MIPS_MIPS74K_GPIOOUT 0x0044
2535 +#define BCMA_MIPS_MIPS74K_GPIOEN 0x0048
2536 +#define BCMA_MIPS_MIPS74K_CLKCTLST 0x01E0
2538 +#define BCMA_MIPS_OOBSELOUTA30 0x100
2540 +struct bcma_device;
2542 +struct bcma_drv_mips {
2543 + struct bcma_device *core;
2545 + unsigned int assigned_irqs;
2548 +#ifdef CONFIG_BCMA_DRIVER_MIPS
2549 +extern void bcma_core_mips_init(struct bcma_drv_mips *mcore);
2551 +static inline void bcma_core_mips_init(struct bcma_drv_mips *mcore) { }
2554 +extern u32 bcma_cpu_clock(struct bcma_drv_mips *mcore);
2556 +extern unsigned int bcma_core_mips_irq(struct bcma_device *dev);
2558 +#endif /* LINUX_BCMA_DRIVER_MIPS_H_ */
2559 --- a/include/linux/bcma/bcma_driver_pci.h
2560 +++ b/include/linux/bcma/bcma_driver_pci.h
2561 @@ -85,5 +85,7 @@ struct bcma_drv_pci {
2562 #define pcicore_write32(pc, offset, val) bcma_write32((pc)->core, offset, val)
2564 extern void bcma_core_pci_init(struct bcma_drv_pci *pc);
2565 +extern int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc,
2566 + struct bcma_device *core, bool enable);
2568 #endif /* LINUX_BCMA_DRIVER_PCI_H_ */
2569 --- a/include/linux/bcma/bcma_regs.h
2570 +++ b/include/linux/bcma/bcma_regs.h
2572 #ifndef LINUX_BCMA_REGS_H_
2573 #define LINUX_BCMA_REGS_H_
2575 +/* Some single registers are shared between many cores */
2576 +/* BCMA_CLKCTLST: ChipCommon (rev >= 20), PCIe, 80211 */
2577 +#define BCMA_CLKCTLST 0x01E0 /* Clock control and status */
2578 +#define BCMA_CLKCTLST_FORCEALP 0x00000001 /* Force ALP request */
2579 +#define BCMA_CLKCTLST_FORCEHT 0x00000002 /* Force HT request */
2580 +#define BCMA_CLKCTLST_FORCEILP 0x00000004 /* Force ILP request */
2581 +#define BCMA_CLKCTLST_HAVEALPREQ 0x00000008 /* ALP available request */
2582 +#define BCMA_CLKCTLST_HAVEHTREQ 0x00000010 /* HT available request */
2583 +#define BCMA_CLKCTLST_HWCROFF 0x00000020 /* Force HW clock request off */
2584 +#define BCMA_CLKCTLST_EXTRESREQ 0x00000700 /* Mask of external resource requests */
2585 +#define BCMA_CLKCTLST_HAVEALP 0x00010000 /* ALP available */
2586 +#define BCMA_CLKCTLST_HAVEHT 0x00020000 /* HT available */
2587 +#define BCMA_CLKCTLST_BP_ON_ALP 0x00040000 /* RO: running on ALP clock */
2588 +#define BCMA_CLKCTLST_BP_ON_HT 0x00080000 /* RO: running on HT clock */
2589 +#define BCMA_CLKCTLST_EXTRESST 0x07000000 /* Mask of external resource status */
2590 +/* Is there any BCM4328 on BCMA bus? */
2591 +#define BCMA_CLKCTLST_4328A0_HAVEHT 0x00010000 /* 4328a0 has reversed bits */
2592 +#define BCMA_CLKCTLST_4328A0_HAVEALP 0x00020000 /* 4328a0 has reversed bits */
2594 /* Agent registers (common for every core) */
2595 -#define BCMA_IOCTL 0x0408
2596 +#define BCMA_IOCTL 0x0408 /* IO control */
2597 #define BCMA_IOCTL_CLK 0x0001
2598 #define BCMA_IOCTL_FGC 0x0002
2599 #define BCMA_IOCTL_CORE_BITS 0x3FFC
2600 #define BCMA_IOCTL_PME_EN 0x4000
2601 #define BCMA_IOCTL_BIST_EN 0x8000
2602 +#define BCMA_IOST 0x0500 /* IO status */
2603 +#define BCMA_IOST_CORE_BITS 0x0FFF
2604 +#define BCMA_IOST_DMA64 0x1000
2605 +#define BCMA_IOST_GATED_CLK 0x2000
2606 +#define BCMA_IOST_BIST_ERROR 0x4000
2607 +#define BCMA_IOST_BIST_DONE 0x8000
2608 #define BCMA_RESET_CTL 0x0800
2609 #define BCMA_RESET_CTL_RESET 0x0001
2612 +++ b/include/linux/bcma/bcma_soc.h
2614 +#ifndef LINUX_BCMA_SOC_H_
2615 +#define LINUX_BCMA_SOC_H_
2617 +#include <linux/bcma/bcma.h>
2620 + struct bcma_bus bus;
2621 + struct bcma_device core_cc;
2622 + struct bcma_device core_mips;
2625 +int __init bcma_host_soc_register(struct bcma_soc *soc);
2627 +int bcma_bus_register(struct bcma_bus *bus);
2629 +#endif /* LINUX_BCMA_SOC_H_ */