Merge branch 'fix/acer-alc889-fix' into fix/hda
[firefly-linux-kernel-4.4.55.git] / drivers / bcma / host_pci.c
index 1b51d8b7ac8024698bc9b053322a2b82ddbe47ab..f59244e3397137ca9b6a6d311612dd53db721646 100644 (file)
@@ -21,48 +21,58 @@ static void bcma_host_pci_switch_core(struct bcma_device *core)
        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);
 }
 
@@ -224,6 +234,35 @@ static void bcma_host_pci_remove(struct pci_dev *dev)
        pci_set_drvdata(dev, NULL);
 }
 
+#ifdef CONFIG_PM
+static int bcma_host_pci_suspend(struct device *dev)
+{
+       struct pci_dev *pdev = to_pci_dev(dev);
+       struct bcma_bus *bus = pci_get_drvdata(pdev);
+
+       bus->mapped_core = NULL;
+
+       return bcma_bus_suspend(bus);
+}
+
+static int bcma_host_pci_resume(struct device *dev)
+{
+       struct pci_dev *pdev = to_pci_dev(dev);
+       struct bcma_bus *bus = pci_get_drvdata(pdev);
+
+       return bcma_bus_resume(bus);
+}
+
+static SIMPLE_DEV_PM_OPS(bcma_pm_ops, bcma_host_pci_suspend,
+                        bcma_host_pci_resume);
+#define BCMA_PM_OPS    (&bcma_pm_ops)
+
+#else /* CONFIG_PM */
+
+#define BCMA_PM_OPS     NULL
+
+#endif /* CONFIG_PM */
+
 static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = {
        { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) },
        { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) },
@@ -239,6 +278,7 @@ static struct pci_driver bcma_pci_bridge_driver = {
        .id_table = bcma_pci_bridge_tbl,
        .probe = bcma_host_pci_probe,
        .remove = bcma_host_pci_remove,
+       .driver.pm = BCMA_PM_OPS,
 };
 
 int __init bcma_host_pci_init(void)