123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527 |
- --- a/drivers/bcma/bcma_private.h
- +++ b/drivers/bcma/bcma_private.h
- @@ -23,22 +23,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);
- @@ -109,6 +105,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
- @@ -319,6 +319,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
|