diff options
Diffstat (limited to 'target/linux/generic/patches-3.3/025-bcma_backport.patch')
-rw-r--r-- | target/linux/generic/patches-3.3/025-bcma_backport.patch | 1147 |
1 files changed, 909 insertions, 238 deletions
diff --git a/target/linux/generic/patches-3.3/025-bcma_backport.patch b/target/linux/generic/patches-3.3/025-bcma_backport.patch index d3f9fb0f83..05d461d74a 100644 --- a/target/linux/generic/patches-3.3/025-bcma_backport.patch +++ b/target/linux/generic/patches-3.3/025-bcma_backport.patch @@ -1,6 +1,21 @@ +--- a/arch/mips/bcm47xx/serial.c ++++ b/arch/mips/bcm47xx/serial.c +@@ -62,7 +62,7 @@ static int __init uart8250_init_bcma(voi + + p->mapbase = (unsigned int) bcma_port->regs; + p->membase = (void *) bcma_port->regs; +- p->irq = bcma_port->irq + 2; ++ p->irq = bcma_port->irq; + p->uartclk = bcma_port->baud_base; + p->regshift = bcma_port->reg_shift; + p->iotype = UPIO_MEM; --- a/drivers/bcma/Kconfig +++ b/drivers/bcma/Kconfig -@@ -29,7 +29,7 @@ config BCMA_HOST_PCI +@@ -26,10 +26,11 @@ config BCMA_HOST_PCI_POSSIBLE + config BCMA_HOST_PCI + bool "Support for BCMA on PCI-host bus" + depends on BCMA_HOST_PCI_POSSIBLE ++ default y config BCMA_DRIVER_PCI_HOSTMODE bool "Driver for PCI core working in hostmode" @@ -9,7 +24,7 @@ help PCI core hostmode operation (external PCI bus). -@@ -46,6 +46,33 @@ config BCMA_DRIVER_MIPS +@@ -46,6 +47,33 @@ config BCMA_DRIVER_MIPS If unsure, say N @@ -60,7 +75,7 @@ obj-$(CONFIG_BCMA) += bcma.o --- a/drivers/bcma/bcma_private.h +++ b/drivers/bcma/bcma_private.h -@@ -10,10 +10,19 @@ +@@ -10,10 +10,21 @@ #define BCMA_CORE_SIZE 0x1000 @@ -77,11 +92,13 @@ /* main.c */ -int bcma_bus_register(struct bcma_bus *bus); ++bool bcma_wait_value(struct bcma_device *core, u16 reg, u32 mask, u32 value, ++ int timeout); +int __devinit bcma_bus_register(struct bcma_bus *bus); void bcma_bus_unregister(struct bcma_bus *bus); int __init bcma_bus_early_register(struct bcma_bus *bus, struct bcma_device *core_cc, -@@ -22,6 +31,8 @@ int __init bcma_bus_early_register(struc +@@ -22,6 +33,8 @@ int __init bcma_bus_early_register(struc int bcma_bus_suspend(struct bcma_bus *bus); int bcma_bus_resume(struct bcma_bus *bus); #endif @@ -90,7 +107,11 @@ /* scan.c */ int bcma_bus_scan(struct bcma_bus *bus); -@@ -39,8 +50,32 @@ void bcma_chipco_serial_init(struct bcma +@@ -36,11 +49,36 @@ int bcma_sprom_get(struct bcma_bus *bus) + /* driver_chipcommon.c */ + #ifdef CONFIG_BCMA_DRIVER_MIPS + void bcma_chipco_serial_init(struct bcma_drv_cc *cc); ++extern struct platform_device bcma_pflash_dev; #endif /* CONFIG_BCMA_DRIVER_MIPS */ /* driver_chipcommon_pmu.c */ @@ -125,7 +146,7 @@ #ifdef CONFIG_BCMA_HOST_PCI /* host_pci.c */ -@@ -48,8 +83,24 @@ extern int __init bcma_host_pci_init(voi +@@ -48,8 +86,29 @@ extern int __init bcma_host_pci_init(voi extern void __exit bcma_host_pci_exit(void); #endif /* CONFIG_BCMA_HOST_PCI */ @@ -143,25 +164,75 @@ +#ifdef CONFIG_BCMA_DRIVER_GPIO +/* driver_gpio.c */ +int bcma_gpio_init(struct bcma_drv_cc *cc); ++int bcma_gpio_unregister(struct bcma_drv_cc *cc); +#else +static inline int bcma_gpio_init(struct bcma_drv_cc *cc) +{ + return -ENOTSUPP; +} ++static inline int bcma_gpio_unregister(struct bcma_drv_cc *cc) ++{ ++ return 0; ++} +#endif /* CONFIG_BCMA_DRIVER_GPIO */ + #endif --- a/drivers/bcma/core.c +++ b/drivers/bcma/core.c -@@ -30,6 +30,7 @@ void bcma_core_disable(struct bcma_devic - udelay(10); +@@ -9,6 +9,25 @@ + #include <linux/export.h> + #include <linux/bcma/bcma.h> + ++static bool bcma_core_wait_value(struct bcma_device *core, u16 reg, u32 mask, ++ u32 value, int timeout) ++{ ++ unsigned long deadline = jiffies + timeout; ++ u32 val; ++ ++ do { ++ val = bcma_aread32(core, reg); ++ if ((val & mask) == value) ++ return true; ++ cpu_relax(); ++ udelay(10); ++ } while (!time_after_eq(jiffies, deadline)); ++ ++ bcma_warn(core->bus, "Timeout waiting for register 0x%04X!\n", reg); ++ ++ return false; ++} ++ + bool bcma_core_is_enabled(struct bcma_device *core) + { + if ((bcma_aread32(core, BCMA_IOCTL) & (BCMA_IOCTL_CLK | BCMA_IOCTL_FGC)) +@@ -25,12 +44,15 @@ void bcma_core_disable(struct bcma_devic + if (bcma_aread32(core, BCMA_RESET_CTL) & BCMA_RESET_CTL_RESET) + return; + +- bcma_awrite32(core, BCMA_IOCTL, flags); +- bcma_aread32(core, BCMA_IOCTL); +- udelay(10); ++ bcma_core_wait_value(core, BCMA_RESET_ST, ~0, 0, 300); bcma_awrite32(core, BCMA_RESET_CTL, BCMA_RESET_CTL_RESET); + bcma_aread32(core, BCMA_RESET_CTL); udelay(1); ++ ++ bcma_awrite32(core, BCMA_IOCTL, flags); ++ bcma_aread32(core, BCMA_IOCTL); ++ udelay(10); } EXPORT_SYMBOL_GPL(bcma_core_disable); -@@ -64,7 +65,7 @@ void bcma_core_set_clockmode(struct bcma + +@@ -42,6 +64,7 @@ int bcma_core_enable(struct bcma_device + bcma_aread32(core, BCMA_IOCTL); + + bcma_awrite32(core, BCMA_RESET_CTL, 0); ++ bcma_aread32(core, BCMA_RESET_CTL); + udelay(1); + + bcma_awrite32(core, BCMA_IOCTL, (BCMA_IOCTL_CLK | flags)); +@@ -64,7 +87,7 @@ void bcma_core_set_clockmode(struct bcma switch (clkmode) { case BCMA_CLKMODE_FAST: bcma_set32(core, BCMA_CLKCTLST, BCMA_CLKCTLST_FORCEHT); @@ -170,7 +241,7 @@ for (i = 0; i < 1500; i++) { if (bcma_read32(core, BCMA_CLKCTLST) & BCMA_CLKCTLST_HAVEHT) { -@@ -74,10 +75,10 @@ void bcma_core_set_clockmode(struct bcma +@@ -74,10 +97,10 @@ void bcma_core_set_clockmode(struct bcma udelay(10); } if (i) @@ -183,7 +254,7 @@ break; } } -@@ -101,9 +102,9 @@ void bcma_core_pll_ctl(struct bcma_devic +@@ -101,9 +124,15 @@ void bcma_core_pll_ctl(struct bcma_devic udelay(10); } if (i) @@ -191,11 +262,17 @@ + bcma_err(core->bus, "PLL enable timeout\n"); } else { - pr_warn("Disabling PLL not supported yet!\n"); -+ bcma_warn(core->bus, "Disabling PLL not supported yet!\n"); ++ /* ++ * Mask the PLL but don't wait for it to be disabled. PLL may be ++ * shared between cores and will be still up if there is another ++ * core using it. ++ */ ++ bcma_mask32(core, BCMA_CLKCTLST, ~req); ++ bcma_read32(core, BCMA_CLKCTLST); } } EXPORT_SYMBOL_GPL(bcma_core_pll_ctl); -@@ -119,8 +120,8 @@ u32 bcma_core_dma_translation(struct bcm +@@ -119,8 +148,8 @@ u32 bcma_core_dma_translation(struct bcm else return BCMA_DMA_TRANSLATION_DMA32_CMT; default: @@ -224,7 +301,7 @@ #include <linux/bcma/bcma.h> static inline u32 bcma_cc_write32_masked(struct bcma_drv_cc *cc, u16 offset, -@@ -22,20 +25,120 @@ static inline u32 bcma_cc_write32_masked +@@ -22,29 +25,136 @@ static inline u32 bcma_cc_write32_masked return value; } @@ -347,9 +424,19 @@ + bcma_core_chipcommon_early_init(cc); + if (cc->core->id.rev >= 20) { - bcma_cc_write32(cc, BCMA_CC_GPIOPULLUP, 0); - bcma_cc_write32(cc, BCMA_CC_GPIOPULLDOWN, 0); -@@ -44,7 +147,7 @@ void bcma_core_chipcommon_init(struct bc +- bcma_cc_write32(cc, BCMA_CC_GPIOPULLUP, 0); +- bcma_cc_write32(cc, BCMA_CC_GPIOPULLDOWN, 0); ++ u32 pullup = 0, pulldown = 0; ++ ++ if (cc->core->bus->chipinfo.id == BCMA_CHIP_ID_BCM43142) { ++ pullup = 0x402e0; ++ pulldown = 0x20500; ++ } ++ ++ bcma_cc_write32(cc, BCMA_CC_GPIOPULLUP, pullup); ++ bcma_cc_write32(cc, BCMA_CC_GPIOPULLDOWN, pulldown); + } + if (cc->capabilities & BCMA_CC_CAP_PMU) bcma_pmu_init(cc); if (cc->capabilities & BCMA_CC_CAP_PCTL) @@ -358,7 +445,7 @@ if (cc->core->id.rev >= 16) { if (cc->core->bus->sprom.leddc_on_time && -@@ -56,15 +159,33 @@ void bcma_core_chipcommon_init(struct bc +@@ -56,15 +166,33 @@ void bcma_core_chipcommon_init(struct bc ((leddc_on << BCMA_CC_GPIOTIMER_ONTIME_SHIFT) | (leddc_off << BCMA_CC_GPIOTIMER_OFFTIME_SHIFT))); } @@ -395,7 +482,7 @@ } void bcma_chipco_irq_mask(struct bcma_drv_cc *cc, u32 mask, u32 value) -@@ -84,28 +205,99 @@ u32 bcma_chipco_gpio_in(struct bcma_drv_ +@@ -84,28 +212,99 @@ u32 bcma_chipco_gpio_in(struct bcma_drv_ u32 bcma_chipco_gpio_out(struct bcma_drv_cc *cc, u32 mask, u32 value) { @@ -500,7 +587,7 @@ } #ifdef CONFIG_BCMA_DRIVER_MIPS -@@ -118,8 +310,7 @@ void bcma_chipco_serial_init(struct bcma +@@ -118,8 +317,7 @@ void bcma_chipco_serial_init(struct bcma struct bcma_serial_port *ports = cc->serial_ports; if (ccrev >= 11 && ccrev != 15) { @@ -510,7 +597,7 @@ if (ccrev >= 21) { /* Turn off UART clock before switching clocksource. */ bcma_cc_write32(cc, BCMA_CC_CORECTL, -@@ -137,8 +328,7 @@ void bcma_chipco_serial_init(struct bcma +@@ -137,12 +335,11 @@ void bcma_chipco_serial_init(struct bcma | BCMA_CC_CORECTL_UARTCLKEN); } } else { @@ -520,6 +607,11 @@ return; } +- irq = bcma_core_mips_irq(cc->core); ++ irq = bcma_core_irq(cc->core); + + /* Determine the registers of the UARTs */ + cc->nr_serial_ports = (cc->capabilities & BCMA_CC_CAP_NRUART); --- /dev/null +++ b/drivers/bcma/driver_chipcommon_nflash.c @@ -0,0 +1,44 @@ @@ -530,11 +622,11 @@ + * Licensed under the GNU/GPL. See COPYING for details. + */ + ++#include "bcma_private.h" ++ +#include <linux/platform_device.h> +#include <linux/bcma/bcma.h> + -+#include "bcma_private.h" -+ +struct platform_device bcma_nflash_dev = { + .name = "bcma_nflash", + .num_resources = 0, @@ -546,7 +638,7 @@ + struct bcma_bus *bus = cc->core->bus; + + if (bus->chipinfo.id != BCMA_CHIP_ID_BCM4706 && -+ cc->core->id.rev != 0x38) { ++ cc->core->id.rev != 38) { + bcma_err(bus, "NAND flash on unsupported board!\n"); + return -ENOTSUPP; + } @@ -594,29 +686,121 @@ void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset, u32 value) { -@@ -54,38 +56,19 @@ void bcma_chipco_regctl_maskset(struct b +@@ -54,19 +56,106 @@ void bcma_chipco_regctl_maskset(struct b } EXPORT_SYMBOL_GPL(bcma_chipco_regctl_maskset); --static void bcma_pmu_pll_init(struct bcma_drv_cc *cc) --{ -- struct bcma_bus *bus = cc->core->bus; -- -- switch (bus->chipinfo.id) { ++static u32 bcma_pmu_xtalfreq(struct bcma_drv_cc *cc) ++{ ++ u32 ilp_ctl, alp_hz; ++ ++ if (!(bcma_cc_read32(cc, BCMA_CC_PMU_STAT) & ++ BCMA_CC_PMU_STAT_EXT_LPO_AVAIL)) ++ return 0; ++ ++ bcma_cc_write32(cc, BCMA_CC_PMU_XTAL_FREQ, ++ BIT(BCMA_CC_PMU_XTAL_FREQ_MEASURE_SHIFT)); ++ usleep_range(1000, 2000); ++ ++ ilp_ctl = bcma_cc_read32(cc, BCMA_CC_PMU_XTAL_FREQ); ++ ilp_ctl &= BCMA_CC_PMU_XTAL_FREQ_ILPCTL_MASK; ++ ++ bcma_cc_write32(cc, BCMA_CC_PMU_XTAL_FREQ, 0); ++ ++ alp_hz = ilp_ctl * 32768 / 4; ++ return (alp_hz + 50000) / 100000 * 100; ++} ++ ++static void bcma_pmu2_pll_init0(struct bcma_drv_cc *cc, u32 xtalfreq) ++{ ++ struct bcma_bus *bus = cc->core->bus; ++ u32 freq_tgt_target = 0, freq_tgt_current; ++ u32 pll0, mask; ++ ++ switch (bus->chipinfo.id) { ++ case BCMA_CHIP_ID_BCM43142: ++ /* pmu2_xtaltab0_adfll_485 */ ++ switch (xtalfreq) { ++ case 12000: ++ freq_tgt_target = 0x50D52; ++ break; ++ case 20000: ++ freq_tgt_target = 0x307FE; ++ break; ++ case 26000: ++ freq_tgt_target = 0x254EA; ++ break; ++ case 37400: ++ freq_tgt_target = 0x19EF8; ++ break; ++ case 52000: ++ freq_tgt_target = 0x12A75; ++ break; ++ } ++ break; ++ } ++ ++ if (!freq_tgt_target) { ++ bcma_err(bus, "Unknown TGT frequency for xtalfreq %d\n", ++ xtalfreq); ++ return; ++ } ++ ++ pll0 = bcma_chipco_pll_read(cc, BCMA_CC_PMU15_PLL_PLLCTL0); ++ freq_tgt_current = (pll0 & BCMA_CC_PMU15_PLL_PC0_FREQTGT_MASK) >> ++ BCMA_CC_PMU15_PLL_PC0_FREQTGT_SHIFT; ++ ++ if (freq_tgt_current == freq_tgt_target) { ++ bcma_debug(bus, "Target TGT frequency already set\n"); ++ return; ++ } ++ ++ /* Turn off PLL */ ++ switch (bus->chipinfo.id) { ++ case BCMA_CHIP_ID_BCM43142: ++ mask = (u32)~(BCMA_RES_4314_HT_AVAIL | ++ BCMA_RES_4314_MACPHY_CLK_AVAIL); ++ ++ bcma_cc_mask32(cc, BCMA_CC_PMU_MINRES_MSK, mask); ++ bcma_cc_mask32(cc, BCMA_CC_PMU_MAXRES_MSK, mask); ++ bcma_wait_value(cc->core, BCMA_CLKCTLST, ++ BCMA_CLKCTLST_HAVEHT, 0, 20000); ++ break; ++ } ++ ++ pll0 &= ~BCMA_CC_PMU15_PLL_PC0_FREQTGT_MASK; ++ pll0 |= freq_tgt_target << BCMA_CC_PMU15_PLL_PC0_FREQTGT_SHIFT; ++ bcma_chipco_pll_write(cc, BCMA_CC_PMU15_PLL_PLLCTL0, pll0); ++ ++ /* Flush */ ++ if (cc->pmu.rev >= 2) ++ bcma_cc_set32(cc, BCMA_CC_PMU_CTL, BCMA_CC_PMU_CTL_PLL_UPD); ++ ++ /* TODO: Do we need to update OTP? */ ++} ++ + static void bcma_pmu_pll_init(struct bcma_drv_cc *cc) + { + struct bcma_bus *bus = cc->core->bus; ++ u32 xtalfreq = bcma_pmu_xtalfreq(cc); + + switch (bus->chipinfo.id) { - case 0x4313: - case 0x4331: - case 43224: - case 43225: -- break; ++ case BCMA_CHIP_ID_BCM43142: ++ if (xtalfreq == 0) ++ xtalfreq = 20000; ++ bcma_pmu2_pll_init0(cc, xtalfreq); + break; - default: - pr_err("PLL init unknown for device 0x%04X\n", - bus->chipinfo.id); -- } --} -- - static void bcma_pmu_resources_init(struct bcma_drv_cc *cc) - { - struct bcma_bus *bus = cc->core->bus; + } + } + +@@ -76,16 +165,32 @@ static void bcma_pmu_resources_init(stru u32 min_msk = 0, max_msk = 0; switch (bus->chipinfo.id) { @@ -627,7 +811,25 @@ break; - case 43224: - case 43225: -- break; ++ case BCMA_CHIP_ID_BCM43142: ++ min_msk = BCMA_RES_4314_LPLDO_PU | ++ BCMA_RES_4314_PMU_SLEEP_DIS | ++ BCMA_RES_4314_PMU_BG_PU | ++ BCMA_RES_4314_CBUCK_LPOM_PU | ++ BCMA_RES_4314_CBUCK_PFM_PU | ++ BCMA_RES_4314_CLDO_PU | ++ BCMA_RES_4314_LPLDO2_LVM | ++ BCMA_RES_4314_WL_PMU_PU | ++ BCMA_RES_4314_LDO3P3_PU | ++ BCMA_RES_4314_OTP_PU | ++ BCMA_RES_4314_WL_PWRSW_PU | ++ BCMA_RES_4314_LQ_AVAIL | ++ BCMA_RES_4314_LOGIC_RET | ++ BCMA_RES_4314_MEM_SLEEP | ++ BCMA_RES_4314_MACPHY_RET | ++ BCMA_RES_4314_WL_CORE_READY; ++ max_msk = 0x3FFFFFFF; + break; default: - pr_err("PMU resource config unknown for device 0x%04X\n", - bus->chipinfo.id); @@ -636,16 +838,16 @@ } /* Set the resource masks. */ -@@ -93,22 +76,12 @@ static void bcma_pmu_resources_init(stru +@@ -93,22 +198,12 @@ static void bcma_pmu_resources_init(stru bcma_cc_write32(cc, BCMA_CC_PMU_MINRES_MSK, min_msk); if (max_msk) bcma_cc_write32(cc, BCMA_CC_PMU_MAXRES_MSK, max_msk); -} -- + -void bcma_pmu_swreg_init(struct bcma_drv_cc *cc) -{ - struct bcma_bus *bus = cc->core->bus; - +- - switch (bus->chipinfo.id) { - case 0x4313: - case 0x4331: @@ -664,7 +866,7 @@ } /* Disable to allow reading SPROM. Don't know the adventages of enabling it. */ -@@ -122,51 +95,69 @@ void bcma_chipco_bcm4331_ext_pa_lines_ct +@@ -122,51 +217,69 @@ void bcma_chipco_bcm4331_ext_pa_lines_ct val |= BCMA_CHIPCTL_4331_EXTPA_EN; if (bus->chipinfo.pkg == 9 || bus->chipinfo.pkg == 11) val |= BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5; @@ -751,14 +953,14 @@ if (cc->pmu.rev == 1) bcma_cc_mask32(cc, BCMA_CC_PMU_CTL, ~BCMA_CC_PMU_CTL_NOILPONW); -@@ -174,37 +165,47 @@ void bcma_pmu_init(struct bcma_drv_cc *c +@@ -174,37 +287,48 @@ void bcma_pmu_init(struct bcma_drv_cc *c bcma_cc_set32(cc, BCMA_CC_PMU_CTL, BCMA_CC_PMU_CTL_NOILPONW); - if (cc->core->id.id == 0x4329 && cc->core->id.rev == 2) - pr_err("Fix for 4329b0 bad LPOM state not implemented!\n"); - -- bcma_pmu_pll_init(cc); + bcma_pmu_pll_init(cc); bcma_pmu_resources_init(cc); - bcma_pmu_swreg_init(cc); bcma_pmu_workarounds(cc); @@ -817,7 +1019,7 @@ } return BCMA_CC_PMU_ALP_CLOCK; } -@@ -212,7 +213,7 @@ u32 bcma_pmu_alp_clock(struct bcma_drv_c +@@ -212,7 +336,7 @@ u32 bcma_pmu_alp_clock(struct bcma_drv_c /* Find the output of the "m" pll divider given pll controls that start with * pllreg "pll0" i.e. 12 for main 6 for phy, 0 for misc. */ @@ -826,7 +1028,7 @@ { u32 tmp, div, ndiv, p1, p2, fc; struct bcma_bus *bus = cc->core->bus; -@@ -221,7 +222,8 @@ static u32 bcma_pmu_clock(struct bcma_dr +@@ -221,7 +345,8 @@ static u32 bcma_pmu_clock(struct bcma_dr BUG_ON(!m || m > 4); @@ -836,7 +1038,7 @@ /* Detect failure in clock setting */ tmp = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT); if (tmp & 0x40000) -@@ -240,60 +242,95 @@ static u32 bcma_pmu_clock(struct bcma_dr +@@ -240,60 +365,96 @@ static u32 bcma_pmu_clock(struct bcma_dr ndiv = (tmp & BCMA_CC_PPL_NDIV_MASK) >> BCMA_CC_PPL_NDIV_SHIFT; /* Do calculation in Mhz */ @@ -880,7 +1082,7 @@ + /* query bus clock frequency for PMU-enabled chipcommon */ -u32 bcma_pmu_get_clockcontrol(struct bcma_drv_cc *cc) -+static u32 bcma_pmu_get_bus_clock(struct bcma_drv_cc *cc) ++u32 bcma_pmu_get_bus_clock(struct bcma_drv_cc *cc) { struct bcma_bus *bus = cc->core->bus; @@ -928,6 +1130,7 @@ } return BCMA_CC_PMU_HT_CLOCK; } ++EXPORT_SYMBOL_GPL(bcma_pmu_get_bus_clock); /* query cpu clock frequency for PMU-enabled chipcommon */ -u32 bcma_pmu_get_clockcpu(struct bcma_drv_cc *cc) @@ -958,7 +1161,7 @@ pll = BCMA_CC_PMU5357_MAINPLL_PLL0; break; default: -@@ -301,10 +338,189 @@ u32 bcma_pmu_get_clockcpu(struct bcma_dr +@@ -301,10 +462,189 @@ u32 bcma_pmu_get_clockcpu(struct bcma_dr break; } @@ -1162,11 +1365,11 @@ + * Licensed under the GNU/GPL. See COPYING for details. + */ + ++#include "bcma_private.h" ++ +#include <linux/platform_device.h> +#include <linux/bcma/bcma.h> + -+#include "bcma_private.h" -+ +static struct resource bcma_sflash_resource = { + .name = "bcma_sflash", + .start = BCMA_SOC_FLASH2, @@ -1187,7 +1390,7 @@ + u16 numblocks; +}; + -+static struct bcma_sflash_tbl_e bcma_sflash_st_tbl[] = { ++static const struct bcma_sflash_tbl_e bcma_sflash_st_tbl[] = { + { "M25P20", 0x11, 0x10000, 4, }, + { "M25P40", 0x12, 0x10000, 8, }, + @@ -1198,7 +1401,7 @@ + { 0 }, +}; + -+static struct bcma_sflash_tbl_e bcma_sflash_sst_tbl[] = { ++static const struct bcma_sflash_tbl_e bcma_sflash_sst_tbl[] = { + { "SST25WF512", 1, 0x1000, 16, }, + { "SST25VF512", 0x48, 0x1000, 16, }, + { "SST25WF010", 2, 0x1000, 32, }, @@ -1216,7 +1419,7 @@ + { 0 }, +}; + -+static struct bcma_sflash_tbl_e bcma_sflash_at_tbl[] = { ++static const struct bcma_sflash_tbl_e bcma_sflash_at_tbl[] = { + { "AT45DB011", 0xc, 256, 512, }, + { "AT45DB021", 0x14, 256, 1024, }, + { "AT45DB041", 0x1c, 256, 2048, }, @@ -1246,7 +1449,7 @@ +{ + struct bcma_bus *bus = cc->core->bus; + struct bcma_sflash *sflash = &cc->sflash; -+ struct bcma_sflash_tbl_e *e; ++ const struct bcma_sflash_tbl_e *e; + u32 id, id2; + + switch (cc->capabilities & BCMA_CC_CAP_FLASHT) { @@ -1339,7 +1542,7 @@ +} --- /dev/null +++ b/drivers/bcma/driver_gpio.c -@@ -0,0 +1,98 @@ +@@ -0,0 +1,114 @@ +/* + * Broadcom specific AMBA + * GPIO driver @@ -1415,6 +1618,16 @@ + bcma_chipco_gpio_pullup(cc, 1 << gpio, 0); +} + ++static int bcma_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) ++{ ++ struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip); ++ ++ if (cc->core->bus->hosttype == BCMA_HOSTTYPE_SOC) ++ return bcma_core_irq(cc->core); ++ else ++ return -EINVAL; ++} ++ +int bcma_gpio_init(struct bcma_drv_cc *cc) +{ + struct gpio_chip *chip = &cc->gpio; @@ -1427,6 +1640,7 @@ + chip->set = bcma_gpio_set_value; + chip->direction_input = bcma_gpio_direction_input; + chip->direction_output = bcma_gpio_direction_output; ++ chip->to_irq = bcma_gpio_to_irq; + chip->ngpio = 16; + /* There is just one SoC in one device and its GPIO addresses should be + * deterministic to address them more easily. The other buses could get @@ -1438,9 +1652,44 @@ + + return gpiochip_add(chip); +} ++ ++int bcma_gpio_unregister(struct bcma_drv_cc *cc) ++{ ++ return gpiochip_remove(&cc->gpio); ++} --- a/drivers/bcma/driver_mips.c +++ b/drivers/bcma/driver_mips.c -@@ -22,15 +22,15 @@ +@@ -14,23 +14,45 @@ + + #include <linux/bcma/bcma.h> + ++#include <linux/mtd/physmap.h> ++#include <linux/platform_device.h> + #include <linux/serial.h> + #include <linux/serial_core.h> + #include <linux/serial_reg.h> + #include <linux/time.h> + ++static const char * const part_probes[] = { "bcm47xxpart", NULL }; ++ ++static struct physmap_flash_data bcma_pflash_data = { ++ .part_probe_types = part_probes, ++}; ++ ++static struct resource bcma_pflash_resource = { ++ .name = "bcma_pflash", ++ .flags = IORESOURCE_MEM, ++}; ++ ++struct platform_device bcma_pflash_dev = { ++ .name = "physmap-flash", ++ .dev = { ++ .platform_data = &bcma_pflash_data, ++ }, ++ .resource = &bcma_pflash_resource, ++ .num_resources = 1, ++}; ++ /* The 47162a0 hangs when reading MIPS DMP registers registers */ static inline bool bcma_core_mips_bcm47162a0_quirk(struct bcma_device *dev) { @@ -1460,7 +1709,7 @@ dev->bus->chipinfo.pkg == 11 && dev->id.id == BCMA_CORE_USB20_HOST; } -@@ -74,11 +74,16 @@ static u32 bcma_core_mips_irqflag(struct +@@ -74,28 +96,41 @@ static u32 bcma_core_mips_irqflag(struct return dev->core_index; flag = bcma_aread32(dev, BCMA_MIPS_OOBSELOUTA30); @@ -1476,9 +1725,11 @@ + * If disabled, 5 is returned. + * If not supported, 6 is returned. */ - unsigned int bcma_core_mips_irq(struct bcma_device *dev) +-unsigned int bcma_core_mips_irq(struct bcma_device *dev) ++static unsigned int bcma_core_mips_irq(struct bcma_device *dev) { -@@ -87,13 +92,15 @@ unsigned int bcma_core_mips_irq(struct b + struct bcma_device *mdev = dev->bus->drv_mips.core; + u32 irqflag; unsigned int irq; irqflag = bcma_core_mips_irqflag(dev); @@ -1493,10 +1744,19 @@ - return 0; + return 5; ++} ++ ++unsigned int bcma_core_irq(struct bcma_device *dev) ++{ ++ unsigned int mips_irq = bcma_core_mips_irq(dev); ++ return mips_irq <= 4 ? mips_irq + 2 : 0; } - EXPORT_SYMBOL(bcma_core_mips_irq); +-EXPORT_SYMBOL(bcma_core_mips_irq); ++EXPORT_SYMBOL(bcma_core_irq); -@@ -114,8 +121,8 @@ static void bcma_core_mips_set_irq(struc + static void bcma_core_mips_set_irq(struct bcma_device *dev, unsigned int irq) + { +@@ -114,8 +149,8 @@ static void bcma_core_mips_set_irq(struc bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0), bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) & ~(1 << irqflag)); @@ -1507,7 +1767,7 @@ /* assign the new one */ if (irq == 0) { -@@ -123,17 +130,17 @@ static void bcma_core_mips_set_irq(struc +@@ -123,17 +158,17 @@ static void bcma_core_mips_set_irq(struc bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) | (1 << irqflag)); } else { @@ -1530,7 +1790,7 @@ bcma_core_mips_set_irq(core, 0); break; } -@@ -143,15 +150,31 @@ static void bcma_core_mips_set_irq(struc +@@ -143,15 +178,31 @@ static void bcma_core_mips_set_irq(struc 1 << irqflag); } @@ -1565,7 +1825,7 @@ for (i = 0; i <= 6; i++) printk(" %s%s", irq_name[i], i == irq ? "*" : " "); printk("\n"); -@@ -161,7 +184,7 @@ static void bcma_core_mips_dump_irq(stru +@@ -161,7 +212,7 @@ static void bcma_core_mips_dump_irq(stru { struct bcma_device *core; @@ -1574,7 +1834,7 @@ bcma_core_mips_print_irq(core, bcma_core_mips_irq(core)); } } -@@ -171,9 +194,9 @@ u32 bcma_cpu_clock(struct bcma_drv_mips +@@ -171,9 +222,9 @@ u32 bcma_cpu_clock(struct bcma_drv_mips struct bcma_bus *bus = mcore->core->bus; if (bus->drv_cc.capabilities & BCMA_CC_CAP_PMU) @@ -1586,11 +1846,12 @@ return 0; } EXPORT_SYMBOL(bcma_cpu_clock); -@@ -181,76 +204,109 @@ EXPORT_SYMBOL(bcma_cpu_clock); +@@ -181,25 +232,81 @@ EXPORT_SYMBOL(bcma_cpu_clock); static void bcma_core_mips_flash_detect(struct bcma_drv_mips *mcore) { struct bcma_bus *bus = mcore->core->bus; + struct bcma_drv_cc *cc = &bus->drv_cc; ++ struct bcma_pflash *pflash = &cc->pflash; - switch (bus->drv_cc.capabilities & BCMA_CC_CAP_FLASHT) { + switch (cc->capabilities & BCMA_CC_CAP_FLASHT) { @@ -1605,18 +1866,23 @@ - bus->drv_cc.pflash.window = 0x1c000000; - bus->drv_cc.pflash.window_size = 0x02000000; + bcma_debug(bus, "Found parallel flash\n"); -+ cc->pflash.present = true; -+ cc->pflash.window = BCMA_SOC_FLASH2; -+ cc->pflash.window_size = BCMA_SOC_FLASH2_SZ; ++ pflash->present = true; ++ pflash->window = BCMA_SOC_FLASH2; ++ pflash->window_size = BCMA_SOC_FLASH2_SZ; - if ((bcma_read32(bus->drv_cc.core, BCMA_CC_FLASH_CFG) & + if ((bcma_read32(cc->core, BCMA_CC_FLASH_CFG) & BCMA_CC_FLASH_CFG_DS) == 0) - bus->drv_cc.pflash.buswidth = 1; -+ cc->pflash.buswidth = 1; ++ pflash->buswidth = 1; else - bus->drv_cc.pflash.buswidth = 2; -+ cc->pflash.buswidth = 2; ++ pflash->buswidth = 2; ++ ++ bcma_pflash_data.width = pflash->buswidth; ++ bcma_pflash_resource.start = pflash->window; ++ bcma_pflash_resource.end = pflash->window + pflash->window_size; ++ break; default: - pr_err("flash not supported.\n"); @@ -1629,9 +1895,9 @@ + bcma_debug(bus, "Found NAND flash\n"); + bcma_nflash_init(cc); + } - } - } - ++ } ++} ++ +void bcma_core_mips_early_init(struct bcma_drv_mips *mcore) +{ + struct bcma_bus *bus = mcore->core->bus; @@ -1645,21 +1911,43 @@ + mcore->early_setup_done = true; +} + - void bcma_core_mips_init(struct bcma_drv_mips *mcore) - { - struct bcma_bus *bus; ++static void bcma_fix_i2s_irqflag(struct bcma_bus *bus) ++{ ++ struct bcma_device *cpu, *pcie, *i2s; ++ ++ /* Fixup the interrupts in 4716/4748 for i2s core (2010 Broadcom SDK) ++ * (IRQ flags > 7 are ignored when setting the interrupt masks) ++ */ ++ if (bus->chipinfo.id != BCMA_CHIP_ID_BCM4716 && ++ bus->chipinfo.id != BCMA_CHIP_ID_BCM4748) ++ return; ++ ++ cpu = bcma_find_core(bus, BCMA_CORE_MIPS_74K); ++ pcie = bcma_find_core(bus, BCMA_CORE_PCIE); ++ i2s = bcma_find_core(bus, BCMA_CORE_I2S); ++ if (cpu && pcie && i2s && ++ bcma_aread32(cpu, BCMA_MIPS_OOBSELINA74) == 0x08060504 && ++ bcma_aread32(pcie, BCMA_MIPS_OOBSELINA74) == 0x08060504 && ++ bcma_aread32(i2s, BCMA_MIPS_OOBSELOUTA30) == 0x88) { ++ bcma_awrite32(cpu, BCMA_MIPS_OOBSELINA74, 0x07060504); ++ bcma_awrite32(pcie, BCMA_MIPS_OOBSELINA74, 0x07060504); ++ bcma_awrite32(i2s, BCMA_MIPS_OOBSELOUTA30, 0x87); ++ bcma_debug(bus, ++ "Moved i2s interrupt to oob line 7 instead of 8\n"); + } + } + +@@ -209,48 +316,59 @@ void bcma_core_mips_init(struct bcma_drv struct bcma_device *core; bus = mcore->core->bus; - pr_info("Initializing MIPS core...\n"); + if (mcore->setup_done) + return; -+ -+ bcma_debug(bus, "Initializing MIPS core...\n"); - if (!mcore->setup_done) - mcore->assigned_irqs = 1; -+ bcma_core_mips_early_init(mcore); ++ bcma_debug(bus, "Initializing MIPS core...\n"); - /* Assign IRQs to all cores on the bus */ - list_for_each_entry_reverse(core, &bus->cores, list) { @@ -1689,6 +1977,10 @@ - bcma_core_mips_set_irq(core, - mcore->assigned_irqs++); - break; ++ bcma_core_mips_early_init(mcore); ++ ++ bcma_fix_i2s_irqflag(bus); ++ + switch (bus->chipinfo.id) { + case BCMA_CHIP_ID_BCM4716: + case BCMA_CHIP_ID_BCM4748: @@ -1725,7 +2017,7 @@ + break; + default: + list_for_each_entry(core, &bus->cores, list) { -+ core->irq = bcma_core_mips_irq(core) + 2; ++ core->irq = bcma_core_irq(core); } + bcma_err(bus, + "Unknown device (0x%x) found, can not configure IRQs\n", @@ -2105,7 +2397,7 @@ +EXPORT_SYMBOL_GPL(bcma_core_pci_extend_L1timer); --- a/drivers/bcma/driver_pci_host.c +++ b/drivers/bcma/driver_pci_host.c -@@ -2,13 +2,600 @@ +@@ -2,13 +2,616 @@ * Broadcom specific AMBA * PCI Core in hostmode * @@ -2186,13 +2478,11 @@ +out: + return addr; +} - --void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc) ++ +static int bcma_extpci_read_config(struct bcma_drv_pci *pc, unsigned int dev, + unsigned int func, unsigned int off, + void *buf, int len) - { -- pr_err("No support for PCI core in hostmode yet\n"); ++{ + int err = -EINVAL; + u32 addr, val; + void __iomem *mmio = 0; @@ -2203,19 +2493,19 @@ + if (dev == 0) { + /* we support only two functions on device 0 */ + if (func > 1) -+ return -EINVAL; ++ goto out; + + /* accesses to config registers with offsets >= 256 + * requires indirect access. + */ + if (off >= PCI_CONFIG_SPACE_SIZE) { + addr = (func << 12); -+ addr |= (off & 0x0FFF); ++ addr |= (off & 0x0FFC); + val = bcma_pcie_read_config(pc, addr); + } else { + addr = BCMA_CORE_PCI_PCICFG0; + addr |= (func << 8); -+ addr |= (off & 0xfc); ++ addr |= (off & 0xFC); + val = pcicore_read32(pc, addr); + } + } else { @@ -2228,11 +2518,9 @@ + goto out; + + if (mips_busprobe32(val, mmio)) { -+ val = 0xffffffff; ++ val = 0xFFFFFFFF; + goto unmap; + } -+ -+ val = readl(mmio); + } + val >>= (8 * (off & 3)); + @@ -2254,13 +2542,15 @@ +out: + return err; +} -+ + +-void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc) +static int bcma_extpci_write_config(struct bcma_drv_pci *pc, unsigned int dev, + unsigned int func, unsigned int off, + const void *buf, int len) -+{ + { +- pr_err("No support for PCI core in hostmode yet\n"); + int err = -EINVAL; -+ u32 addr = 0, val = 0; ++ u32 addr, val; + void __iomem *mmio = 0; + u16 chipid = pc->core->bus->chipinfo.id; + @@ -2268,16 +2558,22 @@ + if (unlikely(len != 1 && len != 2 && len != 4)) + goto out; + if (dev == 0) { ++ /* we support only two functions on device 0 */ ++ if (func > 1) ++ goto out; ++ + /* accesses to config registers with offsets >= 256 + * requires indirect access. + */ -+ if (off < PCI_CONFIG_SPACE_SIZE) { -+ addr = pc->core->addr + BCMA_CORE_PCI_PCICFG0; ++ if (off >= PCI_CONFIG_SPACE_SIZE) { ++ addr = (func << 12); ++ addr |= (off & 0x0FFC); ++ val = bcma_pcie_read_config(pc, addr); ++ } else { ++ addr = BCMA_CORE_PCI_PCICFG0; + addr |= (func << 8); -+ addr |= (off & 0xfc); -+ mmio = ioremap_nocache(addr, sizeof(val)); -+ if (!mmio) -+ goto out; ++ addr |= (off & 0xFC); ++ val = pcicore_read32(pc, addr); + } + } else { + addr = bcma_get_cfgspace_addr(pc, dev, func, off); @@ -2289,19 +2585,17 @@ + goto out; + + if (mips_busprobe32(val, mmio)) { -+ val = 0xffffffff; ++ val = 0xFFFFFFFF; + goto unmap; + } + } + + switch (len) { + case 1: -+ val = readl(mmio); + val &= ~(0xFF << (8 * (off & 3))); + val |= *((const u8 *)buf) << (8 * (off & 3)); + break; + case 2: -+ val = readl(mmio); + val &= ~(0xFFFF << (8 * (off & 3))); + val |= *((const u16 *)buf) << (8 * (off & 3)); + break; @@ -2309,13 +2603,14 @@ + val = *((const u32 *)buf); + break; + } -+ if (dev == 0 && !addr) { ++ if (dev == 0) { + /* accesses to config registers with offsets >= 256 + * requires indirect access. + */ -+ addr = (func << 12); -+ addr |= (off & 0x0FFF); -+ bcma_pcie_write_config(pc, addr, val); ++ if (off >= PCI_CONFIG_SPACE_SIZE) ++ bcma_pcie_write_config(pc, addr, val); ++ else ++ pcicore_write32(pc, addr, val); + } else { + writel(val, mmio); + @@ -2386,7 +2681,7 @@ + /* check for Header type 0 */ + bcma_extpci_read_config(pc, dev, func, PCI_HEADER_TYPE, &byte_val, + sizeof(u8)); -+ if ((byte_val & 0x7f) != PCI_HEADER_TYPE_NORMAL) ++ if ((byte_val & 0x7F) != PCI_HEADER_TYPE_NORMAL) + return cap_ptr; + + /* check if the capability pointer field exists */ @@ -2511,6 +2806,8 @@ + return; + } + ++ spin_lock_init(&pc_host->cfgspace_lock); ++ + pc->host_controller = pc_host; + pc_host->pci_controller.io_resource = &pc_host->io_resource; + pc_host->pci_controller.mem_resource = &pc_host->mem_resource; @@ -2536,7 +2833,7 @@ + /* Reset RC */ + usleep_range(3000, 5000); + pcicore_write32(pc, BCMA_CORE_PCI_CTL, BCMA_CORE_PCI_CTL_RST_OE); -+ usleep_range(1000, 2000); ++ msleep(50); + pcicore_write32(pc, BCMA_CORE_PCI_CTL, BCMA_CORE_PCI_CTL_RST | + BCMA_CORE_PCI_CTL_RST_OE); + @@ -2598,6 +2895,17 @@ + + bcma_core_pci_enable_crs(pc); + ++ if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4706 || ++ bus->chipinfo.id == BCMA_CHIP_ID_BCM4716) { ++ u16 val16; ++ bcma_extpci_read_config(pc, 0, 0, BCMA_CORE_PCI_CFG_DEVCTRL, ++ &val16, sizeof(val16)); ++ val16 |= (2 << 5); /* Max payload size of 512 */ ++ val16 |= (2 << 12); /* MRRS 512 */ ++ bcma_extpci_write_config(pc, 0, 0, BCMA_CORE_PCI_CFG_DEVCTRL, ++ &val16, sizeof(val16)); ++ } ++ + /* Enable PCI bridge BAR0 memory & master access */ + tmp = PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; + bcma_extpci_write_config(pc, 0, 0, PCI_COMMAND, &tmp, sizeof(tmp)); @@ -2686,7 +2994,7 @@ + pr_info("PCI: Fixing up device %s\n", pci_name(dev)); + + /* Fix up interrupt lines */ -+ dev->irq = bcma_core_mips_irq(pc_host->pdev->core) + 2; ++ dev->irq = bcma_core_irq(pc_host->pdev->core); + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + + return 0; @@ -2705,7 +3013,7 @@ + + pc_host = container_of(dev->bus->ops, struct bcma_drv_pci_host, + pci_ops); -+ return bcma_core_mips_irq(pc_host->pdev->core) + 2; ++ return bcma_core_irq(pc_host->pdev->core); } +EXPORT_SYMBOL(bcma_core_pci_pcibios_map_irq); --- a/drivers/bcma/host_pci.c @@ -2799,7 +3107,7 @@ static int bcma_host_pci_suspend(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); -@@ -257,17 +261,20 @@ static SIMPLE_DEV_PM_OPS(bcma_pm_ops, bc +@@ -257,17 +261,21 @@ static SIMPLE_DEV_PM_OPS(bcma_pm_ops, bc bcma_host_pci_resume); #define BCMA_PM_OPS (&bcma_pm_ops) @@ -2819,10 +3127,11 @@ { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4357) }, + { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4358) }, + { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4359) }, ++ { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4365) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) }, { 0, }, }; -@@ -277,7 +284,7 @@ static struct pci_driver bcma_pci_bridge +@@ -277,7 +285,7 @@ static struct pci_driver bcma_pci_bridge .name = "bcma-pci-bridge", .id_table = bcma_pci_bridge_tbl, .probe = bcma_host_pci_probe, @@ -2880,7 +3189,7 @@ { struct bcma_device *core; -@@ -65,6 +79,19 @@ static struct bcma_device *bcma_find_cor +@@ -65,6 +79,38 @@ static struct bcma_device *bcma_find_cor } return NULL; } @@ -2897,10 +3206,29 @@ + } + return NULL; +} ++ ++bool bcma_wait_value(struct bcma_device *core, u16 reg, u32 mask, u32 value, ++ int timeout) ++{ ++ unsigned long deadline = jiffies + timeout; ++ u32 val; ++ ++ do { ++ val = bcma_read32(core, reg); ++ if ((val & mask) == value) ++ return true; ++ cpu_relax(); ++ udelay(10); ++ } while (!time_after_eq(jiffies, deadline)); ++ ++ bcma_warn(core->bus, "Timeout waiting for register 0x%04X!\n", reg); ++ ++ return false; ++} static void bcma_release_core_dev(struct device *dev) { -@@ -84,16 +111,18 @@ static int bcma_register_cores(struct bc +@@ -84,16 +130,23 @@ static int bcma_register_cores(struct bc list_for_each_entry(core, &bus->cores, list) { /* We support that cores ourself */ switch (core->id.id) { @@ -2913,6 +3241,11 @@ continue; } ++ /* Only first GMAC core on BCM4706 is connected and working */ ++ if (core->id.id == BCMA_CORE_4706_MAC_GBIT && ++ core->core_unit > 0) ++ continue; ++ core->dev.release = bcma_release_core_dev; core->dev.bus = &bcma_bus_type; - dev_set_name(&core->dev, "bcma%d:%d", 0/*bus->num*/, dev_id); @@ -2920,7 +3253,7 @@ switch (bus->hosttype) { case BCMA_HOSTTYPE_PCI: -@@ -111,41 +140,90 @@ static int bcma_register_cores(struct bc +@@ -111,41 +164,98 @@ static int bcma_register_cores(struct bc err = device_register(&core->dev); if (err) { @@ -2935,6 +3268,14 @@ dev_id++; } ++#ifdef CONFIG_BCMA_DRIVER_MIPS ++ if (bus->drv_cc.pflash.present) { ++ err = platform_device_register(&bcma_pflash_dev); ++ if (err) ++ bcma_err(bus, "Error registering parallel flash\n"); ++ } ++#endif ++ +#ifdef CONFIG_BCMA_SFLASH + if (bus->drv_cc.sflash.present) { + err = platform_device_register(&bcma_sflash_dev); @@ -3018,7 +3359,7 @@ if (core) { bus->drv_cc.core = core; bcma_core_chipcommon_init(&bus->drv_cc); -@@ -159,30 +237,47 @@ int bcma_bus_register(struct bcma_bus *b +@@ -159,30 +269,54 @@ int bcma_bus_register(struct bcma_bus *b } /* Init PCIE core */ @@ -3063,6 +3404,13 @@ void bcma_bus_unregister(struct bcma_bus *bus) { + struct bcma_device *cores[3]; ++ int err; ++ ++ err = bcma_gpio_unregister(&bus->drv_cc); ++ if (err == -EBUSY) ++ bcma_err(bus, "Some GPIOs are still in use.\n"); ++ else if (err) ++ bcma_err(bus, "Can not unregister GPIO driver: %i\n", err); + + cores[0] = bcma_find_core(bus, BCMA_CORE_MIPS_74K); + cores[1] = bcma_find_core(bus, BCMA_CORE_PCIE); @@ -3076,7 +3424,7 @@ } int __init bcma_bus_early_register(struct bcma_bus *bus, -@@ -196,14 +291,14 @@ int __init bcma_bus_early_register(struc +@@ -196,14 +330,14 @@ int __init bcma_bus_early_register(struc bcma_init_bus(bus); match.manuf = BCMA_MANUF_BCM; @@ -3093,7 +3441,7 @@ return -1; } -@@ -215,25 +310,25 @@ int __init bcma_bus_early_register(struc +@@ -215,25 +349,25 @@ int __init bcma_bus_early_register(struc /* Scan for mips core */ err = bcma_bus_scan_early(bus, &match, core_mips); if (err) { @@ -3126,7 +3474,7 @@ return 0; } -@@ -259,8 +354,7 @@ int bcma_bus_resume(struct bcma_bus *bus +@@ -259,8 +393,7 @@ int bcma_bus_resume(struct bcma_bus *bus struct bcma_device *core; /* Init CC core */ @@ -3192,8 +3540,12 @@ { BCMA_CORE_MAC_GBIT, "GBit MAC" }, { BCMA_CORE_DDR12_MEM_CTL, "DDR1/DDR2 Memory Controller" }, { BCMA_CORE_PCIE_RC, "PCIe Root Complex" }, -@@ -79,16 +86,41 @@ struct bcma_device_id_name bcma_device_n +@@ -77,18 +84,45 @@ struct bcma_device_id_name bcma_device_n + { BCMA_CORE_I2S, "I2S" }, + { BCMA_CORE_SDR_DDR1_MEM_CTL, "SDR/DDR1 Memory Controller" }, { BCMA_CORE_SHIM, "SHIM" }, ++ { BCMA_CORE_PCIE2, "PCIe Gen2" }, ++ { BCMA_CORE_ARM_CR4, "ARM CR4" }, { BCMA_CORE_DEFAULT, "Default" }, }; -const char *bcma_device_name(struct bcma_device_id *id) @@ -3241,7 +3593,74 @@ return "UNKNOWN"; } -@@ -212,6 +244,17 @@ static struct bcma_device *bcma_find_cor +@@ -105,19 +139,19 @@ static void bcma_scan_switch_core(struct + addr); + } + +-static u32 bcma_erom_get_ent(struct bcma_bus *bus, u32 **eromptr) ++static u32 bcma_erom_get_ent(struct bcma_bus *bus, u32 __iomem **eromptr) + { + u32 ent = readl(*eromptr); + (*eromptr)++; + return ent; + } + +-static void bcma_erom_push_ent(u32 **eromptr) ++static void bcma_erom_push_ent(u32 __iomem **eromptr) + { + (*eromptr)--; + } + +-static s32 bcma_erom_get_ci(struct bcma_bus *bus, u32 **eromptr) ++static s32 bcma_erom_get_ci(struct bcma_bus *bus, u32 __iomem **eromptr) + { + u32 ent = bcma_erom_get_ent(bus, eromptr); + if (!(ent & SCAN_ER_VALID)) +@@ -127,14 +161,14 @@ static s32 bcma_erom_get_ci(struct bcma_ + return ent; + } + +-static bool bcma_erom_is_end(struct bcma_bus *bus, u32 **eromptr) ++static bool bcma_erom_is_end(struct bcma_bus *bus, u32 __iomem **eromptr) + { + u32 ent = bcma_erom_get_ent(bus, eromptr); + bcma_erom_push_ent(eromptr); + return (ent == (SCAN_ER_TAG_END | SCAN_ER_VALID)); + } + +-static bool bcma_erom_is_bridge(struct bcma_bus *bus, u32 **eromptr) ++static bool bcma_erom_is_bridge(struct bcma_bus *bus, u32 __iomem **eromptr) + { + u32 ent = bcma_erom_get_ent(bus, eromptr); + bcma_erom_push_ent(eromptr); +@@ -143,7 +177,7 @@ static bool bcma_erom_is_bridge(struct b + ((ent & SCAN_ADDR_TYPE) == SCAN_ADDR_TYPE_BRIDGE)); + } + +-static void bcma_erom_skip_component(struct bcma_bus *bus, u32 **eromptr) ++static void bcma_erom_skip_component(struct bcma_bus *bus, u32 __iomem **eromptr) + { + u32 ent; + while (1) { +@@ -157,7 +191,7 @@ static void bcma_erom_skip_component(str + bcma_erom_push_ent(eromptr); + } + +-static s32 bcma_erom_get_mst_port(struct bcma_bus *bus, u32 **eromptr) ++static s32 bcma_erom_get_mst_port(struct bcma_bus *bus, u32 __iomem **eromptr) + { + u32 ent = bcma_erom_get_ent(bus, eromptr); + if (!(ent & SCAN_ER_VALID)) +@@ -167,7 +201,7 @@ static s32 bcma_erom_get_mst_port(struct + return ent; + } + +-static s32 bcma_erom_get_addr_desc(struct bcma_bus *bus, u32 **eromptr, ++static s32 bcma_erom_get_addr_desc(struct bcma_bus *bus, u32 __iomem **eromptr, + u32 type, u8 port) + { + u32 addrl, addrh, sizel, sizeh = 0; +@@ -212,6 +246,17 @@ static struct bcma_device *bcma_find_cor return NULL; } @@ -3259,7 +3678,7 @@ static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr, struct bcma_device_id *match, int core_num, struct bcma_device *core) -@@ -252,11 +295,15 @@ static int bcma_get_next_core(struct bcm +@@ -252,11 +297,15 @@ static int bcma_get_next_core(struct bcm /* check if component is a core at all */ if (wrappers[0] + wrappers[1] == 0) { @@ -3280,7 +3699,7 @@ } if (bcma_erom_is_bridge(bus, eromptr)) { -@@ -286,6 +333,23 @@ static int bcma_get_next_core(struct bcm +@@ -286,6 +335,23 @@ static int bcma_get_next_core(struct bcm return -EILSEQ; } @@ -3304,7 +3723,7 @@ /* get & parse slave ports */ for (i = 0; i < ports[1]; i++) { for (j = 0; ; j++) { -@@ -298,7 +362,7 @@ static int bcma_get_next_core(struct bcm +@@ -298,7 +364,7 @@ static int bcma_get_next_core(struct bcm break; } else { if (i == 0 && j == 0) @@ -3313,7 +3732,7 @@ } } } -@@ -353,6 +417,7 @@ static int bcma_get_next_core(struct bcm +@@ -353,6 +419,7 @@ static int bcma_get_next_core(struct bcm void bcma_init_bus(struct bcma_bus *bus) { s32 tmp; @@ -3321,7 +3740,7 @@ if (bus->init_done) return; -@@ -363,9 +428,12 @@ void bcma_init_bus(struct bcma_bus *bus) +@@ -363,9 +430,12 @@ void bcma_init_bus(struct bcma_bus *bus) bcma_scan_switch_core(bus, BCMA_ADDR_BASE); tmp = bcma_scan_read32(bus, 0, BCMA_CC_ID); @@ -3337,7 +3756,7 @@ bus->init_done = true; } -@@ -392,9 +460,12 @@ int bcma_bus_scan(struct bcma_bus *bus) +@@ -392,9 +462,12 @@ int bcma_bus_scan(struct bcma_bus *bus) bcma_scan_switch_core(bus, erombase); while (eromptr < eromend) { @@ -3352,7 +3771,7 @@ INIT_LIST_HEAD(&core->list); core->bus = bus; -@@ -409,25 +480,28 @@ int bcma_bus_scan(struct bcma_bus *bus) +@@ -409,25 +482,28 @@ int bcma_bus_scan(struct bcma_bus *bus) } else if (err == -ESPIPE) { break; } @@ -3389,7 +3808,7 @@ } int __init bcma_bus_scan_early(struct bcma_bus *bus, -@@ -467,21 +541,21 @@ int __init bcma_bus_scan_early(struct bc +@@ -467,21 +543,21 @@ int __init bcma_bus_scan_early(struct bc else if (err == -ESPIPE) break; else if (err < 0) @@ -3440,7 +3859,7 @@ * Licensed under the GNU/GPL. See COPYING for details. */ -@@ -14,7 +16,57 @@ +@@ -14,18 +16,68 @@ #include <linux/dma-mapping.h> #include <linux/slab.h> @@ -3499,7 +3918,88 @@ /************************************************** * R/W ops. -@@ -124,10 +176,37 @@ static int bcma_sprom_valid(const u16 *s + **************************************************/ + +-static void bcma_sprom_read(struct bcma_bus *bus, u16 offset, u16 *sprom) ++static void bcma_sprom_read(struct bcma_bus *bus, u16 offset, u16 *sprom, ++ size_t words) + { + int i; +- for (i = 0; i < SSB_SPROMSIZE_WORDS_R4; i++) +- sprom[i] = bcma_read16(bus->drv_cc.core, +- offset + (i * 2)); ++ for (i = 0; i < words; i++) ++ sprom[i] = bcma_read16(bus->drv_cc.core, offset + (i * 2)); + } + + /************************************************** +@@ -72,29 +124,29 @@ static inline u8 bcma_crc8(u8 crc, u8 da + return t[crc ^ data]; + } + +-static u8 bcma_sprom_crc(const u16 *sprom) ++static u8 bcma_sprom_crc(const u16 *sprom, size_t words) + { + int word; + u8 crc = 0xFF; + +- for (word = 0; word < SSB_SPROMSIZE_WORDS_R4 - 1; word++) { ++ for (word = 0; word < words - 1; word++) { + crc = bcma_crc8(crc, sprom[word] & 0x00FF); + crc = bcma_crc8(crc, (sprom[word] & 0xFF00) >> 8); + } +- crc = bcma_crc8(crc, sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & 0x00FF); ++ crc = bcma_crc8(crc, sprom[words - 1] & 0x00FF); + crc ^= 0xFF; + + return crc; + } + +-static int bcma_sprom_check_crc(const u16 *sprom) ++static int bcma_sprom_check_crc(const u16 *sprom, size_t words) + { + u8 crc; + u8 expected_crc; + u16 tmp; + +- crc = bcma_sprom_crc(sprom); +- tmp = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & SSB_SPROM_REVISION_CRC; ++ crc = bcma_sprom_crc(sprom, words); ++ tmp = sprom[words - 1] & SSB_SPROM_REVISION_CRC; + expected_crc = tmp >> SSB_SPROM_REVISION_CRC_SHIFT; + if (crc != expected_crc) + return -EPROTO; +@@ -102,21 +154,25 @@ static int bcma_sprom_check_crc(const u1 + return 0; + } + +-static int bcma_sprom_valid(const u16 *sprom) ++static int bcma_sprom_valid(struct bcma_bus *bus, const u16 *sprom, ++ size_t words) + { + u16 revision; + int err; + +- err = bcma_sprom_check_crc(sprom); ++ err = bcma_sprom_check_crc(sprom, words); + if (err) + return err; + +- revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & SSB_SPROM_REVISION_REV; +- if (revision != 8 && revision != 9) { ++ revision = sprom[words - 1] & SSB_SPROM_REVISION_REV; ++ if (revision != 8 && revision != 9 && revision != 10) { + pr_err("Unsupported SPROM revision: %d\n", revision); + return -ENOENT; + } + ++ bus->sprom.revision = revision; ++ bcma_debug(bus, "Found SPROM revision %d\n", revision); ++ + return 0; + } + +@@ -124,124 +180,439 @@ static int bcma_sprom_valid(const u16 *s * SPROM extraction. **************************************************/ @@ -3529,6 +4029,9 @@ - u16 v; + u16 v, o; int i; +- +- bus->sprom.revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & +- SSB_SPROM_REVISION_REV; + u16 pwr_info_offset[] = { + SSB_SROM8_PWR_INFO_CORE0, SSB_SROM8_PWR_INFO_CORE1, + SSB_SROM8_PWR_INFO_CORE2, SSB_SROM8_PWR_INFO_CORE3 @@ -3536,14 +4039,14 @@ + BUILD_BUG_ON(ARRAY_SIZE(pwr_info_offset) != + ARRAY_SIZE(bus->sprom.core_pwr_info)); - bus->sprom.revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & - SSB_SPROM_REVISION_REV; -@@ -137,107 +216,390 @@ static void bcma_sprom_extract_r8(struct + for (i = 0; i < 3; i++) { + v = sprom[SPOFF(SSB_SPROM8_IL0MAC) + i]; *(((__be16 *)bus->sprom.il0mac) + i) = cpu_to_be16(v); } - bus->sprom.board_rev = sprom[SPOFF(SSB_SPROM8_BOARDREV)]; + SPEX(board_rev, SSB_SPROM8_BOARDREV, ~0, 0); ++ SPEX(board_type, SSB_SPROM1_SPID, ~0, 0); + + SPEX(txpid2g[0], SSB_SPROM4_TXPID2G01, SSB_SPROM4_TXPID2G0, + SSB_SPROM4_TXPID2G0_SHIFT); @@ -3620,71 +4123,7 @@ + SPEX(core_pwr_info[i].pa_5gh[1], o + SSB_SROM8_5GH_PA_1, ~0, 0); + SPEX(core_pwr_info[i].pa_5gh[2], o + SSB_SROM8_5GH_PA_2, ~0, 0); + } - -- bus->sprom.txpid2g[0] = (sprom[SPOFF(SSB_SPROM4_TXPID2G01)] & -- SSB_SPROM4_TXPID2G0) >> SSB_SPROM4_TXPID2G0_SHIFT; -- bus->sprom.txpid2g[1] = (sprom[SPOFF(SSB_SPROM4_TXPID2G01)] & -- SSB_SPROM4_TXPID2G1) >> SSB_SPROM4_TXPID2G1_SHIFT; -- bus->sprom.txpid2g[2] = (sprom[SPOFF(SSB_SPROM4_TXPID2G23)] & -- SSB_SPROM4_TXPID2G2) >> SSB_SPROM4_TXPID2G2_SHIFT; -- bus->sprom.txpid2g[3] = (sprom[SPOFF(SSB_SPROM4_TXPID2G23)] & -- SSB_SPROM4_TXPID2G3) >> SSB_SPROM4_TXPID2G3_SHIFT; -- -- bus->sprom.txpid5gl[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL01)] & -- SSB_SPROM4_TXPID5GL0) >> SSB_SPROM4_TXPID5GL0_SHIFT; -- bus->sprom.txpid5gl[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL01)] & -- SSB_SPROM4_TXPID5GL1) >> SSB_SPROM4_TXPID5GL1_SHIFT; -- bus->sprom.txpid5gl[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL23)] & -- SSB_SPROM4_TXPID5GL2) >> SSB_SPROM4_TXPID5GL2_SHIFT; -- bus->sprom.txpid5gl[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL23)] & -- SSB_SPROM4_TXPID5GL3) >> SSB_SPROM4_TXPID5GL3_SHIFT; -- -- bus->sprom.txpid5g[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5G01)] & -- SSB_SPROM4_TXPID5G0) >> SSB_SPROM4_TXPID5G0_SHIFT; -- bus->sprom.txpid5g[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5G01)] & -- SSB_SPROM4_TXPID5G1) >> SSB_SPROM4_TXPID5G1_SHIFT; -- bus->sprom.txpid5g[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5G23)] & -- SSB_SPROM4_TXPID5G2) >> SSB_SPROM4_TXPID5G2_SHIFT; -- bus->sprom.txpid5g[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5G23)] & -- SSB_SPROM4_TXPID5G3) >> SSB_SPROM4_TXPID5G3_SHIFT; -- -- bus->sprom.txpid5gh[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH01)] & -- SSB_SPROM4_TXPID5GH0) >> SSB_SPROM4_TXPID5GH0_SHIFT; -- bus->sprom.txpid5gh[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH01)] & -- SSB_SPROM4_TXPID5GH1) >> SSB_SPROM4_TXPID5GH1_SHIFT; -- bus->sprom.txpid5gh[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH23)] & -- SSB_SPROM4_TXPID5GH2) >> SSB_SPROM4_TXPID5GH2_SHIFT; -- bus->sprom.txpid5gh[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH23)] & -- SSB_SPROM4_TXPID5GH3) >> SSB_SPROM4_TXPID5GH3_SHIFT; -- -- bus->sprom.boardflags_lo = sprom[SPOFF(SSB_SPROM8_BFLLO)]; -- bus->sprom.boardflags_hi = sprom[SPOFF(SSB_SPROM8_BFLHI)]; -- bus->sprom.boardflags2_lo = sprom[SPOFF(SSB_SPROM8_BFL2LO)]; -- bus->sprom.boardflags2_hi = sprom[SPOFF(SSB_SPROM8_BFL2HI)]; -- -- bus->sprom.country_code = sprom[SPOFF(SSB_SPROM8_CCODE)]; -- -- bus->sprom.fem.ghz2.tssipos = (sprom[SPOFF(SSB_SPROM8_FEM2G)] & -- SSB_SROM8_FEM_TSSIPOS) >> SSB_SROM8_FEM_TSSIPOS_SHIFT; -- bus->sprom.fem.ghz2.extpa_gain = (sprom[SPOFF(SSB_SPROM8_FEM2G)] & -- SSB_SROM8_FEM_EXTPA_GAIN) >> SSB_SROM8_FEM_EXTPA_GAIN_SHIFT; -- bus->sprom.fem.ghz2.pdet_range = (sprom[SPOFF(SSB_SPROM8_FEM2G)] & -- SSB_SROM8_FEM_PDET_RANGE) >> SSB_SROM8_FEM_PDET_RANGE_SHIFT; -- bus->sprom.fem.ghz2.tr_iso = (sprom[SPOFF(SSB_SPROM8_FEM2G)] & -- SSB_SROM8_FEM_TR_ISO) >> SSB_SROM8_FEM_TR_ISO_SHIFT; -- bus->sprom.fem.ghz2.antswlut = (sprom[SPOFF(SSB_SPROM8_FEM2G)] & -- SSB_SROM8_FEM_ANTSWLUT) >> SSB_SROM8_FEM_ANTSWLUT_SHIFT; -- -- bus->sprom.fem.ghz5.tssipos = (sprom[SPOFF(SSB_SPROM8_FEM5G)] & -- SSB_SROM8_FEM_TSSIPOS) >> SSB_SROM8_FEM_TSSIPOS_SHIFT; -- bus->sprom.fem.ghz5.extpa_gain = (sprom[SPOFF(SSB_SPROM8_FEM5G)] & -- SSB_SROM8_FEM_EXTPA_GAIN) >> SSB_SROM8_FEM_EXTPA_GAIN_SHIFT; -- bus->sprom.fem.ghz5.pdet_range = (sprom[SPOFF(SSB_SPROM8_FEM5G)] & -- SSB_SROM8_FEM_PDET_RANGE) >> SSB_SROM8_FEM_PDET_RANGE_SHIFT; -- bus->sprom.fem.ghz5.tr_iso = (sprom[SPOFF(SSB_SPROM8_FEM5G)] & -- SSB_SROM8_FEM_TR_ISO) >> SSB_SROM8_FEM_TR_ISO_SHIFT; -- bus->sprom.fem.ghz5.antswlut = (sprom[SPOFF(SSB_SPROM8_FEM5G)] & -- SSB_SROM8_FEM_ANTSWLUT) >> SSB_SROM8_FEM_ANTSWLUT_SHIFT; ++ + SPEX(fem.ghz2.tssipos, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_TSSIPOS, + SSB_SROM8_FEM_TSSIPOS_SHIFT); + SPEX(fem.ghz2.extpa_gain, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_EXTPA_GAIN, @@ -3866,7 +4305,71 @@ + case BCMA_CHIP_ID_BCM4331: + present_mask = BCMA_CC_CHIPST_4331_SPROM_PRESENT; + break; -+ + +- bus->sprom.txpid2g[0] = (sprom[SPOFF(SSB_SPROM4_TXPID2G01)] & +- SSB_SPROM4_TXPID2G0) >> SSB_SPROM4_TXPID2G0_SHIFT; +- bus->sprom.txpid2g[1] = (sprom[SPOFF(SSB_SPROM4_TXPID2G01)] & +- SSB_SPROM4_TXPID2G1) >> SSB_SPROM4_TXPID2G1_SHIFT; +- bus->sprom.txpid2g[2] = (sprom[SPOFF(SSB_SPROM4_TXPID2G23)] & +- SSB_SPROM4_TXPID2G2) >> SSB_SPROM4_TXPID2G2_SHIFT; +- bus->sprom.txpid2g[3] = (sprom[SPOFF(SSB_SPROM4_TXPID2G23)] & +- SSB_SPROM4_TXPID2G3) >> SSB_SPROM4_TXPID2G3_SHIFT; +- +- bus->sprom.txpid5gl[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL01)] & +- SSB_SPROM4_TXPID5GL0) >> SSB_SPROM4_TXPID5GL0_SHIFT; +- bus->sprom.txpid5gl[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL01)] & +- SSB_SPROM4_TXPID5GL1) >> SSB_SPROM4_TXPID5GL1_SHIFT; +- bus->sprom.txpid5gl[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL23)] & +- SSB_SPROM4_TXPID5GL2) >> SSB_SPROM4_TXPID5GL2_SHIFT; +- bus->sprom.txpid5gl[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL23)] & +- SSB_SPROM4_TXPID5GL3) >> SSB_SPROM4_TXPID5GL3_SHIFT; +- +- bus->sprom.txpid5g[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5G01)] & +- SSB_SPROM4_TXPID5G0) >> SSB_SPROM4_TXPID5G0_SHIFT; +- bus->sprom.txpid5g[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5G01)] & +- SSB_SPROM4_TXPID5G1) >> SSB_SPROM4_TXPID5G1_SHIFT; +- bus->sprom.txpid5g[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5G23)] & +- SSB_SPROM4_TXPID5G2) >> SSB_SPROM4_TXPID5G2_SHIFT; +- bus->sprom.txpid5g[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5G23)] & +- SSB_SPROM4_TXPID5G3) >> SSB_SPROM4_TXPID5G3_SHIFT; +- +- bus->sprom.txpid5gh[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH01)] & +- SSB_SPROM4_TXPID5GH0) >> SSB_SPROM4_TXPID5GH0_SHIFT; +- bus->sprom.txpid5gh[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH01)] & +- SSB_SPROM4_TXPID5GH1) >> SSB_SPROM4_TXPID5GH1_SHIFT; +- bus->sprom.txpid5gh[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH23)] & +- SSB_SPROM4_TXPID5GH2) >> SSB_SPROM4_TXPID5GH2_SHIFT; +- bus->sprom.txpid5gh[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH23)] & +- SSB_SPROM4_TXPID5GH3) >> SSB_SPROM4_TXPID5GH3_SHIFT; +- +- bus->sprom.boardflags_lo = sprom[SPOFF(SSB_SPROM8_BFLLO)]; +- bus->sprom.boardflags_hi = sprom[SPOFF(SSB_SPROM8_BFLHI)]; +- bus->sprom.boardflags2_lo = sprom[SPOFF(SSB_SPROM8_BFL2LO)]; +- bus->sprom.boardflags2_hi = sprom[SPOFF(SSB_SPROM8_BFL2HI)]; +- +- bus->sprom.country_code = sprom[SPOFF(SSB_SPROM8_CCODE)]; +- +- bus->sprom.fem.ghz2.tssipos = (sprom[SPOFF(SSB_SPROM8_FEM2G)] & +- SSB_SROM8_FEM_TSSIPOS) >> SSB_SROM8_FEM_TSSIPOS_SHIFT; +- bus->sprom.fem.ghz2.extpa_gain = (sprom[SPOFF(SSB_SPROM8_FEM2G)] & +- SSB_SROM8_FEM_EXTPA_GAIN) >> SSB_SROM8_FEM_EXTPA_GAIN_SHIFT; +- bus->sprom.fem.ghz2.pdet_range = (sprom[SPOFF(SSB_SPROM8_FEM2G)] & +- SSB_SROM8_FEM_PDET_RANGE) >> SSB_SROM8_FEM_PDET_RANGE_SHIFT; +- bus->sprom.fem.ghz2.tr_iso = (sprom[SPOFF(SSB_SPROM8_FEM2G)] & +- SSB_SROM8_FEM_TR_ISO) >> SSB_SROM8_FEM_TR_ISO_SHIFT; +- bus->sprom.fem.ghz2.antswlut = (sprom[SPOFF(SSB_SPROM8_FEM2G)] & +- SSB_SROM8_FEM_ANTSWLUT) >> SSB_SROM8_FEM_ANTSWLUT_SHIFT; +- +- bus->sprom.fem.ghz5.tssipos = (sprom[SPOFF(SSB_SPROM8_FEM5G)] & +- SSB_SROM8_FEM_TSSIPOS) >> SSB_SROM8_FEM_TSSIPOS_SHIFT; +- bus->sprom.fem.ghz5.extpa_gain = (sprom[SPOFF(SSB_SPROM8_FEM5G)] & +- SSB_SROM8_FEM_EXTPA_GAIN) >> SSB_SROM8_FEM_EXTPA_GAIN_SHIFT; +- bus->sprom.fem.ghz5.pdet_range = (sprom[SPOFF(SSB_SPROM8_FEM5G)] & +- SSB_SROM8_FEM_PDET_RANGE) >> SSB_SROM8_FEM_PDET_RANGE_SHIFT; +- bus->sprom.fem.ghz5.tr_iso = (sprom[SPOFF(SSB_SPROM8_FEM5G)] & +- SSB_SROM8_FEM_TR_ISO) >> SSB_SROM8_FEM_TR_ISO_SHIFT; +- bus->sprom.fem.ghz5.antswlut = (sprom[SPOFF(SSB_SPROM8_FEM5G)] & +- SSB_SROM8_FEM_ANTSWLUT) >> SSB_SROM8_FEM_ANTSWLUT_SHIFT; + default: + return true; + } @@ -3892,7 +4395,7 @@ + case BCMA_CHIP_ID_BCM4331: + present = chip_status & BCMA_CC_CHIPST_4331_OTP_PRESENT; + break; -+ ++ case BCMA_CHIP_ID_BCM43142: + case BCMA_CHIP_ID_BCM43224: + case BCMA_CHIP_ID_BCM43225: + /* for these chips OTP is always available */ @@ -3941,7 +4444,10 @@ - u16 offset; + u16 offset = BCMA_CC_SPROM; u16 *sprom; - int err = 0; +- int err = 0; ++ size_t sprom_sizes[] = { SSB_SPROMSIZE_WORDS_R4, ++ SSB_SPROMSIZE_WORDS_R10, }; ++ int i, err = 0; if (!bus->drv_cc.core) return -EOPNOTSUPP; @@ -3950,7 +4456,11 @@ - return -ENOENT; + if (!bcma_sprom_ext_available(bus)) { + bool sprom_onchip; -+ + +- sprom = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16), +- GFP_KERNEL); +- if (!sprom) +- return -ENOMEM; + /* + * External SPROM takes precedence so check + * on-chip OTP only when no external SPROM @@ -3972,11 +4482,6 @@ + } + } - sprom = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16), - GFP_KERNEL); - if (!sprom) - return -ENOMEM; - - if (bus->chipinfo.id == 0x4331) + if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4331 || + bus->chipinfo.id == BCMA_CHIP_ID_BCM43431) @@ -3987,24 +4492,45 @@ - * TODO: understand this condition and use it */ - offset = (bus->chipinfo.id == 0x4331) ? BCMA_CC_SPROM : - BCMA_CC_SPROM_PCIE6; +- bcma_sprom_read(bus, offset, sprom); + bcma_debug(bus, "SPROM offset 0x%x\n", offset); - bcma_sprom_read(bus, offset, sprom); ++ for (i = 0; i < ARRAY_SIZE(sprom_sizes); i++) { ++ size_t words = sprom_sizes[i]; ++ ++ sprom = kcalloc(words, sizeof(u16), GFP_KERNEL); ++ if (!sprom) ++ return -ENOMEM; ++ ++ bcma_sprom_read(bus, offset, sprom, words); ++ err = bcma_sprom_valid(bus, sprom, words); ++ if (!err) ++ break; - if (bus->chipinfo.id == 0x4331) +- bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, true); ++ kfree(sprom); ++ } + +- err = bcma_sprom_valid(sprom); +- if (err) +- goto out; + if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4331 || + bus->chipinfo.id == BCMA_CHIP_ID_BCM43431) - bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, true); ++ bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, true); - err = bcma_sprom_valid(sprom); -- if (err) +- bcma_sprom_extract_r8(bus, sprom); + if (err) { -+ bcma_warn(bus, "invalid sprom read from the PCIe card, try to use fallback sprom\n"); ++ bcma_warn(bus, "Invalid SPROM read from the PCIe card, trying to use fallback SPROM\n"); + err = bcma_fill_sprom_with_fallback(bus, &bus->sprom); - goto out; ++ } else { ++ bcma_sprom_extract_r8(bus, sprom); ++ kfree(sprom); + } - bcma_sprom_extract_r8(bus, sprom); - +-out: +- kfree(sprom); + return err; + } --- a/include/linux/bcma/bcma.h +++ b/include/linux/bcma/bcma.h @@ -7,9 +7,10 @@ @@ -4045,17 +4571,21 @@ #define BCMA_CORE_INVALID 0x700 #define BCMA_CORE_CHIPCOMMON 0x800 #define BCMA_CORE_ILINE20 0x801 -@@ -121,10 +134,46 @@ struct bcma_host_ops { +@@ -121,10 +134,104 @@ struct bcma_host_ops { #define BCMA_CORE_I2S 0x834 #define BCMA_CORE_SDR_DDR1_MEM_CTL 0x835 /* SDR/DDR1 memory controller core */ #define BCMA_CORE_SHIM 0x837 /* SHIM component in ubus/6362 */ -+#define BCMA_CORE_ARM_CR4 0x83e ++#define BCMA_CORE_PHY_AC 0x83B ++#define BCMA_CORE_PCIE2 0x83C /* PCI Express Gen2 */ ++#define BCMA_CORE_USB30_DEV 0x83D ++#define BCMA_CORE_ARM_CR4 0x83E #define BCMA_CORE_DEFAULT 0xFFF #define BCMA_MAX_NR_CORES 16 +/* Chip IDs of PCIe devices */ +#define BCMA_CHIP_ID_BCM4313 0x4313 ++#define BCMA_CHIP_ID_BCM43142 43142 +#define BCMA_CHIP_ID_BCM43224 43224 +#define BCMA_PKG_ID_BCM43224_FAB_CSM 0x8 +#define BCMA_PKG_ID_BCM43224_FAB_SMIC 0xa @@ -4089,10 +4619,64 @@ +#define BCMA_CHIP_ID_BCM53572 53572 +#define BCMA_PKG_ID_BCM47188 9 + ++/* Board types (on PCI usually equals to the subsystem dev id) */ ++/* BCM4313 */ ++#define BCMA_BOARD_TYPE_BCM94313BU 0X050F ++#define BCMA_BOARD_TYPE_BCM94313HM 0X0510 ++#define BCMA_BOARD_TYPE_BCM94313EPA 0X0511 ++#define BCMA_BOARD_TYPE_BCM94313HMG 0X051C ++/* BCM4716 */ ++#define BCMA_BOARD_TYPE_BCM94716NR2 0X04CD ++/* BCM43224 */ ++#define BCMA_BOARD_TYPE_BCM943224X21 0X056E ++#define BCMA_BOARD_TYPE_BCM943224X21_FCC 0X00D1 ++#define BCMA_BOARD_TYPE_BCM943224X21B 0X00E9 ++#define BCMA_BOARD_TYPE_BCM943224M93 0X008B ++#define BCMA_BOARD_TYPE_BCM943224M93A 0X0090 ++#define BCMA_BOARD_TYPE_BCM943224X16 0X0093 ++#define BCMA_BOARD_TYPE_BCM94322X9 0X008D ++#define BCMA_BOARD_TYPE_BCM94322M35E 0X008E ++/* BCM43228 */ ++#define BCMA_BOARD_TYPE_BCM943228BU8 0X0540 ++#define BCMA_BOARD_TYPE_BCM943228BU9 0X0541 ++#define BCMA_BOARD_TYPE_BCM943228BU 0X0542 ++#define BCMA_BOARD_TYPE_BCM943227HM4L 0X0543 ++#define BCMA_BOARD_TYPE_BCM943227HMB 0X0544 ++#define BCMA_BOARD_TYPE_BCM943228HM4L 0X0545 ++#define BCMA_BOARD_TYPE_BCM943228SD 0X0573 ++/* BCM4331 */ ++#define BCMA_BOARD_TYPE_BCM94331X19 0X00D6 ++#define BCMA_BOARD_TYPE_BCM94331X28 0X00E4 ++#define BCMA_BOARD_TYPE_BCM94331X28B 0X010E ++#define BCMA_BOARD_TYPE_BCM94331PCIEBT3AX 0X00E4 ++#define BCMA_BOARD_TYPE_BCM94331X12_2G 0X00EC ++#define BCMA_BOARD_TYPE_BCM94331X12_5G 0X00ED ++#define BCMA_BOARD_TYPE_BCM94331X29B 0X00EF ++#define BCMA_BOARD_TYPE_BCM94331CSAX 0X00EF ++#define BCMA_BOARD_TYPE_BCM94331X19C 0X00F5 ++#define BCMA_BOARD_TYPE_BCM94331X33 0X00F4 ++#define BCMA_BOARD_TYPE_BCM94331BU 0X0523 ++#define BCMA_BOARD_TYPE_BCM94331S9BU 0X0524 ++#define BCMA_BOARD_TYPE_BCM94331MC 0X0525 ++#define BCMA_BOARD_TYPE_BCM94331MCI 0X0526 ++#define BCMA_BOARD_TYPE_BCM94331PCIEBT4 0X0527 ++#define BCMA_BOARD_TYPE_BCM94331HM 0X0574 ++#define BCMA_BOARD_TYPE_BCM94331PCIEDUAL 0X059B ++#define BCMA_BOARD_TYPE_BCM94331MCH5 0X05A9 ++#define BCMA_BOARD_TYPE_BCM94331CS 0X05C6 ++#define BCMA_BOARD_TYPE_BCM94331CD 0X05DA ++/* BCM53572 */ ++#define BCMA_BOARD_TYPE_BCM953572BU 0X058D ++#define BCMA_BOARD_TYPE_BCM953572NR2 0X058E ++#define BCMA_BOARD_TYPE_BCM947188NR2 0X058F ++#define BCMA_BOARD_TYPE_BCM953572SDRNR2 0X0590 ++/* BCM43142 */ ++#define BCMA_BOARD_TYPE_BCM943142HM 0X05E0 ++ struct bcma_device { struct bcma_bus *bus; struct bcma_device_id id; -@@ -136,8 +185,10 @@ struct bcma_device { +@@ -136,8 +243,10 @@ struct bcma_device { bool dev_registered; u8 core_index; @@ -4103,7 +4687,7 @@ u32 wrap; void __iomem *io_addr; -@@ -175,6 +226,12 @@ int __bcma_driver_register(struct bcma_d +@@ -175,6 +284,12 @@ int __bcma_driver_register(struct bcma_d extern void bcma_driver_unregister(struct bcma_driver *drv); @@ -4116,7 +4700,7 @@ struct bcma_bus { /* The MMIO area. */ void __iomem *mmio; -@@ -191,14 +248,18 @@ struct bcma_bus { +@@ -191,14 +306,18 @@ struct bcma_bus { struct bcma_chipinfo chipinfo; @@ -4136,7 +4720,7 @@ /* We decided to share SPROM struct with SSB as long as we do not need * any hacks for BCMA. This simplifies drivers code. */ -@@ -282,6 +343,7 @@ static inline void bcma_maskset16(struct +@@ -282,6 +401,7 @@ static inline void bcma_maskset16(struct bcma_write16(cc, offset, (bcma_read16(cc, offset) & mask) | set); } @@ -4144,7 +4728,7 @@ extern bool bcma_core_is_enabled(struct bcma_device *core); extern void bcma_core_disable(struct bcma_device *core, u32 flags); extern int bcma_core_enable(struct bcma_device *core, u32 flags); -@@ -289,6 +351,7 @@ extern void bcma_core_set_clockmode(stru +@@ -289,6 +409,7 @@ extern void bcma_core_set_clockmode(stru enum bcma_clkmode clkmode); extern void bcma_core_pll_ctl(struct bcma_device *core, u32 req, u32 status, bool on); @@ -4169,7 +4753,7 @@ #define BCMA_CC_FLASHT_STSER 0x00000100 /* ST serial flash */ #define BCMA_CC_FLASHT_ATSER 0x00000200 /* Atmel serial flash */ -#define BCMA_CC_FLASHT_NFLASH 0x00000200 -+#define BCMA_CC_FLASHT_NFLASH 0x00000200 /* NAND flash */ ++#define BCMA_CC_FLASHT_NAND 0x00000300 /* NAND flash */ #define BCMA_CC_FLASHT_PARA 0x00000700 /* Parallel flash */ #define BCMA_CC_CAP_PLLT 0x00038000 /* PLL Type */ #define BCMA_PLLTYPE_NONE 0x00000000 @@ -4339,9 +4923,24 @@ #define BCMA_CC_PMU_CTL_PLL_UPD 0x00000400 #define BCMA_CC_PMU_CTL_NOILPONW 0x00000200 /* No ILP on wait */ #define BCMA_CC_PMU_CTL_HTREQEN 0x00000100 /* HT req enable */ -@@ -240,7 +356,60 @@ +@@ -214,6 +330,8 @@ + #define BCMA_CC_PMU_CAP 0x0604 /* PMU capabilities */ + #define BCMA_CC_PMU_CAP_REVISION 0x000000FF /* Revision mask */ + #define BCMA_CC_PMU_STAT 0x0608 /* PMU status */ ++#define BCMA_CC_PMU_STAT_EXT_LPO_AVAIL 0x00000100 ++#define BCMA_CC_PMU_STAT_WDRESET 0x00000080 + #define BCMA_CC_PMU_STAT_INTPEND 0x00000040 /* Interrupt pending */ + #define BCMA_CC_PMU_STAT_SBCLKST 0x00000030 /* Backplane clock status? */ + #define BCMA_CC_PMU_STAT_HAVEALP 0x00000008 /* ALP available */ +@@ -239,8 +357,66 @@ + #define BCMA_CC_REGCTL_DATA 0x065C #define BCMA_CC_PLLCTL_ADDR 0x0660 #define BCMA_CC_PLLCTL_DATA 0x0664 ++#define BCMA_CC_PMU_STRAPOPT 0x0668 /* (corerev >= 28) */ ++#define BCMA_CC_PMU_XTAL_FREQ 0x066C /* (pmurev >= 10) */ ++#define BCMA_CC_PMU_XTAL_FREQ_ILPCTL_MASK 0x00001FFF ++#define BCMA_CC_PMU_XTAL_FREQ_MEASURE_MASK 0x80000000 ++#define BCMA_CC_PMU_XTAL_FREQ_MEASURE_SHIFT 31 #define BCMA_CC_SPROM 0x0800 /* SPROM beginning */ -#define BCMA_CC_SPROM_PCIE6 0x0830 /* SPROM beginning on PCIe rev >= 6 */ +/* NAND flash MLC controller registers (corerev >= 38) */ @@ -4401,7 +5000,7 @@ /* Divider allocation in 4716/47162/5356 */ #define BCMA_CC_PMU5_MAINPLL_CPU 1 -@@ -256,6 +425,15 @@ +@@ -256,6 +432,32 @@ /* 4706 PMU */ #define BCMA_CC_PMU4706_MAINPLL_PLL0 0 @@ -4414,10 +5013,27 @@ +#define BCMA_CC_PMU6_4706_PROC_NDIV_INT_SHIFT 3 +#define BCMA_CC_PMU6_4706_PROC_NDIV_MODE_MASK 0x00000007 +#define BCMA_CC_PMU6_4706_PROC_NDIV_MODE_SHIFT 0 ++ ++/* PMU rev 15 */ ++#define BCMA_CC_PMU15_PLL_PLLCTL0 0 ++#define BCMA_CC_PMU15_PLL_PC0_CLKSEL_MASK 0x00000003 ++#define BCMA_CC_PMU15_PLL_PC0_CLKSEL_SHIFT 0 ++#define BCMA_CC_PMU15_PLL_PC0_FREQTGT_MASK 0x003FFFFC ++#define BCMA_CC_PMU15_PLL_PC0_FREQTGT_SHIFT 2 ++#define BCMA_CC_PMU15_PLL_PC0_PRESCALE_MASK 0x00C00000 ++#define BCMA_CC_PMU15_PLL_PC0_PRESCALE_SHIFT 22 ++#define BCMA_CC_PMU15_PLL_PC0_KPCTRL_MASK 0x07000000 ++#define BCMA_CC_PMU15_PLL_PC0_KPCTRL_SHIFT 24 ++#define BCMA_CC_PMU15_PLL_PC0_FCNTCTRL_MASK 0x38000000 ++#define BCMA_CC_PMU15_PLL_PC0_FCNTCTRL_SHIFT 27 ++#define BCMA_CC_PMU15_PLL_PC0_FDCMODE_MASK 0x40000000 ++#define BCMA_CC_PMU15_PLL_PC0_FDCMODE_SHIFT 30 ++#define BCMA_CC_PMU15_PLL_PC0_CTRLBIAS_MASK 0x80000000 ++#define BCMA_CC_PMU15_PLL_PC0_CTRLBIAS_SHIFT 31 /* ALP clock on pre-PMU chips */ #define BCMA_CC_PMU_ALP_CLOCK 20000000 -@@ -284,6 +462,19 @@ +@@ -284,6 +486,19 @@ #define BCMA_CC_PPL_PCHI_OFF 5 #define BCMA_CC_PPL_PCHI_MASK 0x0000003f @@ -4437,7 +5053,7 @@ /* BCM4331 ChipControl numbers. */ #define BCMA_CHIPCTL_4331_BT_COEXIST BIT(0) /* 0 disable */ #define BCMA_CHIPCTL_4331_SECI BIT(1) /* 0 SECI is disabled (JATG functional) */ -@@ -297,9 +488,25 @@ +@@ -297,9 +512,56 @@ #define BCMA_CHIPCTL_4331_OVR_PIPEAUXPWRDOWN BIT(9) /* override core control on pipe_AuxPowerDown */ #define BCMA_CHIPCTL_4331_PCIE_AUXCLKEN BIT(10) /* pcie_auxclkenable */ #define BCMA_CHIPCTL_4331_PCIE_PIPE_PLLDOWN BIT(11) /* pcie_pipe_pllpowerdown */ @@ -4460,10 +5076,41 @@ +#define BCMA_CHIPCTL_5357_I2S_PINS_ENABLE BIT(18) +#define BCMA_CHIPCTL_5357_I2CSPI_PINS_ENABLE BIT(19) + ++#define BCMA_RES_4314_LPLDO_PU BIT(0) ++#define BCMA_RES_4314_PMU_SLEEP_DIS BIT(1) ++#define BCMA_RES_4314_PMU_BG_PU BIT(2) ++#define BCMA_RES_4314_CBUCK_LPOM_PU BIT(3) ++#define BCMA_RES_4314_CBUCK_PFM_PU BIT(4) ++#define BCMA_RES_4314_CLDO_PU BIT(5) ++#define BCMA_RES_4314_LPLDO2_LVM BIT(6) ++#define BCMA_RES_4314_WL_PMU_PU BIT(7) ++#define BCMA_RES_4314_LNLDO_PU BIT(8) ++#define BCMA_RES_4314_LDO3P3_PU BIT(9) ++#define BCMA_RES_4314_OTP_PU BIT(10) ++#define BCMA_RES_4314_XTAL_PU BIT(11) ++#define BCMA_RES_4314_WL_PWRSW_PU BIT(12) ++#define BCMA_RES_4314_LQ_AVAIL BIT(13) ++#define BCMA_RES_4314_LOGIC_RET BIT(14) ++#define BCMA_RES_4314_MEM_SLEEP BIT(15) ++#define BCMA_RES_4314_MACPHY_RET BIT(16) ++#define BCMA_RES_4314_WL_CORE_READY BIT(17) ++#define BCMA_RES_4314_ILP_REQ BIT(18) ++#define BCMA_RES_4314_ALP_AVAIL BIT(19) ++#define BCMA_RES_4314_MISC_PWRSW_PU BIT(20) ++#define BCMA_RES_4314_SYNTH_PWRSW_PU BIT(21) ++#define BCMA_RES_4314_RX_PWRSW_PU BIT(22) ++#define BCMA_RES_4314_RADIO_PU BIT(23) ++#define BCMA_RES_4314_VCO_LDO_PU BIT(24) ++#define BCMA_RES_4314_AFE_LDO_PU BIT(25) ++#define BCMA_RES_4314_RX_LDO_PU BIT(26) ++#define BCMA_RES_4314_TX_LDO_PU BIT(27) ++#define BCMA_RES_4314_HT_AVAIL BIT(28) ++#define BCMA_RES_4314_MACPHY_CLK_AVAIL BIT(29) ++ /* Data for the PMU, if available. * Check availability with ((struct bcma_chipcommon)->capabilities & BCMA_CC_CAP_PMU) */ -@@ -310,11 +517,35 @@ struct bcma_chipcommon_pmu { +@@ -310,11 +572,36 @@ struct bcma_chipcommon_pmu { #ifdef CONFIG_BCMA_DRIVER_MIPS struct bcma_pflash { @@ -4482,6 +5129,7 @@ + u32 size; + + struct mtd_info *mtd; ++ void *priv; +}; +#endif + @@ -4499,7 +5147,7 @@ struct bcma_serial_port { void *regs; unsigned long clockspeed; -@@ -330,15 +561,30 @@ struct bcma_drv_cc { +@@ -330,15 +617,30 @@ struct bcma_drv_cc { u32 capabilities; u32 capabilities_ext; u8 setup_done:1; @@ -4530,7 +5178,7 @@ }; /* Register access */ -@@ -355,14 +601,16 @@ struct bcma_drv_cc { +@@ -355,14 +657,16 @@ struct bcma_drv_cc { bcma_cc_write32(cc, offset, (bcma_cc_read32(cc, offset) & (mask)) | (set)) extern void bcma_core_chipcommon_init(struct bcma_drv_cc *cc); @@ -4549,7 +5197,7 @@ void bcma_chipco_irq_mask(struct bcma_drv_cc *cc, u32 mask, u32 value); -@@ -375,9 +623,12 @@ u32 bcma_chipco_gpio_outen(struct bcma_d +@@ -375,9 +679,12 @@ u32 bcma_chipco_gpio_outen(struct bcma_d u32 bcma_chipco_gpio_control(struct bcma_drv_cc *cc, u32 mask, u32 value); u32 bcma_chipco_gpio_intmask(struct bcma_drv_cc *cc, u32 mask, u32 value); u32 bcma_chipco_gpio_polarity(struct bcma_drv_cc *cc, u32 mask, u32 value); @@ -4562,11 +5210,13 @@ extern void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset, u32 value); -@@ -387,5 +638,6 @@ extern void bcma_chipco_chipctl_maskset( +@@ -387,5 +694,8 @@ extern void bcma_chipco_chipctl_maskset( u32 offset, u32 mask, u32 set); extern void bcma_chipco_regctl_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask, u32 set); +extern void bcma_pmu_spuravoid_pllupdate(struct bcma_drv_cc *cc, int spuravoid); ++ ++extern u32 bcma_pmu_get_bus_clock(struct bcma_drv_cc *cc); #endif /* LINUX_BCMA_DRIVER_CC_H_ */ --- /dev/null @@ -4674,7 +5324,15 @@ +#endif /* LINUX_BCMA_DRIVER_GMAC_CMN_H_ */ --- a/include/linux/bcma/bcma_driver_mips.h +++ b/include/linux/bcma/bcma_driver_mips.h -@@ -35,13 +35,15 @@ struct bcma_device; +@@ -28,6 +28,7 @@ + #define BCMA_MIPS_MIPS74K_GPIOEN 0x0048 + #define BCMA_MIPS_MIPS74K_CLKCTLST 0x01E0 + ++#define BCMA_MIPS_OOBSELINA74 0x004 + #define BCMA_MIPS_OOBSELOUTA30 0x100 + + struct bcma_device; +@@ -35,17 +36,24 @@ struct bcma_device; struct bcma_drv_mips { struct bcma_device *core; u8 setup_done:1; @@ -4685,12 +5343,23 @@ #ifdef CONFIG_BCMA_DRIVER_MIPS extern void bcma_core_mips_init(struct bcma_drv_mips *mcore); +extern void bcma_core_mips_early_init(struct bcma_drv_mips *mcore); ++ ++extern unsigned int bcma_core_irq(struct bcma_device *core); #else static inline void bcma_core_mips_init(struct bcma_drv_mips *mcore) { } +static inline void bcma_core_mips_early_init(struct bcma_drv_mips *mcore) { } ++ ++static inline unsigned int bcma_core_irq(struct bcma_device *core) ++{ ++ return 0; ++} #endif extern u32 bcma_cpu_clock(struct bcma_drv_mips *mcore); + +-extern unsigned int bcma_core_mips_irq(struct bcma_device *dev); +- + #endif /* LINUX_BCMA_DRIVER_MIPS_H_ */ --- a/include/linux/bcma/bcma_driver_pci.h +++ b/include/linux/bcma/bcma_driver_pci.h @@ -53,11 +53,47 @@ struct pci_dev; @@ -4741,7 +5410,7 @@ /* SBtoPCIx */ #define BCMA_CORE_PCI_SBTOPCI_MEM 0x00000000 -@@ -72,20 +108,118 @@ struct pci_dev; +@@ -72,20 +108,120 @@ struct pci_dev; #define BCMA_CORE_PCI_SBTOPCI_RC_READL 0x00000010 /* Memory read line */ #define BCMA_CORE_PCI_SBTOPCI_RC_READM 0x00000020 /* Memory read multiple */ @@ -4816,6 +5485,8 @@ +#define BCMA_CORE_PCI_CFG_FUN_MASK 7 /* Function mask */ +#define BCMA_CORE_PCI_CFG_OFF_MASK 0xfff /* Register mask */ + ++#define BCMA_CORE_PCI_CFG_DEVCTRL 0xd8 ++ +/* PCIE Root Capability Register bits (Host mode only) */ +#define BCMA_CORE_PCI_RC_CRS_VISIBILITY 0x0001 + |