diff options
Diffstat (limited to 'target/linux/generic/patches-3.6/025-bcma_backport.patch')
-rw-r--r-- | target/linux/generic/patches-3.6/025-bcma_backport.patch | 1188 |
1 files changed, 1089 insertions, 99 deletions
diff --git a/target/linux/generic/patches-3.6/025-bcma_backport.patch b/target/linux/generic/patches-3.6/025-bcma_backport.patch index 15f54a7..9ad3ce3 100644 --- a/target/linux/generic/patches-3.6/025-bcma_backport.patch +++ b/target/linux/generic/patches-3.6/025-bcma_backport.patch @@ -1,6 +1,25 @@ +--- 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 -@@ -48,12 +48,12 @@ config BCMA_DRIVER_MIPS +@@ -26,6 +26,7 @@ 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" +@@ -48,12 +49,12 @@ config BCMA_DRIVER_MIPS config BCMA_SFLASH bool @@ -15,7 +34,7 @@ default y config BCMA_DRIVER_GMAC_CMN -@@ -65,6 +65,14 @@ config BCMA_DRIVER_GMAC_CMN +@@ -65,6 +66,14 @@ config BCMA_DRIVER_GMAC_CMN If unsure, say N @@ -42,7 +61,16 @@ obj-$(CONFIG_BCMA) += bcma.o --- a/drivers/bcma/bcma_private.h +++ b/drivers/bcma/bcma_private.h -@@ -31,6 +31,8 @@ int __init bcma_bus_early_register(struc +@@ -22,6 +22,8 @@ + struct bcma_bus; + + /* main.c */ ++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, +@@ -31,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 @@ -51,7 +79,11 @@ /* scan.c */ int bcma_bus_scan(struct bcma_bus *bus); -@@ -48,12 +50,13 @@ void bcma_chipco_serial_init(struct bcma +@@ -45,15 +49,17 @@ 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 */ @@ -67,7 +99,7 @@ #else static inline int bcma_sflash_init(struct bcma_drv_cc *cc) { -@@ -65,6 +68,7 @@ static inline int bcma_sflash_init(struc +@@ -65,6 +71,7 @@ static inline int bcma_sflash_init(struc #ifdef CONFIG_BCMA_NFLASH /* driver_chipcommon_nflash.c */ int bcma_nflash_init(struct bcma_drv_cc *cc); @@ -75,7 +107,7 @@ #else static inline int bcma_nflash_init(struct bcma_drv_cc *cc) { -@@ -82,9 +86,21 @@ extern void __exit bcma_host_pci_exit(vo +@@ -82,9 +89,26 @@ extern void __exit bcma_host_pci_exit(vo /* driver_pci.c */ u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address); @@ -89,17 +121,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 -@@ -65,7 +65,7 @@ void bcma_core_set_clockmode(struct bcma +@@ -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,13 +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); + +@@ -43,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)); +@@ -65,7 +87,7 @@ void bcma_core_set_clockmode(struct bcma switch (clkmode) { case BCMA_CLKMODE_FAST: bcma_set32(core, BCMA_CLKCTLST, BCMA_CLKCTLST_FORCEHT); @@ -108,6 +198,21 @@ for (i = 0; i < 1500; i++) { if (bcma_read32(core, BCMA_CLKCTLST) & BCMA_CLKCTLST_HAVEHT) { +@@ -104,7 +126,13 @@ void bcma_core_pll_ctl(struct bcma_devic + if (i) + bcma_err(core->bus, "PLL enable timeout\n"); + } else { +- 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); --- a/drivers/bcma/driver_chipcommon.c +++ b/drivers/bcma/driver_chipcommon.c @@ -4,12 +4,15 @@ @@ -126,7 +231,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,23 +25,130 @@ static inline u32 bcma_cc_write32_masked return value; } @@ -249,9 +354,21 @@ + 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); -@@ -56,15 +159,33 @@ 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) +@@ -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))); } @@ -288,7 +405,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) { @@ -393,7 +510,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) { @@ -403,24 +520,34 @@ if (ccrev >= 21) { /* Turn off UART clock before switching clocksource. */ bcma_cc_write32(cc, BCMA_CC_CORECTL, +@@ -141,7 +339,7 @@ void bcma_chipco_serial_init(struct bcma + 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); --- a/drivers/bcma/driver_chipcommon_nflash.c +++ b/drivers/bcma/driver_chipcommon_nflash.c @@ -5,15 +5,40 @@ * Licensed under the GNU/GPL. See COPYING for details. */ ++#include "bcma_private.h" ++ +#include <linux/platform_device.h> #include <linux/bcma/bcma.h> -#include <linux/bcma/bcma_driver_chipcommon.h> -#include <linux/delay.h> - #include "bcma_private.h" - +-#include "bcma_private.h" +struct platform_device bcma_nflash_dev = { + .name = "bcma_nflash", + .num_resources = 0, +}; -+ + /* Initialize NAND flash access */ int bcma_nflash_init(struct bcma_drv_cc *cc) { @@ -428,7 +555,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; + } @@ -466,7 +593,143 @@ void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset, u32 value) { -@@ -76,7 +77,10 @@ static void bcma_pmu_resources_init(stru +@@ -55,6 +56,109 @@ void bcma_chipco_regctl_maskset(struct b + } + EXPORT_SYMBOL_GPL(bcma_chipco_regctl_maskset); + ++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 BCMA_CHIP_ID_BCM43142: ++ if (xtalfreq == 0) ++ xtalfreq = 20000; ++ bcma_pmu2_pll_init0(cc, xtalfreq); ++ break; ++ } ++} ++ + static void bcma_pmu_resources_init(struct bcma_drv_cc *cc) + { + struct bcma_bus *bus = cc->core->bus; +@@ -65,6 +169,25 @@ static void bcma_pmu_resources_init(stru + min_msk = 0x200D; + max_msk = 0xFFFF; + 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: + bcma_debug(bus, "PMU resource config unknown or not needed for device 0x%04X\n", + bus->chipinfo.id); +@@ -76,7 +199,10 @@ static void bcma_pmu_resources_init(stru if (max_msk) bcma_cc_write32(cc, BCMA_CC_PMU_MAXRES_MSK, max_msk); @@ -478,7 +741,7 @@ mdelay(2); } -@@ -101,7 +105,7 @@ void bcma_chipco_bcm4331_ext_pa_lines_ct +@@ -101,7 +227,7 @@ void bcma_chipco_bcm4331_ext_pa_lines_ct bcma_cc_write32(cc, BCMA_CC_CHIPCTL, val); } @@ -487,7 +750,7 @@ { struct bcma_bus *bus = cc->core->bus; -@@ -141,7 +145,7 @@ void bcma_pmu_workarounds(struct bcma_dr +@@ -141,7 +267,7 @@ void bcma_pmu_workarounds(struct bcma_dr } } @@ -496,7 +759,7 @@ { u32 pmucap; -@@ -150,7 +154,10 @@ void bcma_pmu_init(struct bcma_drv_cc *c +@@ -150,7 +276,10 @@ void bcma_pmu_init(struct bcma_drv_cc *c bcma_debug(cc->core->bus, "Found rev %u PMU (capabilities 0x%08X)\n", cc->pmu.rev, pmucap); @@ -507,7 +770,12 @@ if (cc->pmu.rev == 1) bcma_cc_mask32(cc, BCMA_CC_PMU_CTL, ~BCMA_CC_PMU_CTL_NOILPONW); -@@ -162,24 +169,40 @@ void bcma_pmu_init(struct bcma_drv_cc *c +@@ -158,28 +287,45 @@ void bcma_pmu_init(struct bcma_drv_cc *c + bcma_cc_set32(cc, BCMA_CC_PMU_CTL, + BCMA_CC_PMU_CTL_NOILPONW); + ++ bcma_pmu_pll_init(cc); + bcma_pmu_resources_init(cc); bcma_pmu_workarounds(cc); } @@ -553,7 +821,7 @@ default: bcma_warn(bus, "No ALP clock specified for %04X device, pmu rev. %d, using default %d Hz\n", bus->chipinfo.id, cc->pmu.rev, BCMA_CC_PMU_ALP_CLOCK); -@@ -190,7 +213,7 @@ u32 bcma_pmu_alp_clock(struct bcma_drv_c +@@ -190,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. */ @@ -562,7 +830,7 @@ { u32 tmp, div, ndiv, p1, p2, fc; struct bcma_bus *bus = cc->core->bus; -@@ -219,14 +242,14 @@ static u32 bcma_pmu_clock(struct bcma_dr +@@ -219,14 +365,14 @@ static u32 bcma_pmu_clock(struct bcma_dr ndiv = (tmp & BCMA_CC_PPL_NDIV_MASK) >> BCMA_CC_PPL_NDIV_SHIFT; /* Do calculation in Mhz */ @@ -579,16 +847,16 @@ { u32 tmp, ndiv, p1div, p2div; u32 clock; -@@ -257,7 +280,7 @@ static u32 bcma_pmu_clock_bcm4706(struct +@@ -257,7 +403,7 @@ static u32 bcma_pmu_clock_bcm4706(struct } /* 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; -@@ -265,40 +288,42 @@ u32 bcma_pmu_get_clockcontrol(struct bcm +@@ -265,40 +411,43 @@ u32 bcma_pmu_get_clockcontrol(struct bcm case BCMA_CHIP_ID_BCM4716: case BCMA_CHIP_ID_BCM4748: case BCMA_CHIP_ID_BCM47162: @@ -622,6 +890,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) @@ -642,7 +911,7 @@ BCMA_CC_PMU4706_MAINPLL_PLL0, BCMA_CC_PMU5_MAINPLL_CPU); case BCMA_CHIP_ID_BCM5356: -@@ -313,10 +338,11 @@ u32 bcma_pmu_get_clockcpu(struct bcma_dr +@@ -313,10 +462,11 @@ u32 bcma_pmu_get_clockcpu(struct bcma_dr break; } @@ -656,7 +925,7 @@ } static void bcma_pmu_spuravoid_pll_write(struct bcma_drv_cc *cc, u32 offset, -@@ -362,7 +388,7 @@ void bcma_pmu_spuravoid_pllupdate(struct +@@ -362,7 +512,7 @@ void bcma_pmu_spuravoid_pllupdate(struct tmp |= (bcm5357_bcm43236_ndiv[spuravoid]) << BCMA_CC_PMU1_PLL0_PC2_NDIV_INT_SHIFT; bcma_cc_write32(cc, BCMA_CC_PLLCTL_DATA, tmp); @@ -665,7 +934,7 @@ break; case BCMA_CHIP_ID_BCM4331: -@@ -383,7 +409,7 @@ void bcma_pmu_spuravoid_pllupdate(struct +@@ -383,7 +533,7 @@ void bcma_pmu_spuravoid_pllupdate(struct bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL2, 0x03000a08); } @@ -674,7 +943,7 @@ break; case BCMA_CHIP_ID_BCM43224: -@@ -416,7 +442,7 @@ void bcma_pmu_spuravoid_pllupdate(struct +@@ -416,7 +566,7 @@ void bcma_pmu_spuravoid_pllupdate(struct bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL5, 0x88888815); } @@ -683,7 +952,7 @@ break; case BCMA_CHIP_ID_BCM4716: -@@ -450,7 +476,7 @@ void bcma_pmu_spuravoid_pllupdate(struct +@@ -450,7 +600,7 @@ void bcma_pmu_spuravoid_pllupdate(struct 0x88888815); } @@ -692,7 +961,7 @@ break; case BCMA_CHIP_ID_BCM43227: -@@ -486,7 +512,7 @@ void bcma_pmu_spuravoid_pllupdate(struct +@@ -486,7 +636,7 @@ void bcma_pmu_spuravoid_pllupdate(struct bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL5, 0x88888815); } @@ -707,13 +976,14 @@ * Licensed under the GNU/GPL. See COPYING for details. */ ++#include "bcma_private.h" ++ +#include <linux/platform_device.h> #include <linux/bcma/bcma.h> -#include <linux/bcma/bcma_driver_chipcommon.h> -#include <linux/delay.h> - #include "bcma_private.h" - +-#include "bcma_private.h" +static struct resource bcma_sflash_resource = { + .name = "bcma_sflash", + .start = BCMA_SOC_FLASH2, @@ -734,7 +1004,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, }, + @@ -745,7 +1015,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, }, @@ -763,7 +1033,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, }, @@ -787,14 +1057,14 @@ + } + bcma_err(cc->core->bus, "SFLASH control command failed (timeout)!\n"); +} -+ + /* Initialize serial flash access */ int bcma_sflash_init(struct bcma_drv_cc *cc) { - bcma_err(cc->core->bus, "Serial flash support is broken\n"); + 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) { @@ -870,7 +1140,7 @@ } --- /dev/null +++ b/drivers/bcma/driver_gpio.c -@@ -0,0 +1,98 @@ +@@ -0,0 +1,114 @@ +/* + * Broadcom specific AMBA + * GPIO driver @@ -946,6 +1216,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; @@ -958,6 +1238,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 @@ -969,9 +1250,48 @@ + + 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 -@@ -74,11 +74,16 @@ static u32 bcma_core_mips_irqflag(struct +@@ -14,11 +14,33 @@ + + #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) + { +@@ -74,28 +96,41 @@ static u32 bcma_core_mips_irqflag(struct return dev->core_index; flag = bcma_aread32(dev, BCMA_MIPS_OOBSELOUTA30); @@ -987,9 +1307,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); @@ -1004,10 +1326,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)); @@ -1018,7 +1349,7 @@ /* assign the new one */ if (irq == 0) { -@@ -123,9 +130,9 @@ static void bcma_core_mips_set_irq(struc +@@ -123,9 +158,9 @@ static void bcma_core_mips_set_irq(struc bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) | (1 << irqflag)); } else { @@ -1031,7 +1362,7 @@ struct bcma_device *core; /* backplane irq line is in use, find out who uses -@@ -133,7 +140,7 @@ static void bcma_core_mips_set_irq(struc +@@ -133,7 +168,7 @@ static void bcma_core_mips_set_irq(struc */ list_for_each_entry(core, &bus->cores, list) { if ((1 << bcma_core_mips_irqflag(core)) == @@ -1040,7 +1371,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); } @@ -1075,7 +1406,7 @@ for (i = 0; i <= 6; i++) printk(" %s%s", irq_name[i], i == irq ? "*" : " "); printk("\n"); -@@ -171,7 +194,7 @@ u32 bcma_cpu_clock(struct bcma_drv_mips +@@ -171,7 +222,7 @@ u32 bcma_cpu_clock(struct bcma_drv_mips struct bcma_bus *bus = mcore->core->bus; if (bus->drv_cc.capabilities & BCMA_CC_CAP_PMU) @@ -1084,11 +1415,12 @@ bcma_err(bus, "No PMU available, need this to get the cpu clock\n"); return 0; -@@ -181,85 +204,109 @@ EXPORT_SYMBOL(bcma_cpu_clock); +@@ -181,85 +232,143 @@ 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) { @@ -1102,18 +1434,23 @@ bcma_debug(bus, "Found parallel flash\n"); - bus->drv_cc.pflash.window = 0x1c000000; - bus->drv_cc.pflash.window_size = 0x02000000; -+ 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: bcma_err(bus, "Flash type not supported\n"); @@ -1144,6 +1481,32 @@ + mcore->early_setup_done = true; +} + ++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"); ++ } ++} ++ void bcma_core_mips_init(struct bcma_drv_mips *mcore) { struct bcma_bus *bus; @@ -1188,6 +1551,8 @@ - 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: @@ -1224,7 +1589,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", @@ -1284,7 +1649,130 @@ bcma_core_enable(pc->core, 0); return !mips_busprobe32(tmp, pc->core->io_addr); -@@ -396,6 +391,11 @@ void __devinit bcma_core_pci_hostmode_in +@@ -99,19 +94,19 @@ static int bcma_extpci_read_config(struc + 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 { +@@ -124,11 +119,9 @@ static int bcma_extpci_read_config(struc + goto out; + + if (mips_busprobe32(val, mmio)) { +- val = 0xffffffff; ++ val = 0xFFFFFFFF; + goto unmap; + } +- +- val = readl(mmio); + } + val >>= (8 * (off & 3)); + +@@ -156,7 +149,7 @@ static int bcma_extpci_write_config(stru + const void *buf, int len) + { + int err = -EINVAL; +- u32 addr = 0, val = 0; ++ u32 addr, val; + void __iomem *mmio = 0; + u16 chipid = pc->core->bus->chipinfo.id; + +@@ -164,16 +157,22 @@ static int bcma_extpci_write_config(stru + 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); +@@ -185,19 +184,17 @@ static int bcma_extpci_write_config(stru + 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; +@@ -205,13 +202,14 @@ static int bcma_extpci_write_config(stru + 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); + +@@ -282,7 +280,7 @@ static u8 __devinit bcma_find_pci_capabi + /* 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 */ +@@ -396,12 +394,19 @@ void __devinit bcma_core_pci_hostmode_in bcma_info(bus, "PCIEcore in host mode found\n"); @@ -1296,7 +1784,15 @@ pc_host = kzalloc(sizeof(*pc_host), GFP_KERNEL); if (!pc_host) { bcma_err(bus, "can not allocate memory"); -@@ -425,9 +425,9 @@ void __devinit bcma_core_pci_hostmode_in + 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; +@@ -425,9 +430,9 @@ void __devinit bcma_core_pci_hostmode_in pc_host->io_resource.flags = IORESOURCE_IO | IORESOURCE_PCI_FIXED; /* Reset RC */ @@ -1304,11 +1800,11 @@ + usleep_range(3000, 5000); pcicore_write32(pc, BCMA_CORE_PCI_CTL, BCMA_CORE_PCI_CTL_RST_OE); - udelay(1000); -+ usleep_range(1000, 2000); ++ msleep(50); pcicore_write32(pc, BCMA_CORE_PCI_CTL, BCMA_CORE_PCI_CTL_RST | BCMA_CORE_PCI_CTL_RST_OE); -@@ -452,6 +452,8 @@ void __devinit bcma_core_pci_hostmode_in +@@ -452,6 +457,8 @@ void __devinit bcma_core_pci_hostmode_in pc_host->mem_resource.start = BCMA_SOC_PCI_MEM; pc_host->mem_resource.end = BCMA_SOC_PCI_MEM + BCMA_SOC_PCI_MEM_SZ - 1; @@ -1317,7 +1813,7 @@ pci_membase_1G = BCMA_SOC_PCIE_DMA_H32; pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0, tmp | BCMA_SOC_PCI_MEM); -@@ -459,6 +461,8 @@ void __devinit bcma_core_pci_hostmode_in +@@ -459,6 +466,8 @@ void __devinit bcma_core_pci_hostmode_in pc_host->mem_resource.start = BCMA_SOC_PCI1_MEM; pc_host->mem_resource.end = BCMA_SOC_PCI1_MEM + BCMA_SOC_PCI_MEM_SZ - 1; @@ -1326,7 +1822,7 @@ pci_membase_1G = BCMA_SOC_PCIE1_DMA_H32; pc_host->host_cfg_addr = BCMA_SOC_PCI1_CFG; pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0, -@@ -481,7 +485,7 @@ void __devinit bcma_core_pci_hostmode_in +@@ -481,10 +490,21 @@ void __devinit bcma_core_pci_hostmode_in * before issuing configuration requests to PCI Express * devices. */ @@ -1335,7 +1831,21 @@ bcma_core_pci_enable_crs(pc); -@@ -501,7 +505,7 @@ void __devinit bcma_core_pci_hostmode_in ++ 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)); +@@ -501,7 +521,7 @@ void __devinit bcma_core_pci_hostmode_in set_io_port_base(pc_host->pci_controller.io_map_base); /* Give some time to the PCI controller to configure itself with the new * values. Not waiting at this point causes crashes of the machine. */ @@ -1344,7 +1854,7 @@ register_pci_controller(&pc_host->pci_controller); return; } -@@ -534,7 +538,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ +@@ -534,7 +554,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ static void bcma_core_pci_fixup_addresses(struct pci_dev *dev) { struct resource *res; @@ -1353,7 +1863,7 @@ if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) { /* This is not a device on the PCI-core bridge. */ -@@ -547,8 +551,12 @@ static void bcma_core_pci_fixup_addresse +@@ -547,8 +567,12 @@ static void bcma_core_pci_fixup_addresse for (pos = 0; pos < 6; pos++) { res = &dev->resource[pos]; @@ -1368,6 +1878,23 @@ } } DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, bcma_core_pci_fixup_addresses); +@@ -569,7 +593,7 @@ int bcma_core_pci_plat_dev_init(struct p + 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; +@@ -588,6 +612,6 @@ int bcma_core_pci_pcibios_map_irq(const + + 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 +++ b/drivers/bcma/host_pci.c @@ -77,8 +77,8 @@ static void bcma_host_pci_write32(struct @@ -1425,14 +1952,16 @@ static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = { { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) }, -@@ -272,6 +273,7 @@ static DEFINE_PCI_DEVICE_TABLE(bcma_pci_ +@@ -272,7 +273,9 @@ static DEFINE_PCI_DEVICE_TABLE(bcma_pci_ { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4353) }, { 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, }, + }; --- a/drivers/bcma/host_soc.c +++ b/drivers/bcma/host_soc.c @@ -143,7 +143,7 @@ static void bcma_host_soc_awrite32(struc @@ -1454,7 +1983,7 @@ #include <linux/bcma/bcma.h> #include <linux/slab.h> -@@ -80,6 +81,18 @@ struct bcma_device *bcma_find_core(struc +@@ -80,6 +81,37 @@ struct bcma_device *bcma_find_core(struc } EXPORT_SYMBOL_GPL(bcma_find_core); @@ -1470,13 +1999,52 @@ + 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) { struct bcma_device *core = container_of(dev, struct bcma_device, dev); -@@ -136,6 +149,33 @@ static int bcma_register_cores(struct bc +@@ -107,6 +139,11 @@ static int bcma_register_cores(struct bc + 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", bus->num, dev_id); +@@ -136,6 +173,41 @@ static int bcma_register_cores(struct bc 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); @@ -1507,7 +2075,7 @@ return 0; } -@@ -148,6 +188,8 @@ static void bcma_unregister_cores(struct +@@ -148,6 +220,8 @@ static void bcma_unregister_cores(struct if (core->dev_registered) device_unregister(&core->dev); } @@ -1516,7 +2084,7 @@ } int __devinit bcma_bus_register(struct bcma_bus *bus) -@@ -166,6 +208,20 @@ int __devinit bcma_bus_register(struct b +@@ -166,6 +240,20 @@ int __devinit bcma_bus_register(struct b return -1; } @@ -1537,28 +2105,28 @@ /* Init CC core */ core = bcma_find_core(bus, bcma_cc_core_id(bus)); if (core) { -@@ -181,10 +237,17 @@ int __devinit bcma_bus_register(struct b +@@ -181,10 +269,17 @@ int __devinit bcma_bus_register(struct b } /* Init PCIE core */ - core = bcma_find_core(bus, BCMA_CORE_PCIE); + core = bcma_find_core_unit(bus, BCMA_CORE_PCIE, 0); -+ if (core) { + if (core) { +- bus->drv_pci.core = core; +- bcma_core_pci_init(&bus->drv_pci); + bus->drv_pci[0].core = core; + bcma_core_pci_init(&bus->drv_pci[0]); + } + + /* Init PCIE core */ + core = bcma_find_core_unit(bus, BCMA_CORE_PCIE, 1); - if (core) { -- bus->drv_pci.core = core; -- bcma_core_pci_init(&bus->drv_pci); ++ if (core) { + bus->drv_pci[1].core = core; + bcma_core_pci_init(&bus->drv_pci[1]); } /* Init GBIT MAC COMMON core */ -@@ -194,13 +257,6 @@ int __devinit bcma_bus_register(struct b +@@ -194,13 +289,6 @@ int __devinit bcma_bus_register(struct b bcma_core_gmac_cmn_init(&bus->drv_gmac_cmn); } @@ -1572,11 +2140,18 @@ /* Register found cores */ bcma_register_cores(bus); -@@ -211,7 +267,17 @@ int __devinit bcma_bus_register(struct b +@@ -211,7 +299,24 @@ int __devinit bcma_bus_register(struct b 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); @@ -1590,7 +2165,7 @@ } int __init bcma_bus_early_register(struct bcma_bus *bus, -@@ -248,18 +314,18 @@ int __init bcma_bus_early_register(struc +@@ -248,18 +353,18 @@ int __init bcma_bus_early_register(struc return -1; } @@ -1613,9 +2188,194 @@ } bcma_info(bus, "Early bus registered\n"); +--- a/drivers/bcma/scan.c ++++ b/drivers/bcma/scan.c +@@ -84,6 +84,8 @@ static const struct bcma_device_id_name + { 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" }, + }; + +@@ -137,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)) +@@ -159,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); +@@ -175,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) { +@@ -189,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)) +@@ -199,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; --- a/drivers/bcma/sprom.c +++ b/drivers/bcma/sprom.c -@@ -507,7 +507,9 @@ static bool bcma_sprom_onchip_available( +@@ -72,12 +72,12 @@ fail: + * R/W ops. + **************************************************/ + +-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)); + } + + /************************************************** +@@ -124,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; +@@ -154,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; + } + +@@ -208,15 +212,13 @@ static void bcma_sprom_extract_r8(struct + 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; +- + for (i = 0; i < 3; i++) { + v = sprom[SPOFF(SSB_SPROM8_IL0MAC) + i]; + *(((__be16 *)bus->sprom.il0mac) + i) = cpu_to_be16(v); + } + + 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); +@@ -501,13 +503,15 @@ static bool bcma_sprom_onchip_available( + 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 */ present = true; break; @@ -1625,19 +2385,68 @@ present = chip_status & BCMA_CC_CHIPST_43228_OTP_PRESENT; break; default: -@@ -593,8 +595,11 @@ int bcma_sprom_get(struct bcma_bus *bus) +@@ -547,7 +551,9 @@ int bcma_sprom_get(struct bcma_bus *bus) + { + u16 offset = BCMA_CC_SPROM; + u16 *sprom; +- 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; +@@ -576,29 +582,37 @@ int bcma_sprom_get(struct bcma_bus *bus) + } + } + +- sprom = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16), +- GFP_KERNEL); +- if (!sprom) +- return -ENOMEM; +- + 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, false); + + 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; ++ ++ kfree(sprom); ++ } + + 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); - err = bcma_sprom_valid(sprom); +- err = bcma_sprom_valid(sprom); - if (err) +- goto out; +- +- 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 @@ -10,7 +10,7 @@ @@ -1649,15 +2458,25 @@ struct bcma_device; struct bcma_bus; -@@ -134,6 +134,7 @@ struct bcma_host_ops { +@@ -134,12 +134,17 @@ 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 -@@ -157,6 +158,7 @@ struct bcma_host_ops { + + /* 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 +@@ -157,6 +162,7 @@ struct bcma_host_ops { /* Chip IDs of SoCs */ #define BCMA_CHIP_ID_BCM4706 0x5300 @@ -1665,7 +2484,7 @@ #define BCMA_CHIP_ID_BCM4716 0x4716 #define BCMA_PKG_ID_BCM4716 8 #define BCMA_PKG_ID_BCM4717 9 -@@ -166,7 +168,11 @@ struct bcma_host_ops { +@@ -166,7 +172,65 @@ struct bcma_host_ops { #define BCMA_CHIP_ID_BCM4749 0x4749 #define BCMA_CHIP_ID_BCM5356 0x5356 #define BCMA_CHIP_ID_BCM5357 0x5357 @@ -1674,10 +2493,64 @@ +#define BCMA_PKG_ID_BCM5357 11 #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; -@@ -251,7 +257,7 @@ struct bcma_bus { +@@ -251,7 +315,7 @@ struct bcma_bus { u8 num; struct bcma_drv_cc drv_cc; @@ -1686,7 +2559,7 @@ struct bcma_drv_mips drv_mips; struct bcma_drv_gmac_cmn drv_gmac_cmn; -@@ -345,6 +351,7 @@ extern void bcma_core_set_clockmode(stru +@@ -345,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); @@ -1706,6 +2579,15 @@ /** ChipCommon core registers. **/ #define BCMA_CC_ID 0x0000 #define BCMA_CC_ID_ID 0x0000FFFF +@@ -24,7 +27,7 @@ + #define BCMA_CC_FLASHT_NONE 0x00000000 /* No flash */ + #define BCMA_CC_FLASHT_STSER 0x00000100 /* ST serial flash */ + #define BCMA_CC_FLASHT_ATSER 0x00000200 /* Atmel serial flash */ +-#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 @@ -100,6 +103,8 @@ #define BCMA_CC_CHIPST_4706_SFLASH_TYPE BIT(2) /* 0: 8b-p/ST-s flash, 1: 16b-p/Atmal-s flash */ #define BCMA_CC_CHIPST_4706_MIPS_BENDIAN BIT(3) /* 0: little, 1: big endian */ @@ -1755,9 +2637,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 */ -@@ -325,6 +356,60 @@ +@@ -299,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 */ +@@ -324,7 +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 */ +/* NAND flash MLC controller registers (corerev >= 38) */ +#define BCMA_CC_NAND_REVISION 0x0C00 @@ -1816,7 +2713,31 @@ /* Divider allocation in 4716/47162/5356 */ #define BCMA_CC_PMU5_MAINPLL_CPU 1 -@@ -415,6 +500,13 @@ +@@ -350,6 +442,23 @@ + #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 + /* HT clock for systems with PMU-enabled chipcommon */ +@@ -415,6 +524,44 @@ /* 4313 Chip specific ChipControl register bits */ #define BCMA_CCTRL_4313_12MA_LED_DRIVE 0x00000007 /* 12 mA drive strengh for later 4313 */ @@ -1827,10 +2748,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) */ -@@ -425,11 +517,35 @@ struct bcma_chipcommon_pmu { +@@ -425,11 +572,36 @@ struct bcma_chipcommon_pmu { #ifdef CONFIG_BCMA_DRIVER_MIPS struct bcma_pflash { @@ -1849,6 +2801,7 @@ + u32 size; + + struct mtd_info *mtd; ++ void *priv; +}; +#endif + @@ -1866,7 +2819,7 @@ struct bcma_serial_port { void *regs; unsigned long clockspeed; -@@ -445,15 +561,30 @@ struct bcma_drv_cc { +@@ -445,15 +617,30 @@ struct bcma_drv_cc { u32 capabilities; u32 capabilities_ext; u8 setup_done:1; @@ -1897,7 +2850,7 @@ }; /* Register access */ -@@ -470,14 +601,16 @@ struct bcma_drv_cc { +@@ -470,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); @@ -1916,7 +2869,7 @@ void bcma_chipco_irq_mask(struct bcma_drv_cc *cc, u32 mask, u32 value); -@@ -490,9 +623,12 @@ u32 bcma_chipco_gpio_outen(struct bcma_d +@@ -490,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); @@ -1929,9 +2882,24 @@ extern void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset, u32 value); +@@ -504,4 +696,6 @@ extern void bcma_chipco_regctl_maskset(s + 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_ */ --- 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; @@ -1942,12 +2910,34 @@ #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 +@@ -179,6 +179,8 @@ struct pci_dev; + #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 + --- a/include/linux/bcma/bcma_regs.h +++ b/include/linux/bcma/bcma_regs.h @@ -11,11 +11,13 @@ |