From: gabriele paoloni <gabriele.paoloni@xxxxxxxxxx> This patch reworks the current Designware framework to enable ACPI based controllers. Signed-off-by: Gabriele Paoloni <gabriele.paoloni@xxxxxxxxxx> Signed-off-by: Dongdong Liu <liudongdong3@xxxxxxxxxx> --- drivers/pci/host/pcie-designware.c | 39 +++++++++++++++++++++++++++++++++----- drivers/pci/host/pcie-designware.h | 1 + 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c index 02a7452..4ced20d 100644 --- a/drivers/pci/host/pcie-designware.c +++ b/drivers/pci/host/pcie-designware.c @@ -11,6 +11,7 @@ * published by the Free Software Foundation. */ +#include <linux/acpi.h> #include <linux/irq.h> #include <linux/irqdomain.h> #include <linux/kernel.h> @@ -19,6 +20,7 @@ #include <linux/of_address.h> #include <linux/of_pci.h> #include <linux/pci.h> +#include <linux/pci-acpi.h> #include <linux/pci_regs.h> #include <linux/platform_device.h> #include <linux/types.h> @@ -46,7 +48,6 @@ #define PCIE_MSI_INTR0_ENABLE 0x828 #define PCIE_MSI_INTR0_MASK 0x82C #define PCIE_MSI_INTR0_STATUS 0x830 - #define PCIE_ATU_VIEWPORT 0x900 #define PCIE_ATU_REGION_INBOUND (0x1 << 31) #define PCIE_ATU_REGION_OUTBOUND (0x0 << 31) @@ -69,7 +70,7 @@ #define PCIE_ATU_FUNC(x) (((x) & 0x7) << 16) #define PCIE_ATU_UPPER_TARGET 0x91C -static struct pci_ops dw_pcie_ops; +struct pci_ops dw_pcie_ops; int dw_pcie_cfg_read(void __iomem *addr, int size, u32 *val) { @@ -657,8 +658,22 @@ static int dw_pcie_valid_config(struct pcie_port *pp, static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, int size, u32 *val) { - struct pcie_port *pp = bus->sysdata; int ret; + struct pcie_port *pp; + struct pci_bus *bridge_bus; + + for (bridge_bus = bus; bridge_bus->parent; + bridge_bus = bridge_bus->parent) + ; + + if (has_acpi_companion(bridge_bus->bridge)) { +#ifdef CONFIG_ACPI_PCI_HOST_GENERIC + struct acpi_pci_root *root = bus->sysdata; + + pp = root->sysdata; +#endif /* CONFIG_ACPI_PCI_HOST_GENERIC */ + } else + pp = bus->sysdata; if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) { *val = 0xffffffff; @@ -681,8 +696,22 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn, int where, int size, u32 val) { - struct pcie_port *pp = bus->sysdata; int ret; + struct pcie_port *pp; + struct pci_bus *bridge_bus; + + for (bridge_bus = bus; bridge_bus->parent; + bridge_bus = bridge_bus->parent) + ; + + if (has_acpi_companion(bridge_bus->bridge)) { +#ifdef CONFIG_ACPI_PCI_HOST_GENERIC + struct acpi_pci_root *root = bus->sysdata; + + pp = root->sysdata; +#endif /* CONFIG_ACPI_PCI_HOST_GENERIC */ + } else + pp = bus->sysdata; if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) return PCIBIOS_DEVICE_NOT_FOUND; @@ -700,7 +729,7 @@ static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn, return ret; } -static struct pci_ops dw_pcie_ops = { +struct pci_ops dw_pcie_ops = { .read = dw_pcie_rd_conf, .write = dw_pcie_wr_conf, }; diff --git a/drivers/pci/host/pcie-designware.h b/drivers/pci/host/pcie-designware.h index 2356d29..fd27fa4 100644 --- a/drivers/pci/host/pcie-designware.h +++ b/drivers/pci/host/pcie-designware.h @@ -80,4 +80,5 @@ int dw_pcie_link_up(struct pcie_port *pp); void dw_pcie_setup_rc(struct pcie_port *pp); int dw_pcie_host_init(struct pcie_port *pp); +extern struct pci_ops dw_pcie_ops; #endif /* _PCIE_DESIGNWARE_H */ -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html