In preparation to allow drivers to set their own root and child pci_ops instead of using the DWC specific config space ops, we need to make the pci_host_bridge pointer available and move setting the bridge->ops and bridge->child_ops pointer to before the .host_init() hook. Cc: Jingoo Han <jingoohan1@xxxxxxxxx> Cc: Gustavo Pimentel <gustavo.pimentel@xxxxxxxxxxxx> Cc: Lorenzo Pieralisi <lorenzo.pieralisi@xxxxxxx> Cc: Bjorn Helgaas <bhelgaas@xxxxxxxxxx> Signed-off-by: Rob Herring <robh@xxxxxxxxxx> --- drivers/pci/controller/dwc/pcie-designware-host.c | 15 ++++++++++----- drivers/pci/controller/dwc/pcie-designware.h | 1 + 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c index 6232aefbbdb4..7cd8c9528d4c 100644 --- a/drivers/pci/controller/dwc/pcie-designware-host.c +++ b/drivers/pci/controller/dwc/pcie-designware-host.c @@ -344,6 +344,8 @@ int dw_pcie_host_init(struct pcie_port *pp) if (!bridge) return -ENOMEM; + pp->bridge = bridge; + ret = pci_parse_request_of_pci_ranges(dev, &bridge->windows, &bridge->dma_ranges, NULL); if (ret) @@ -450,6 +452,10 @@ int dw_pcie_host_init(struct pcie_port *pp) } } + /* Set default bus ops */ + bridge->ops = &dw_pcie_ops; + bridge->child_ops = &dw_pcie_ops; + if (pp->ops->host_init) { ret = pp->ops->host_init(pp); if (ret) @@ -461,7 +467,6 @@ int dw_pcie_host_init(struct pcie_port *pp) bridge->dev.parent = dev; bridge->sysdata = pp; bridge->busnr = pp->root_bus_nr; - bridge->ops = &dw_pcie_ops; bridge->map_irq = of_irq_parse_and_map_pci; bridge->swizzle_irq = pci_common_swizzle; @@ -667,11 +672,11 @@ void dw_pcie_setup_rc(struct pcie_port *pp) dw_pcie_writel_dbi(pci, PCI_COMMAND, val); /* - * If the platform provides ->rd_other_conf, it means the platform - * uses its own address translation component rather than ATU, so - * we should not program the ATU here. + * If the platform provides its own child bus config accesses, it means + * the platform uses its own address translation component rather than + * ATU, so we should not program the ATU here. */ - if (!pp->ops->rd_other_conf) { + if (pp->bridge->child_ops == &dw_pcie_ops && !pp->ops->rd_other_conf) { dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX0, PCIE_ATU_TYPE_MEM, pp->mem_base, pp->mem_bus_addr, pp->mem_size); diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h index 656e00f8fbeb..bad3cddab28e 100644 --- a/drivers/pci/controller/dwc/pcie-designware.h +++ b/drivers/pci/controller/dwc/pcie-designware.h @@ -201,6 +201,7 @@ struct pcie_port { u32 num_vectors; u32 irq_mask[MAX_MSI_CTRLS]; struct pci_bus *root_bus; + struct pci_host_bridge *bridge; raw_spinlock_t lock; DECLARE_BITMAP(msi_irq_in_use, MAX_MSI_IRQS); }; -- 2.25.1