summaryrefslogtreecommitdiff
path: root/target/linux/generic/patches-3.2/025-bcma_backport.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/generic/patches-3.2/025-bcma_backport.patch')
-rw-r--r--target/linux/generic/patches-3.2/025-bcma_backport.patch974
1 files changed, 675 insertions, 299 deletions
diff --git a/target/linux/generic/patches-3.2/025-bcma_backport.patch b/target/linux/generic/patches-3.2/025-bcma_backport.patch
index fdb1b8dd2b..3149fd3ced 100644
--- a/target/linux/generic/patches-3.2/025-bcma_backport.patch
+++ b/target/linux/generic/patches-3.2/025-bcma_backport.patch
@@ -1,3 +1,14 @@
+--- a/drivers/bcma/Kconfig
++++ b/drivers/bcma/Kconfig
+@@ -29,7 +29,7 @@ config BCMA_HOST_PCI
+
+ config BCMA_DRIVER_PCI_HOSTMODE
+ bool "Driver for PCI core working in hostmode"
+- depends on BCMA && MIPS
++ depends on BCMA && MIPS && BCMA_HOST_PCI
+ help
+ PCI core hostmode operation (external PCI bus).
+
--- a/drivers/bcma/bcma_private.h
+++ b/drivers/bcma/bcma_private.h
@@ -13,12 +13,13 @@
@@ -29,277 +40,25 @@
#endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */
#endif
---- a/drivers/bcma/host_pci.c
-+++ b/drivers/bcma/host_pci.c
-@@ -21,48 +21,58 @@ static void bcma_host_pci_switch_core(st
- pr_debug("Switched to core: 0x%X\n", core->id.id);
- }
-
--static u8 bcma_host_pci_read8(struct bcma_device *core, u16 offset)
--{
-+/* Provides access to the requested core. Returns base offset that has to be
-+ * used. It makes use of fixed windows when possible. */
-+static u16 bcma_host_pci_provide_access_to_core(struct bcma_device *core)
-+{
-+ switch (core->id.id) {
-+ case BCMA_CORE_CHIPCOMMON:
-+ return 3 * BCMA_CORE_SIZE;
-+ case BCMA_CORE_PCIE:
-+ return 2 * BCMA_CORE_SIZE;
-+ }
-+
- if (core->bus->mapped_core != core)
- bcma_host_pci_switch_core(core);
-+ return 0;
-+}
-+
-+static u8 bcma_host_pci_read8(struct bcma_device *core, u16 offset)
-+{
-+ offset += bcma_host_pci_provide_access_to_core(core);
- return ioread8(core->bus->mmio + offset);
- }
-
- static u16 bcma_host_pci_read16(struct bcma_device *core, u16 offset)
- {
-- if (core->bus->mapped_core != core)
-- bcma_host_pci_switch_core(core);
-+ offset += bcma_host_pci_provide_access_to_core(core);
- return ioread16(core->bus->mmio + offset);
- }
-
- static u32 bcma_host_pci_read32(struct bcma_device *core, u16 offset)
- {
-- if (core->bus->mapped_core != core)
-- bcma_host_pci_switch_core(core);
-+ offset += bcma_host_pci_provide_access_to_core(core);
- return ioread32(core->bus->mmio + offset);
- }
-
- static void bcma_host_pci_write8(struct bcma_device *core, u16 offset,
- u8 value)
- {
-- if (core->bus->mapped_core != core)
-- bcma_host_pci_switch_core(core);
-+ offset += bcma_host_pci_provide_access_to_core(core);
- iowrite8(value, core->bus->mmio + offset);
- }
-
- static void bcma_host_pci_write16(struct bcma_device *core, u16 offset,
- u16 value)
- {
-- if (core->bus->mapped_core != core)
-- bcma_host_pci_switch_core(core);
-+ offset += bcma_host_pci_provide_access_to_core(core);
- iowrite16(value, core->bus->mmio + offset);
- }
-
- static void bcma_host_pci_write32(struct bcma_device *core, u16 offset,
- u32 value)
- {
-- if (core->bus->mapped_core != core)
-- bcma_host_pci_switch_core(core);
-+ offset += bcma_host_pci_provide_access_to_core(core);
- iowrite32(value, core->bus->mmio + offset);
- }
-
-@@ -144,8 +154,8 @@ const struct bcma_host_ops bcma_host_pci
- .awrite32 = bcma_host_pci_awrite32,
- };
-
--static int bcma_host_pci_probe(struct pci_dev *dev,
-- const struct pci_device_id *id)
-+static int __devinit bcma_host_pci_probe(struct pci_dev *dev,
-+ const struct pci_device_id *id)
- {
- struct bcma_bus *bus;
- int err = -ENOMEM;
-@@ -225,41 +235,32 @@ static void bcma_host_pci_remove(struct
- }
-
- #ifdef CONFIG_PM
--static int bcma_host_pci_suspend(struct pci_dev *dev, pm_message_t state)
-+static int bcma_host_pci_suspend(struct device *dev)
- {
-- struct bcma_bus *bus = pci_get_drvdata(dev);
--
-- /* Host specific */
-- pci_save_state(dev);
-- pci_disable_device(dev);
-- pci_set_power_state(dev, pci_choose_state(dev, state));
-+ struct pci_dev *pdev = to_pci_dev(dev);
-+ struct bcma_bus *bus = pci_get_drvdata(pdev);
-
- bus->mapped_core = NULL;
-- return 0;
-+
-+ return bcma_bus_suspend(bus);
- }
-
--static int bcma_host_pci_resume(struct pci_dev *dev)
-+static int bcma_host_pci_resume(struct device *dev)
- {
-- struct bcma_bus *bus = pci_get_drvdata(dev);
-- int err;
-+ struct pci_dev *pdev = to_pci_dev(dev);
-+ struct bcma_bus *bus = pci_get_drvdata(pdev);
-
-- /* Host specific */
-- pci_set_power_state(dev, 0);
-- err = pci_enable_device(dev);
-- if (err)
-- return err;
-- pci_restore_state(dev);
-+ return bcma_bus_resume(bus);
-+}
-
-- /* Bus specific */
-- err = bcma_bus_resume(bus);
-- if (err)
-- return err;
-+static SIMPLE_DEV_PM_OPS(bcma_pm_ops, bcma_host_pci_suspend,
-+ bcma_host_pci_resume);
-+#define BCMA_PM_OPS (&bcma_pm_ops)
-
-- return 0;
--}
- #else /* CONFIG_PM */
--# define bcma_host_pci_suspend NULL
--# define bcma_host_pci_resume NULL
-+
-+#define BCMA_PM_OPS NULL
-+
- #endif /* CONFIG_PM */
-
- static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = {
-@@ -277,8 +278,7 @@ static struct pci_driver bcma_pci_bridge
- .id_table = bcma_pci_bridge_tbl,
- .probe = bcma_host_pci_probe,
- .remove = bcma_host_pci_remove,
-- .suspend = bcma_host_pci_suspend,
-- .resume = bcma_host_pci_resume,
-+ .driver.pm = BCMA_PM_OPS,
- };
-
- int __init bcma_host_pci_init(void)
---- a/drivers/bcma/main.c
-+++ b/drivers/bcma/main.c
-@@ -13,6 +13,12 @@
- MODULE_DESCRIPTION("Broadcom's specific AMBA driver");
- MODULE_LICENSE("GPL");
-
-+/* contains the number the next bus should get. */
-+static unsigned int bcma_bus_next_num = 0;
-+
-+/* bcma_buses_mutex locks the bcma_bus_next_num */
-+static DEFINE_MUTEX(bcma_buses_mutex);
-+
- static int bcma_bus_match(struct device *dev, struct device_driver *drv);
- static int bcma_device_probe(struct device *dev);
- static int bcma_device_remove(struct device *dev);
-@@ -55,7 +61,7 @@ static struct bus_type bcma_bus_type = {
- .dev_attrs = bcma_device_attrs,
- };
-
--static struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid)
-+struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid)
- {
- struct bcma_device *core;
-
-@@ -65,6 +71,7 @@ static struct bcma_device *bcma_find_cor
- }
- return NULL;
- }
-+EXPORT_SYMBOL_GPL(bcma_find_core);
-
- static void bcma_release_core_dev(struct device *dev)
- {
-@@ -93,7 +100,7 @@ static int bcma_register_cores(struct bc
-
- core->dev.release = bcma_release_core_dev;
- core->dev.bus = &bcma_bus_type;
-- dev_set_name(&core->dev, "bcma%d:%d", 0/*bus->num*/, dev_id);
-+ dev_set_name(&core->dev, "bcma%d:%d", bus->num, dev_id);
-
- switch (bus->hosttype) {
- case BCMA_HOSTTYPE_PCI:
-@@ -132,11 +139,15 @@ static void bcma_unregister_cores(struct
- }
- }
-
--int bcma_bus_register(struct bcma_bus *bus)
-+int __devinit bcma_bus_register(struct bcma_bus *bus)
- {
- 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) {
-@@ -169,10 +180,8 @@ int bcma_bus_register(struct bcma_bus *b
- err = bcma_sprom_get(bus);
- if (err == -ENOENT) {
- pr_err("No SPROM available\n");
-- } else if (err) {
-+ } else if (err)
- pr_err("Failed to get SPROM: %d\n", err);
-- return -ENOENT;
-- }
+--- a/drivers/bcma/core.c
++++ b/drivers/bcma/core.c
+@@ -30,6 +30,7 @@ void bcma_core_disable(struct bcma_devic
+ udelay(10);
- /* Register found cores */
- bcma_register_cores(bus);
-@@ -241,6 +250,21 @@ int __init bcma_bus_early_register(struc
+ bcma_awrite32(core, BCMA_RESET_CTL, BCMA_RESET_CTL_RESET);
++ bcma_aread32(core, BCMA_RESET_CTL);
+ udelay(1);
}
-
- #ifdef CONFIG_PM
-+int bcma_bus_suspend(struct bcma_bus *bus)
-+{
-+ struct bcma_device *core;
-+
-+ list_for_each_entry(core, &bus->cores, list) {
-+ struct device_driver *drv = core->dev.driver;
-+ if (drv) {
-+ struct bcma_driver *adrv = container_of(drv, struct bcma_driver, drv);
-+ if (adrv->suspend)
-+ adrv->suspend(core);
-+ }
-+ }
-+ return 0;
-+}
-+
- int bcma_bus_resume(struct bcma_bus *bus)
- {
- struct bcma_device *core;
-@@ -252,6 +276,15 @@ int bcma_bus_resume(struct bcma_bus *bus
- bcma_core_chipcommon_init(&bus->drv_cc);
+ EXPORT_SYMBOL_GPL(bcma_core_disable);
+@@ -77,7 +78,7 @@ void bcma_core_set_clockmode(struct bcma
+ pr_err("HT force timeout\n");
+ break;
+ case BCMA_CLKMODE_DYNAMIC:
+- pr_warn("Dynamic clockmode not supported yet!\n");
++ bcma_set32(core, BCMA_CLKCTLST, ~BCMA_CLKCTLST_FORCEHT);
+ break;
}
-
-+ list_for_each_entry(core, &bus->cores, list) {
-+ struct device_driver *drv = core->dev.driver;
-+ if (drv) {
-+ struct bcma_driver *adrv = container_of(drv, struct bcma_driver, drv);
-+ if (adrv->resume)
-+ adrv->resume(core);
-+ }
-+ }
-+
- return 0;
}
- #endif
---- a/drivers/bcma/Kconfig
-+++ b/drivers/bcma/Kconfig
-@@ -29,7 +29,7 @@ config BCMA_HOST_PCI
-
- config BCMA_DRIVER_PCI_HOSTMODE
- bool "Driver for PCI core working in hostmode"
-- depends on BCMA && MIPS
-+ depends on BCMA && MIPS && BCMA_HOST_PCI
- help
- PCI core hostmode operation (external PCI bus).
-
--- a/drivers/bcma/driver_chipcommon_pmu.c
+++ b/drivers/bcma/driver_chipcommon_pmu.c
@@ -80,6 +80,7 @@ static void bcma_pmu_resources_init(stru
@@ -323,7 +82,7 @@
*
* Licensed under the GNU/GPL. See COPYING for details.
*/
-@@ -16,40 +17,41 @@
+@@ -16,40 +17,39 @@
* R/W ops.
**************************************************/
@@ -338,7 +97,7 @@
+ return pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_DATA);
}
- #if 0
+-#if 0
static void bcma_pcie_write(struct bcma_drv_pci *pc, u32 address, u32 data)
{
- pcicore_write32(pc, 0x130, address);
@@ -348,7 +107,7 @@
+ pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_ADDR);
+ pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_DATA, data);
}
- #endif
+-#endif
static void bcma_pcie_mdio_set_phy(struct bcma_drv_pci *pc, u8 phy)
{
@@ -381,7 +140,7 @@
break;
msleep(1);
}
-@@ -57,79 +59,84 @@ static void bcma_pcie_mdio_set_phy(struc
+@@ -57,79 +57,84 @@ static void bcma_pcie_mdio_set_phy(struc
static u16 bcma_pcie_mdio_read(struct bcma_drv_pci *pc, u8 device, u8 address)
{
@@ -497,7 +256,7 @@
}
/**************************************************
-@@ -138,72 +145,53 @@ static void bcma_pcie_mdio_write(struct
+@@ -138,72 +143,90 @@ static void bcma_pcie_mdio_write(struct
static u8 bcma_pcicore_polarity_workaround(struct bcma_drv_pci *pc)
{
@@ -532,6 +291,41 @@
+ bcma_pcie_mdio_write(pc, BCMA_CORE_PCI_MDIODATA_DEV_PLL,
+ BCMA_CORE_PCI_SERDES_PLL_CTRL,
+ 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)
++{
++ u16 val16;
++ uint regoff;
++
++ regoff = BCMA_CORE_PCI_SPROM(BCMA_CORE_PCI_SPROM_MISC_CONFIG);
++
++ val16 = pcicore_read16(pc, regoff);
++
++ if (!(val16 & BCMA_CORE_PCI_SPROM_L23READY_EXIT_NOPERST)) {
++ val16 |= BCMA_CORE_PCI_SPROM_L23READY_EXIT_NOPERST;
++ pcicore_write16(pc, regoff, val16);
++ }
}
/**************************************************
@@ -541,7 +335,9 @@
-static void bcma_core_pci_clientmode_init(struct bcma_drv_pci *pc)
+static void __devinit 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);
}
-static bool bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc)
@@ -593,6 +389,24 @@
}
int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core,
+@@ -236,3 +259,17 @@ out:
+ return err;
+ }
+ EXPORT_SYMBOL_GPL(bcma_core_pci_irq_ctl);
++
++void bcma_core_pci_extend_L1timer(struct bcma_drv_pci *pc, bool extend)
++{
++ u32 w;
++
++ w = bcma_pcie_read(pc, BCMA_CORE_PCI_DLLP_PMTHRESHREG);
++ if (extend)
++ w |= BCMA_CORE_PCI_ASPMTIMER_EXTEND;
++ else
++ w &= ~BCMA_CORE_PCI_ASPMTIMER_EXTEND;
++ bcma_pcie_write(pc, BCMA_CORE_PCI_DLLP_PMTHRESHREG, w);
++ bcma_pcie_read(pc, BCMA_CORE_PCI_DLLP_PMTHRESHREG);
++}
++EXPORT_SYMBOL_GPL(bcma_core_pci_extend_L1timer);
--- a/drivers/bcma/driver_pci_host.c
+++ b/drivers/bcma/driver_pci_host.c
@@ -2,13 +2,588 @@
@@ -718,7 +532,7 @@
+ if (unlikely(!addr))
+ goto out;
+ err = -ENOMEM;
-+ mmio = ioremap_nocache(addr, len);
++ mmio = ioremap_nocache(addr, sizeof(val));
+ if (!mmio)
+ goto out;
+
@@ -770,7 +584,7 @@
+ addr = pc->core->addr + BCMA_CORE_PCI_PCICFG0;
+ addr |= (func << 8);
+ addr |= (off & 0xfc);
-+ mmio = ioremap_nocache(addr, len);
++ mmio = ioremap_nocache(addr, sizeof(val));
+ if (!mmio)
+ goto out;
+ }
@@ -779,7 +593,7 @@
+ if (unlikely(!addr))
+ goto out;
+ err = -ENOMEM;
-+ mmio = ioremap_nocache(addr, len);
++ mmio = ioremap_nocache(addr, sizeof(val));
+ if (!mmio)
+ goto out;
+
@@ -1090,8 +904,8 @@
+ /* Ok, ready to run, register it to the system.
+ * The following needs change, if we want to port hostmode
+ * to non-MIPS platform. */
-+ io_map_base = (unsigned long)ioremap_nocache(BCMA_SOC_PCI_MEM,
-+ 0x04000000);
++ io_map_base = (unsigned long)ioremap_nocache(pc_host->mem_resource.start,
++ resource_size(&pc_host->mem_resource));
+ pc_host->pci_controller.io_map_base = io_map_base;
+ set_io_port_base(pc_host->pci_controller.io_map_base);
+ /* Give some time to the PCI controller to configure itself with the new
@@ -1186,9 +1000,387 @@
+ return bcma_core_mips_irq(pc_host->pdev->core) + 2;
}
+EXPORT_SYMBOL(bcma_core_pci_pcibios_map_irq);
+--- a/drivers/bcma/host_pci.c
++++ b/drivers/bcma/host_pci.c
+@@ -21,48 +21,58 @@ static void bcma_host_pci_switch_core(st
+ pr_debug("Switched to core: 0x%X\n", core->id.id);
+ }
+
+-static u8 bcma_host_pci_read8(struct bcma_device *core, u16 offset)
+-{
++/* Provides access to the requested core. Returns base offset that has to be
++ * used. It makes use of fixed windows when possible. */
++static u16 bcma_host_pci_provide_access_to_core(struct bcma_device *core)
++{
++ switch (core->id.id) {
++ case BCMA_CORE_CHIPCOMMON:
++ return 3 * BCMA_CORE_SIZE;
++ case BCMA_CORE_PCIE:
++ return 2 * BCMA_CORE_SIZE;
++ }
++
+ if (core->bus->mapped_core != core)
+ bcma_host_pci_switch_core(core);
++ return 0;
++}
++
++static u8 bcma_host_pci_read8(struct bcma_device *core, u16 offset)
++{
++ offset += bcma_host_pci_provide_access_to_core(core);
+ return ioread8(core->bus->mmio + offset);
+ }
+
+ static u16 bcma_host_pci_read16(struct bcma_device *core, u16 offset)
+ {
+- if (core->bus->mapped_core != core)
+- bcma_host_pci_switch_core(core);
++ offset += bcma_host_pci_provide_access_to_core(core);
+ return ioread16(core->bus->mmio + offset);
+ }
+
+ static u32 bcma_host_pci_read32(struct bcma_device *core, u16 offset)
+ {
+- if (core->bus->mapped_core != core)
+- bcma_host_pci_switch_core(core);
++ offset += bcma_host_pci_provide_access_to_core(core);
+ return ioread32(core->bus->mmio + offset);
+ }
+
+ static void bcma_host_pci_write8(struct bcma_device *core, u16 offset,
+ u8 value)
+ {
+- if (core->bus->mapped_core != core)
+- bcma_host_pci_switch_core(core);
++ offset += bcma_host_pci_provide_access_to_core(core);
+ iowrite8(value, core->bus->mmio + offset);
+ }
+
+ static void bcma_host_pci_write16(struct bcma_device *core, u16 offset,
+ u16 value)
+ {
+- if (core->bus->mapped_core != core)
+- bcma_host_pci_switch_core(core);
++ offset += bcma_host_pci_provide_access_to_core(core);
+ iowrite16(value, core->bus->mmio + offset);
+ }
+
+ static void bcma_host_pci_write32(struct bcma_device *core, u16 offset,
+ u32 value)
+ {
+- if (core->bus->mapped_core != core)
+- bcma_host_pci_switch_core(core);
++ offset += bcma_host_pci_provide_access_to_core(core);
+ iowrite32(value, core->bus->mmio + offset);
+ }
+
+@@ -144,8 +154,8 @@ const struct bcma_host_ops bcma_host_pci
+ .awrite32 = bcma_host_pci_awrite32,
+ };
+
+-static int bcma_host_pci_probe(struct pci_dev *dev,
+- const struct pci_device_id *id)
++static int __devinit bcma_host_pci_probe(struct pci_dev *dev,
++ const struct pci_device_id *id)
+ {
+ struct bcma_bus *bus;
+ int err = -ENOMEM;
+@@ -191,6 +201,9 @@ static int bcma_host_pci_probe(struct pc
+ bus->hosttype = BCMA_HOSTTYPE_PCI;
+ bus->ops = &bcma_host_pci_ops;
+
++ bus->boardinfo.vendor = bus->host_pci->subsystem_vendor;
++ bus->boardinfo.type = bus->host_pci->subsystem_device;
++
+ /* Register */
+ err = bcma_bus_register(bus);
+ if (err)
+@@ -212,7 +225,7 @@ err_kfree_bus:
+ return err;
+ }
+
+-static void bcma_host_pci_remove(struct pci_dev *dev)
++static void __devexit bcma_host_pci_remove(struct pci_dev *dev)
+ {
+ struct bcma_bus *bus = pci_get_drvdata(dev);
+
+@@ -225,41 +238,32 @@ static void bcma_host_pci_remove(struct
+ }
+
+ #ifdef CONFIG_PM
+-static int bcma_host_pci_suspend(struct pci_dev *dev, pm_message_t state)
++static int bcma_host_pci_suspend(struct device *dev)
+ {
+- struct bcma_bus *bus = pci_get_drvdata(dev);
+-
+- /* Host specific */
+- pci_save_state(dev);
+- pci_disable_device(dev);
+- pci_set_power_state(dev, pci_choose_state(dev, state));
++ struct pci_dev *pdev = to_pci_dev(dev);
++ struct bcma_bus *bus = pci_get_drvdata(pdev);
+
+ bus->mapped_core = NULL;
+- return 0;
++
++ return bcma_bus_suspend(bus);
+ }
+
+-static int bcma_host_pci_resume(struct pci_dev *dev)
++static int bcma_host_pci_resume(struct device *dev)
+ {
+- struct bcma_bus *bus = pci_get_drvdata(dev);
+- int err;
++ struct pci_dev *pdev = to_pci_dev(dev);
++ struct bcma_bus *bus = pci_get_drvdata(pdev);
+
+- /* Host specific */
+- pci_set_power_state(dev, 0);
+- err = pci_enable_device(dev);
+- if (err)
+- return err;
+- pci_restore_state(dev);
++ return bcma_bus_resume(bus);
++}
+
+- /* Bus specific */
+- err = bcma_bus_resume(bus);
+- if (err)
+- return err;
++static SIMPLE_DEV_PM_OPS(bcma_pm_ops, bcma_host_pci_suspend,
++ bcma_host_pci_resume);
++#define BCMA_PM_OPS (&bcma_pm_ops)
+
+- return 0;
+-}
+ #else /* CONFIG_PM */
+-# define bcma_host_pci_suspend NULL
+-# define bcma_host_pci_resume NULL
++
++#define BCMA_PM_OPS NULL
++
+ #endif /* CONFIG_PM */
+
+ static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = {
+@@ -276,9 +280,8 @@ static struct pci_driver bcma_pci_bridge
+ .name = "bcma-pci-bridge",
+ .id_table = bcma_pci_bridge_tbl,
+ .probe = bcma_host_pci_probe,
+- .remove = bcma_host_pci_remove,
+- .suspend = bcma_host_pci_suspend,
+- .resume = bcma_host_pci_resume,
++ .remove = __devexit_p(bcma_host_pci_remove),
++ .driver.pm = BCMA_PM_OPS,
+ };
+
+ int __init bcma_host_pci_init(void)
+--- a/drivers/bcma/main.c
++++ b/drivers/bcma/main.c
+@@ -13,6 +13,12 @@
+ MODULE_DESCRIPTION("Broadcom's specific AMBA driver");
+ MODULE_LICENSE("GPL");
+
++/* contains the number the next bus should get. */
++static unsigned int bcma_bus_next_num = 0;
++
++/* bcma_buses_mutex locks the bcma_bus_next_num */
++static DEFINE_MUTEX(bcma_buses_mutex);
++
+ static int bcma_bus_match(struct device *dev, struct device_driver *drv);
+ static int bcma_device_probe(struct device *dev);
+ static int bcma_device_remove(struct device *dev);
+@@ -55,7 +61,7 @@ static struct bus_type bcma_bus_type = {
+ .dev_attrs = bcma_device_attrs,
+ };
+
+-static struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid)
++struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid)
+ {
+ struct bcma_device *core;
+
+@@ -65,6 +71,7 @@ static struct bcma_device *bcma_find_cor
+ }
+ return NULL;
+ }
++EXPORT_SYMBOL_GPL(bcma_find_core);
+
+ static void bcma_release_core_dev(struct device *dev)
+ {
+@@ -93,7 +100,7 @@ static int bcma_register_cores(struct bc
+
+ core->dev.release = bcma_release_core_dev;
+ core->dev.bus = &bcma_bus_type;
+- dev_set_name(&core->dev, "bcma%d:%d", 0/*bus->num*/, dev_id);
++ dev_set_name(&core->dev, "bcma%d:%d", bus->num, dev_id);
+
+ switch (bus->hosttype) {
+ case BCMA_HOSTTYPE_PCI:
+@@ -132,11 +139,15 @@ static void bcma_unregister_cores(struct
+ }
+ }
+
+-int bcma_bus_register(struct bcma_bus *bus)
++int __devinit bcma_bus_register(struct bcma_bus *bus)
+ {
+ 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) {
+@@ -169,10 +180,8 @@ int bcma_bus_register(struct bcma_bus *b
+ err = bcma_sprom_get(bus);
+ if (err == -ENOENT) {
+ pr_err("No SPROM available\n");
+- } else if (err) {
++ } else if (err)
+ pr_err("Failed to get SPROM: %d\n", err);
+- return -ENOENT;
+- }
+
+ /* Register found cores */
+ bcma_register_cores(bus);
+@@ -241,6 +250,21 @@ int __init bcma_bus_early_register(struc
+ }
+
+ #ifdef CONFIG_PM
++int bcma_bus_suspend(struct bcma_bus *bus)
++{
++ struct bcma_device *core;
++
++ list_for_each_entry(core, &bus->cores, list) {
++ struct device_driver *drv = core->dev.driver;
++ if (drv) {
++ struct bcma_driver *adrv = container_of(drv, struct bcma_driver, drv);
++ if (adrv->suspend)
++ adrv->suspend(core);
++ }
++ }
++ return 0;
++}
++
+ int bcma_bus_resume(struct bcma_bus *bus)
+ {
+ struct bcma_device *core;
+@@ -252,6 +276,15 @@ int bcma_bus_resume(struct bcma_bus *bus
+ bcma_core_chipcommon_init(&bus->drv_cc);
+ }
+
++ list_for_each_entry(core, &bus->cores, list) {
++ struct device_driver *drv = core->dev.driver;
++ if (drv) {
++ struct bcma_driver *adrv = container_of(drv, struct bcma_driver, drv);
++ if (adrv->resume)
++ adrv->resume(core);
++ }
++ }
++
+ return 0;
+ }
+ #endif
--- a/drivers/bcma/scan.c
+++ b/drivers/bcma/scan.c
-@@ -212,6 +212,17 @@ static struct bcma_device *bcma_find_cor
+@@ -19,7 +19,14 @@ struct bcma_device_id_name {
+ u16 id;
+ const char *name;
+ };
+-struct bcma_device_id_name bcma_device_names[] = {
++
++static const struct bcma_device_id_name bcma_arm_device_names[] = {
++ { BCMA_CORE_ARM_1176, "ARM 1176" },
++ { BCMA_CORE_ARM_7TDMI, "ARM 7TDMI" },
++ { BCMA_CORE_ARM_CM3, "ARM CM3" },
++};
++
++static const struct bcma_device_id_name bcma_bcm_device_names[] = {
+ { BCMA_CORE_OOB_ROUTER, "OOB Router" },
+ { BCMA_CORE_INVALID, "Invalid" },
+ { BCMA_CORE_CHIPCOMMON, "ChipCommon" },
+@@ -27,7 +34,6 @@ struct bcma_device_id_name bcma_device_n
+ { BCMA_CORE_SRAM, "SRAM" },
+ { BCMA_CORE_SDRAM, "SDRAM" },
+ { BCMA_CORE_PCI, "PCI" },
+- { BCMA_CORE_MIPS, "MIPS" },
+ { BCMA_CORE_ETHERNET, "Fast Ethernet" },
+ { BCMA_CORE_V90, "V90" },
+ { BCMA_CORE_USB11_HOSTDEV, "USB 1.1 Hostdev" },
+@@ -44,7 +50,6 @@ struct bcma_device_id_name bcma_device_n
+ { BCMA_CORE_PHY_A, "PHY A" },
+ { BCMA_CORE_PHY_B, "PHY B" },
+ { BCMA_CORE_PHY_G, "PHY G" },
+- { BCMA_CORE_MIPS_3302, "MIPS 3302" },
+ { BCMA_CORE_USB11_HOST, "USB 1.1 Host" },
+ { BCMA_CORE_USB11_DEV, "USB 1.1 Device" },
+ { BCMA_CORE_USB20_HOST, "USB 2.0 Host" },
+@@ -58,15 +63,11 @@ struct bcma_device_id_name bcma_device_n
+ { BCMA_CORE_PHY_N, "PHY N" },
+ { BCMA_CORE_SRAM_CTL, "SRAM Controller" },
+ { BCMA_CORE_MINI_MACPHY, "Mini MACPHY" },
+- { BCMA_CORE_ARM_1176, "ARM 1176" },
+- { BCMA_CORE_ARM_7TDMI, "ARM 7TDMI" },
+ { BCMA_CORE_PHY_LP, "PHY LP" },
+ { BCMA_CORE_PMU, "PMU" },
+ { BCMA_CORE_PHY_SSN, "PHY SSN" },
+ { BCMA_CORE_SDIO_DEV, "SDIO Device" },
+- { BCMA_CORE_ARM_CM3, "ARM CM3" },
+ { BCMA_CORE_PHY_HT, "PHY HT" },
+- { BCMA_CORE_MIPS_74K, "MIPS 74K" },
+ { BCMA_CORE_MAC_GBIT, "GBit MAC" },
+ { BCMA_CORE_DDR12_MEM_CTL, "DDR1/DDR2 Memory Controller" },
+ { BCMA_CORE_PCIE_RC, "PCIe Root Complex" },
+@@ -79,16 +80,41 @@ struct bcma_device_id_name bcma_device_n
+ { BCMA_CORE_SHIM, "SHIM" },
+ { BCMA_CORE_DEFAULT, "Default" },
+ };
+-const char *bcma_device_name(struct bcma_device_id *id)
++
++static const struct bcma_device_id_name bcma_mips_device_names[] = {
++ { BCMA_CORE_MIPS, "MIPS" },
++ { BCMA_CORE_MIPS_3302, "MIPS 3302" },
++ { BCMA_CORE_MIPS_74K, "MIPS 74K" },
++};
++
++static const char *bcma_device_name(const struct bcma_device_id *id)
+ {
+- int i;
++ const struct bcma_device_id_name *names;
++ int size, i;
+
+- if (id->manuf == BCMA_MANUF_BCM) {
+- for (i = 0; i < ARRAY_SIZE(bcma_device_names); i++) {
+- if (bcma_device_names[i].id == id->id)
+- return bcma_device_names[i].name;
+- }
++ /* search manufacturer specific names */
++ switch (id->manuf) {
++ case BCMA_MANUF_ARM:
++ names = bcma_arm_device_names;
++ size = ARRAY_SIZE(bcma_arm_device_names);
++ break;
++ case BCMA_MANUF_BCM:
++ names = bcma_bcm_device_names;
++ size = ARRAY_SIZE(bcma_bcm_device_names);
++ break;
++ case BCMA_MANUF_MIPS:
++ names = bcma_mips_device_names;
++ size = ARRAY_SIZE(bcma_mips_device_names);
++ break;
++ default:
++ return "UNKNOWN";
++ }
++
++ for (i = 0; i < size; i++) {
++ if (names[i].id == id->id)
++ return names[i].name;
+ }
++
+ return "UNKNOWN";
+ }
+
+@@ -212,6 +238,17 @@ static struct bcma_device *bcma_find_cor
return NULL;
}
@@ -1206,7 +1398,7 @@
static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
struct bcma_device_id *match, int core_num,
struct bcma_device *core)
-@@ -353,6 +364,7 @@ static int bcma_get_next_core(struct bcm
+@@ -353,6 +390,7 @@ static int bcma_get_next_core(struct bcm
void bcma_init_bus(struct bcma_bus *bus)
{
s32 tmp;
@@ -1214,7 +1406,7 @@
if (bus->init_done)
return;
-@@ -363,9 +375,12 @@ void bcma_init_bus(struct bcma_bus *bus)
+@@ -363,9 +401,12 @@ void bcma_init_bus(struct bcma_bus *bus)
bcma_scan_switch_core(bus, BCMA_ADDR_BASE);
tmp = bcma_scan_read32(bus, 0, BCMA_CC_ID);
@@ -1230,7 +1422,7 @@
bus->init_done = true;
}
-@@ -392,6 +407,7 @@ int bcma_bus_scan(struct bcma_bus *bus)
+@@ -392,6 +433,7 @@ int bcma_bus_scan(struct bcma_bus *bus)
bcma_scan_switch_core(bus, erombase);
while (eromptr < eromend) {
@@ -1238,7 +1430,7 @@
struct bcma_device *core = kzalloc(sizeof(*core), GFP_KERNEL);
if (!core)
return -ENOMEM;
-@@ -399,18 +415,23 @@ int bcma_bus_scan(struct bcma_bus *bus)
+@@ -399,18 +441,23 @@ int bcma_bus_scan(struct bcma_bus *bus)
core->bus = bus;
err = bcma_get_next_core(bus, &eromptr, NULL, core_num, core);
@@ -1340,7 +1532,7 @@
/**************************************************
* R/W ops.
-@@ -124,37 +176,253 @@ static int bcma_sprom_valid(const u16 *s
+@@ -124,37 +176,403 @@ static int bcma_sprom_valid(const u16 *s
* SPROM extraction.
**************************************************/
@@ -1349,6 +1541,22 @@
+#define SPEX(_field, _offset, _mask, _shift) \
+ bus->sprom._field = ((sprom[SPOFF(_offset)] & (_mask)) >> (_shift))
+
++#define SPEX32(_field, _offset, _mask, _shift) \
++ bus->sprom._field = ((((u32)sprom[SPOFF((_offset)+2)] << 16 | \
++ sprom[SPOFF(_offset)]) & (_mask)) >> (_shift))
++
++#define SPEX_ARRAY8(_field, _offset, _mask, _shift) \
++ do { \
++ SPEX(_field[0], _offset + 0, _mask, _shift); \
++ SPEX(_field[1], _offset + 2, _mask, _shift); \
++ SPEX(_field[2], _offset + 4, _mask, _shift); \
++ SPEX(_field[3], _offset + 6, _mask, _shift); \
++ SPEX(_field[4], _offset + 8, _mask, _shift); \
++ SPEX(_field[5], _offset + 10, _mask, _shift); \
++ SPEX(_field[6], _offset + 12, _mask, _shift); \
++ SPEX(_field[7], _offset + 14, _mask, _shift); \
++ } while (0)
++
static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
{
- u16 v;
@@ -1417,7 +1625,8 @@
+ SPEX(boardflags2_lo, SSB_SPROM8_BFL2LO, ~0, 0);
+ SPEX(boardflags2_hi, SSB_SPROM8_BFL2HI, ~0, 0);
+
-+ SPEX(country_code, SSB_SPROM8_CCODE, ~0, 0);
++ SPEX(alpha2[0], SSB_SPROM8_CCODE, 0xff00, 8);
++ SPEX(alpha2[1], SSB_SPROM8_CCODE, 0x00ff, 0);
+
+ /* Extract cores power info info */
+ for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) {
@@ -1472,6 +1681,136 @@
+ SSB_SROM8_FEM_TR_ISO_SHIFT);
+ SPEX(fem.ghz5.antswlut, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_ANTSWLUT,
+ SSB_SROM8_FEM_ANTSWLUT_SHIFT);
++
++ SPEX(ant_available_a, SSB_SPROM8_ANTAVAIL, SSB_SPROM8_ANTAVAIL_A,
++ SSB_SPROM8_ANTAVAIL_A_SHIFT);
++ SPEX(ant_available_bg, SSB_SPROM8_ANTAVAIL, SSB_SPROM8_ANTAVAIL_BG,
++ SSB_SPROM8_ANTAVAIL_BG_SHIFT);
++ SPEX(maxpwr_bg, SSB_SPROM8_MAXP_BG, SSB_SPROM8_MAXP_BG_MASK, 0);
++ SPEX(itssi_bg, SSB_SPROM8_MAXP_BG, SSB_SPROM8_ITSSI_BG,
++ SSB_SPROM8_ITSSI_BG_SHIFT);
++ SPEX(maxpwr_a, SSB_SPROM8_MAXP_A, SSB_SPROM8_MAXP_A_MASK, 0);
++ SPEX(itssi_a, SSB_SPROM8_MAXP_A, SSB_SPROM8_ITSSI_A,
++ SSB_SPROM8_ITSSI_A_SHIFT);
++ SPEX(maxpwr_ah, SSB_SPROM8_MAXP_AHL, SSB_SPROM8_MAXP_AH_MASK, 0);
++ SPEX(maxpwr_al, SSB_SPROM8_MAXP_AHL, SSB_SPROM8_MAXP_AL_MASK,
++ SSB_SPROM8_MAXP_AL_SHIFT);
++ SPEX(gpio0, SSB_SPROM8_GPIOA, SSB_SPROM8_GPIOA_P0, 0);
++ SPEX(gpio1, SSB_SPROM8_GPIOA, SSB_SPROM8_GPIOA_P1,
++ SSB_SPROM8_GPIOA_P1_SHIFT);
++ SPEX(gpio2, SSB_SPROM8_GPIOB, SSB_SPROM8_GPIOB_P2, 0);
++ SPEX(gpio3, SSB_SPROM8_GPIOB, SSB_SPROM8_GPIOB_P3,
++ SSB_SPROM8_GPIOB_P3_SHIFT);
++ SPEX(tri2g, SSB_SPROM8_TRI25G, SSB_SPROM8_TRI2G, 0);
++ SPEX(tri5g, SSB_SPROM8_TRI25G, SSB_SPROM8_TRI5G,
++ SSB_SPROM8_TRI5G_SHIFT);
++ SPEX(tri5gl, SSB_SPROM8_TRI5GHL, SSB_SPROM8_TRI5GL, 0);
++ SPEX(tri5gh, SSB_SPROM8_TRI5GHL, SSB_SPROM8_TRI5GH,
++ SSB_SPROM8_TRI5GH_SHIFT);
++ SPEX(rxpo2g, SSB_SPROM8_RXPO, SSB_SPROM8_RXPO2G,
++ SSB_SPROM8_RXPO2G_SHIFT);
++ SPEX(rxpo5g, SSB_SPROM8_RXPO, SSB_SPROM8_RXPO5G,
++ SSB_SPROM8_RXPO5G_SHIFT);
++ SPEX(rssismf2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISMF2G, 0);
++ SPEX(rssismc2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISMC2G,
++ SSB_SPROM8_RSSISMC2G_SHIFT);
++ SPEX(rssisav2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISAV2G,
++ SSB_SPROM8_RSSISAV2G_SHIFT);
++ SPEX(bxa2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_BXA2G,
++ SSB_SPROM8_BXA2G_SHIFT);
++ SPEX(rssismf5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISMF5G, 0);
++ SPEX(rssismc5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISMC5G,
++ SSB_SPROM8_RSSISMC5G_SHIFT);
++ SPEX(rssisav5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISAV5G,
++ SSB_SPROM8_RSSISAV5G_SHIFT);
++ SPEX(bxa5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_BXA5G,
++ SSB_SPROM8_BXA5G_SHIFT);
++
++ SPEX(pa0b0, SSB_SPROM8_PA0B0, ~0, 0);
++ SPEX(pa0b1, SSB_SPROM8_PA0B1, ~0, 0);
++ SPEX(pa0b2, SSB_SPROM8_PA0B2, ~0, 0);
++ SPEX(pa1b0, SSB_SPROM8_PA1B0, ~0, 0);
++ SPEX(pa1b1, SSB_SPROM8_PA1B1, ~0, 0);
++ SPEX(pa1b2, SSB_SPROM8_PA1B2, ~0, 0);
++ SPEX(pa1lob0, SSB_SPROM8_PA1LOB0, ~0, 0);
++ SPEX(pa1lob1, SSB_SPROM8_PA1LOB1, ~0, 0);
++ SPEX(pa1lob2, SSB_SPROM8_PA1LOB2, ~0, 0);
++ SPEX(pa1hib0, SSB_SPROM8_PA1HIB0, ~0, 0);
++ SPEX(pa1hib1, SSB_SPROM8_PA1HIB1, ~0, 0);
++ SPEX(pa1hib2, SSB_SPROM8_PA1HIB2, ~0, 0);
++ SPEX(cck2gpo, SSB_SPROM8_CCK2GPO, ~0, 0);
++ SPEX32(ofdm2gpo, SSB_SPROM8_OFDM2GPO, ~0, 0);
++ SPEX32(ofdm5glpo, SSB_SPROM8_OFDM5GLPO, ~0, 0);
++ SPEX32(ofdm5gpo, SSB_SPROM8_OFDM5GPO, ~0, 0);
++ SPEX32(ofdm5ghpo, SSB_SPROM8_OFDM5GHPO, ~0, 0);
++
++ /* Extract the antenna gain values. */
++ SPEX(antenna_gain.a0, SSB_SPROM8_AGAIN01,
++ SSB_SPROM8_AGAIN0, SSB_SPROM8_AGAIN0_SHIFT);
++ SPEX(antenna_gain.a1, SSB_SPROM8_AGAIN01,
++ SSB_SPROM8_AGAIN1, SSB_SPROM8_AGAIN1_SHIFT);
++ SPEX(antenna_gain.a2, SSB_SPROM8_AGAIN23,
++ SSB_SPROM8_AGAIN2, SSB_SPROM8_AGAIN2_SHIFT);
++ SPEX(antenna_gain.a3, SSB_SPROM8_AGAIN23,
++ SSB_SPROM8_AGAIN3, SSB_SPROM8_AGAIN3_SHIFT);
++
++ SPEX(leddc_on_time, SSB_SPROM8_LEDDC, SSB_SPROM8_LEDDC_ON,
++ SSB_SPROM8_LEDDC_ON_SHIFT);
++ SPEX(leddc_off_time, SSB_SPROM8_LEDDC, SSB_SPROM8_LEDDC_OFF,
++ SSB_SPROM8_LEDDC_OFF_SHIFT);
++
++ SPEX(txchain, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_TXCHAIN,
++ SSB_SPROM8_TXRXC_TXCHAIN_SHIFT);
++ SPEX(rxchain, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_RXCHAIN,
++ SSB_SPROM8_TXRXC_RXCHAIN_SHIFT);
++ SPEX(antswitch, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_SWITCH,
++ SSB_SPROM8_TXRXC_SWITCH_SHIFT);
++
++ SPEX(opo, SSB_SPROM8_OFDM2GPO, 0x00ff, 0);
++
++ SPEX_ARRAY8(mcs2gpo, SSB_SPROM8_2G_MCSPO, ~0, 0);
++ SPEX_ARRAY8(mcs5gpo, SSB_SPROM8_5G_MCSPO, ~0, 0);
++ SPEX_ARRAY8(mcs5glpo, SSB_SPROM8_5GL_MCSPO, ~0, 0);
++ SPEX_ARRAY8(mcs5ghpo, SSB_SPROM8_5GH_MCSPO, ~0, 0);
++
++ SPEX(rawtempsense, SSB_SPROM8_RAWTS, SSB_SPROM8_RAWTS_RAWTEMP,
++ SSB_SPROM8_RAWTS_RAWTEMP_SHIFT);
++ SPEX(measpower, SSB_SPROM8_RAWTS, SSB_SPROM8_RAWTS_MEASPOWER,
++ SSB_SPROM8_RAWTS_MEASPOWER_SHIFT);
++ SPEX(tempsense_slope, SSB_SPROM8_OPT_CORRX,
++ SSB_SPROM8_OPT_CORRX_TEMP_SLOPE,
++ SSB_SPROM8_OPT_CORRX_TEMP_SLOPE_SHIFT);
++ SPEX(tempcorrx, SSB_SPROM8_OPT_CORRX, SSB_SPROM8_OPT_CORRX_TEMPCORRX,
++ SSB_SPROM8_OPT_CORRX_TEMPCORRX_SHIFT);
++ SPEX(tempsense_option, SSB_SPROM8_OPT_CORRX,
++ SSB_SPROM8_OPT_CORRX_TEMP_OPTION,
++ SSB_SPROM8_OPT_CORRX_TEMP_OPTION_SHIFT);
++ SPEX(freqoffset_corr, SSB_SPROM8_HWIQ_IQSWP,
++ SSB_SPROM8_HWIQ_IQSWP_FREQ_CORR,
++ SSB_SPROM8_HWIQ_IQSWP_FREQ_CORR_SHIFT);
++ SPEX(iqcal_swp_dis, SSB_SPROM8_HWIQ_IQSWP,
++ SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP,
++ SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP_SHIFT);
++ SPEX(hw_iqcal_en, SSB_SPROM8_HWIQ_IQSWP, SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL,
++ SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL_SHIFT);
++
++ SPEX(bw40po, SSB_SPROM8_BW40PO, ~0, 0);
++ SPEX(cddpo, SSB_SPROM8_CDDPO, ~0, 0);
++ SPEX(stbcpo, SSB_SPROM8_STBCPO, ~0, 0);
++ SPEX(bwduppo, SSB_SPROM8_BWDUPPO, ~0, 0);
++
++ SPEX(tempthresh, SSB_SPROM8_THERMAL, SSB_SPROM8_THERMAL_TRESH,
++ SSB_SPROM8_THERMAL_TRESH_SHIFT);
++ SPEX(tempoffset, SSB_SPROM8_THERMAL, SSB_SPROM8_THERMAL_OFFSET,
++ SSB_SPROM8_THERMAL_OFFSET_SHIFT);
++ SPEX(phycal_tempdelta, SSB_SPROM8_TEMPDELTA,
++ SSB_SPROM8_TEMPDELTA_PHYCAL,
++ SSB_SPROM8_TEMPDELTA_PHYCAL_SHIFT);
++ SPEX(temps_period, SSB_SPROM8_TEMPDELTA, SSB_SPROM8_TEMPDELTA_PERIOD,
++ SSB_SPROM8_TEMPDELTA_PERIOD_SHIFT);
++ SPEX(temps_hysteresis, SSB_SPROM8_TEMPDELTA,
++ SSB_SPROM8_TEMPDELTA_HYSTERESIS,
++ SSB_SPROM8_TEMPDELTA_HYSTERESIS_SHIFT);
+}
+
+/*
@@ -1491,7 +1830,8 @@
+ BCMA_CC_SROM_CONTROL);
+ return srom_control & BCMA_CC_SROM_CONTROL_PRESENT;
+ }
-+
+
+- bus->sprom.country_code = sprom[SPOFF(SSB_SPROM8_CCODE)];
+ /* older chipcommon revisions use chip status register */
+ chip_status = bcma_read32(bus->drv_cc.core, BCMA_CC_CHIPSTAT);
+ switch (bus->chipinfo.id) {
@@ -1539,8 +1879,7 @@
+ present = false;
+ break;
+ }
-
-- bus->sprom.country_code = sprom[SPOFF(SSB_SPROM8_CCODE)];
++
+ if (present) {
+ otpsize = bus->drv_cc.capabilities & BCMA_CC_CAP_OTPS;
+ otpsize >>= BCMA_CC_CAP_OTPS_SHIFT;
@@ -1582,16 +1921,19 @@
- if (!(bus->drv_cc.capabilities & BCMA_CC_CAP_SPROM))
- return -ENOENT;
+ if (!bcma_sprom_ext_available(bus)) {
++ bool sprom_onchip;
++
+ /*
+ * External SPROM takes precedence so check
+ * on-chip OTP only when no external SPROM
+ * is present.
+ */
-+ if (bcma_sprom_onchip_available(bus)) {
++ sprom_onchip = bcma_sprom_onchip_available(bus);
++ if (sprom_onchip) {
+ /* determine offset */
+ offset = bcma_sprom_onchip_offset(bus);
+ }
-+ if (!offset) {
++ if (!offset || !sprom_onchip) {
+ /*
+ * Maybe there is no SPROM on the device?
+ * Now we ask the arch code if there is some sprom
@@ -1604,7 +1946,7 @@
sprom = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16),
GFP_KERNEL);
-@@ -164,11 +432,7 @@ int bcma_sprom_get(struct bcma_bus *bus)
+@@ -164,11 +582,7 @@ int bcma_sprom_get(struct bcma_bus *bus)
if (bus->chipinfo.id == 0x4331)
bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, false);
@@ -1619,7 +1961,19 @@
if (bus->chipinfo.id == 0x4331)
--- a/include/linux/bcma/bcma.h
+++ b/include/linux/bcma/bcma.h
-@@ -136,6 +136,7 @@ struct bcma_device {
+@@ -26,6 +26,11 @@ struct bcma_chipinfo {
+ u8 pkg;
+ };
+
++struct bcma_boardinfo {
++ u16 vendor;
++ u16 type;
++};
++
+ enum bcma_clkmode {
+ BCMA_CLKMODE_FAST,
+ BCMA_CLKMODE_DYNAMIC,
+@@ -136,6 +141,7 @@ struct bcma_device {
bool dev_registered;
u8 core_index;
@@ -1627,7 +1981,7 @@
u32 addr;
u32 wrap;
-@@ -162,7 +163,7 @@ struct bcma_driver {
+@@ -162,7 +168,7 @@ struct bcma_driver {
int (*probe)(struct bcma_device *dev);
void (*remove)(struct bcma_device *dev);
@@ -1636,7 +1990,7 @@
int (*resume)(struct bcma_device *dev);
void (*shutdown)(struct bcma_device *dev);
-@@ -175,6 +176,12 @@ int __bcma_driver_register(struct bcma_d
+@@ -175,6 +181,12 @@ int __bcma_driver_register(struct bcma_d
extern void bcma_driver_unregister(struct bcma_driver *drv);
@@ -1649,7 +2003,13 @@
struct bcma_bus {
/* The MMIO area. */
void __iomem *mmio;
-@@ -195,6 +202,7 @@ struct bcma_bus {
+@@ -191,10 +203,13 @@ struct bcma_bus {
+
+ struct bcma_chipinfo chipinfo;
+
++ struct bcma_boardinfo boardinfo;
++
+ struct bcma_device *mapped_core;
struct list_head cores;
u8 nr_cores;
u8 init_done:1;
@@ -1657,7 +2017,7 @@
struct bcma_drv_cc drv_cc;
struct bcma_drv_pci drv_pci;
-@@ -205,62 +213,84 @@ struct bcma_bus {
+@@ -205,62 +220,84 @@ struct bcma_bus {
struct ssb_sprom sprom;
};
@@ -1832,7 +2192,7 @@
#define BCMA_CC_PMU5_MAINPLL_CPU 1
--- a/include/linux/bcma/bcma_driver_pci.h
+++ b/include/linux/bcma/bcma_driver_pci.h
-@@ -53,6 +53,35 @@ struct pci_dev;
+@@ -53,11 +53,47 @@ struct pci_dev;
#define BCMA_CORE_PCI_SBTOPCI1_MASK 0xFC000000
#define BCMA_CORE_PCI_SBTOPCI2 0x0108 /* Backplane to PCI translation 2 (sbtopci2) */
#define BCMA_CORE_PCI_SBTOPCI2_MASK 0xC0000000
@@ -1868,7 +2228,19 @@
#define BCMA_CORE_PCI_PCICFG0 0x0400 /* PCI config space 0 (rev >= 8) */
#define BCMA_CORE_PCI_PCICFG1 0x0500 /* PCI config space 1 (rev >= 8) */
#define BCMA_CORE_PCI_PCICFG2 0x0600 /* PCI config space 2 (rev >= 8) */
-@@ -72,20 +101,114 @@ struct pci_dev;
+ #define BCMA_CORE_PCI_PCICFG3 0x0700 /* PCI config space 3 (rev >= 8) */
+ #define BCMA_CORE_PCI_SPROM(wordoffset) (0x0800 + ((wordoffset) * 2)) /* SPROM shadow area (72 bytes) */
++#define BCMA_CORE_PCI_SPROM_PI_OFFSET 0 /* first word */
++#define BCMA_CORE_PCI_SPROM_PI_MASK 0xf000 /* bit 15:12 */
++#define BCMA_CORE_PCI_SPROM_PI_SHIFT 12 /* bit 15:12 */
++#define BCMA_CORE_PCI_SPROM_MISC_CONFIG 5 /* word 5 */
++#define BCMA_CORE_PCI_SPROM_L23READY_EXIT_NOPERST 0x8000 /* bit 15 */
++#define BCMA_CORE_PCI_SPROM_CLKREQ_OFFSET_REV5 20 /* word 20 for srom rev <= 5 */
++#define BCMA_CORE_PCI_SPROM_CLKREQ_ENB 0x0800 /* bit 11 */
+
+ /* SBtoPCIx */
+ #define BCMA_CORE_PCI_SBTOPCI_MEM 0x00000000
+@@ -72,20 +108,118 @@ struct pci_dev;
#define BCMA_CORE_PCI_SBTOPCI_RC_READL 0x00000010 /* Memory read line */
#define BCMA_CORE_PCI_SBTOPCI_RC_READM 0x00000020 /* Memory read multiple */
@@ -1904,6 +2276,7 @@
+#define BCMA_CORE_PCI_DLLP_LRREG 0x120 /* Link Replay */
+#define BCMA_CORE_PCI_DLLP_LACKTOREG 0x124 /* Link Ack Timeout */
+#define BCMA_CORE_PCI_DLLP_PMTHRESHREG 0x128 /* Power Management Threshold */
++#define BCMA_CORE_PCI_ASPMTIMER_EXTEND 0x01000000 /* > rev7: enable extend ASPM timer */
+#define BCMA_CORE_PCI_DLLP_RTRYWPREG 0x12C /* Retry buffer write ptr */
+#define BCMA_CORE_PCI_DLLP_RTRYRPREG 0x130 /* Retry buffer Read ptr */
+#define BCMA_CORE_PCI_DLLP_RTRYPPREG 0x134 /* Retry buffer Purged ptr */
@@ -1972,17 +2345,20 @@
};
/* Register access */
++#define pcicore_read16(pc, offset) bcma_read16((pc)->core, offset)
#define pcicore_read32(pc, offset) bcma_read32((pc)->core, offset)
++#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_init(struct bcma_drv_pci *pc);
+extern void __devinit 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);
-
++extern void bcma_core_pci_extend_L1timer(struct bcma_drv_pci *pc, bool extend);
++
+extern int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev);
+extern int bcma_core_pci_plat_dev_init(struct pci_dev *dev);
-+
+
#endif /* LINUX_BCMA_DRIVER_PCI_H_ */
--- a/include/linux/bcma/bcma_regs.h
+++ b/include/linux/bcma/bcma_regs.h