From 4f9d2a78d3c2d0f202b5a75769d2806b5e45a9f0 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 20 Aug 2020 21:53:41 -0600 Subject: [PATCH] PCI: Allow root and child buses to have different pci_ops PCI host bridges often have different ways to access the root and child bus config spaces. The host bridge drivers have invented their own abstractions to handle this. Let's support having different root and child bus pci_ops so these per driver abstractions can be removed. Link: https://lore.kernel.org/r/20200821035420.380495-2-robh@kernel.org Signed-off-by: Rob Herring Signed-off-by: Lorenzo Pieralisi Cc: Bjorn Helgaas --- drivers/pci/probe.c | 8 +++++++- include/linux/pci.h | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 03d37128a24f2..0c9ebc72532e7 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -1036,6 +1036,7 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent, struct pci_dev *bridge, int busnr) { struct pci_bus *child; + struct pci_host_bridge *host; int i; int ret; @@ -1045,11 +1046,16 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent, return NULL; child->parent = parent; - child->ops = parent->ops; child->msi = parent->msi; child->sysdata = parent->sysdata; child->bus_flags = parent->bus_flags; + host = pci_find_host_bridge(parent); + if (host->child_ops) + child->ops = host->child_ops; + else + child->ops = parent->ops; + /* * Initialize some portions of the bus device, but don't register * it now as the parent is not properly set up yet. diff --git a/include/linux/pci.h b/include/linux/pci.h index 835530605c0d7..1fbe95a7d3867 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -523,6 +523,7 @@ struct pci_host_bridge { struct device dev; struct pci_bus *bus; /* Root bus */ struct pci_ops *ops; + struct pci_ops *child_ops; void *sysdata; int busnr; struct list_head windows; /* resource_entry */ -- 2.39.5