diff options
author | Rafał Miłecki <zajec5@gmail.com> | 2015-03-04 07:08:39 +0000 |
---|---|---|
committer | Rafał Miłecki <zajec5@gmail.com> | 2015-03-04 07:08:39 +0000 |
commit | 0d1eaa903d0742d0088fa03cb4ee9d58313f5c57 (patch) | |
tree | 4b5e5f5d781097ce1bbc486843cd30037a554221 /target/linux/generic | |
parent | 599bab39a82d31ce0cd34989362c0b580f0eb476 (diff) | |
download | upstream-0d1eaa903d0742d0088fa03cb4ee9d58313f5c57.tar.gz upstream-0d1eaa903d0742d0088fa03cb4ee9d58313f5c57.tar.bz2 upstream-0d1eaa903d0742d0088fa03cb4ee9d58313f5c57.zip |
kernel: backport bcma changes to 3.19 and 4.0
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@44597 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/generic')
4 files changed, 1238 insertions, 1 deletions
diff --git a/target/linux/generic/patches-3.19/020-bcma-from-4.0.patch b/target/linux/generic/patches-3.19/020-bcma-from-4.0.patch new file mode 100644 index 0000000000..17c06b001f --- /dev/null +++ b/target/linux/generic/patches-3.19/020-bcma-from-4.0.patch @@ -0,0 +1,527 @@ +--- a/drivers/bcma/bcma_private.h ++++ b/drivers/bcma/bcma_private.h +@@ -25,22 +25,18 @@ struct bcma_bus; + bool bcma_wait_value(struct bcma_device *core, u16 reg, u32 mask, u32 value, + int timeout); + void bcma_prepare_core(struct bcma_bus *bus, struct bcma_device *core); ++void bcma_init_bus(struct bcma_bus *bus); + int 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, +- struct bcma_device *core_mips); ++int __init bcma_bus_early_register(struct bcma_bus *bus); + #ifdef CONFIG_PM + int bcma_bus_suspend(struct bcma_bus *bus); + int bcma_bus_resume(struct bcma_bus *bus); + #endif + + /* scan.c */ ++void bcma_detect_chip(struct bcma_bus *bus); + int bcma_bus_scan(struct bcma_bus *bus); +-int __init bcma_bus_scan_early(struct bcma_bus *bus, +- struct bcma_device_id *match, +- struct bcma_device *core); +-void bcma_init_bus(struct bcma_bus *bus); + + /* sprom.c */ + int bcma_sprom_get(struct bcma_bus *bus); +@@ -111,6 +107,14 @@ extern int bcma_chipco_watchdog_register + #ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE + bool bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc); + void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc); ++#else ++static inline bool bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc) ++{ ++ return false; ++} ++static inline void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc) ++{ ++} + #endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */ + + #ifdef CONFIG_BCMA_DRIVER_GPIO +--- a/drivers/bcma/driver_chipcommon.c ++++ b/drivers/bcma/driver_chipcommon.c +@@ -79,7 +79,9 @@ static int bcma_chipco_watchdog_ticks_pe + + if (cc->capabilities & BCMA_CC_CAP_PMU) { + if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4706) +- /* 4706 CC and PMU watchdogs are clocked at 1/4 of ALP clock */ ++ /* 4706 CC and PMU watchdogs are clocked at 1/4 of ALP ++ * clock ++ */ + return bcma_chipco_get_alp_clock(cc) / 4000; + else + /* based on 32KHz ILP clock */ +@@ -97,7 +99,8 @@ int bcma_chipco_watchdog_register(struct + wdt.driver_data = cc; + wdt.timer_set = bcma_chipco_watchdog_timer_set_wdt; + wdt.timer_set_ms = bcma_chipco_watchdog_timer_set_ms_wdt; +- wdt.max_timer_ms = bcma_chipco_watchdog_get_max_timer(cc) / cc->ticks_per_ms; ++ wdt.max_timer_ms = ++ bcma_chipco_watchdog_get_max_timer(cc) / cc->ticks_per_ms; + + pdev = platform_device_register_data(NULL, "bcm47xx-wdt", + cc->core->bus->num, &wdt, +@@ -175,7 +178,6 @@ void bcma_core_chipcommon_init(struct bc + u32 bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc, u32 ticks) + { + u32 maxt; +- enum bcma_clkmode clkmode; + + maxt = bcma_chipco_watchdog_get_max_timer(cc); + if (cc->capabilities & BCMA_CC_CAP_PMU) { +@@ -185,8 +187,13 @@ u32 bcma_chipco_watchdog_timer_set(struc + ticks = maxt; + bcma_cc_write32(cc, BCMA_CC_PMU_WATCHDOG, ticks); + } else { +- clkmode = ticks ? BCMA_CLKMODE_FAST : BCMA_CLKMODE_DYNAMIC; +- bcma_core_set_clockmode(cc->core, clkmode); ++ struct bcma_bus *bus = cc->core->bus; ++ ++ if (bus->chipinfo.id != BCMA_CHIP_ID_BCM4707 && ++ bus->chipinfo.id != BCMA_CHIP_ID_BCM53018) ++ bcma_core_set_clockmode(cc->core, ++ ticks ? BCMA_CLKMODE_FAST : BCMA_CLKMODE_DYNAMIC); ++ + if (ticks > maxt) + ticks = maxt; + /* instant NMI */ +@@ -335,7 +342,8 @@ void bcma_chipco_serial_init(struct bcma + | BCMA_CC_CORECTL_UARTCLKEN); + } + } else { +- bcma_err(cc->core->bus, "serial not supported on this device ccrev: 0x%x\n", ccrev); ++ bcma_err(cc->core->bus, "serial not supported on this device ccrev: 0x%x\n", ++ ccrev); + return; + } + +--- a/drivers/bcma/driver_pci.c ++++ b/drivers/bcma/driver_pci.c +@@ -145,6 +145,47 @@ static u16 bcma_pcie_mdio_writeread(stru + } + + /************************************************** ++ * Early init. ++ **************************************************/ ++ ++static void bcma_core_pci_fixcfg(struct bcma_drv_pci *pc) ++{ ++ struct bcma_device *core = pc->core; ++ u16 val16, core_index; ++ uint regoff; ++ ++ regoff = BCMA_CORE_PCI_SPROM(BCMA_CORE_PCI_SPROM_PI_OFFSET); ++ core_index = (u16)core->core_index; ++ ++ val16 = pcicore_read16(pc, regoff); ++ if (((val16 & BCMA_CORE_PCI_SPROM_PI_MASK) >> BCMA_CORE_PCI_SPROM_PI_SHIFT) ++ != core_index) { ++ val16 = (core_index << BCMA_CORE_PCI_SPROM_PI_SHIFT) | ++ (val16 & ~BCMA_CORE_PCI_SPROM_PI_MASK); ++ pcicore_write16(pc, regoff, val16); ++ } ++} ++ ++/* ++ * Apply some early fixes required before accessing SPROM. ++ * See also si_pci_fixcfg. ++ */ ++void bcma_core_pci_early_init(struct bcma_drv_pci *pc) ++{ ++ if (pc->early_setup_done) ++ return; ++ ++ pc->hostmode = bcma_core_pci_is_in_hostmode(pc); ++ if (pc->hostmode) ++ goto out; ++ ++ bcma_core_pci_fixcfg(pc); ++ ++out: ++ pc->early_setup_done = true; ++} ++ ++/************************************************** + * Workarounds. + **************************************************/ + +@@ -175,24 +216,6 @@ static void bcma_pcicore_serdes_workarou + tmp & ~BCMA_CORE_PCI_PLL_CTRL_FREQDET_EN); + } + +-static void bcma_core_pci_fixcfg(struct bcma_drv_pci *pc) +-{ +- struct bcma_device *core = pc->core; +- u16 val16, core_index; +- uint regoff; +- +- regoff = BCMA_CORE_PCI_SPROM(BCMA_CORE_PCI_SPROM_PI_OFFSET); +- core_index = (u16)core->core_index; +- +- val16 = pcicore_read16(pc, regoff); +- if (((val16 & BCMA_CORE_PCI_SPROM_PI_MASK) >> BCMA_CORE_PCI_SPROM_PI_SHIFT) +- != core_index) { +- val16 = (core_index << BCMA_CORE_PCI_SPROM_PI_SHIFT) | +- (val16 & ~BCMA_CORE_PCI_SPROM_PI_MASK); +- pcicore_write16(pc, regoff, val16); +- } +-} +- + /* Fix MISC config to allow coming out of L2/L3-Ready state w/o PRST */ + /* Needs to happen when coming out of 'standby'/'hibernate' */ + static void bcma_core_pci_config_fixup(struct bcma_drv_pci *pc) +@@ -216,7 +239,6 @@ static void bcma_core_pci_config_fixup(s + + static void bcma_core_pci_clientmode_init(struct bcma_drv_pci *pc) + { +- bcma_core_pci_fixcfg(pc); + bcma_pcicore_serdes_workaround(pc); + bcma_core_pci_config_fixup(pc); + } +@@ -226,13 +248,11 @@ void bcma_core_pci_init(struct bcma_drv_ + if (pc->setup_done) + return; + +-#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE +- pc->hostmode = bcma_core_pci_is_in_hostmode(pc); ++ bcma_core_pci_early_init(pc); ++ + if (pc->hostmode) + bcma_core_pci_hostmode_init(pc); +-#endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */ +- +- if (!pc->hostmode) ++ else + bcma_core_pci_clientmode_init(pc); + } + +--- a/drivers/bcma/host_pci.c ++++ b/drivers/bcma/host_pci.c +@@ -13,10 +13,12 @@ + + static void bcma_host_pci_switch_core(struct bcma_device *core) + { ++ int win2 = core->bus->host_is_pcie2 ? ++ BCMA_PCIE2_BAR0_WIN2 : BCMA_PCI_BAR0_WIN2; ++ + pci_write_config_dword(core->bus->host_pci, BCMA_PCI_BAR0_WIN, + core->addr); +- pci_write_config_dword(core->bus->host_pci, BCMA_PCI_BAR0_WIN2, +- core->wrap); ++ pci_write_config_dword(core->bus->host_pci, win2, core->wrap); + core->bus->mapped_core = core; + bcma_debug(core->bus, "Switched to core: 0x%X\n", core->id.id); + } +--- a/drivers/bcma/host_soc.c ++++ b/drivers/bcma/host_soc.c +@@ -193,7 +193,7 @@ int __init bcma_host_soc_init(struct bcm + int err; + + /* Scan bus and initialize it */ +- err = bcma_bus_early_register(bus, &soc->core_cc, &soc->core_mips); ++ err = bcma_bus_early_register(bus); + if (err) + iounmap(bus->mmio); + +--- a/drivers/bcma/main.c ++++ b/drivers/bcma/main.c +@@ -268,6 +268,18 @@ void bcma_prepare_core(struct bcma_bus * + } + } + ++void bcma_init_bus(struct bcma_bus *bus) ++{ ++ mutex_lock(&bcma_buses_mutex); ++ bus->num = bcma_bus_next_num++; ++ mutex_unlock(&bcma_buses_mutex); ++ ++ INIT_LIST_HEAD(&bus->cores); ++ bus->nr_cores = 0; ++ ++ bcma_detect_chip(bus); ++} ++ + static void bcma_register_core(struct bcma_bus *bus, struct bcma_device *core) + { + int err; +@@ -356,12 +368,19 @@ static void bcma_unregister_cores(struct + struct bcma_device *core, *tmp; + + list_for_each_entry_safe(core, tmp, &bus->cores, list) { ++ if (!core->dev_registered) ++ continue; + list_del(&core->list); +- if (core->dev_registered) +- device_unregister(&core->dev); ++ device_unregister(&core->dev); + } + if (bus->hosttype == BCMA_HOSTTYPE_SOC) + platform_device_unregister(bus->drv_cc.watchdog); ++ ++ /* Now noone uses internally-handled cores, we can free them */ ++ list_for_each_entry_safe(core, tmp, &bus->cores, list) { ++ list_del(&core->list); ++ kfree(core); ++ } + } + + int bcma_bus_register(struct bcma_bus *bus) +@@ -369,10 +388,6 @@ int bcma_bus_register(struct bcma_bus *b + int err; + struct bcma_device *core; + +- mutex_lock(&bcma_buses_mutex); +- bus->num = bcma_bus_next_num++; +- mutex_unlock(&bcma_buses_mutex); +- + /* Scan for devices (cores) */ + err = bcma_bus_scan(bus); + if (err) { +@@ -387,6 +402,13 @@ int bcma_bus_register(struct bcma_bus *b + bcma_core_chipcommon_early_init(&bus->drv_cc); + } + ++ /* Early init PCIE core */ ++ core = bcma_find_core(bus, BCMA_CORE_PCIE); ++ if (core) { ++ bus->drv_pci[0].core = core; ++ bcma_core_pci_early_init(&bus->drv_pci[0]); ++ } ++ + /* Cores providing flash access go before SPROM init */ + list_for_each_entry(core, &bus->cores, list) { + if (bcma_is_core_needed_early(core->id.id)) +@@ -459,7 +481,6 @@ int bcma_bus_register(struct bcma_bus *b + + void bcma_bus_unregister(struct bcma_bus *bus) + { +- struct bcma_device *cores[3]; + int err; + + err = bcma_gpio_unregister(&bus->drv_cc); +@@ -470,46 +491,23 @@ void bcma_bus_unregister(struct bcma_bus + + bcma_core_chipcommon_b_free(&bus->drv_cc_b); + +- cores[0] = bcma_find_core(bus, BCMA_CORE_MIPS_74K); +- cores[1] = bcma_find_core(bus, BCMA_CORE_PCIE); +- cores[2] = bcma_find_core(bus, BCMA_CORE_4706_MAC_GBIT_COMMON); +- + bcma_unregister_cores(bus); +- +- kfree(cores[2]); +- kfree(cores[1]); +- kfree(cores[0]); + } + +-int __init bcma_bus_early_register(struct bcma_bus *bus, +- struct bcma_device *core_cc, +- struct bcma_device *core_mips) ++/* ++ * This is a special version of bus registration function designed for SoCs. ++ * It scans bus and performs basic initialization of main cores only. ++ * Please note it requires memory allocation, however it won't try to sleep. ++ */ ++int __init bcma_bus_early_register(struct bcma_bus *bus) + { + int err; + struct bcma_device *core; +- struct bcma_device_id match; +- +- match.manuf = BCMA_MANUF_BCM; +- match.id = bcma_cc_core_id(bus); +- match.class = BCMA_CL_SIM; +- match.rev = BCMA_ANY_REV; + +- /* Scan for chip common core */ +- err = bcma_bus_scan_early(bus, &match, core_cc); +- if (err) { +- bcma_err(bus, "Failed to scan for common core: %d\n", err); +- return -1; +- } +- +- match.manuf = BCMA_MANUF_MIPS; +- match.id = BCMA_CORE_MIPS_74K; +- match.class = BCMA_CL_SIM; +- match.rev = BCMA_ANY_REV; +- +- /* Scan for mips core */ +- err = bcma_bus_scan_early(bus, &match, core_mips); ++ /* Scan for devices (cores) */ ++ err = bcma_bus_scan(bus); + if (err) { +- bcma_err(bus, "Failed to scan for mips core: %d\n", err); ++ bcma_err(bus, "Failed to scan bus: %d\n", err); + return -1; + } + +--- a/drivers/bcma/scan.c ++++ b/drivers/bcma/scan.c +@@ -435,15 +435,12 @@ static int bcma_get_next_core(struct bcm + return 0; + } + +-void bcma_init_bus(struct bcma_bus *bus) ++void bcma_detect_chip(struct bcma_bus *bus) + { + s32 tmp; + struct bcma_chipinfo *chipinfo = &(bus->chipinfo); + char chip_id[8]; + +- INIT_LIST_HEAD(&bus->cores); +- bus->nr_cores = 0; +- + bcma_scan_switch_core(bus, BCMA_ADDR_BASE); + + tmp = bcma_scan_read32(bus, 0, BCMA_CC_ID); +@@ -464,6 +461,10 @@ int bcma_bus_scan(struct bcma_bus *bus) + + int err, core_num = 0; + ++ /* Skip if bus was already scanned (e.g. during early register) */ ++ if (bus->nr_cores) ++ return 0; ++ + erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM); + if (bus->hosttype == BCMA_HOSTTYPE_SOC) { + eromptr = ioremap_nocache(erombase, BCMA_CORE_SIZE); +@@ -519,64 +520,6 @@ int bcma_bus_scan(struct bcma_bus *bus) + out: + if (bus->hosttype == BCMA_HOSTTYPE_SOC) + iounmap(eromptr); +- +- return err; +-} +- +-int __init bcma_bus_scan_early(struct bcma_bus *bus, +- struct bcma_device_id *match, +- struct bcma_device *core) +-{ +- u32 erombase; +- u32 __iomem *eromptr, *eromend; +- +- int err = -ENODEV; +- int core_num = 0; +- +- erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM); +- if (bus->hosttype == BCMA_HOSTTYPE_SOC) { +- eromptr = ioremap_nocache(erombase, BCMA_CORE_SIZE); +- if (!eromptr) +- return -ENOMEM; +- } else { +- eromptr = bus->mmio; +- } +- +- eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32); +- +- bcma_scan_switch_core(bus, erombase); +- +- while (eromptr < eromend) { +- memset(core, 0, sizeof(*core)); +- INIT_LIST_HEAD(&core->list); +- core->bus = bus; +- +- err = bcma_get_next_core(bus, &eromptr, match, core_num, core); +- if (err == -ENODEV) { +- core_num++; +- continue; +- } else if (err == -ENXIO) +- continue; +- else if (err == -ESPIPE) +- break; +- else if (err < 0) +- goto out; +- +- core->core_index = core_num++; +- bus->nr_cores++; +- bcma_info(bus, "Core %d found: %s (manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n", +- core->core_index, bcma_device_name(&core->id), +- core->id.manuf, core->id.id, core->id.rev, +- core->id.class); +- +- list_add_tail(&core->list, &bus->cores); +- err = 0; +- break; +- } +- +-out: +- if (bus->hosttype == BCMA_HOSTTYPE_SOC) +- iounmap(eromptr); + + return err; + } +--- a/drivers/bcma/sprom.c ++++ b/drivers/bcma/sprom.c +@@ -579,7 +579,8 @@ int bcma_sprom_get(struct bcma_bus *bus) + u16 offset = BCMA_CC_SPROM; + u16 *sprom; + size_t sprom_sizes[] = { SSB_SPROMSIZE_WORDS_R4, +- SSB_SPROMSIZE_WORDS_R10, }; ++ SSB_SPROMSIZE_WORDS_R10, ++ SSB_SPROMSIZE_WORDS_R11, }; + int i, err = 0; + + if (!bus->drv_cc.core) +--- a/include/linux/bcma/bcma.h ++++ b/include/linux/bcma/bcma.h +@@ -318,6 +318,7 @@ struct bcma_bus { + const struct bcma_host_ops *ops; + + enum bcma_hosttype hosttype; ++ bool host_is_pcie2; /* Used for BCMA_HOSTTYPE_PCI only */ + union { + /* Pointer to the PCI bus (only for BCMA_HOSTTYPE_PCI) */ + struct pci_dev *host_pci; +--- a/include/linux/bcma/bcma_driver_pci.h ++++ b/include/linux/bcma/bcma_driver_pci.h +@@ -223,6 +223,7 @@ struct bcma_drv_pci_host { + + struct bcma_drv_pci { + struct bcma_device *core; ++ u8 early_setup_done:1; + u8 setup_done:1; + u8 hostmode:1; + +@@ -237,6 +238,7 @@ struct bcma_drv_pci { + #define pcicore_write16(pc, offset, val) bcma_write16((pc)->core, offset, val) + #define pcicore_write32(pc, offset, val) bcma_write32((pc)->core, offset, val) + ++extern void bcma_core_pci_early_init(struct bcma_drv_pci *pc); + extern void bcma_core_pci_init(struct bcma_drv_pci *pc); + extern int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, + struct bcma_device *core, bool enable); +--- a/include/linux/bcma/bcma_regs.h ++++ b/include/linux/bcma/bcma_regs.h +@@ -64,6 +64,8 @@ + #define BCMA_PCI_GPIO_XTAL 0x40 /* PCI config space GPIO 14 for Xtal powerup */ + #define BCMA_PCI_GPIO_PLL 0x80 /* PCI config space GPIO 15 for PLL powerdown */ + ++#define BCMA_PCIE2_BAR0_WIN2 0x70 ++ + /* SiliconBackplane Address Map. + * All regions may not exist on all chips. + */ +--- a/include/linux/bcma/bcma_soc.h ++++ b/include/linux/bcma/bcma_soc.h +@@ -5,8 +5,6 @@ + + struct bcma_soc { + struct bcma_bus bus; +- struct bcma_device core_cc; +- struct bcma_device core_mips; + }; + + int __init bcma_host_soc_register(struct bcma_soc *soc); +--- a/include/linux/ssb/ssb_regs.h ++++ b/include/linux/ssb/ssb_regs.h +@@ -173,6 +173,7 @@ + #define SSB_SPROMSIZE_BYTES_R123 (SSB_SPROMSIZE_WORDS_R123 * sizeof(u16)) + #define SSB_SPROMSIZE_BYTES_R4 (SSB_SPROMSIZE_WORDS_R4 * sizeof(u16)) + #define SSB_SPROMSIZE_WORDS_R10 230 ++#define SSB_SPROMSIZE_WORDS_R11 234 + #define SSB_SPROM_BASE1 0x1000 + #define SSB_SPROM_BASE31 0x0800 + #define SSB_SPROM_REVISION 0x007E diff --git a/target/linux/generic/patches-3.19/021-bcma-from-4.1.patch b/target/linux/generic/patches-3.19/021-bcma-from-4.1.patch new file mode 100644 index 0000000000..325d0d1c30 --- /dev/null +++ b/target/linux/generic/patches-3.19/021-bcma-from-4.1.patch @@ -0,0 +1,355 @@ +--- a/drivers/bcma/bcma_private.h ++++ b/drivers/bcma/bcma_private.h +@@ -26,6 +26,7 @@ bool bcma_wait_value(struct bcma_device + int timeout); + void bcma_prepare_core(struct bcma_bus *bus, struct bcma_device *core); + void bcma_init_bus(struct bcma_bus *bus); ++void bcma_unregister_cores(struct bcma_bus *bus); + int 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); +@@ -101,6 +102,11 @@ static inline void __exit bcma_host_soc_ + + /* driver_pci.c */ + u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address); ++void bcma_core_pci_up(struct bcma_drv_pci *pc); ++void bcma_core_pci_down(struct bcma_drv_pci *pc); ++ ++/* driver_pcie2.c */ ++void bcma_core_pcie2_up(struct bcma_drv_pcie2 *pcie2); + + extern int bcma_chipco_watchdog_register(struct bcma_drv_cc *cc); + +--- a/drivers/bcma/driver_gpio.c ++++ b/drivers/bcma/driver_gpio.c +@@ -76,7 +76,7 @@ static void bcma_gpio_free(struct gpio_c + bcma_chipco_gpio_pullup(cc, 1 << gpio, 0); + } + +-#if IS_BUILTIN(CONFIG_BCM47XX) ++#if IS_BUILTIN(CONFIG_BCM47XX) || IS_BUILTIN(CONFIG_ARCH_BCM_5301X) + static int bcma_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) + { + struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip); +@@ -215,7 +215,7 @@ int bcma_gpio_init(struct bcma_drv_cc *c + chip->set = bcma_gpio_set_value; + chip->direction_input = bcma_gpio_direction_input; + chip->direction_output = bcma_gpio_direction_output; +-#if IS_BUILTIN(CONFIG_BCM47XX) ++#if IS_BUILTIN(CONFIG_BCM47XX) || IS_BUILTIN(CONFIG_ARCH_BCM_5301X) + chip->to_irq = bcma_gpio_to_irq; + #endif + #if IS_BUILTIN(CONFIG_OF) +--- a/drivers/bcma/driver_pci.c ++++ b/drivers/bcma/driver_pci.c +@@ -282,21 +282,21 @@ void bcma_core_pci_power_save(struct bcm + } + EXPORT_SYMBOL_GPL(bcma_core_pci_power_save); + +-int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core, ++int bcma_core_pci_irq_ctl(struct bcma_bus *bus, struct bcma_device *core, + bool enable) + { + struct pci_dev *pdev; + u32 coremask, tmp; + int err = 0; + +- if (!pc || core->bus->hosttype != BCMA_HOSTTYPE_PCI) { ++ if (bus->hosttype != BCMA_HOSTTYPE_PCI) { + /* This bcma device is not on a PCI host-bus. So the IRQs are + * not routed through the PCI core. + * So we must not enable routing through the PCI core. */ + goto out; + } + +- pdev = pc->core->bus->host_pci; ++ pdev = bus->host_pci; + + err = pci_read_config_dword(pdev, BCMA_PCI_IRQMASK, &tmp); + if (err) +@@ -328,28 +328,12 @@ static void bcma_core_pci_extend_L1timer + bcma_pcie_read(pc, BCMA_CORE_PCI_DLLP_PMTHRESHREG); + } + +-void bcma_core_pci_up(struct bcma_bus *bus) ++void bcma_core_pci_up(struct bcma_drv_pci *pc) + { +- struct bcma_drv_pci *pc; +- +- if (bus->hosttype != BCMA_HOSTTYPE_PCI) +- return; +- +- pc = &bus->drv_pci[0]; +- + bcma_core_pci_extend_L1timer(pc, true); + } +-EXPORT_SYMBOL_GPL(bcma_core_pci_up); + +-void bcma_core_pci_down(struct bcma_bus *bus) ++void bcma_core_pci_down(struct bcma_drv_pci *pc) + { +- struct bcma_drv_pci *pc; +- +- if (bus->hosttype != BCMA_HOSTTYPE_PCI) +- return; +- +- pc = &bus->drv_pci[0]; +- + bcma_core_pci_extend_L1timer(pc, false); + } +-EXPORT_SYMBOL_GPL(bcma_core_pci_down); +--- a/drivers/bcma/driver_pci_host.c ++++ b/drivers/bcma/driver_pci_host.c +@@ -11,6 +11,7 @@ + + #include "bcma_private.h" + #include <linux/pci.h> ++#include <linux/slab.h> + #include <linux/export.h> + #include <linux/bcma/bcma.h> + #include <asm/paccess.h> +--- a/drivers/bcma/driver_pcie2.c ++++ b/drivers/bcma/driver_pcie2.c +@@ -10,6 +10,7 @@ + + #include "bcma_private.h" + #include <linux/bcma/bcma.h> ++#include <linux/pci.h> + + /************************************************** + * R/W ops. +@@ -156,14 +157,23 @@ static void pciedev_reg_pm_clk_period(st + + void bcma_core_pcie2_init(struct bcma_drv_pcie2 *pcie2) + { +- struct bcma_chipinfo *ci = &pcie2->core->bus->chipinfo; ++ struct bcma_bus *bus = pcie2->core->bus; ++ struct bcma_chipinfo *ci = &bus->chipinfo; + u32 tmp; + + tmp = pcie2_read32(pcie2, BCMA_CORE_PCIE2_SPROM(54)); + if ((tmp & 0xe) >> 1 == 2) + bcma_core_pcie2_cfg_write(pcie2, 0x4e0, 0x17); + +- /* TODO: Do we need pcie_reqsize? */ ++ switch (bus->chipinfo.id) { ++ case BCMA_CHIP_ID_BCM4360: ++ case BCMA_CHIP_ID_BCM4352: ++ pcie2->reqsize = 1024; ++ break; ++ default: ++ pcie2->reqsize = 128; ++ break; ++ } + + if (ci->id == BCMA_CHIP_ID_BCM4360 && ci->rev > 3) + bcma_core_pcie2_war_delay_perst_enab(pcie2, true); +@@ -173,3 +183,18 @@ void bcma_core_pcie2_init(struct bcma_dr + pciedev_crwlpciegen2_180(pcie2); + pciedev_crwlpciegen2_182(pcie2); + } ++ ++/************************************************** ++ * Runtime ops. ++ **************************************************/ ++ ++void bcma_core_pcie2_up(struct bcma_drv_pcie2 *pcie2) ++{ ++ struct bcma_bus *bus = pcie2->core->bus; ++ struct pci_dev *dev = bus->host_pci; ++ int err; ++ ++ err = pcie_set_readrq(dev, pcie2->reqsize); ++ if (err) ++ bcma_err(bus, "Error setting PCI_EXP_DEVCTL_READRQ: %d\n", err); ++} +--- a/drivers/bcma/host_pci.c ++++ b/drivers/bcma/host_pci.c +@@ -213,16 +213,26 @@ static int bcma_host_pci_probe(struct pc + /* Initialize struct, detect chip */ + bcma_init_bus(bus); + ++ /* Scan bus to find out generation of PCIe core */ ++ err = bcma_bus_scan(bus); ++ if (err) ++ goto err_pci_unmap_mmio; ++ ++ if (bcma_find_core(bus, BCMA_CORE_PCIE2)) ++ bus->host_is_pcie2 = true; ++ + /* Register */ + err = bcma_bus_register(bus); + if (err) +- goto err_pci_unmap_mmio; ++ goto err_unregister_cores; + + pci_set_drvdata(dev, bus); + + out: + return err; + ++err_unregister_cores: ++ bcma_unregister_cores(bus); + err_pci_unmap_mmio: + pci_iounmap(dev, bus->mmio); + err_pci_release_regions: +@@ -283,9 +293,12 @@ static const struct pci_device_id bcma_p + { 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, 0x4360) }, + { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4365) }, ++ { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43a0) }, + { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43a9) }, + { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43aa) }, ++ { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43b1) }, + { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) }, + { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 43227) }, /* 0xa8db, BCM43217 (sic!) */ + { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 43228) }, /* 0xa8dc */ +@@ -310,3 +323,31 @@ void __exit bcma_host_pci_exit(void) + { + pci_unregister_driver(&bcma_pci_bridge_driver); + } ++ ++/************************************************** ++ * Runtime ops for drivers. ++ **************************************************/ ++ ++/* See also pcicore_up */ ++void bcma_host_pci_up(struct bcma_bus *bus) ++{ ++ if (bus->hosttype != BCMA_HOSTTYPE_PCI) ++ return; ++ ++ if (bus->host_is_pcie2) ++ bcma_core_pcie2_up(&bus->drv_pcie2); ++ else ++ bcma_core_pci_up(&bus->drv_pci[0]); ++} ++EXPORT_SYMBOL_GPL(bcma_host_pci_up); ++ ++/* See also pcicore_down */ ++void bcma_host_pci_down(struct bcma_bus *bus) ++{ ++ if (bus->hosttype != BCMA_HOSTTYPE_PCI) ++ return; ++ ++ if (!bus->host_is_pcie2) ++ bcma_core_pci_down(&bus->drv_pci[0]); ++} ++EXPORT_SYMBOL_GPL(bcma_host_pci_down); +--- a/drivers/bcma/main.c ++++ b/drivers/bcma/main.c +@@ -363,7 +363,7 @@ static int bcma_register_devices(struct + return 0; + } + +-static void bcma_unregister_cores(struct bcma_bus *bus) ++void bcma_unregister_cores(struct bcma_bus *bus) + { + struct bcma_device *core, *tmp; + +--- a/drivers/net/wireless/b43/main.c ++++ b/drivers/net/wireless/b43/main.c +@@ -4770,7 +4770,7 @@ static void b43_wireless_core_exit(struc + switch (dev->dev->bus_type) { + #ifdef CONFIG_B43_BCMA + case B43_BUS_BCMA: +- bcma_core_pci_down(dev->dev->bdev->bus); ++ bcma_host_pci_down(dev->dev->bdev->bus); + break; + #endif + #ifdef CONFIG_B43_SSB +@@ -4817,9 +4817,9 @@ static int b43_wireless_core_init(struct + switch (dev->dev->bus_type) { + #ifdef CONFIG_B43_BCMA + case B43_BUS_BCMA: +- bcma_core_pci_irq_ctl(&dev->dev->bdev->bus->drv_pci[0], ++ bcma_core_pci_irq_ctl(dev->dev->bdev->bus, + dev->dev->bdev, true); +- bcma_core_pci_up(dev->dev->bdev->bus); ++ bcma_host_pci_up(dev->dev->bdev->bus); + break; + #endif + #ifdef CONFIG_B43_SSB +--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c ++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c +@@ -4668,7 +4668,7 @@ static int brcms_b_attach(struct brcms_c + brcms_c_coredisable(wlc_hw); + + /* Match driver "down" state */ +- bcma_core_pci_down(wlc_hw->d11core->bus); ++ bcma_host_pci_down(wlc_hw->d11core->bus); + + /* turn off pll and xtal to match driver "down" state */ + brcms_b_xtal(wlc_hw, OFF); +@@ -4959,7 +4959,7 @@ static int brcms_b_up_prep(struct brcms_ + * Configure pci/pcmcia here instead of in brcms_c_attach() + * to allow mfg hotswap: down, hotswap (chip power cycle), up. + */ +- bcma_core_pci_irq_ctl(&wlc_hw->d11core->bus->drv_pci[0], wlc_hw->d11core, ++ bcma_core_pci_irq_ctl(wlc_hw->d11core->bus, wlc_hw->d11core, + true); + + /* +@@ -4969,12 +4969,12 @@ static int brcms_b_up_prep(struct brcms_ + */ + if (brcms_b_radio_read_hwdisabled(wlc_hw)) { + /* put SB PCI in down state again */ +- bcma_core_pci_down(wlc_hw->d11core->bus); ++ bcma_host_pci_down(wlc_hw->d11core->bus); + brcms_b_xtal(wlc_hw, OFF); + return -ENOMEDIUM; + } + +- bcma_core_pci_up(wlc_hw->d11core->bus); ++ bcma_host_pci_up(wlc_hw->d11core->bus); + + /* reset the d11 core */ + brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS); +@@ -5171,7 +5171,7 @@ static int brcms_b_down_finish(struct br + + /* turn off primary xtal and pll */ + if (!wlc_hw->noreset) { +- bcma_core_pci_down(wlc_hw->d11core->bus); ++ bcma_host_pci_down(wlc_hw->d11core->bus); + brcms_b_xtal(wlc_hw, OFF); + } + } +--- a/include/linux/bcma/bcma.h ++++ b/include/linux/bcma/bcma.h +@@ -434,6 +434,9 @@ static inline struct bcma_device *bcma_f + return bcma_find_core_unit(bus, coreid, 0); + } + ++extern void bcma_host_pci_up(struct bcma_bus *bus); ++extern void bcma_host_pci_down(struct bcma_bus *bus); ++ + 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); +--- a/include/linux/bcma/bcma_driver_pci.h ++++ b/include/linux/bcma/bcma_driver_pci.h +@@ -240,10 +240,8 @@ struct bcma_drv_pci { + + extern void bcma_core_pci_early_init(struct bcma_drv_pci *pc); + extern void bcma_core_pci_init(struct bcma_drv_pci *pc); +-extern int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, ++extern int bcma_core_pci_irq_ctl(struct bcma_bus *bus, + struct bcma_device *core, bool enable); +-extern void bcma_core_pci_up(struct bcma_bus *bus); +-extern void bcma_core_pci_down(struct bcma_bus *bus); + extern void bcma_core_pci_power_save(struct bcma_bus *bus, bool up); + + extern int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev); +--- a/include/linux/bcma/bcma_driver_pcie2.h ++++ b/include/linux/bcma/bcma_driver_pcie2.h +@@ -143,6 +143,8 @@ + + struct bcma_drv_pcie2 { + struct bcma_device *core; ++ ++ u16 reqsize; + }; + + #define pcie2_read16(pcie2, offset) bcma_read16((pcie2)->core, offset) diff --git a/target/linux/generic/patches-3.19/700-swconfig.patch b/target/linux/generic/patches-3.19/700-swconfig.patch index bf62025d2a..8e81f23297 100644 --- a/target/linux/generic/patches-3.19/700-swconfig.patch +++ b/target/linux/generic/patches-3.19/700-swconfig.patch @@ -29,7 +29,7 @@ obj-$(CONFIG_CICADA_PHY) += cicada.o --- a/include/uapi/linux/Kbuild +++ b/include/uapi/linux/Kbuild -@@ -379,6 +379,7 @@ header-y += stddef.h +@@ -378,6 +378,7 @@ header-y += stddef.h header-y += string.h header-y += suspend_ioctls.h header-y += swab.h diff --git a/target/linux/generic/patches-4.0/021-bcma-from-4.1.patch b/target/linux/generic/patches-4.0/021-bcma-from-4.1.patch new file mode 100644 index 0000000000..fb751cb33c --- /dev/null +++ b/target/linux/generic/patches-4.0/021-bcma-from-4.1.patch @@ -0,0 +1,355 @@ +--- a/drivers/bcma/bcma_private.h ++++ b/drivers/bcma/bcma_private.h +@@ -26,6 +26,7 @@ bool bcma_wait_value(struct bcma_device + int timeout); + void bcma_prepare_core(struct bcma_bus *bus, struct bcma_device *core); + void bcma_init_bus(struct bcma_bus *bus); ++void bcma_unregister_cores(struct bcma_bus *bus); + int 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); +@@ -101,6 +102,11 @@ static inline void __exit bcma_host_soc_ + + /* driver_pci.c */ + u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address); ++void bcma_core_pci_up(struct bcma_drv_pci *pc); ++void bcma_core_pci_down(struct bcma_drv_pci *pc); ++ ++/* driver_pcie2.c */ ++void bcma_core_pcie2_up(struct bcma_drv_pcie2 *pcie2); + + extern int bcma_chipco_watchdog_register(struct bcma_drv_cc *cc); + +--- a/drivers/bcma/driver_gpio.c ++++ b/drivers/bcma/driver_gpio.c +@@ -76,7 +76,7 @@ static void bcma_gpio_free(struct gpio_c + bcma_chipco_gpio_pullup(cc, 1 << gpio, 0); + } + +-#if IS_BUILTIN(CONFIG_BCM47XX) ++#if IS_BUILTIN(CONFIG_BCM47XX) || IS_BUILTIN(CONFIG_ARCH_BCM_5301X) + static int bcma_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) + { + struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip); +@@ -215,7 +215,7 @@ int bcma_gpio_init(struct bcma_drv_cc *c + chip->set = bcma_gpio_set_value; + chip->direction_input = bcma_gpio_direction_input; + chip->direction_output = bcma_gpio_direction_output; +-#if IS_BUILTIN(CONFIG_BCM47XX) ++#if IS_BUILTIN(CONFIG_BCM47XX) || IS_BUILTIN(CONFIG_ARCH_BCM_5301X) + chip->to_irq = bcma_gpio_to_irq; + #endif + #if IS_BUILTIN(CONFIG_OF) +--- a/drivers/bcma/driver_pci.c ++++ b/drivers/bcma/driver_pci.c +@@ -282,21 +282,21 @@ void bcma_core_pci_power_save(struct bcm + } + EXPORT_SYMBOL_GPL(bcma_core_pci_power_save); + +-int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core, ++int bcma_core_pci_irq_ctl(struct bcma_bus *bus, struct bcma_device *core, + bool enable) + { + struct pci_dev *pdev; + u32 coremask, tmp; + int err = 0; + +- if (!pc || core->bus->hosttype != BCMA_HOSTTYPE_PCI) { ++ if (bus->hosttype != BCMA_HOSTTYPE_PCI) { + /* This bcma device is not on a PCI host-bus. So the IRQs are + * not routed through the PCI core. + * So we must not enable routing through the PCI core. */ + goto out; + } + +- pdev = pc->core->bus->host_pci; ++ pdev = bus->host_pci; + + err = pci_read_config_dword(pdev, BCMA_PCI_IRQMASK, &tmp); + if (err) +@@ -328,28 +328,12 @@ static void bcma_core_pci_extend_L1timer + bcma_pcie_read(pc, BCMA_CORE_PCI_DLLP_PMTHRESHREG); + } + +-void bcma_core_pci_up(struct bcma_bus *bus) ++void bcma_core_pci_up(struct bcma_drv_pci *pc) + { +- struct bcma_drv_pci *pc; +- +- if (bus->hosttype != BCMA_HOSTTYPE_PCI) +- return; +- +- pc = &bus->drv_pci[0]; +- + bcma_core_pci_extend_L1timer(pc, true); + } +-EXPORT_SYMBOL_GPL(bcma_core_pci_up); + +-void bcma_core_pci_down(struct bcma_bus *bus) ++void bcma_core_pci_down(struct bcma_drv_pci *pc) + { +- struct bcma_drv_pci *pc; +- +- if (bus->hosttype != BCMA_HOSTTYPE_PCI) +- return; +- +- pc = &bus->drv_pci[0]; +- + bcma_core_pci_extend_L1timer(pc, false); + } +-EXPORT_SYMBOL_GPL(bcma_core_pci_down); +--- a/drivers/bcma/driver_pci_host.c ++++ b/drivers/bcma/driver_pci_host.c +@@ -11,6 +11,7 @@ + + #include "bcma_private.h" + #include <linux/pci.h> ++#include <linux/slab.h> + #include <linux/export.h> + #include <linux/bcma/bcma.h> + #include <asm/paccess.h> +--- a/drivers/bcma/driver_pcie2.c ++++ b/drivers/bcma/driver_pcie2.c +@@ -10,6 +10,7 @@ + + #include "bcma_private.h" + #include <linux/bcma/bcma.h> ++#include <linux/pci.h> + + /************************************************** + * R/W ops. +@@ -156,14 +157,23 @@ static void pciedev_reg_pm_clk_period(st + + void bcma_core_pcie2_init(struct bcma_drv_pcie2 *pcie2) + { +- struct bcma_chipinfo *ci = &pcie2->core->bus->chipinfo; ++ struct bcma_bus *bus = pcie2->core->bus; ++ struct bcma_chipinfo *ci = &bus->chipinfo; + u32 tmp; + + tmp = pcie2_read32(pcie2, BCMA_CORE_PCIE2_SPROM(54)); + if ((tmp & 0xe) >> 1 == 2) + bcma_core_pcie2_cfg_write(pcie2, 0x4e0, 0x17); + +- /* TODO: Do we need pcie_reqsize? */ ++ switch (bus->chipinfo.id) { ++ case BCMA_CHIP_ID_BCM4360: ++ case BCMA_CHIP_ID_BCM4352: ++ pcie2->reqsize = 1024; ++ break; ++ default: ++ pcie2->reqsize = 128; ++ break; ++ } + + if (ci->id == BCMA_CHIP_ID_BCM4360 && ci->rev > 3) + bcma_core_pcie2_war_delay_perst_enab(pcie2, true); +@@ -173,3 +183,18 @@ void bcma_core_pcie2_init(struct bcma_dr + pciedev_crwlpciegen2_180(pcie2); + pciedev_crwlpciegen2_182(pcie2); + } ++ ++/************************************************** ++ * Runtime ops. ++ **************************************************/ ++ ++void bcma_core_pcie2_up(struct bcma_drv_pcie2 *pcie2) ++{ ++ struct bcma_bus *bus = pcie2->core->bus; ++ struct pci_dev *dev = bus->host_pci; ++ int err; ++ ++ err = pcie_set_readrq(dev, pcie2->reqsize); ++ if (err) ++ bcma_err(bus, "Error setting PCI_EXP_DEVCTL_READRQ: %d\n", err); ++} +--- a/drivers/bcma/host_pci.c ++++ b/drivers/bcma/host_pci.c +@@ -213,16 +213,26 @@ static int bcma_host_pci_probe(struct pc + /* Initialize struct, detect chip */ + bcma_init_bus(bus); + ++ /* Scan bus to find out generation of PCIe core */ ++ err = bcma_bus_scan(bus); ++ if (err) ++ goto err_pci_unmap_mmio; ++ ++ if (bcma_find_core(bus, BCMA_CORE_PCIE2)) ++ bus->host_is_pcie2 = true; ++ + /* Register */ + err = bcma_bus_register(bus); + if (err) +- goto err_pci_unmap_mmio; ++ goto err_unregister_cores; + + pci_set_drvdata(dev, bus); + + out: + return err; + ++err_unregister_cores: ++ bcma_unregister_cores(bus); + err_pci_unmap_mmio: + pci_iounmap(dev, bus->mmio); + err_pci_release_regions: +@@ -283,9 +293,12 @@ static const struct pci_device_id bcma_p + { 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, 0x4360) }, + { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4365) }, ++ { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43a0) }, + { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43a9) }, + { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43aa) }, ++ { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43b1) }, + { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) }, + { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 43227) }, /* 0xa8db, BCM43217 (sic!) */ + { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 43228) }, /* 0xa8dc */ +@@ -310,3 +323,31 @@ void __exit bcma_host_pci_exit(void) + { + pci_unregister_driver(&bcma_pci_bridge_driver); + } ++ ++/************************************************** ++ * Runtime ops for drivers. ++ **************************************************/ ++ ++/* See also pcicore_up */ ++void bcma_host_pci_up(struct bcma_bus *bus) ++{ ++ if (bus->hosttype != BCMA_HOSTTYPE_PCI) ++ return; ++ ++ if (bus->host_is_pcie2) ++ bcma_core_pcie2_up(&bus->drv_pcie2); ++ else ++ bcma_core_pci_up(&bus->drv_pci[0]); ++} ++EXPORT_SYMBOL_GPL(bcma_host_pci_up); ++ ++/* See also pcicore_down */ ++void bcma_host_pci_down(struct bcma_bus *bus) ++{ ++ if (bus->hosttype != BCMA_HOSTTYPE_PCI) ++ return; ++ ++ if (!bus->host_is_pcie2) ++ bcma_core_pci_down(&bus->drv_pci[0]); ++} ++EXPORT_SYMBOL_GPL(bcma_host_pci_down); +--- a/drivers/bcma/main.c ++++ b/drivers/bcma/main.c +@@ -363,7 +363,7 @@ static int bcma_register_devices(struct + return 0; + } + +-static void bcma_unregister_cores(struct bcma_bus *bus) ++void bcma_unregister_cores(struct bcma_bus *bus) + { + struct bcma_device *core, *tmp; + +--- a/drivers/net/wireless/b43/main.c ++++ b/drivers/net/wireless/b43/main.c +@@ -4819,7 +4819,7 @@ static void b43_wireless_core_exit(struc + switch (dev->dev->bus_type) { + #ifdef CONFIG_B43_BCMA + case B43_BUS_BCMA: +- bcma_core_pci_down(dev->dev->bdev->bus); ++ bcma_host_pci_down(dev->dev->bdev->bus); + break; + #endif + #ifdef CONFIG_B43_SSB +@@ -4866,9 +4866,9 @@ static int b43_wireless_core_init(struct + switch (dev->dev->bus_type) { + #ifdef CONFIG_B43_BCMA + case B43_BUS_BCMA: +- bcma_core_pci_irq_ctl(&dev->dev->bdev->bus->drv_pci[0], ++ bcma_core_pci_irq_ctl(dev->dev->bdev->bus, + dev->dev->bdev, true); +- bcma_core_pci_up(dev->dev->bdev->bus); ++ bcma_host_pci_up(dev->dev->bdev->bus); + break; + #endif + #ifdef CONFIG_B43_SSB +--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c ++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c +@@ -4668,7 +4668,7 @@ static int brcms_b_attach(struct brcms_c + brcms_c_coredisable(wlc_hw); + + /* Match driver "down" state */ +- bcma_core_pci_down(wlc_hw->d11core->bus); ++ bcma_host_pci_down(wlc_hw->d11core->bus); + + /* turn off pll and xtal to match driver "down" state */ + brcms_b_xtal(wlc_hw, OFF); +@@ -4959,7 +4959,7 @@ static int brcms_b_up_prep(struct brcms_ + * Configure pci/pcmcia here instead of in brcms_c_attach() + * to allow mfg hotswap: down, hotswap (chip power cycle), up. + */ +- bcma_core_pci_irq_ctl(&wlc_hw->d11core->bus->drv_pci[0], wlc_hw->d11core, ++ bcma_core_pci_irq_ctl(wlc_hw->d11core->bus, wlc_hw->d11core, + true); + + /* +@@ -4969,12 +4969,12 @@ static int brcms_b_up_prep(struct brcms_ + */ + if (brcms_b_radio_read_hwdisabled(wlc_hw)) { + /* put SB PCI in down state again */ +- bcma_core_pci_down(wlc_hw->d11core->bus); ++ bcma_host_pci_down(wlc_hw->d11core->bus); + brcms_b_xtal(wlc_hw, OFF); + return -ENOMEDIUM; + } + +- bcma_core_pci_up(wlc_hw->d11core->bus); ++ bcma_host_pci_up(wlc_hw->d11core->bus); + + /* reset the d11 core */ + brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS); +@@ -5171,7 +5171,7 @@ static int brcms_b_down_finish(struct br + + /* turn off primary xtal and pll */ + if (!wlc_hw->noreset) { +- bcma_core_pci_down(wlc_hw->d11core->bus); ++ bcma_host_pci_down(wlc_hw->d11core->bus); + brcms_b_xtal(wlc_hw, OFF); + } + } +--- a/include/linux/bcma/bcma.h ++++ b/include/linux/bcma/bcma.h +@@ -434,6 +434,9 @@ static inline struct bcma_device *bcma_f + return bcma_find_core_unit(bus, coreid, 0); + } + ++extern void bcma_host_pci_up(struct bcma_bus *bus); ++extern void bcma_host_pci_down(struct bcma_bus *bus); ++ + 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); +--- a/include/linux/bcma/bcma_driver_pci.h ++++ b/include/linux/bcma/bcma_driver_pci.h +@@ -240,10 +240,8 @@ struct bcma_drv_pci { + + extern void bcma_core_pci_early_init(struct bcma_drv_pci *pc); + extern void bcma_core_pci_init(struct bcma_drv_pci *pc); +-extern int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, ++extern int bcma_core_pci_irq_ctl(struct bcma_bus *bus, + struct bcma_device *core, bool enable); +-extern void bcma_core_pci_up(struct bcma_bus *bus); +-extern void bcma_core_pci_down(struct bcma_bus *bus); + extern void bcma_core_pci_power_save(struct bcma_bus *bus, bool up); + + extern int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev); +--- a/include/linux/bcma/bcma_driver_pcie2.h ++++ b/include/linux/bcma/bcma_driver_pcie2.h +@@ -143,6 +143,8 @@ + + struct bcma_drv_pcie2 { + struct bcma_device *core; ++ ++ u16 reqsize; + }; + + #define pcie2_read16(pcie2, offset) bcma_read16((pcie2)->core, offset) |