Commit 444ddca5 authored by Rob Herring's avatar Rob Herring Committed by Lorenzo Pieralisi

PCI: dwc: Allow overriding bridge pci_ops

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.

Link: https://lore.kernel.org/r/20200821035420.380495-4-robh@kernel.orgSigned-off-by: default avatarRob Herring <robh@kernel.org>
Signed-off-by: default avatarLorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Jingoo Han <jingoohan1@gmail.com>
Cc: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Bjorn Helgaas <bhelgaas@google.com>
parent f81c770d
...@@ -344,6 +344,8 @@ int dw_pcie_host_init(struct pcie_port *pp) ...@@ -344,6 +344,8 @@ int dw_pcie_host_init(struct pcie_port *pp)
if (!bridge) if (!bridge)
return -ENOMEM; return -ENOMEM;
pp->bridge = bridge;
/* Get the I/O and memory ranges from DT */ /* Get the I/O and memory ranges from DT */
resource_list_for_each_entry(win, &bridge->windows) { resource_list_for_each_entry(win, &bridge->windows) {
switch (resource_type(win->res)) { switch (resource_type(win->res)) {
...@@ -445,6 +447,10 @@ int dw_pcie_host_init(struct pcie_port *pp) ...@@ -445,6 +447,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) { if (pp->ops->host_init) {
ret = pp->ops->host_init(pp); ret = pp->ops->host_init(pp);
if (ret) if (ret)
...@@ -452,7 +458,6 @@ int dw_pcie_host_init(struct pcie_port *pp) ...@@ -452,7 +458,6 @@ int dw_pcie_host_init(struct pcie_port *pp)
} }
bridge->sysdata = pp; bridge->sysdata = pp;
bridge->ops = &dw_pcie_ops;
ret = pci_scan_root_bus_bridge(bridge); ret = pci_scan_root_bus_bridge(bridge);
if (ret) if (ret)
...@@ -654,11 +659,11 @@ void dw_pcie_setup_rc(struct pcie_port *pp) ...@@ -654,11 +659,11 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
dw_pcie_writel_dbi(pci, PCI_COMMAND, val); dw_pcie_writel_dbi(pci, PCI_COMMAND, val);
/* /*
* If the platform provides ->rd_other_conf, it means the platform * If the platform provides its own child bus config accesses, it means
* uses its own address translation component rather than ATU, so * the platform uses its own address translation component rather than
* we should not program the ATU here. * 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, dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX0,
PCIE_ATU_TYPE_MEM, pp->mem_base, PCIE_ATU_TYPE_MEM, pp->mem_base,
pp->mem_bus_addr, pp->mem_size); pp->mem_bus_addr, pp->mem_size);
......
...@@ -200,6 +200,7 @@ struct pcie_port { ...@@ -200,6 +200,7 @@ struct pcie_port {
u32 num_vectors; u32 num_vectors;
u32 irq_mask[MAX_MSI_CTRLS]; u32 irq_mask[MAX_MSI_CTRLS];
struct pci_bus *root_bus; struct pci_bus *root_bus;
struct pci_host_bridge *bridge;
raw_spinlock_t lock; raw_spinlock_t lock;
DECLARE_BITMAP(msi_irq_in_use, MAX_MSI_IRQS); DECLARE_BITMAP(msi_irq_in_use, MAX_MSI_IRQS);
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment