linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC 00/15] PCI: turn some __weak functions into callbacks
@ 2018-08-17 10:26 Arnd Bergmann
  2018-08-17 10:26 ` [RFC 01/15] PCI: clean up legacy host bridge scan functions Arnd Bergmann
                   ` (16 more replies)
  0 siblings, 17 replies; 28+ messages in thread
From: Arnd Bergmann @ 2018-08-17 10:26 UTC (permalink / raw)
  To: linux-pci, Bjorn Helgaas
  Cc: linux-kernel, Christoph Hellwig, Lorenzo Pieralisi,
	Benjamin Herrenschmidt, linuxppc-dev, linux-acpi, Arnd Bergmann

Hi Bjorn and others,

Triggered by Christoph's patches, I had another go at converting
all of the remaining pci host bridge implementations to be based
on pci_alloc_host_bridge and a separate registration function.

This is made possible through work from Lorenzo and others to
convert many of the existing drivers, as well as the removal
of some of the older architectures that nobody used.

I'm adding a bit of duplication into the less maintained code
here, but it makes everything more consistent, and gives an
easy place to hook up callback functions etc.

The three parts of this series are:

a) push up the registration into the callers (this is where
   code gets added)
b) clean up some of the more common host bridge
   implementations again to integrate that code better.
   This could be done for the rest as well, or we could just
   leave them alone.
c) start moving the __weak functions into callbacks in
   pci_host_bridge. This is intentionally incomplete, since
   it is a lot of work to do it for all those functions,
   and I want to get consensus on the approach first, as well
   as maybe get other developers to help out with the rest.

Please have a look.

       Arnd

[1] https://lore.kernel.org/lkml/4288331.jNpl6KXlNO@wuerfel/
[2] https://patchwork.kernel.org/patch/10555657/

Arnd Bergmann (15):
  PCI: clean up legacy host bridge scan functions
  PCI: move pci_scan_bus into callers
  PCI: move pci_scan_root_bus into callers
  PCI: export pci_register_host_bridge
  PCI: move pci_create_root_bus into callers
  powerpc/pci: fold pci_create_root_bus into pcibios_scan_phb
  PCI/ACPI: clean up acpi_pci_root_create()
  x86: PCI: clean up pcibios_scan_root()
  PCI: xenfront: clean up pcifront_scan_root()
  sparc/PCI: simplify pci_scan_one_pbm
  PCI: hyperv: convert to pci_scan_root_bus_bridge
  PCI: make pcibios_bus_add_device() a callback function
  PCI: turn pcibios_alloc_irq into a callback
  PCI: make pcibios_root_bridge_prepare a callback
  PCI: make pcibios_add_bus/remove_bus callbacks

 arch/arm64/kernel/pci.c               |  40 ++-----
 arch/ia64/pci/pci.c                   |  25 +----
 arch/ia64/sn/kernel/io_init.c         |  27 +++++
 arch/microblaze/pci/pci-common.c      |  27 +++++
 arch/powerpc/include/asm/pci-bridge.h |   3 +
 arch/powerpc/kernel/pci-common.c      |  60 +++++------
 arch/s390/pci/pci.c                   |  30 +++++-
 arch/sh/drivers/pci/pci.c             |   1 +
 arch/sh/drivers/pci/pcie-sh7786.c     |   3 +-
 arch/sh/include/asm/pci.h             |   2 +
 arch/sparc/kernel/pci.c               |  40 ++++---
 arch/sparc/kernel/pcic.c              |  35 ++++++
 arch/x86/pci/acpi.c                   |  15 +--
 arch/x86/pci/common.c                 |  42 ++++----
 arch/xtensa/kernel/pci.c              |  27 +++++
 drivers/acpi/pci_root.c               |  43 +++++---
 drivers/parisc/dino.c                 |  28 +++++
 drivers/parisc/lba_pci.c              |  28 +++++
 drivers/pci/bus.c                     |   8 +-
 drivers/pci/controller/pci-hyperv.c   |  47 ++++----
 drivers/pci/controller/vmd.c          |  30 +++++-
 drivers/pci/hotplug/ibmphp_core.c     |  35 ++++++
 drivers/pci/pci-driver.c              |  13 ++-
 drivers/pci/probe.c                   | 150 +++++++++-----------------
 drivers/pci/xen-pcifront.c            |  40 +++----
 include/linux/acpi.h                  |   2 +
 include/linux/pci.h                   |  17 ++-
 27 files changed, 514 insertions(+), 304 deletions(-)

-- 
2.18.0


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [RFC 01/15] PCI: clean up legacy host bridge scan functions
  2018-08-17 10:26 [RFC 00/15] PCI: turn some __weak functions into callbacks Arnd Bergmann
@ 2018-08-17 10:26 ` Arnd Bergmann
  2018-08-17 10:26 ` [RFC 02/15] PCI: move pci_scan_bus into callers Arnd Bergmann
                   ` (15 subsequent siblings)
  16 siblings, 0 replies; 28+ messages in thread
From: Arnd Bergmann @ 2018-08-17 10:26 UTC (permalink / raw)
  To: linux-pci, Bjorn Helgaas
  Cc: linux-kernel, Christoph Hellwig, Lorenzo Pieralisi,
	Benjamin Herrenschmidt, linuxppc-dev, linux-acpi, Arnd Bergmann

Aside from the modern pci_host_bridge based interfaces, we have a couple
of interfaces from old times that are still used in a couple of platforms:
pci_create_root_bus(), pci_scan_bus() and pci_scan_root_bus().

As a first step towards getting everybody to use the new interfaces,
this simplifies the latter two to call the pci_alloc_host_bridge() and
pci_register_host_bridge()/pci_scan_root_bus_bridge() interfaces directly.

The behavior should be entirely unchanged here, but we can then push
down the functions into the individual host implementations.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 drivers/pci/probe.c | 86 ++++++++++++++++++++++++---------------------
 1 file changed, 45 insertions(+), 41 deletions(-)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index ec784009a36b..b0f666271245 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -23,13 +23,6 @@
 #define CARDBUS_LATENCY_TIMER	176	/* secondary latency timer */
 #define CARDBUS_RESERVE_BUSNR	3
 
-static struct resource busn_resource = {
-	.name	= "PCI busn",
-	.start	= 0,
-	.end	= 255,
-	.flags	= IORESOURCE_BUS,
-};
-
 /* Ugh.  Need to stop exporting this to modules. */
 LIST_HEAD(pci_root_buses);
 EXPORT_SYMBOL(pci_root_buses);
@@ -3060,53 +3053,64 @@ EXPORT_SYMBOL(pci_scan_root_bus_bridge);
 struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
 		struct pci_ops *ops, void *sysdata, struct list_head *resources)
 {
-	struct resource_entry *window;
-	bool found = false;
-	struct pci_bus *b;
-	int max;
-
-	resource_list_for_each_entry(window, resources)
-		if (window->res->flags & IORESOURCE_BUS) {
-			found = true;
-			break;
-		}
+	struct pci_host_bridge *bridge;
+	int error;
 
-	b = pci_create_root_bus(parent, bus, ops, sysdata, resources);
-	if (!b)
+	bridge = pci_alloc_host_bridge(0);
+	if (!bridge)
 		return NULL;
 
-	if (!found) {
-		dev_info(&b->dev,
-		 "No busn resource found for root bus, will use [bus %02x-ff]\n",
-			bus);
-		pci_bus_insert_busn_res(b, bus, 255);
-	}
+	list_splice_init(resources, &bridge->windows);
+	bridge->dev.parent = parent;
+	bridge->sysdata = sysdata;
+	bridge->busnr = bus;
+	bridge->ops = ops;
 
-	max = pci_scan_child_bus(b);
+	error = pci_scan_root_bus_bridge(bridge);
+	if (error < 0)
+		goto err_out;
 
-	if (!found)
-		pci_bus_update_busn_res_end(b, max);
+	return bridge->bus;
 
-	return b;
+err_out:
+	kfree(bridge);
+	return NULL;
 }
 EXPORT_SYMBOL(pci_scan_root_bus);
 
+static struct resource busn_resource = {
+	.name	= "PCI busn",
+	.start	= 0,
+	.end	= 255,
+	.flags	= IORESOURCE_BUS,
+};
+
 struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops,
 					void *sysdata)
 {
-	LIST_HEAD(resources);
-	struct pci_bus *b;
+	struct pci_host_bridge *bridge;
+	int error;
 
-	pci_add_resource(&resources, &ioport_resource);
-	pci_add_resource(&resources, &iomem_resource);
-	pci_add_resource(&resources, &busn_resource);
-	b = pci_create_root_bus(NULL, bus, ops, sysdata, &resources);
-	if (b) {
-		pci_scan_child_bus(b);
-	} else {
-		pci_free_resource_list(&resources);
-	}
-	return b;
+	bridge = pci_alloc_host_bridge(0);
+	if (!bridge)
+		goto err;
+
+	pci_add_resource(&bridge->windows, &ioport_resource);
+	pci_add_resource(&bridge->windows, &iomem_resource);
+	pci_add_resource(&bridge->windows, &busn_resource);
+	bridge->sysdata = sysdata;
+	bridge->busnr = bus;
+	bridge->ops = ops;
+
+	error = pci_scan_root_bus_bridge(bridge);
+	if (error < 0)
+		goto err;
+
+	return bridge->bus;
+
+err:
+	pci_free_host_bridge(bridge);
+	return NULL;
 }
 EXPORT_SYMBOL(pci_scan_bus);
 
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [RFC 02/15] PCI: move pci_scan_bus into callers
  2018-08-17 10:26 [RFC 00/15] PCI: turn some __weak functions into callbacks Arnd Bergmann
  2018-08-17 10:26 ` [RFC 01/15] PCI: clean up legacy host bridge scan functions Arnd Bergmann
@ 2018-08-17 10:26 ` Arnd Bergmann
  2018-08-17 10:26 ` [RFC 03/15] PCI: move pci_scan_root_bus " Arnd Bergmann
                   ` (14 subsequent siblings)
  16 siblings, 0 replies; 28+ messages in thread
From: Arnd Bergmann @ 2018-08-17 10:26 UTC (permalink / raw)
  To: linux-pci, Bjorn Helgaas
  Cc: linux-kernel, Christoph Hellwig, Lorenzo Pieralisi,
	Benjamin Herrenschmidt, linuxppc-dev, linux-acpi, Arnd Bergmann

There are only two remaining callers of the old pci_scan_bus()
interface. Since we want to expose the pci_host_bridge structure
everywhere and discourage users from calling the old interfaces,
let's move the implementation into the respective callsites.

While this duplicates the source code, it makes the object code
smaller for all users by avoiding the global implementation,
and it allows further cleanup of the two callers.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 arch/sparc/kernel/pcic.c          | 35 ++++++++++++++++++++++++++++++
 drivers/pci/hotplug/ibmphp_core.c | 35 ++++++++++++++++++++++++++++++
 drivers/pci/probe.c               | 36 -------------------------------
 include/linux/pci.h               |  1 -
 4 files changed, 70 insertions(+), 37 deletions(-)

diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c
index ee4c9a9a171c..0197b80fe590 100644
--- a/arch/sparc/kernel/pcic.c
+++ b/arch/sparc/kernel/pcic.c
@@ -387,6 +387,41 @@ int __init pcic_probe(void)
 	return 0;
 }
 
+static struct resource busn_resource = {
+	.name	= "PCI busn",
+	.start	= 0,
+	.end	= 255,
+	.flags	= IORESOURCE_BUS,
+};
+
+static struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops,
+					void *sysdata)
+{
+	struct pci_host_bridge *bridge;
+	int error;
+
+	bridge = pci_alloc_host_bridge(0);
+	if (!bridge)
+		return NULL;
+
+	pci_add_resource(&bridge->windows, &ioport_resource);
+	pci_add_resource(&bridge->windows, &iomem_resource);
+	pci_add_resource(&bridge->windows, &busn_resource);
+	bridge->sysdata = sysdata;
+	bridge->busnr = bus;
+	bridge->ops = ops;
+
+	error = pci_scan_root_bus_bridge(bridge);
+	if (error < 0)
+		goto err;
+
+	return bridge->bus;
+
+err_res:
+	pci_free_host_bridge(bridge);
+	return NULL;
+}
+
 static void __init pcic_pbm_scan_bus(struct linux_pcic *pcic)
 {
 	struct linux_pbm_info *pbm = &pcic->pbm;
diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c
index 4ea57e9019f1..d35463ee96ba 100644
--- a/drivers/pci/hotplug/ibmphp_core.c
+++ b/drivers/pci/hotplug/ibmphp_core.c
@@ -717,6 +717,41 @@ static void ibm_unconfigure_device(struct pci_func *func)
 	pci_unlock_rescan_remove();
 }
 
+static struct resource busn_resource = {
+	.name	= "pci busn",
+	.start	= 0,
+	.end	= 255,
+	.flags	= IORESOURCE_BUS,
+};
+
+static struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops,
+					void *sysdata)
+{
+	struct pci_host_bridge *bridge;
+	int error;
+
+	bridge = pci_alloc_host_bridge(0);
+	if (!bridge)
+		return NULL;
+
+	pci_add_resource(&bridge->windows, &ioport_resource);
+	pci_add_resource(&bridge->windows, &iomem_resource);
+	pci_add_resource(&bridge->windows, &busn_resource);
+	bridge->sysdata = sysdata;
+	bridge->busnr = bus;
+	bridge->ops = ops;
+
+	error = pci_scan_root_bus_bridge(bridge);
+	if (error < 0)
+		goto err;
+
+	return bridge->bus;
+
+err:
+	pci_free_host_bridge(bridge);
+	return NULL;
+}
+
 /*
  * The following function is to fix kernel bug regarding
  * getting bus entries, here we manually add those primary
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index b0f666271245..12c3aa63c34d 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -3078,42 +3078,6 @@ struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
 }
 EXPORT_SYMBOL(pci_scan_root_bus);
 
-static struct resource busn_resource = {
-	.name	= "PCI busn",
-	.start	= 0,
-	.end	= 255,
-	.flags	= IORESOURCE_BUS,
-};
-
-struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops,
-					void *sysdata)
-{
-	struct pci_host_bridge *bridge;
-	int error;
-
-	bridge = pci_alloc_host_bridge(0);
-	if (!bridge)
-		goto err;
-
-	pci_add_resource(&bridge->windows, &ioport_resource);
-	pci_add_resource(&bridge->windows, &iomem_resource);
-	pci_add_resource(&bridge->windows, &busn_resource);
-	bridge->sysdata = sysdata;
-	bridge->busnr = bus;
-	bridge->ops = ops;
-
-	error = pci_scan_root_bus_bridge(bridge);
-	if (error < 0)
-		goto err;
-
-	return bridge->bus;
-
-err:
-	pci_free_host_bridge(bridge);
-	return NULL;
-}
-EXPORT_SYMBOL(pci_scan_bus);
-
 /**
  * pci_rescan_bus_bridge_resize - Scan a PCI bus for devices
  * @bridge: PCI bridge for the bus to scan
diff --git a/include/linux/pci.h b/include/linux/pci.h
index e72ca8dd6241..d77ce35a2b33 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -905,7 +905,6 @@ void pcibios_bus_to_resource(struct pci_bus *bus, struct resource *res,
 void pcibios_scan_specific_bus(int busn);
 struct pci_bus *pci_find_bus(int domain, int busnr);
 void pci_bus_add_devices(const struct pci_bus *bus);
-struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata);
 struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
 				    struct pci_ops *ops, void *sysdata,
 				    struct list_head *resources);
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [RFC 03/15] PCI: move pci_scan_root_bus into callers
  2018-08-17 10:26 [RFC 00/15] PCI: turn some __weak functions into callbacks Arnd Bergmann
  2018-08-17 10:26 ` [RFC 01/15] PCI: clean up legacy host bridge scan functions Arnd Bergmann
  2018-08-17 10:26 ` [RFC 02/15] PCI: move pci_scan_bus into callers Arnd Bergmann
@ 2018-08-17 10:26 ` Arnd Bergmann
  2018-08-17 10:26 ` [RFC 04/15] PCI: export pci_register_host_bridge Arnd Bergmann
                   ` (13 subsequent siblings)
  16 siblings, 0 replies; 28+ messages in thread
From: Arnd Bergmann @ 2018-08-17 10:26 UTC (permalink / raw)
  To: linux-pci, Bjorn Helgaas
  Cc: linux-kernel, Christoph Hellwig, Lorenzo Pieralisi,
	Benjamin Herrenschmidt, linuxppc-dev, linux-acpi, Arnd Bergmann

There are only six remaining callers of the old pci_scan_root_bus()
interface. Since we want to expose the pci_host_bridge structure
everywhere and discourage users from calling the old interfaces, let's
move the implementation into the respective callsites.

While this duplicates the source code, it makes the object code smaller
for almost all users by avoiding the global implementation, and it allows
further cleanup of the callers.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 arch/ia64/sn/kernel/io_init.c    | 27 +++++++++++++++++++++++++++
 arch/microblaze/pci/pci-common.c | 27 +++++++++++++++++++++++++++
 arch/s390/pci/pci.c              | 27 +++++++++++++++++++++++++++
 arch/x86/pci/common.c            | 27 +++++++++++++++++++++++++++
 arch/xtensa/kernel/pci.c         | 27 +++++++++++++++++++++++++++
 drivers/pci/probe.c              | 28 ----------------------------
 drivers/pci/xen-pcifront.c       | 27 +++++++++++++++++++++++++++
 include/linux/pci.h              |  3 ---
 8 files changed, 162 insertions(+), 31 deletions(-)

diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c
index d63809a6adfa..e768702a7b45 100644
--- a/arch/ia64/sn/kernel/io_init.c
+++ b/arch/ia64/sn/kernel/io_init.c
@@ -213,6 +213,33 @@ sn_io_slot_fixup(struct pci_dev *dev)
 }
 EXPORT_SYMBOL(sn_io_slot_fixup);
 
+static struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
+		struct pci_ops *ops, void *sysdata, struct list_head *resources)
+{
+	struct pci_host_bridge *bridge;
+	int error;
+
+	bridge = pci_alloc_host_bridge(0);
+	if (!bridge)
+		return NULL;
+
+	list_splice_init(resources, &bridge->windows);
+	bridge->dev.parent = parent;
+	bridge->sysdata = sysdata;
+	bridge->busnr = bus;
+	bridge->ops = ops;
+
+	error = pci_scan_root_bus_bridge(bridge);
+	if (error < 0)
+		goto err_out;
+
+	return bridge->bus;
+
+err_out:
+	kfree(bridge);
+	return NULL;
+}
+
 /*
  * sn_pci_controller_fixup() - This routine sets up a bus's resources
  *			       consistent with the Linux PCI abstraction layer.
diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c
index f34346d56095..302071385e1b 100644
--- a/arch/microblaze/pci/pci-common.c
+++ b/arch/microblaze/pci/pci-common.c
@@ -977,6 +977,33 @@ static void pcibios_setup_phb_resources(struct pci_controller *hose,
 		 (unsigned long)hose->io_base_virt - _IO_BASE);
 }
 
+static struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
+		struct pci_ops *ops, void *sysdata, struct list_head *resources)
+{
+	struct pci_host_bridge *bridge;
+	int error;
+
+	bridge = pci_alloc_host_bridge(0);
+	if (!bridge)
+		return NULL;
+
+	list_splice_init(resources, &bridge->windows);
+	bridge->dev.parent = parent;
+	bridge->sysdata = sysdata;
+	bridge->busnr = bus;
+	bridge->ops = ops;
+
+	error = pci_scan_root_bus_bridge(bridge);
+	if (error < 0)
+		goto err_out;
+
+	return bridge->bus;
+
+err_out:
+	kfree(bridge);
+	return NULL;
+}
+
 static void pcibios_scan_phb(struct pci_controller *hose)
 {
 	LIST_HEAD(resources);
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
index 9f6f392a4461..b21205f131ce 100644
--- a/arch/s390/pci/pci.c
+++ b/arch/s390/pci/pci.c
@@ -786,6 +786,33 @@ void pcibios_remove_bus(struct pci_bus *bus)
 	kfree(zdev);
 }
 
+static struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
+		struct pci_ops *ops, void *sysdata, struct list_head *resources)
+{
+	struct pci_host_bridge *bridge;
+	int error;
+
+	bridge = pci_alloc_host_bridge(0);
+	if (!bridge)
+		return NULL;
+
+	list_splice_init(resources, &bridge->windows);
+	bridge->dev.parent = parent;
+	bridge->sysdata = sysdata;
+	bridge->busnr = bus;
+	bridge->ops = ops;
+
+	error = pci_scan_root_bus_bridge(bridge);
+	if (error < 0)
+		goto err_out;
+
+	return bridge->bus;
+
+err_out:
+	kfree(bridge);
+	return NULL;
+}
+
 static int zpci_scan_bus(struct zpci_dev *zdev)
 {
 	LIST_HEAD(resources);
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index d4ec117c1142..e740d9aa4024 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -453,6 +453,33 @@ void __init dmi_check_pciprobe(void)
 	dmi_check_system(pciprobe_dmi_table);
 }
 
+static struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
+		struct pci_ops *ops, void *sysdata, struct list_head *resources)
+{
+	struct pci_host_bridge *bridge;
+	int error;
+
+	bridge = pci_alloc_host_bridge(0);
+	if (!bridge)
+		return NULL;
+
+	list_splice_init(resources, &bridge->windows);
+	bridge->dev.parent = parent;
+	bridge->sysdata = sysdata;
+	bridge->busnr = bus;
+	bridge->ops = ops;
+
+	error = pci_scan_root_bus_bridge(bridge);
+	if (error < 0)
+		goto err_out;
+
+	return bridge->bus;
+
+err_out:
+	kfree(bridge);
+	return NULL;
+}
+
 void pcibios_scan_root(int busnum)
 {
 	struct pci_bus *bus;
diff --git a/arch/xtensa/kernel/pci.c b/arch/xtensa/kernel/pci.c
index 21f13e9aabe1..5a8fd67e6c5e 100644
--- a/arch/xtensa/kernel/pci.c
+++ b/arch/xtensa/kernel/pci.c
@@ -116,6 +116,33 @@ static void __init pci_controller_apertures(struct pci_controller *pci_ctrl,
 	}
 }
 
+static struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
+		struct pci_ops *ops, void *sysdata, struct list_head *resources)
+{
+	struct pci_host_bridge *bridge;
+	int error;
+
+	bridge = pci_alloc_host_bridge(0);
+	if (!bridge)
+		return NULL;
+
+	list_splice_init(resources, &bridge->windows);
+	bridge->dev.parent = parent;
+	bridge->sysdata = sysdata;
+	bridge->busnr = bus;
+	bridge->ops = ops;
+
+	error = pci_scan_root_bus_bridge(bridge);
+	if (error < 0)
+		goto err_out;
+
+	return bridge->bus;
+
+err_out:
+	kfree(bridge);
+	return NULL;
+}
+
 static int __init pcibios_init(void)
 {
 	struct pci_controller *pci_ctrl;
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 12c3aa63c34d..cf169742c03e 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -3050,34 +3050,6 @@ int pci_scan_root_bus_bridge(struct pci_host_bridge *bridge)
 }
 EXPORT_SYMBOL(pci_scan_root_bus_bridge);
 
-struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
-		struct pci_ops *ops, void *sysdata, struct list_head *resources)
-{
-	struct pci_host_bridge *bridge;
-	int error;
-
-	bridge = pci_alloc_host_bridge(0);
-	if (!bridge)
-		return NULL;
-
-	list_splice_init(resources, &bridge->windows);
-	bridge->dev.parent = parent;
-	bridge->sysdata = sysdata;
-	bridge->busnr = bus;
-	bridge->ops = ops;
-
-	error = pci_scan_root_bus_bridge(bridge);
-	if (error < 0)
-		goto err_out;
-
-	return bridge->bus;
-
-err_out:
-	kfree(bridge);
-	return NULL;
-}
-EXPORT_SYMBOL(pci_scan_root_bus);
-
 /**
  * pci_rescan_bus_bridge_resize - Scan a PCI bus for devices
  * @bridge: PCI bridge for the bus to scan
diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c
index eba6e33147a2..24070e1c5f22 100644
--- a/drivers/pci/xen-pcifront.c
+++ b/drivers/pci/xen-pcifront.c
@@ -443,6 +443,33 @@ static int pcifront_scan_bus(struct pcifront_device *pdev,
 	return 0;
 }
 
+static struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
+		struct pci_ops *ops, void *sysdata, struct list_head *resources)
+{
+	struct pci_host_bridge *bridge;
+	int error;
+
+	bridge = pci_alloc_host_bridge(0);
+	if (!bridge)
+		return NULL;
+
+	list_splice_init(resources, &bridge->windows);
+	bridge->dev.parent = parent;
+	bridge->sysdata = sysdata;
+	bridge->busnr = bus;
+	bridge->ops = ops;
+
+	error = pci_scan_root_bus_bridge(bridge);
+	if (error < 0)
+		goto err_out;
+
+	return bridge->bus;
+
+err_out:
+	kfree(bridge);
+	return NULL;
+}
+
 static int pcifront_scan_root(struct pcifront_device *pdev,
 				 unsigned int domain, unsigned int bus)
 {
diff --git a/include/linux/pci.h b/include/linux/pci.h
index d77ce35a2b33..d226e06fb5e5 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -912,9 +912,6 @@ int pci_host_probe(struct pci_host_bridge *bridge);
 int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int busmax);
 int pci_bus_update_busn_res_end(struct pci_bus *b, int busmax);
 void pci_bus_release_busn_res(struct pci_bus *b);
-struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
-				  struct pci_ops *ops, void *sysdata,
-				  struct list_head *resources);
 int pci_scan_root_bus_bridge(struct pci_host_bridge *bridge);
 struct pci_bus *pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev,
 				int busnr);
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [RFC 04/15] PCI: export pci_register_host_bridge
  2018-08-17 10:26 [RFC 00/15] PCI: turn some __weak functions into callbacks Arnd Bergmann
                   ` (2 preceding siblings ...)
  2018-08-17 10:26 ` [RFC 03/15] PCI: move pci_scan_root_bus " Arnd Bergmann
@ 2018-08-17 10:26 ` Arnd Bergmann
  2018-08-17 10:26 ` [RFC 05/15] PCI: move pci_create_root_bus into callers Arnd Bergmann
                   ` (12 subsequent siblings)
  16 siblings, 0 replies; 28+ messages in thread
From: Arnd Bergmann @ 2018-08-17 10:26 UTC (permalink / raw)
  To: linux-pci, Bjorn Helgaas
  Cc: linux-kernel, Christoph Hellwig, Lorenzo Pieralisi,
	Benjamin Herrenschmidt, linuxppc-dev, linux-acpi, Arnd Bergmann

There are a couple of users of the old pci_create_root_bus() interface,
which calls pci_register_host_bridge() without actually scanning the bus.

In order to get those callers a little closer to the current method
of separating the allocation and probing of the host bridge, this
exports the internal interface to modules. If all the callers can
get moved over to pci_host_probe() or pci_scan_root_bus_bridge()
later, the export can be removed again.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 drivers/pci/probe.c | 25 ++++++++++++++++++++++++-
 include/linux/pci.h |  1 +
 2 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index cf169742c03e..5ca7d5941ad0 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -762,7 +762,29 @@ static void pci_set_bus_msi_domain(struct pci_bus *bus)
 	dev_set_msi_domain(&bus->dev, d);
 }
 
-static int pci_register_host_bridge(struct pci_host_bridge *bridge)
+/*
+ * pci_register_host_bridge() - Register a host bridge without scanning
+ *
+ * @bridge: a newly allocated host bridge structure
+ *
+ * This is the core part of bringing up a new PCI host bridge,
+ * before we scan for attached devices and register them as
+ * pci_dev.
+ *
+ * For the most part, this is an implementation detail of the
+ * pci_host_probe() interface, which brings up the entire bus,
+ * bus some older platforms still call it directly and manually
+ * scan for devices.
+ *
+ * If your driver uses this, try to convert it to using
+ * pci_host_probe() instead.
+ *
+ * Return: zero on suggess, or a negative error code.
+ * Note: after pci_register_host_bridge() successfully returns,
+ * the pci_host_bridge device is alive in driver core, and must
+ * not be freed directly.
+ */
+int pci_register_host_bridge(struct pci_host_bridge *bridge)
 {
 	struct device *parent = bridge->dev.parent;
 	struct resource_entry *window, *n;
@@ -877,6 +899,7 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
 	kfree(bus);
 	return err;
 }
+EXPORT_SYMBOL_GPL(pci_register_host_bridge);
 
 static bool pci_bridge_child_ext_cfg_accessible(struct pci_dev *bridge)
 {
diff --git a/include/linux/pci.h b/include/linux/pci.h
index d226e06fb5e5..e1337148cf9f 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -909,6 +909,7 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
 				    struct pci_ops *ops, void *sysdata,
 				    struct list_head *resources);
 int pci_host_probe(struct pci_host_bridge *bridge);
+int pci_register_host_bridge(struct pci_host_bridge *);
 int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int busmax);
 int pci_bus_update_busn_res_end(struct pci_bus *b, int busmax);
 void pci_bus_release_busn_res(struct pci_bus *b);
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [RFC 05/15] PCI: move pci_create_root_bus into callers
  2018-08-17 10:26 [RFC 00/15] PCI: turn some __weak functions into callbacks Arnd Bergmann
                   ` (3 preceding siblings ...)
  2018-08-17 10:26 ` [RFC 04/15] PCI: export pci_register_host_bridge Arnd Bergmann
@ 2018-08-17 10:26 ` Arnd Bergmann
  2018-08-17 10:26 ` [RFC 06/15] powerpc/pci: fold pci_create_root_bus into pcibios_scan_phb Arnd Bergmann
                   ` (11 subsequent siblings)
  16 siblings, 0 replies; 28+ messages in thread
From: Arnd Bergmann @ 2018-08-17 10:26 UTC (permalink / raw)
  To: linux-pci, Bjorn Helgaas
  Cc: linux-kernel, Christoph Hellwig, Lorenzo Pieralisi,
	Benjamin Herrenschmidt, linuxppc-dev, linux-acpi, Arnd Bergmann

There are only seven remaining callers of the old pci_scan_root_bus()
interface. Since we want to expose the pci_host_bridge structure
everywhere and discourage users from calling the old interfaces, let's
move the implementation into the respective callsites.

While this duplicates the source code, it makes the object code smaller
for almost all users by avoiding the global implementation, and it allows
further cleanup of the callers.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 arch/powerpc/kernel/pci-common.c    | 28 +++++++++++++++++++++++++++
 arch/sparc/kernel/pci.c             | 28 +++++++++++++++++++++++++++
 drivers/acpi/pci_root.c             | 30 ++++++++++++++++++++++++++++-
 drivers/parisc/dino.c               | 28 +++++++++++++++++++++++++++
 drivers/parisc/lba_pci.c            | 28 +++++++++++++++++++++++++++
 drivers/pci/controller/pci-hyperv.c | 28 +++++++++++++++++++++++++++
 drivers/pci/controller/vmd.c        | 30 ++++++++++++++++++++++++++++-
 drivers/pci/probe.c                 | 29 ----------------------------
 include/linux/pci.h                 |  3 ---
 9 files changed, 198 insertions(+), 34 deletions(-)

diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 88e4f69a09e5..57ca621a32f4 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -1587,6 +1587,34 @@ struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus)
 	return of_node_get(hose->dn);
 }
 
+static struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
+		struct pci_ops *ops, void *sysdata, struct list_head *resources)
+{
+	int error;
+	struct pci_host_bridge *bridge;
+
+	bridge = pci_alloc_host_bridge(0);
+	if (!bridge)
+		return NULL;
+
+	bridge->dev.parent = parent;
+
+	list_splice_init(resources, &bridge->windows);
+	bridge->sysdata = sysdata;
+	bridge->busnr = bus;
+	bridge->ops = ops;
+
+	error = pci_register_host_bridge(bridge);
+	if (error < 0)
+		goto err_out;
+
+	return bridge->bus;
+
+err_out:
+	kfree(bridge);
+	return NULL;
+}
+
 /**
  * pci_scan_phb - Given a pci_controller, setup and scan the PCI bus
  * @hose: Pointer to the PCI host controller instance structure
diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
index 17ea16a1337c..afbce59d9231 100644
--- a/arch/sparc/kernel/pci.c
+++ b/arch/sparc/kernel/pci.c
@@ -691,6 +691,34 @@ static void pci_claim_bus_resources(struct pci_bus *bus)
 		pci_claim_bus_resources(child_bus);
 }
 
+static struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
+		struct pci_ops *ops, void *sysdata, struct list_head *resources)
+{
+	int error;
+	struct pci_host_bridge *bridge;
+
+	bridge = pci_alloc_host_bridge(0);
+	if (!bridge)
+		return NULL;
+
+	bridge->dev.parent = parent;
+
+	list_splice_init(resources, &bridge->windows);
+	bridge->sysdata = sysdata;
+	bridge->busnr = bus;
+	bridge->ops = ops;
+
+	error = pci_register_host_bridge(bridge);
+	if (error < 0)
+		goto err_out;
+
+	return bridge->bus;
+
+err_out:
+	kfree(bridge);
+	return NULL;
+}
+
 struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm,
 				 struct device *parent)
 {
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 7433035ded95..85dbcf47015b 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -873,6 +873,34 @@ static void acpi_pci_root_release_info(struct pci_host_bridge *bridge)
 	__acpi_pci_root_release_info(bridge->release_data);
 }
 
+static struct pci_bus *acpi_pci_create_root_bus(struct device *parent, int bus,
+		struct pci_ops *ops, void *sysdata, struct list_head *resources)
+{
+	int error;
+	struct pci_host_bridge *bridge;
+
+	bridge = pci_alloc_host_bridge(0);
+	if (!bridge)
+		return NULL;
+
+	bridge->dev.parent = parent;
+
+	list_splice_init(resources, &bridge->windows);
+	bridge->sysdata = sysdata;
+	bridge->busnr = bus;
+	bridge->ops = ops;
+
+	error = pci_register_host_bridge(bridge);
+	if (error < 0)
+		goto err_out;
+
+	return bridge->bus;
+
+err_out:
+	kfree(bridge);
+	return NULL;
+}
+
 struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
 				     struct acpi_pci_root_ops *ops,
 				     struct acpi_pci_root_info *info,
@@ -902,7 +930,7 @@ struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
 
 	pci_acpi_root_add_resources(info);
 	pci_add_resource(&info->resources, &root->secondary);
-	bus = pci_create_root_bus(NULL, busnum, ops->pci_ops,
+	bus = acpi_pci_create_root_bus(NULL, busnum, ops->pci_ops,
 				  sysdata, &info->resources);
 	if (!bus)
 		goto out_release_info;
diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c
index 7390fb8ca9d1..91c837de7616 100644
--- a/drivers/parisc/dino.c
+++ b/drivers/parisc/dino.c
@@ -882,6 +882,34 @@ static const char *cujo_vers[] = {
 
 void ccio_cujo20_fixup(struct parisc_device *dev, u32 iovp);
 
+static struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
+		struct pci_ops *ops, void *sysdata, struct list_head *resources)
+{
+	int error;
+	struct pci_host_bridge *bridge;
+
+	bridge = pci_alloc_host_bridge(0);
+	if (!bridge)
+		return NULL;
+
+	bridge->dev.parent = parent;
+
+	list_splice_init(resources, &bridge->windows);
+	bridge->sysdata = sysdata;
+	bridge->busnr = bus;
+	bridge->ops = ops;
+
+	error = pci_register_host_bridge(bridge);
+	if (error < 0)
+		goto err_out;
+
+	return bridge->bus;
+
+err_out:
+	kfree(bridge);
+	return NULL;
+}
+
 /*
 ** Determine if dino should claim this chip (return 0) or not (return 1).
 ** If so, initialize the chip appropriately (card-mode vs bridge mode).
diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c
index 69bd98421eb1..901b7f07fe91 100644
--- a/drivers/parisc/lba_pci.c
+++ b/drivers/parisc/lba_pci.c
@@ -1464,6 +1464,34 @@ lba_hw_init(struct lba_device *d)
  */
 static unsigned int lba_next_bus = 0;
 
+static struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
+		struct pci_ops *ops, void *sysdata, struct list_head *resources)
+{
+	int error;
+	struct pci_host_bridge *bridge;
+
+	bridge = pci_alloc_host_bridge(0);
+	if (!bridge)
+		return NULL;
+
+	bridge->dev.parent = parent;
+
+	list_splice_init(resources, &bridge->windows);
+	bridge->sysdata = sysdata;
+	bridge->busnr = bus;
+	bridge->ops = ops;
+
+	error = pci_register_host_bridge(bridge);
+	if (error < 0)
+		goto err_out;
+
+	return bridge->bus;
+
+err_out:
+	kfree(bridge);
+	return NULL;
+}
+
 /*
  * Determine if lba should claim this chip (return 0) or not (return 1).
  * If so, initialize the chip and tell other partners in crime they
diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c
index c00f82cc54aa..df7cddea8e30 100644
--- a/drivers/pci/controller/pci-hyperv.c
+++ b/drivers/pci/controller/pci-hyperv.c
@@ -1457,6 +1457,34 @@ static void prepopulate_bars(struct hv_pcibus_device *hbus)
 	spin_unlock_irqrestore(&hbus->device_list_lock, flags);
 }
 
+static struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
+		struct pci_ops *ops, void *sysdata, struct list_head *resources)
+{
+	int error;
+	struct pci_host_bridge *bridge;
+
+	bridge = pci_alloc_host_bridge(0);
+	if (!bridge)
+		return NULL;
+
+	bridge->dev.parent = parent;
+
+	list_splice_init(resources, &bridge->windows);
+	bridge->sysdata = sysdata;
+	bridge->busnr = bus;
+	bridge->ops = ops;
+
+	error = pci_register_host_bridge(bridge);
+	if (error < 0)
+		goto err_out;
+
+	return bridge->bus;
+
+err_out:
+	kfree(bridge);
+	return NULL;
+}
+
 /**
  * create_root_hv_pci_bus() - Expose a new root PCI bus
  * @hbus:	Root PCI bus, as understood by this driver
diff --git a/drivers/pci/controller/vmd.c b/drivers/pci/controller/vmd.c
index fd2dbd7eed7b..311c9f6761ae 100644
--- a/drivers/pci/controller/vmd.c
+++ b/drivers/pci/controller/vmd.c
@@ -579,6 +579,34 @@ static int vmd_find_free_domain(void)
 	return domain + 1;
 }
 
+static struct pci_bus *vmd_create_root_bus(struct device *parent, int bus,
+		struct pci_ops *ops, void *sysdata, struct list_head *resources)
+{
+	int error;
+	struct pci_host_bridge *bridge;
+
+	bridge = pci_alloc_host_bridge(0);
+	if (!bridge)
+		return NULL;
+
+	bridge->dev.parent = parent;
+
+	list_splice_init(resources, &bridge->windows);
+	bridge->sysdata = sysdata;
+	bridge->busnr = bus;
+	bridge->ops = ops;
+
+	error = pci_register_host_bridge(bridge);
+	if (error < 0)
+		goto err_out;
+
+	return bridge->bus;
+
+err_out:
+	kfree(bridge);
+	return NULL;
+}
+
 static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features)
 {
 	struct pci_sysdata *sd = &vmd->sysdata;
@@ -705,7 +733,7 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features)
 	pci_add_resource_offset(&resources, &vmd->resources[1], offset[0]);
 	pci_add_resource_offset(&resources, &vmd->resources[2], offset[1]);
 
-	vmd->bus = pci_create_root_bus(&vmd->dev->dev, busn_start, &vmd_ops,
+	vmd->bus = vmd_create_root_bus(&vmd->dev->dev, busn_start, &vmd_ops,
 				       sd, &resources);
 	if (!vmd->bus) {
 		pci_free_resource_list(&resources);
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 5ca7d5941ad0..eaedb4fe143a 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -2909,35 +2909,6 @@ void __weak pcibios_remove_bus(struct pci_bus *bus)
 {
 }
 
-struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
-		struct pci_ops *ops, void *sysdata, struct list_head *resources)
-{
-	int error;
-	struct pci_host_bridge *bridge;
-
-	bridge = pci_alloc_host_bridge(0);
-	if (!bridge)
-		return NULL;
-
-	bridge->dev.parent = parent;
-
-	list_splice_init(resources, &bridge->windows);
-	bridge->sysdata = sysdata;
-	bridge->busnr = bus;
-	bridge->ops = ops;
-
-	error = pci_register_host_bridge(bridge);
-	if (error < 0)
-		goto err_out;
-
-	return bridge->bus;
-
-err_out:
-	kfree(bridge);
-	return NULL;
-}
-EXPORT_SYMBOL_GPL(pci_create_root_bus);
-
 int pci_host_probe(struct pci_host_bridge *bridge)
 {
 	struct pci_bus *bus, *child;
diff --git a/include/linux/pci.h b/include/linux/pci.h
index e1337148cf9f..1dd8a3ecf753 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -905,9 +905,6 @@ void pcibios_bus_to_resource(struct pci_bus *bus, struct resource *res,
 void pcibios_scan_specific_bus(int busn);
 struct pci_bus *pci_find_bus(int domain, int busnr);
 void pci_bus_add_devices(const struct pci_bus *bus);
-struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
-				    struct pci_ops *ops, void *sysdata,
-				    struct list_head *resources);
 int pci_host_probe(struct pci_host_bridge *bridge);
 int pci_register_host_bridge(struct pci_host_bridge *);
 int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int busmax);
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [RFC 06/15] powerpc/pci: fold pci_create_root_bus into pcibios_scan_phb
  2018-08-17 10:26 [RFC 00/15] PCI: turn some __weak functions into callbacks Arnd Bergmann
                   ` (4 preceding siblings ...)
  2018-08-17 10:26 ` [RFC 05/15] PCI: move pci_create_root_bus into callers Arnd Bergmann
@ 2018-08-17 10:26 ` Arnd Bergmann
  2018-08-17 10:26 ` [RFC 07/15] PCI/ACPI: clean up acpi_pci_root_create() Arnd Bergmann
                   ` (10 subsequent siblings)
  16 siblings, 0 replies; 28+ messages in thread
From: Arnd Bergmann @ 2018-08-17 10:26 UTC (permalink / raw)
  To: linux-pci, Bjorn Helgaas
  Cc: linux-kernel, Christoph Hellwig, Lorenzo Pieralisi,
	Benjamin Herrenschmidt, linuxppc-dev, linux-acpi, Arnd Bergmann

This slightly simplifies the pcibios_scan_phb() implementation, and
gives us an easier point to add further fields in the pci_host_bridge
structure.

I tried removing fields that are duplicated between pci_host_bridge
and pci_controller (which really serve the same purpose), but
ran into the problem that we can't call pci_alloc_host_bridge()
as early as pcibios_alloc_controller(). Some more refactoring
is needed for that, but it could noticably clean the powerpc code
up more.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 arch/powerpc/include/asm/pci-bridge.h |  3 ++
 arch/powerpc/kernel/pci-common.c      | 72 ++++++++++-----------------
 2 files changed, 30 insertions(+), 45 deletions(-)

diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
index 94d449031b18..42ae567084d9 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -51,8 +51,11 @@ struct pci_controller_ops {
 
 /*
  * Structure of a PCI controller (host bridge)
+ * Some members here are duplicated in struct pci_host_bridge
+ * and should be moved there.
  */
 struct pci_controller {
+	struct pci_host_bridge *bridge;
 	struct pci_bus *bus;
 	char is_dynamic;
 #ifdef CONFIG_PPC64
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 57ca621a32f4..096011ec8670 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -1587,81 +1587,63 @@ struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus)
 	return of_node_get(hose->dn);
 }
 
-static struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
-		struct pci_ops *ops, void *sysdata, struct list_head *resources)
-{
-	int error;
-	struct pci_host_bridge *bridge;
-
-	bridge = pci_alloc_host_bridge(0);
-	if (!bridge)
-		return NULL;
-
-	bridge->dev.parent = parent;
-
-	list_splice_init(resources, &bridge->windows);
-	bridge->sysdata = sysdata;
-	bridge->busnr = bus;
-	bridge->ops = ops;
-
-	error = pci_register_host_bridge(bridge);
-	if (error < 0)
-		goto err_out;
-
-	return bridge->bus;
-
-err_out:
-	kfree(bridge);
-	return NULL;
-}
-
 /**
  * pci_scan_phb - Given a pci_controller, setup and scan the PCI bus
  * @hose: Pointer to the PCI host controller instance structure
  */
 void pcibios_scan_phb(struct pci_controller *hose)
 {
-	LIST_HEAD(resources);
-	struct pci_bus *bus;
 	struct device_node *node = hose->dn;
 	int mode;
+	struct pci_host_bridge *bridge;
+	int error;
 
 	pr_debug("PCI: Scanning PHB %pOF\n", node);
 
+	/* The allocation should ideally be done in pcibios_alloc_controller(),
+	 * but pci_alloc_host_bridge() requires slab to work first */
+	bridge = pci_alloc_host_bridge(0);
+	if (!bridge)
+		return;
+
 	/* Get some IO space for the new PHB */
 	pcibios_setup_phb_io_space(hose);
 
 	/* Wire up PHB bus resources */
-	pcibios_setup_phb_resources(hose, &resources);
+	pcibios_setup_phb_resources(hose, &bridge->windows);
 
 	hose->busn.start = hose->first_busno;
 	hose->busn.end	 = hose->last_busno;
 	hose->busn.flags = IORESOURCE_BUS;
-	pci_add_resource(&resources, &hose->busn);
+	pci_add_resource(&bridge->windows, &hose->busn);
+
+	bridge->dev.parent = hose->parent;
+	bridge->sysdata = hose;
+	bridge->busnr = hose->first_busno;
+	bridge->ops = hose->ops;
 
-	/* Create an empty bus for the toplevel */
-	bus = pci_create_root_bus(hose->parent, hose->first_busno,
-				  hose->ops, hose, &resources);
-	if (bus == NULL) {
+	error = pci_register_host_bridge(bridge);
+	if (error < 0) {
 		pr_err("Failed to create bus for PCI domain %04x\n",
 			hose->global_number);
-		pci_free_resource_list(&resources);
+		pci_free_host_bridge(bridge);
 		return;
 	}
-	hose->bus = bus;
+	hose->bridge = bridge;
+	hose->bus = bridge->bus;
 
 	/* Get probe mode and perform scan */
 	mode = PCI_PROBE_NORMAL;
 	if (node && hose->controller_ops.probe_mode)
-		mode = hose->controller_ops.probe_mode(bus);
+		mode = hose->controller_ops.probe_mode(bridge->bus);
 	pr_debug("    probe mode: %d\n", mode);
 	if (mode == PCI_PROBE_DEVTREE)
-		of_scan_bus(node, bus);
+		of_scan_bus(node, bridge->bus);
 
 	if (mode == PCI_PROBE_NORMAL) {
-		pci_bus_update_busn_res_end(bus, 255);
-		hose->last_busno = pci_scan_child_bus(bus);
-		pci_bus_update_busn_res_end(bus, hose->last_busno);
+		pci_bus_update_busn_res_end(bridge->bus, 255);
+		hose->last_busno = pci_scan_child_bus(bridge->bus);
+		pci_bus_update_busn_res_end(bridge->bus, hose->last_busno);
 	}
 
 	/* Platform gets a chance to do some global fixups before
@@ -1671,9 +1653,9 @@ void pcibios_scan_phb(struct pci_controller *hose)
 		ppc_md.pcibios_fixup_phb(hose);
 
 	/* Configure PCI Express settings */
-	if (bus && !pci_has_flag(PCI_PROBE_ONLY)) {
+	if (bridge->bus && !pci_has_flag(PCI_PROBE_ONLY)) {
 		struct pci_bus *child;
-		list_for_each_entry(child, &bus->children, node)
+		list_for_each_entry(child, &bridge->bus->children, node)
 			pcie_bus_configure_settings(child);
 	}
 }
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [RFC 07/15] PCI/ACPI: clean up acpi_pci_root_create()
  2018-08-17 10:26 [RFC 00/15] PCI: turn some __weak functions into callbacks Arnd Bergmann
                   ` (5 preceding siblings ...)
  2018-08-17 10:26 ` [RFC 06/15] powerpc/pci: fold pci_create_root_bus into pcibios_scan_phb Arnd Bergmann
@ 2018-08-17 10:26 ` Arnd Bergmann
  2018-08-20  8:23   ` Rafael J. Wysocki
  2018-08-17 10:26 ` [RFC 08/15] x86: PCI: clean up pcibios_scan_root() Arnd Bergmann
                   ` (9 subsequent siblings)
  16 siblings, 1 reply; 28+ messages in thread
From: Arnd Bergmann @ 2018-08-17 10:26 UTC (permalink / raw)
  To: linux-pci, Bjorn Helgaas
  Cc: linux-kernel, Christoph Hellwig, Lorenzo Pieralisi,
	Benjamin Herrenschmidt, linuxppc-dev, linux-acpi, Arnd Bergmann

The acpi_pci_create_root_bus() can be fully integrated into
acpi_pci_root_create(), improving a few things:

* We can call pci_scan_root_bus_bridge(), which registers and
  scans the bridge in one step.
* After a failure in pci_register_host_bridge(), we correctly
  clean up the resources.
* The bridge settings (release function, flags, operations etc)
  can get set up before registering the bridge.
* Further cleanup would be possible, removing duplication between
  pci_host_bridge and some ACPI structures.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 drivers/acpi/pci_root.c | 68 +++++++++++++++--------------------------
 1 file changed, 24 insertions(+), 44 deletions(-)

diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 85dbcf47015b..5f73de3b67c8 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -873,34 +873,6 @@ static void acpi_pci_root_release_info(struct pci_host_bridge *bridge)
 	__acpi_pci_root_release_info(bridge->release_data);
 }
 
-static struct pci_bus *acpi_pci_create_root_bus(struct device *parent, int bus,
-		struct pci_ops *ops, void *sysdata, struct list_head *resources)
-{
-	int error;
-	struct pci_host_bridge *bridge;
-
-	bridge = pci_alloc_host_bridge(0);
-	if (!bridge)
-		return NULL;
-
-	bridge->dev.parent = parent;
-
-	list_splice_init(resources, &bridge->windows);
-	bridge->sysdata = sysdata;
-	bridge->busnr = bus;
-	bridge->ops = ops;
-
-	error = pci_register_host_bridge(bridge);
-	if (error < 0)
-		goto err_out;
-
-	return bridge->bus;
-
-err_out:
-	kfree(bridge);
-	return NULL;
-}
-
 struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
 				     struct acpi_pci_root_ops *ops,
 				     struct acpi_pci_root_info *info,
@@ -909,8 +881,7 @@ struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
 	int ret, busnum = root->secondary.start;
 	struct acpi_device *device = root->device;
 	int node = acpi_get_node(device->handle);
-	struct pci_bus *bus;
-	struct pci_host_bridge *host_bridge;
+	struct pci_host_bridge *bridge;
 
 	info->root = root;
 	info->bridge = device;
@@ -930,30 +901,39 @@ struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
 
 	pci_acpi_root_add_resources(info);
 	pci_add_resource(&info->resources, &root->secondary);
-	bus = acpi_pci_create_root_bus(NULL, busnum, ops->pci_ops,
-				  sysdata, &info->resources);
-	if (!bus)
+
+	bridge = pci_alloc_host_bridge(0);
+	if (!bridge)
 		goto out_release_info;
 
-	host_bridge = to_pci_host_bridge(bus->bridge);
+	list_splice_init(&info->resources, &bridge->windows);
+	bridge->sysdata = sysdata;
+	bridge->busnr = busnum;
+	bridge->ops = ops->pci_ops;
+	pci_set_host_bridge_release(bridge, acpi_pci_root_release_info,
+				    info);
+
 	if (!(root->osc_control_set & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL))
-		host_bridge->native_pcie_hotplug = 0;
+		bridge->native_pcie_hotplug = 0;
 	if (!(root->osc_control_set & OSC_PCI_SHPC_NATIVE_HP_CONTROL))
-		host_bridge->native_shpc_hotplug = 0;
+		bridge->native_shpc_hotplug = 0;
 	if (!(root->osc_control_set & OSC_PCI_EXPRESS_AER_CONTROL))
-		host_bridge->native_aer = 0;
+		bridge->native_aer = 0;
 	if (!(root->osc_control_set & OSC_PCI_EXPRESS_PME_CONTROL))
-		host_bridge->native_pme = 0;
+		bridge->native_pme = 0;
 	if (!(root->osc_control_set & OSC_PCI_EXPRESS_LTR_CONTROL))
-		host_bridge->native_ltr = 0;
+		bridge->native_ltr = 0;
+
+	ret = pci_scan_root_bus_bridge(bridge);
+	if (ret < 0)
+		goto out_release_bridge;
 
-	pci_scan_child_bus(bus);
-	pci_set_host_bridge_release(host_bridge, acpi_pci_root_release_info,
-				    info);
 	if (node != NUMA_NO_NODE)
-		dev_printk(KERN_DEBUG, &bus->dev, "on NUMA node %d\n", node);
-	return bus;
+		dev_printk(KERN_DEBUG, &bridge->bus->dev, "on NUMA node %d\n", node);
+	return bridge->bus;
 
+out_release_bridge:
+	pci_free_host_bridge(bridge);
 out_release_info:
 	__acpi_pci_root_release_info(info);
 	return NULL;
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [RFC 08/15] x86: PCI: clean up pcibios_scan_root()
  2018-08-17 10:26 [RFC 00/15] PCI: turn some __weak functions into callbacks Arnd Bergmann
                   ` (6 preceding siblings ...)
  2018-08-17 10:26 ` [RFC 07/15] PCI/ACPI: clean up acpi_pci_root_create() Arnd Bergmann
@ 2018-08-17 10:26 ` Arnd Bergmann
  2018-08-20  8:31   ` Rafael J. Wysocki
  2018-08-17 10:26 ` [RFC 09/15] PCI: xenfront: clean up pcifront_scan_root() Arnd Bergmann
                   ` (8 subsequent siblings)
  16 siblings, 1 reply; 28+ messages in thread
From: Arnd Bergmann @ 2018-08-17 10:26 UTC (permalink / raw)
  To: linux-pci, Bjorn Helgaas
  Cc: linux-kernel, Christoph Hellwig, Lorenzo Pieralisi,
	Benjamin Herrenschmidt, linuxppc-dev, linux-acpi, Arnd Bergmann

pcibios_scan_root() is now just a wrapper around pci_scan_root_bus(),
and merging the two into one makes it shorter and more readable.

We can also take advantage of pci_alloc_host_bridge() doing the
allocation of the sysdata for us, which helps if we ever want to
allow hot-unplugging the host bridge itself.

We might be able to simplify it further using pci_host_probe(),
but I wasn't sure about the resource registration there.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 arch/x86/pci/common.c | 53 ++++++++++++++-----------------------------
 1 file changed, 17 insertions(+), 36 deletions(-)

diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index e740d9aa4024..920d0885434c 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -453,54 +453,35 @@ void __init dmi_check_pciprobe(void)
 	dmi_check_system(pciprobe_dmi_table);
 }
 
-static struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
-		struct pci_ops *ops, void *sysdata, struct list_head *resources)
+void pcibios_scan_root(int busnum)
 {
+	struct pci_sysdata *sd;
 	struct pci_host_bridge *bridge;
 	int error;
 
-	bridge = pci_alloc_host_bridge(0);
-	if (!bridge)
-		return NULL;
+	bridge = pci_alloc_host_bridge(sizeof(sd));
+	if (!bridge) {
+		printk(KERN_ERR "PCI: OOM, skipping PCI bus %02x\n", busnum);
+		return;
+	}
+	sd = pci_host_bridge_priv(bridge);
 
-	list_splice_init(resources, &bridge->windows);
-	bridge->dev.parent = parent;
-	bridge->sysdata = sysdata;
-	bridge->busnr = bus;
-	bridge->ops = ops;
+	sd->node = x86_pci_root_bus_node(busnum);
+	x86_pci_root_bus_resources(busnum, &bridge->windows);
+	bridge->sysdata = sd;
+	bridge->busnr = busnum;
+	bridge->ops = &pci_root_ops;
 
+	printk(KERN_DEBUG "PCI: Probing PCI hardware (bus %02x)\n", busnum);
 	error = pci_scan_root_bus_bridge(bridge);
 	if (error < 0)
 		goto err_out;
 
-	return bridge->bus;
+	pci_bus_add_devices(bridge->bus);
+	return;
 
 err_out:
-	kfree(bridge);
-	return NULL;
-}
-
-void pcibios_scan_root(int busnum)
-{
-	struct pci_bus *bus;
-	struct pci_sysdata *sd;
-	LIST_HEAD(resources);
-
-	sd = kzalloc(sizeof(*sd), GFP_KERNEL);
-	if (!sd) {
-		printk(KERN_ERR "PCI: OOM, skipping PCI bus %02x\n", busnum);
-		return;
-	}
-	sd->node = x86_pci_root_bus_node(busnum);
-	x86_pci_root_bus_resources(busnum, &resources);
-	printk(KERN_DEBUG "PCI: Probing PCI hardware (bus %02x)\n", busnum);
-	bus = pci_scan_root_bus(NULL, busnum, &pci_root_ops, sd, &resources);
-	if (!bus) {
-		pci_free_resource_list(&resources);
-		kfree(sd);
-		return;
-	}
-	pci_bus_add_devices(bus);
+	pci_free_host_bridge(bridge);
 }
 
 void __init pcibios_set_cache_line_size(void)
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [RFC 09/15] PCI: xenfront: clean up pcifront_scan_root()
  2018-08-17 10:26 [RFC 00/15] PCI: turn some __weak functions into callbacks Arnd Bergmann
                   ` (7 preceding siblings ...)
  2018-08-17 10:26 ` [RFC 08/15] x86: PCI: clean up pcibios_scan_root() Arnd Bergmann
@ 2018-08-17 10:26 ` Arnd Bergmann
  2018-08-17 10:26 ` [RFC 10/15] sparc/PCI: simplify pci_scan_one_pbm Arnd Bergmann
                   ` (7 subsequent siblings)
  16 siblings, 0 replies; 28+ messages in thread
From: Arnd Bergmann @ 2018-08-17 10:26 UTC (permalink / raw)
  To: linux-pci, Bjorn Helgaas
  Cc: linux-kernel, Christoph Hellwig, Lorenzo Pieralisi,
	Benjamin Herrenschmidt, linuxppc-dev, linux-acpi, Arnd Bergmann

Merging pci_scan_root_bus() into pcifront_scan_root() simplifies
the implementation and makes it more readable. We can allocate
the pcifront_sd structure along with the bridge structure, which
helps manage its lifetime rules so we don't free it before the
device has been released.

There are two small issues that I noticed that could be improved:

- It seems we unregister the 'bus' device that is a child of the
  'pci_host_bridge' device after we unregister its parent in
  pcifront_free_roots(), which seems odd.
- We probably don't need an extra pci_bus_entry list at all,
  but could instead walk the children of the pcifront_device,
  which are all pci_host_bridge devices.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 drivers/pci/xen-pcifront.c | 67 ++++++++++++--------------------------
 1 file changed, 21 insertions(+), 46 deletions(-)

diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c
index 24070e1c5f22..a5eb6cb02bec 100644
--- a/drivers/pci/xen-pcifront.c
+++ b/drivers/pci/xen-pcifront.c
@@ -443,40 +443,12 @@ static int pcifront_scan_bus(struct pcifront_device *pdev,
 	return 0;
 }
 
-static struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
-		struct pci_ops *ops, void *sysdata, struct list_head *resources)
-{
-	struct pci_host_bridge *bridge;
-	int error;
-
-	bridge = pci_alloc_host_bridge(0);
-	if (!bridge)
-		return NULL;
-
-	list_splice_init(resources, &bridge->windows);
-	bridge->dev.parent = parent;
-	bridge->sysdata = sysdata;
-	bridge->busnr = bus;
-	bridge->ops = ops;
-
-	error = pci_scan_root_bus_bridge(bridge);
-	if (error < 0)
-		goto err_out;
-
-	return bridge->bus;
-
-err_out:
-	kfree(bridge);
-	return NULL;
-}
-
 static int pcifront_scan_root(struct pcifront_device *pdev,
 				 unsigned int domain, unsigned int bus)
 {
-	struct pci_bus *b;
-	LIST_HEAD(resources);
 	struct pcifront_sd *sd = NULL;
 	struct pci_bus_entry *bus_entry = NULL;
+	struct pci_host_bridge *bridge;
 	int err = 0;
 	static struct resource busn_res = {
 		.start = 0,
@@ -498,50 +470,55 @@ static int pcifront_scan_root(struct pcifront_device *pdev,
 	dev_info(&pdev->xdev->dev, "Creating PCI Frontend Bus %04x:%02x\n",
 		 domain, bus);
 
+	bridge = pci_alloc_host_bridge(sizeof(*sd));
+	if (!bridge)
+		return -ENOMEM;
+
 	bus_entry = kzalloc(sizeof(*bus_entry), GFP_KERNEL);
-	sd = kzalloc(sizeof(*sd), GFP_KERNEL);
-	if (!bus_entry || !sd) {
+	sd = pci_host_bridge_priv(bridge);
+	if (!bus_entry) {
 		err = -ENOMEM;
 		goto err_out;
 	}
-	pci_add_resource(&resources, &ioport_resource);
-	pci_add_resource(&resources, &iomem_resource);
-	pci_add_resource(&resources, &busn_res);
+	pci_add_resource(&bridge->windows, &ioport_resource);
+	pci_add_resource(&bridge->windows, &iomem_resource);
+	pci_add_resource(&bridge->windows, &busn_res);
 	pcifront_init_sd(sd, domain, bus, pdev);
+	bridge->dev.parent = &pdev->xdev->dev;
+	bridge->sysdata = sd;
+	bridge->busnr = bus;
+	bridge->ops = &pcifront_bus_ops;
 
 	pci_lock_rescan_remove();
 
-	b = pci_scan_root_bus(&pdev->xdev->dev, bus,
-				  &pcifront_bus_ops, sd, &resources);
-	if (!b) {
+	err = pci_scan_root_bus_bridge(bridge);
+	if (err < 0) {
 		dev_err(&pdev->xdev->dev,
 			"Error creating PCI Frontend Bus!\n");
-		err = -ENOMEM;
 		pci_unlock_rescan_remove();
-		pci_free_resource_list(&resources);
 		goto err_out;
 	}
 
-	bus_entry->bus = b;
+	bus_entry->bus = bridge->bus;
 
 	list_add(&bus_entry->list, &pdev->root_buses);
 
 	/* pci_scan_root_bus skips devices which do not have a
 	* devfn==0. The pcifront_scan_bus enumerates all devfn. */
-	err = pcifront_scan_bus(pdev, domain, bus, b);
+	err = pcifront_scan_bus(pdev, domain, bus, bridge->bus);
 
 	/* Claim resources before going "live" with our devices */
-	pci_walk_bus(b, pcifront_claim_resource, pdev);
+	pci_walk_bus(bridge->bus, pcifront_claim_resource, pdev);
 
 	/* Create SysFS and notify udev of the devices. Aka: "going live" */
-	pci_bus_add_devices(b);
+	pci_bus_add_devices(bridge->bus);
 
 	pci_unlock_rescan_remove();
 	return err;
 
 err_out:
+	pci_free_host_bridge(bridge);
 	kfree(bus_entry);
-	kfree(sd);
 
 	return err;
 }
@@ -605,8 +582,6 @@ static void pcifront_free_roots(struct pcifront_device *pdev)
 
 		free_root_bus_devs(bus_entry->bus);
 
-		kfree(bus_entry->bus->sysdata);
-
 		device_unregister(bus_entry->bus->bridge);
 		pci_remove_bus(bus_entry->bus);
 
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [RFC 10/15] sparc/PCI: simplify pci_scan_one_pbm
  2018-08-17 10:26 [RFC 00/15] PCI: turn some __weak functions into callbacks Arnd Bergmann
                   ` (8 preceding siblings ...)
  2018-08-17 10:26 ` [RFC 09/15] PCI: xenfront: clean up pcifront_scan_root() Arnd Bergmann
@ 2018-08-17 10:26 ` Arnd Bergmann
  2018-08-17 10:26 ` [RFC 11/15] PCI: hyperv: convert to pci_scan_root_bus_bridge Arnd Bergmann
                   ` (6 subsequent siblings)
  16 siblings, 0 replies; 28+ messages in thread
From: Arnd Bergmann @ 2018-08-17 10:26 UTC (permalink / raw)
  To: linux-pci, Bjorn Helgaas
  Cc: linux-kernel, Christoph Hellwig, Lorenzo Pieralisi,
	Benjamin Herrenschmidt, linuxppc-dev, linux-acpi, Arnd Bergmann

We no longer need a separate pci_create_root_bus() function, and
merging it into pci_scan_one_pbm() makes the implementation easier
to understand.

A possible future cleanup would move the allocation of the
pci_host_bridge structure into the callers of pci_scan_one_pbm,
and avoid duplication between pci_host_bridge and pci_pbm_info
fields.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 arch/sparc/kernel/pci.c | 62 ++++++++++++++---------------------------
 1 file changed, 21 insertions(+), 41 deletions(-)

diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
index afbce59d9231..0d34fb2ac55b 100644
--- a/arch/sparc/kernel/pci.c
+++ b/arch/sparc/kernel/pci.c
@@ -691,70 +691,50 @@ static void pci_claim_bus_resources(struct pci_bus *bus)
 		pci_claim_bus_resources(child_bus);
 }
 
-static struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
-		struct pci_ops *ops, void *sysdata, struct list_head *resources)
+struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm,
+				 struct device *parent)
 {
-	int error;
+	struct device_node *node = pbm->op->dev.of_node;
 	struct pci_host_bridge *bridge;
+	int ret;
 
 	bridge = pci_alloc_host_bridge(0);
 	if (!bridge)
 		return NULL;
 
 	bridge->dev.parent = parent;
+	bridge->sysdata = pbm;
+	bridge->busnr = pbm->pci_first_busno;
+	bridge->ops = pbm->pci_ops;
 
-	list_splice_init(resources, &bridge->windows);
-	bridge->sysdata = sysdata;
-	bridge->busnr = bus;
-	bridge->ops = ops;
-
-	error = pci_register_host_bridge(bridge);
-	if (error < 0)
-		goto err_out;
-
-	return bridge->bus;
-
-err_out:
-	kfree(bridge);
-	return NULL;
-}
-
-struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm,
-				 struct device *parent)
-{
-	LIST_HEAD(resources);
-	struct device_node *node = pbm->op->dev.of_node;
-	struct pci_bus *bus;
-
-	printk("PCI: Scanning PBM %s\n", node->full_name);
-
-	pci_add_resource_offset(&resources, &pbm->io_space,
+	pci_add_resource_offset(&bridge->windows, &pbm->io_space,
 				pbm->io_offset);
-	pci_add_resource_offset(&resources, &pbm->mem_space,
+	pci_add_resource_offset(&bridge->windows, &pbm->mem_space,
 				pbm->mem_offset);
 	if (pbm->mem64_space.flags)
-		pci_add_resource_offset(&resources, &pbm->mem64_space,
+		pci_add_resource_offset(&bridge->windows, &pbm->mem64_space,
 					pbm->mem64_offset);
 	pbm->busn.start = pbm->pci_first_busno;
 	pbm->busn.end	= pbm->pci_last_busno;
 	pbm->busn.flags	= IORESOURCE_BUS;
-	pci_add_resource(&resources, &pbm->busn);
-	bus = pci_create_root_bus(parent, pbm->pci_first_busno, pbm->pci_ops,
-				  pbm, &resources);
-	if (!bus) {
+	pci_add_resource(&bridge->windows, &pbm->busn);
+
+	printk("PCI: Scanning PBM %s\n", node->full_name);
+	ret = pci_register_host_bridge(bridge);
+	if (!ret) {
 		printk(KERN_ERR "Failed to create bus for %s\n",
 		       node->full_name);
-		pci_free_resource_list(&resources);
+		pci_free_host_bridge(bridge);
 		return NULL;
 	}
 
-	pci_of_scan_bus(pbm, node, bus);
-	pci_bus_register_of_sysfs(bus);
+	pci_of_scan_bus(pbm, node, bridge->bus);
+	pci_bus_register_of_sysfs(bridge->bus);
 
-	pci_claim_bus_resources(bus);
+	pci_claim_bus_resources(bridge->bus);
 
-	pci_bus_add_devices(bus);
-	return bus;
+	pci_bus_add_devices(bridge->bus);
+	return bridge->bus;
 }
 
 int pcibios_enable_device(struct pci_dev *dev, int mask)
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [RFC 11/15] PCI: hyperv: convert to pci_scan_root_bus_bridge
  2018-08-17 10:26 [RFC 00/15] PCI: turn some __weak functions into callbacks Arnd Bergmann
                   ` (9 preceding siblings ...)
  2018-08-17 10:26 ` [RFC 10/15] sparc/PCI: simplify pci_scan_one_pbm Arnd Bergmann
@ 2018-08-17 10:26 ` Arnd Bergmann
  2018-08-17 10:26 ` [RFC 12/15] PCI: make pcibios_bus_add_device() a callback function Arnd Bergmann
                   ` (5 subsequent siblings)
  16 siblings, 0 replies; 28+ messages in thread
From: Arnd Bergmann @ 2018-08-17 10:26 UTC (permalink / raw)
  To: linux-pci, Bjorn Helgaas
  Cc: linux-kernel, Christoph Hellwig, Lorenzo Pieralisi,
	Benjamin Herrenschmidt, linuxppc-dev, linux-acpi, Arnd Bergmann

create_root_hv_pci_bus() uses a rather generic method of probing the host
bridge, which can be simplified by just calling pci_scan_root_bus_bridge()
after setting up the pci_host_bridge structure.

Since we can no longer assign hbus->pci_bus in the middle, I just remove
that member completely and use the pci_host_bridge instead.

Ideally we'd convert it to pci_host_probe() for simplicity, but
that is a bit different and I could not easily test it. Using
pci_scan_root_bus_bridge should not change the behavior at all.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 drivers/pci/controller/pci-hyperv.c | 75 +++++++++++------------------
 1 file changed, 28 insertions(+), 47 deletions(-)

diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c
index df7cddea8e30..49586aefa38b 100644
--- a/drivers/pci/controller/pci-hyperv.c
+++ b/drivers/pci/controller/pci-hyperv.c
@@ -443,7 +443,7 @@ struct hv_pcibus_device {
 	struct resource *high_mmio_res;
 	struct completion *survey_event;
 	struct completion remove_event;
-	struct pci_bus *pci_bus;
+	struct pci_host_bridge *bridge;
 	spinlock_t config_lock;	/* Avoid two threads writing index page */
 	spinlock_t device_list_lock;	/* Protect lists below */
 	void __iomem *cfg_addr;
@@ -1457,34 +1457,6 @@ static void prepopulate_bars(struct hv_pcibus_device *hbus)
 	spin_unlock_irqrestore(&hbus->device_list_lock, flags);
 }
 
-static struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
-		struct pci_ops *ops, void *sysdata, struct list_head *resources)
-{
-	int error;
-	struct pci_host_bridge *bridge;
-
-	bridge = pci_alloc_host_bridge(0);
-	if (!bridge)
-		return NULL;
-
-	bridge->dev.parent = parent;
-
-	list_splice_init(resources, &bridge->windows);
-	bridge->sysdata = sysdata;
-	bridge->busnr = bus;
-	bridge->ops = ops;
-
-	error = pci_register_host_bridge(bridge);
-	if (error < 0)
-		goto err_out;
-
-	return bridge->bus;
-
-err_out:
-	kfree(bridge);
-	return NULL;
-}
-
 /**
  * create_root_hv_pci_bus() - Expose a new root PCI bus
  * @hbus:	Root PCI bus, as understood by this driver
@@ -1493,25 +1465,34 @@ static struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
  */
 static int create_root_hv_pci_bus(struct hv_pcibus_device *hbus)
 {
-	/* Register the device */
-	hbus->pci_bus = pci_create_root_bus(&hbus->hdev->device,
-					    0, /* bus number is always zero */
-					    &hv_pcifront_ops,
-					    &hbus->sysdata,
-					    &hbus->resources_for_children);
-	if (!hbus->pci_bus)
-		return -ENODEV;
+	struct pci_host_bridge *bridge;
+	int ret;
+
+	bridge = pci_alloc_host_bridge(0);
+	if (!bridge)
+		return -ENOMEM;
 
-	hbus->pci_bus->msi = &hbus->msi_chip;
-	hbus->pci_bus->msi->dev = &hbus->hdev->device;
+	hbus->bridge = bridge;
+	bridge->dev.parent = &hbus->hdev->device;
+	list_splice_init(&hbus->resources_for_children, &bridge->windows);
+	bridge->sysdata = &hbus->sysdata;
+	bridge->ops = &hv_pcifront_ops;
+	bridge->msi = &hbus->msi_chip;
+	bridge->msi->dev = &hbus->hdev->device;
 
 	pci_lock_rescan_remove();
-	pci_scan_child_bus(hbus->pci_bus);
-	pci_bus_assign_resources(hbus->pci_bus);
-	pci_bus_add_devices(hbus->pci_bus);
-	pci_unlock_rescan_remove();
+	/* ideally we should use pci_host_probe here */
+	ret = pci_scan_root_bus_bridge(bridge);
+	if (ret < 0) {
+		pci_free_host_bridge(bridge);
+		goto error;
+	}
+	pci_bus_assign_resources(bridge->bus);
+	pci_bus_add_devices(bridge->bus);
 	hbus->state = hv_pcibus_installed;
-	return 0;
+error:
+	pci_unlock_rescan_remove();
+	return ret;
 }
 
 struct q_res_req_compl {
@@ -1769,7 +1750,7 @@ static void pci_devices_present_work(struct work_struct *work)
 		 * because there may have been changes.
 		 */
 		pci_lock_rescan_remove();
-		pci_scan_child_bus(hbus->pci_bus);
+		pci_scan_child_bus(hbus->bridge->bus);
 		pci_unlock_rescan_remove();
 		break;
 
@@ -2669,8 +2650,8 @@ static int hv_pci_remove(struct hv_device *hdev)
 	if (hbus->state == hv_pcibus_installed) {
 		/* Remove the bus from PCI's point of view. */
 		pci_lock_rescan_remove();
-		pci_stop_root_bus(hbus->pci_bus);
-		pci_remove_root_bus(hbus->pci_bus);
+		pci_stop_root_bus(hbus->bridge->bus);
+		pci_remove_root_bus(hbus->bridge->bus);
 		pci_unlock_rescan_remove();
 		hbus->state = hv_pcibus_removed;
 	}
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [RFC 12/15] PCI: make pcibios_bus_add_device() a callback function
  2018-08-17 10:26 [RFC 00/15] PCI: turn some __weak functions into callbacks Arnd Bergmann
                   ` (10 preceding siblings ...)
  2018-08-17 10:26 ` [RFC 11/15] PCI: hyperv: convert to pci_scan_root_bus_bridge Arnd Bergmann
@ 2018-08-17 10:26 ` Arnd Bergmann
  2018-08-17 10:26 ` [RFC 13/15] PCI: turn pcibios_alloc_irq into a callback Arnd Bergmann
                   ` (4 subsequent siblings)
  16 siblings, 0 replies; 28+ messages in thread
From: Arnd Bergmann @ 2018-08-17 10:26 UTC (permalink / raw)
  To: linux-pci, Bjorn Helgaas
  Cc: linux-kernel, Christoph Hellwig, Lorenzo Pieralisi,
	Benjamin Herrenschmidt, linuxppc-dev, linux-acpi, Arnd Bergmann

Weak functions are confusion, and we can now add callback pointers
to pci host bridges for any controller, so let's make this one
a callback rather than a __weak global function.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 arch/powerpc/kernel/pci-common.c  | 7 +------
 arch/sh/drivers/pci/pci.c         | 1 +
 arch/sh/drivers/pci/pcie-sh7786.c | 3 ++-
 arch/sh/include/asm/pci.h         | 2 ++
 drivers/pci/bus.c                 | 8 +++++++-
 include/linux/pci.h               | 2 +-
 6 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 096011ec8670..afc9598e4349 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -270,12 +270,6 @@ int pcibios_sriov_disable(struct pci_dev *pdev)
 
 #endif /* CONFIG_PCI_IOV */
 
-void pcibios_bus_add_device(struct pci_dev *pdev)
-{
-	if (ppc_md.pcibios_bus_add_device)
-		ppc_md.pcibios_bus_add_device(pdev);
-}
-
 static resource_size_t pcibios_io_size(const struct pci_controller *hose)
 {
 #ifdef CONFIG_PPC64
@@ -1617,6 +1611,7 @@ void pcibios_scan_phb(struct pci_controller *hose)
 	hose->busn.flags = IORESOURCE_BUS;
 	pci_add_resource(&bridge->windows, &hose->busn);
 
+	bridge->bus_add_device = ppc_md->pcibios_bus_add_device;
 	bridge->dev.parent = hose->parent;
 	bridge->sysdata = hose;
 	bridge->busnr = hose->first_busno;
diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c
index 8256626bc53c..d5c01a86cde1 100644
--- a/arch/sh/drivers/pci/pci.c
+++ b/arch/sh/drivers/pci/pci.c
@@ -65,6 +65,7 @@ static void pcibios_scanbus(struct pci_channel *hose)
 	bridge->ops = hose->pci_ops;
 	bridge->swizzle_irq = pci_common_swizzle;
 	bridge->map_irq = pcibios_map_platform_irq;
+	bridge->bus_add_device = hose->bus_add_device;
 
 	ret = pci_scan_root_bus_bridge(bridge);
 	if (ret) {
diff --git a/arch/sh/drivers/pci/pcie-sh7786.c b/arch/sh/drivers/pci/pcie-sh7786.c
index 3d81a8b80942..ab78356681a0 100644
--- a/arch/sh/drivers/pci/pcie-sh7786.c
+++ b/arch/sh/drivers/pci/pcie-sh7786.c
@@ -122,6 +122,7 @@ extern struct pci_ops sh7786_pci_ops;
 	.reg_base	= start,					\
 	.mem_offset	= 0,						\
 	.io_offset	= 0,						\
+	.bus_add_device = sh7786_pci_bus_add_device,			\
 }
 
 static struct pci_channel sh7786_pci_channels[] = {
@@ -488,7 +489,7 @@ int pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
         return evt2irq(0xae0);
 }
 
-void pcibios_bus_add_device(struct pci_dev *pdev)
+static void sh7786_pci_bus_add_device(struct pci_dev *pdev)
 {
 	pdev->dev.dma_pfn_offset = dma_pfn_offset;
 }
diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h
index 10a36b1cf2ea..e605141cbcbe 100644
--- a/arch/sh/include/asm/pci.h
+++ b/arch/sh/include/asm/pci.h
@@ -35,6 +35,8 @@ struct pci_channel {
 	/* Optional error handling */
 	struct timer_list	err_timer, serr_timer;
 	unsigned int		err_irq, serr_irq;
+
+	void (*bus_add_device)(struct pci_dev *pdev);
 };
 
 /* arch/sh/drivers/pci/pci.c */
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index 5cb40b2518f9..45873ac1a49c 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -299,7 +299,13 @@ bool pci_bus_clip_resource(struct pci_dev *dev, int idx)
 
 void __weak pcibios_resource_survey_bus(struct pci_bus *bus) { }
 
-void __weak pcibios_bus_add_device(struct pci_dev *pdev) { }
+static void pcibios_bus_add_device(struct pci_dev *pdev)
+{
+	struct pci_host_bridge *bridge = pci_find_host_bridge(pdev->bus);
+
+	if (bridge->bus_add_device)
+		bridge->bus_add_device(pdev);
+}
 
 /**
  * pci_bus_add_device - start driver for a single device
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 1dd8a3ecf753..d1072690cb4f 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -475,6 +475,7 @@ struct pci_host_bridge {
 	u8 (*swizzle_irq)(struct pci_dev *, u8 *); /* Platform IRQ swizzler */
 	int (*map_irq)(const struct pci_dev *, u8, u8);
 	void (*release_fn)(struct pci_host_bridge *);
+	void (*bus_add_device)(struct pci_dev *pdev);
 	void		*release_data;
 	struct msi_controller *msi;
 	unsigned int	ignore_reset_delay:1;	/* For entire hierarchy */
@@ -880,7 +881,6 @@ extern struct list_head pci_root_buses;	/* List of all known PCI buses */
 int no_pci_devices(void);
 
 void pcibios_resource_survey_bus(struct pci_bus *bus);
-void pcibios_bus_add_device(struct pci_dev *pdev);
 void pcibios_add_bus(struct pci_bus *bus);
 void pcibios_remove_bus(struct pci_bus *bus);
 void pcibios_fixup_bus(struct pci_bus *);
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [RFC 13/15] PCI: turn pcibios_alloc_irq into a callback
  2018-08-17 10:26 [RFC 00/15] PCI: turn some __weak functions into callbacks Arnd Bergmann
                   ` (11 preceding siblings ...)
  2018-08-17 10:26 ` [RFC 12/15] PCI: make pcibios_bus_add_device() a callback function Arnd Bergmann
@ 2018-08-17 10:26 ` Arnd Bergmann
  2018-08-17 10:26 ` [RFC 14/15] PCI: make pcibios_root_bridge_prepare " Arnd Bergmann
                   ` (3 subsequent siblings)
  16 siblings, 0 replies; 28+ messages in thread
From: Arnd Bergmann @ 2018-08-17 10:26 UTC (permalink / raw)
  To: linux-pci, Bjorn Helgaas
  Cc: linux-kernel, Christoph Hellwig, Lorenzo Pieralisi,
	Benjamin Herrenschmidt, linuxppc-dev, linux-acpi, Arnd Bergmann

Weak functions are a bit confusing, and we can better deal with
this using a callback function. pcibios_free_irq() is actually
completely unused, but it seems better to treat it the same way
as the allocation, unless we want to remove it completely.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 arch/arm64/kernel/pci.c  | 16 +++-------------
 drivers/pci/pci-driver.c | 13 +++++++++++--
 include/linux/pci.h      |  2 ++
 3 files changed, 16 insertions(+), 15 deletions(-)

diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c
index 0e2ea1c78542..3d196c68e362 100644
--- a/arch/arm64/kernel/pci.c
+++ b/arch/arm64/kernel/pci.c
@@ -22,19 +22,6 @@
 #include <linux/pci-ecam.h>
 #include <linux/slab.h>
 
-#ifdef CONFIG_ACPI
-/*
- * Try to assign the IRQ number when probing a new device
- */
-int pcibios_alloc_irq(struct pci_dev *dev)
-{
-	if (!acpi_disabled)
-		acpi_pci_irq_enable(dev);
-
-	return 0;
-}
-#endif
-
 /*
  * raw_pci_read/write - Platform-specific PCI config space access.
  */
@@ -93,6 +80,9 @@ int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
 
 		ACPI_COMPANION_SET(&bridge->dev, adev);
 		set_dev_node(bus_dev, acpi_get_node(acpi_device_handle(adev)));
+
+		/* Try to assign the IRQ number when probing a new device */
+		bridge->alloc_irq = acpi_pci_irq_enable;
 	}
 
 	return 0;
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index bef17c3fca67..c96bc7bd56da 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -387,13 +387,22 @@ static int __pci_device_probe(struct pci_driver *drv, struct pci_dev *pci_dev)
 	return error;
 }
 
-int __weak pcibios_alloc_irq(struct pci_dev *dev)
+int pcibios_alloc_irq(struct pci_dev *dev)
 {
+	struct pci_host_bridge *bridge = pci_find_host_bridge(dev->bus);
+
+	if (bridge->alloc_irq)
+		return bridge->alloc_irq(dev);
+
 	return 0;
 }
 
-void __weak pcibios_free_irq(struct pci_dev *dev)
+void pcibios_free_irq(struct pci_dev *dev)
 {
+	struct pci_host_bridge *bridge = pci_find_host_bridge(dev->bus);
+
+	if (bridge->free_irq)
+		bridge->free_irq(dev);
 }
 
 #ifdef CONFIG_PCI_IOV
diff --git a/include/linux/pci.h b/include/linux/pci.h
index d1072690cb4f..1296d9fcc5da 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -476,6 +476,8 @@ struct pci_host_bridge {
 	int (*map_irq)(const struct pci_dev *, u8, u8);
 	void (*release_fn)(struct pci_host_bridge *);
 	void (*bus_add_device)(struct pci_dev *pdev);
+	int (*alloc_irq)(struct pci_dev *);
+	int (*free_irq)(struct pci_dev *);
 	void		*release_data;
 	struct msi_controller *msi;
 	unsigned int	ignore_reset_delay:1;	/* For entire hierarchy */
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [RFC 14/15] PCI: make pcibios_root_bridge_prepare a callback
  2018-08-17 10:26 [RFC 00/15] PCI: turn some __weak functions into callbacks Arnd Bergmann
                   ` (12 preceding siblings ...)
  2018-08-17 10:26 ` [RFC 13/15] PCI: turn pcibios_alloc_irq into a callback Arnd Bergmann
@ 2018-08-17 10:26 ` Arnd Bergmann
  2018-08-17 10:26 ` [RFC 15/15] PCI: make pcibios_add_bus/remove_bus callbacks Arnd Bergmann
                   ` (2 subsequent siblings)
  16 siblings, 0 replies; 28+ messages in thread
From: Arnd Bergmann @ 2018-08-17 10:26 UTC (permalink / raw)
  To: linux-pci, Bjorn Helgaas
  Cc: linux-kernel, Christoph Hellwig, Lorenzo Pieralisi,
	Benjamin Herrenschmidt, linuxppc-dev, linux-acpi, Arnd Bergmann

pcibios_root_bridge_prepare() is always used as a per host bridge
function, not per architecture.

Making it a callback in the pci_host_bridge instead lets the host
bridge implementation easily override it, and avoids the checks
in the architecture for which host bridge implementation is being
used.

Alternatively, we could probably just call the pcibios_root_bridge_prepare
after alloc_pci_host_bridge() here and get rid of it as a generic
interface altogether, but doing that has a slightly higher chance
of breaking something subtle.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 arch/arm64/kernel/pci.c          | 18 ++++++++----------
 arch/ia64/pci/pci.c              | 15 ++++-----------
 arch/powerpc/kernel/pci-common.c |  9 +--------
 arch/x86/pci/acpi.c              | 15 ++++-----------
 drivers/acpi/pci_root.c          |  1 +
 drivers/pci/probe.c              | 28 ++++++++++++++++------------
 include/linux/acpi.h             |  2 ++
 include/linux/pci.h              |  3 +--
 8 files changed, 37 insertions(+), 54 deletions(-)

diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c
index 3d196c68e362..8958a7c32a9f 100644
--- a/arch/arm64/kernel/pci.c
+++ b/arch/arm64/kernel/pci.c
@@ -71,19 +71,17 @@ int acpi_pci_bus_find_domain_nr(struct pci_bus *bus)
 	return root->segment;
 }
 
-int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
+int acpi_pci_root_bridge_prepare(struct pci_host_bridge *bridge)
 {
-	if (!acpi_disabled) {
-		struct pci_config_window *cfg = bridge->bus->sysdata;
-		struct acpi_device *adev = to_acpi_device(cfg->parent);
-		struct device *bus_dev = &bridge->bus->dev;
+	struct pci_config_window *cfg = bridge->bus->sysdata;
+	struct acpi_device *adev = to_acpi_device(cfg->parent);
+	struct device *bus_dev = &bridge->bus->dev;
 
-		ACPI_COMPANION_SET(&bridge->dev, adev);
-		set_dev_node(bus_dev, acpi_get_node(acpi_device_handle(adev)));
+	ACPI_COMPANION_SET(&bridge->dev, adev);
+	set_dev_node(bus_dev, acpi_get_node(acpi_device_handle(adev)));
 
-		/* Try to assign the IRQ number when probing a new device */
-		bridge->alloc_irq = acpi_pci_irq_enable;
-	}
+	/* Try to assign the IRQ number when probing a new device */
+	bridge->alloc_irq = acpi_pci_irq_enable;
 
 	return 0;
 }
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index 7ccc64d5fe3e..511b8a058d80 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -308,18 +308,11 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
 				    &info->common, &info->controller);
 }
 
-int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
+int acpi_pci_root_bridge_prepare(struct pci_host_bridge *bridge)
 {
-	/*
-	 * We pass NULL as parent to pci_create_root_bus(), so if it is not NULL
-	 * here, pci_create_root_bus() has been called by someone else and
-	 * sysdata is likely to be different from what we expect.  Let it go in
-	 * that case.
-	 */
-	if (!bridge->dev.parent) {
-		struct pci_controller *controller = bridge->bus->sysdata;
-		ACPI_COMPANION_SET(&bridge->dev, controller->companion);
-	}
+	struct pci_controller *controller = bridge->bus->sysdata;
+	ACPI_COMPANION_SET(&bridge->dev, controller->companion);
+
 	return 0;
 }
 
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index afc9598e4349..5e5c6dd7ebe8 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -771,14 +771,6 @@ int pci_proc_domain(struct pci_bus *bus)
 	return 1;
 }
 
-int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
-{
-	if (ppc_md.pcibios_root_bridge_prepare)
-		return ppc_md.pcibios_root_bridge_prepare(bridge);
-
-	return 0;
-}
-
 /* This header fixup will do the resource fixup for all devices as they are
  * probed, but not for bridge ranges
  */
@@ -1612,6 +1604,7 @@ void pcibios_scan_phb(struct pci_controller *hose)
 	pci_add_resource(&bridge->windows, &hose->busn);
 
 	bridge->bus_add_device = ppc_md->pcibios_bus_add_device;
+	bridge->prepare = ppc_md->pcibios_root_bridge_prepare;
 	bridge->dev.parent = hose->parent;
 	bridge->sysdata = hose;
 	bridge->busnr = hose->first_busno;
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c
index 5559dcaddd5e..041b2003707c 100644
--- a/arch/x86/pci/acpi.c
+++ b/arch/x86/pci/acpi.c
@@ -382,18 +382,11 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
 	return bus;
 }
 
-int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
+int acpi_pci_root_bridge_prepare(struct pci_host_bridge *bridge)
 {
-	/*
-	 * We pass NULL as parent to pci_create_root_bus(), so if it is not NULL
-	 * here, pci_create_root_bus() has been called by someone else and
-	 * sysdata is likely to be different from what we expect.  Let it go in
-	 * that case.
-	 */
-	if (!bridge->dev.parent) {
-		struct pci_sysdata *sd = bridge->bus->sysdata;
-		ACPI_COMPANION_SET(&bridge->dev, sd->companion);
-	}
+	struct pci_sysdata *sd = bridge->bus->sysdata;
+	ACPI_COMPANION_SET(&bridge->dev, sd->companion);
+
 	return 0;
 }
 
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 5f73de3b67c8..5da0f70c4e65 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -910,6 +910,7 @@ struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
 	bridge->sysdata = sysdata;
 	bridge->busnr = busnum;
 	bridge->ops = ops->pci_ops;
+	bridge->prepare = acpi_pci_root_bridge_prepare;
 	pci_set_host_bridge_release(bridge, acpi_pci_root_release_info,
 				    info);
 
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index eaedb4fe143a..f493d7e299e6 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -762,6 +762,22 @@ static void pci_set_bus_msi_domain(struct pci_bus *bus)
 	dev_set_msi_domain(&bus->dev, d);
 }
 
+/**
+ * pcibios_root_bridge_prepare - Platform-specific host bridge setup
+ * @bridge: Host bridge to set up
+ *
+ * Host bridge drivers can do some last minute fixups on the bridge
+ * here. Usually this should be done before calling pci_register_host_bridge
+ * though, so this hook can be removed.
+ */
+static int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
+{
+	if (bridge->prepare)
+		return bridge->prepare(bridge);
+
+	return 0;
+}
+
 /*
  * pci_register_host_bridge() - Register a host bridge without scanning
  *
@@ -2889,18 +2905,6 @@ unsigned int pci_scan_child_bus(struct pci_bus *bus)
 }
 EXPORT_SYMBOL_GPL(pci_scan_child_bus);
 
-/**
- * pcibios_root_bridge_prepare - Platform-specific host bridge setup
- * @bridge: Host bridge to set up
- *
- * Default empty implementation.  Replace with an architecture-specific setup
- * routine, if necessary.
- */
-int __weak pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
-{
-	return 0;
-}
-
 void __weak pcibios_add_bus(struct pci_bus *bus)
 {
 }
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 9967ba2e0b31..62c0278a7614 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -336,12 +336,14 @@ extern int acpi_get_override_irq(u32 gsi, int *trigger, int *polarity);
 void acpi_unregister_gsi (u32 gsi);
 
 struct pci_dev;
+struct pci_host_bridge;
 
 int acpi_pci_irq_enable (struct pci_dev *dev);
 void acpi_penalize_isa_irq(int irq, int active);
 bool acpi_isa_irq_available(int irq);
 void acpi_penalize_sci_irq(int irq, int trigger, int polarity);
 void acpi_pci_irq_disable (struct pci_dev *dev);
+int acpi_pci_root_bridge_prepare(struct pci_host_bridge *bridge);
 
 extern int ec_read(u8 addr, u8 *val);
 extern int ec_write(u8 addr, u8 val);
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 1296d9fcc5da..24216daef6f8 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -472,6 +472,7 @@ struct pci_host_bridge {
 	void		*sysdata;
 	int		busnr;
 	struct list_head windows;	/* resource_entry */
+	int (*prepare)(struct pci_host_bridge *bridge);
 	u8 (*swizzle_irq)(struct pci_dev *, u8 *); /* Platform IRQ swizzler */
 	int (*map_irq)(const struct pci_dev *, u8, u8);
 	void (*release_fn)(struct pci_host_bridge *);
@@ -518,8 +519,6 @@ void pci_set_host_bridge_release(struct pci_host_bridge *bridge,
 				 void (*release_fn)(struct pci_host_bridge *),
 				 void *release_data);
 
-int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge);
-
 /*
  * The first PCI_BRIDGE_RESOURCE_NUM PCI bus resources (those that correspond
  * to P2P or CardBus bridge windows) go in a table.  Additional ones (for
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [RFC 15/15] PCI: make pcibios_add_bus/remove_bus callbacks
  2018-08-17 10:26 [RFC 00/15] PCI: turn some __weak functions into callbacks Arnd Bergmann
                   ` (13 preceding siblings ...)
  2018-08-17 10:26 ` [RFC 14/15] PCI: make pcibios_root_bridge_prepare " Arnd Bergmann
@ 2018-08-17 10:26 ` Arnd Bergmann
  2018-08-21  6:14 ` [RFC 00/15] PCI: turn some __weak functions into callbacks Christoph Hellwig
  2018-10-02 20:59 ` Bjorn Helgaas
  16 siblings, 0 replies; 28+ messages in thread
From: Arnd Bergmann @ 2018-08-17 10:26 UTC (permalink / raw)
  To: linux-pci, Bjorn Helgaas
  Cc: linux-kernel, Christoph Hellwig, Lorenzo Pieralisi,
	Benjamin Herrenschmidt, linuxppc-dev, linux-acpi, Arnd Bergmann

These are mostly not architecture specific but are meant for particular
PCI host bridge implementations, in particular for the ACPI version.

Turn them both into callback functions that are implemented by the
APCI PCI implementation as well as the one architecture that overrides
pcibios_remove_bus.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 arch/arm64/kernel/pci.c | 10 ----------
 arch/ia64/pci/pci.c     | 10 ----------
 arch/s390/pci/pci.c     |  3 ++-
 arch/x86/pci/common.c   | 10 ----------
 drivers/acpi/pci_root.c |  2 ++
 drivers/pci/probe.c     | 12 ++++++++++--
 include/linux/pci.h     |  2 ++
 7 files changed, 16 insertions(+), 33 deletions(-)

diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c
index 8958a7c32a9f..99fac25efe88 100644
--- a/arch/arm64/kernel/pci.c
+++ b/arch/arm64/kernel/pci.c
@@ -191,14 +191,4 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
 	return bus;
 }
 
-void pcibios_add_bus(struct pci_bus *bus)
-{
-	acpi_pci_add_bus(bus);
-}
-
-void pcibios_remove_bus(struct pci_bus *bus)
-{
-	acpi_pci_remove_bus(bus);
-}
-
 #endif
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index 511b8a058d80..f47e0920d308 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -367,16 +367,6 @@ void pcibios_fixup_bus(struct pci_bus *b)
 	platform_pci_fixup_bus(b);
 }
 
-void pcibios_add_bus(struct pci_bus *bus)
-{
-	acpi_pci_add_bus(bus);
-}
-
-void pcibios_remove_bus(struct pci_bus *bus)
-{
-	acpi_pci_remove_bus(bus);
-}
-
 void pcibios_set_master (struct pci_dev *dev)
 {
 	/* No special bus mastering setup handling */
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
index b21205f131ce..120beb83b6a5 100644
--- a/arch/s390/pci/pci.c
+++ b/arch/s390/pci/pci.c
@@ -769,7 +769,7 @@ static void zpci_free_domain(struct zpci_dev *zdev)
 	spin_unlock(&zpci_domain_lock);
 }
 
-void pcibios_remove_bus(struct pci_bus *bus)
+static void zpci_remove_bus(struct pci_bus *bus)
 {
 	struct zpci_dev *zdev = get_zdev_by_bus(bus);
 
@@ -801,6 +801,7 @@ static struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
 	bridge->sysdata = sysdata;
 	bridge->busnr = bus;
 	bridge->ops = ops;
+	bridge->remove_bus = zpci_remove_bus;
 
 	error = pci_scan_root_bus_bridge(bridge);
 	if (error < 0)
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index 920d0885434c..987e6fefd5d3 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -168,16 +168,6 @@ void pcibios_fixup_bus(struct pci_bus *b)
 		pcibios_fixup_device_resources(dev);
 }
 
-void pcibios_add_bus(struct pci_bus *bus)
-{
-	acpi_pci_add_bus(bus);
-}
-
-void pcibios_remove_bus(struct pci_bus *bus)
-{
-	acpi_pci_remove_bus(bus);
-}
-
 /*
  * Only use DMI information to set this if nothing was passed
  * on the kernel command line (which was parsed earlier).
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 5da0f70c4e65..cf7a9a7bf1e7 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -911,6 +911,8 @@ struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
 	bridge->busnr = busnum;
 	bridge->ops = ops->pci_ops;
 	bridge->prepare = acpi_pci_root_bridge_prepare;
+	bridge->add_bus = acpi_pci_add_bus;
+	bridge->remove_bus = acpi_pci_remove_bus;
 	pci_set_host_bridge_release(bridge, acpi_pci_root_release_info,
 				    info);
 
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index f493d7e299e6..86a678fa8c13 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -2905,12 +2905,20 @@ unsigned int pci_scan_child_bus(struct pci_bus *bus)
 }
 EXPORT_SYMBOL_GPL(pci_scan_child_bus);
 
-void __weak pcibios_add_bus(struct pci_bus *bus)
+void pcibios_add_bus(struct pci_bus *bus)
 {
+	struct pci_host_bridge *bridge = pci_find_host_bridge(bus);
+
+	if (bridge->add_bus)
+		bridge->add_bus(bus);
 }
 
-void __weak pcibios_remove_bus(struct pci_bus *bus)
+void pcibios_remove_bus(struct pci_bus *bus)
 {
+	struct pci_host_bridge *bridge = pci_find_host_bridge(bus);
+
+	if (bridge->remove_bus)
+		bridge->remove_bus(bus);
 }
 
 int pci_host_probe(struct pci_host_bridge *bridge)
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 24216daef6f8..bc9635313747 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -479,6 +479,8 @@ struct pci_host_bridge {
 	void (*bus_add_device)(struct pci_dev *pdev);
 	int (*alloc_irq)(struct pci_dev *);
 	int (*free_irq)(struct pci_dev *);
+	void (*add_bus)(struct pci_bus *);
+	void (*remove_bus)(struct pci_bus *);
 	void		*release_data;
 	struct msi_controller *msi;
 	unsigned int	ignore_reset_delay:1;	/* For entire hierarchy */
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* Re: [RFC 07/15] PCI/ACPI: clean up acpi_pci_root_create()
  2018-08-17 10:26 ` [RFC 07/15] PCI/ACPI: clean up acpi_pci_root_create() Arnd Bergmann
@ 2018-08-20  8:23   ` Rafael J. Wysocki
  2018-08-20 11:19     ` Arnd Bergmann
  0 siblings, 1 reply; 28+ messages in thread
From: Rafael J. Wysocki @ 2018-08-20  8:23 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Linux PCI, Bjorn Helgaas, Linux Kernel Mailing List,
	Christoph Hellwig, Lorenzo Pieralisi, Benjamin Herrenschmidt,
	linuxppc-dev, ACPI Devel Maling List

On Fri, Aug 17, 2018 at 12:33 PM Arnd Bergmann <arnd@arndb.de> wrote:
>
> The acpi_pci_create_root_bus() can be fully integrated into
> acpi_pci_root_create(), improving a few things:
>
> * We can call pci_scan_root_bus_bridge(), which registers and
>   scans the bridge in one step.
> * After a failure in pci_register_host_bridge(), we correctly
>   clean up the resources.
> * The bridge settings (release function, flags, operations etc)
>   can get set up before registering the bridge.
> * Further cleanup would be possible, removing duplication between
>   pci_host_bridge and some ACPI structures.
>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
>  drivers/acpi/pci_root.c | 68 +++++++++++++++--------------------------
>  1 file changed, 24 insertions(+), 44 deletions(-)
>
> diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
> index 85dbcf47015b..5f73de3b67c8 100644
> --- a/drivers/acpi/pci_root.c
> +++ b/drivers/acpi/pci_root.c
> @@ -873,34 +873,6 @@ static void acpi_pci_root_release_info(struct pci_host_bridge *bridge)
>         __acpi_pci_root_release_info(bridge->release_data);
>  }
>
> -static struct pci_bus *acpi_pci_create_root_bus(struct device *parent, int bus,
> -               struct pci_ops *ops, void *sysdata, struct list_head *resources)
> -{
> -       int error;
> -       struct pci_host_bridge *bridge;
> -
> -       bridge = pci_alloc_host_bridge(0);
> -       if (!bridge)
> -               return NULL;
> -
> -       bridge->dev.parent = parent;
> -
> -       list_splice_init(resources, &bridge->windows);
> -       bridge->sysdata = sysdata;
> -       bridge->busnr = bus;
> -       bridge->ops = ops;
> -
> -       error = pci_register_host_bridge(bridge);
> -       if (error < 0)
> -               goto err_out;
> -
> -       return bridge->bus;
> -
> -err_out:
> -       kfree(bridge);
> -       return NULL;
> -}
> -
>  struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
>                                      struct acpi_pci_root_ops *ops,
>                                      struct acpi_pci_root_info *info,
> @@ -909,8 +881,7 @@ struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
>         int ret, busnum = root->secondary.start;
>         struct acpi_device *device = root->device;
>         int node = acpi_get_node(device->handle);
> -       struct pci_bus *bus;
> -       struct pci_host_bridge *host_bridge;
> +       struct pci_host_bridge *bridge;

Why "bridge" and not "host" or even something to stand for "root complex"?

Or maybe it can still be "host_bridge"?

>
>         info->root = root;
>         info->bridge = device;
> @@ -930,30 +901,39 @@ struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
>
>         pci_acpi_root_add_resources(info);
>         pci_add_resource(&info->resources, &root->secondary);
> -       bus = acpi_pci_create_root_bus(NULL, busnum, ops->pci_ops,
> -                                 sysdata, &info->resources);
> -       if (!bus)
> +
> +       bridge = pci_alloc_host_bridge(0);
> +       if (!bridge)
>                 goto out_release_info;
>
> -       host_bridge = to_pci_host_bridge(bus->bridge);
> +       list_splice_init(&info->resources, &bridge->windows);
> +       bridge->sysdata = sysdata;
> +       bridge->busnr = busnum;
> +       bridge->ops = ops->pci_ops;
> +       pci_set_host_bridge_release(bridge, acpi_pci_root_release_info,
> +                                   info);
> +
>         if (!(root->osc_control_set & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL))
> -               host_bridge->native_pcie_hotplug = 0;
> +               bridge->native_pcie_hotplug = 0;
>         if (!(root->osc_control_set & OSC_PCI_SHPC_NATIVE_HP_CONTROL))
> -               host_bridge->native_shpc_hotplug = 0;
> +               bridge->native_shpc_hotplug = 0;
>         if (!(root->osc_control_set & OSC_PCI_EXPRESS_AER_CONTROL))
> -               host_bridge->native_aer = 0;
> +               bridge->native_aer = 0;
>         if (!(root->osc_control_set & OSC_PCI_EXPRESS_PME_CONTROL))
> -               host_bridge->native_pme = 0;
> +               bridge->native_pme = 0;
>         if (!(root->osc_control_set & OSC_PCI_EXPRESS_LTR_CONTROL))
> -               host_bridge->native_ltr = 0;
> +               bridge->native_ltr = 0;
> +
> +       ret = pci_scan_root_bus_bridge(bridge);
> +       if (ret < 0)
> +               goto out_release_bridge;
>
> -       pci_scan_child_bus(bus);
> -       pci_set_host_bridge_release(host_bridge, acpi_pci_root_release_info,
> -                                   info);
>         if (node != NUMA_NO_NODE)
> -               dev_printk(KERN_DEBUG, &bus->dev, "on NUMA node %d\n", node);
> -       return bus;
> +               dev_printk(KERN_DEBUG, &bridge->bus->dev, "on NUMA node %d\n", node);
> +       return bridge->bus;
>
> +out_release_bridge:
> +       pci_free_host_bridge(bridge);
>  out_release_info:
>         __acpi_pci_root_release_info(info);
>         return NULL;
> --
> 2.18.0
>

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [RFC 08/15] x86: PCI: clean up pcibios_scan_root()
  2018-08-17 10:26 ` [RFC 08/15] x86: PCI: clean up pcibios_scan_root() Arnd Bergmann
@ 2018-08-20  8:31   ` Rafael J. Wysocki
  2018-08-20 11:16     ` Arnd Bergmann
  0 siblings, 1 reply; 28+ messages in thread
From: Rafael J. Wysocki @ 2018-08-20  8:31 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Linux PCI, Bjorn Helgaas, Linux Kernel Mailing List,
	Christoph Hellwig, Lorenzo Pieralisi, Benjamin Herrenschmidt,
	linuxppc-dev, ACPI Devel Maling List

On Fri, Aug 17, 2018 at 12:32 PM Arnd Bergmann <arnd@arndb.de> wrote:
>
> pcibios_scan_root() is now just a wrapper around pci_scan_root_bus(),
> and merging the two into one makes it shorter and more readable.
>
> We can also take advantage of pci_alloc_host_bridge() doing the
> allocation of the sysdata for us, which helps if we ever want to
> allow hot-unplugging the host bridge itself.
>
> We might be able to simplify it further using pci_host_probe(),
> but I wasn't sure about the resource registration there.
>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
>  arch/x86/pci/common.c | 53 ++++++++++++++-----------------------------
>  1 file changed, 17 insertions(+), 36 deletions(-)
>
> diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
> index e740d9aa4024..920d0885434c 100644
> --- a/arch/x86/pci/common.c
> +++ b/arch/x86/pci/common.c
> @@ -453,54 +453,35 @@ void __init dmi_check_pciprobe(void)
>         dmi_check_system(pciprobe_dmi_table);
>  }
>
> -static struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
> -               struct pci_ops *ops, void *sysdata, struct list_head *resources)
> +void pcibios_scan_root(int busnum)
>  {
> +       struct pci_sysdata *sd;
>         struct pci_host_bridge *bridge;
>         int error;
>
> -       bridge = pci_alloc_host_bridge(0);
> -       if (!bridge)
> -               return NULL;
> +       bridge = pci_alloc_host_bridge(sizeof(sd));
> +       if (!bridge) {
> +               printk(KERN_ERR "PCI: OOM, skipping PCI bus %02x\n", busnum);
> +               return;
> +       }
> +       sd = pci_host_bridge_priv(bridge);

This looks fishy, as bridge->private is not set at this point AFAICS,
unless one of the previous patches changes that.

>
> -       list_splice_init(resources, &bridge->windows);
> -       bridge->dev.parent = parent;
> -       bridge->sysdata = sysdata;
> -       bridge->busnr = bus;
> -       bridge->ops = ops;
> +       sd->node = x86_pci_root_bus_node(busnum);
> +       x86_pci_root_bus_resources(busnum, &bridge->windows);
> +       bridge->sysdata = sd;
> +       bridge->busnr = busnum;
> +       bridge->ops = &pci_root_ops;
>
> +       printk(KERN_DEBUG "PCI: Probing PCI hardware (bus %02x)\n", busnum);
>         error = pci_scan_root_bus_bridge(bridge);
>         if (error < 0)
>                 goto err_out;
>
> -       return bridge->bus;
> +       pci_bus_add_devices(bridge->bus);
> +       return;
>
>  err_out:
> -       kfree(bridge);
> -       return NULL;
> -}
> -
> -void pcibios_scan_root(int busnum)
> -{
> -       struct pci_bus *bus;
> -       struct pci_sysdata *sd;
> -       LIST_HEAD(resources);
> -
> -       sd = kzalloc(sizeof(*sd), GFP_KERNEL);
> -       if (!sd) {
> -               printk(KERN_ERR "PCI: OOM, skipping PCI bus %02x\n", busnum);
> -               return;
> -       }
> -       sd->node = x86_pci_root_bus_node(busnum);
> -       x86_pci_root_bus_resources(busnum, &resources);
> -       printk(KERN_DEBUG "PCI: Probing PCI hardware (bus %02x)\n", busnum);
> -       bus = pci_scan_root_bus(NULL, busnum, &pci_root_ops, sd, &resources);
> -       if (!bus) {
> -               pci_free_resource_list(&resources);
> -               kfree(sd);
> -               return;
> -       }
> -       pci_bus_add_devices(bus);
> +       pci_free_host_bridge(bridge);
>  }
>
>  void __init pcibios_set_cache_line_size(void)
> --
> 2.18.0
>

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [RFC 08/15] x86: PCI: clean up pcibios_scan_root()
  2018-08-20  8:31   ` Rafael J. Wysocki
@ 2018-08-20 11:16     ` Arnd Bergmann
  2018-08-20 11:26       ` Rafael J. Wysocki
  0 siblings, 1 reply; 28+ messages in thread
From: Arnd Bergmann @ 2018-08-20 11:16 UTC (permalink / raw)
  To: Rafael Wysocki
  Cc: linux-pci, Bjorn Helgaas, Linux Kernel Mailing List,
	Christoph Hellwig, Lorenzo Pieralisi, Benjamin Herrenschmidt,
	linuxppc-dev, ACPI Devel Maling List

On Mon, Aug 20, 2018 at 10:31 AM Rafael J. Wysocki <rafael@kernel.org> wrote:
> On Fri, Aug 17, 2018 at 12:32 PM Arnd Bergmann <arnd@arndb.de> wrote:

> > -static struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
> > -               struct pci_ops *ops, void *sysdata, struct list_head *resources)
> > +void pcibios_scan_root(int busnum)
> >  {
> > +       struct pci_sysdata *sd;
> >         struct pci_host_bridge *bridge;
> >         int error;
> >
> > -       bridge = pci_alloc_host_bridge(0);
> > -       if (!bridge)
> > -               return NULL;
> > +       bridge = pci_alloc_host_bridge(sizeof(sd));
> > +       if (!bridge) {
> > +               printk(KERN_ERR "PCI: OOM, skipping PCI bus %02x\n", busnum);
> > +               return;
> > +       }
> > +       sd = pci_host_bridge_priv(bridge);
>
> This looks fishy, as bridge->private is not set at this point AFAICS,
> unless one of the previous patches changes that.

bridge->private what comes after the bridge structure, and it's allocated
by pci_alloc_host_bridge() passing the size of the structure we want
for this private area.

         Arnd

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [RFC 07/15] PCI/ACPI: clean up acpi_pci_root_create()
  2018-08-20  8:23   ` Rafael J. Wysocki
@ 2018-08-20 11:19     ` Arnd Bergmann
  2018-08-20 11:24       ` Rafael J. Wysocki
  0 siblings, 1 reply; 28+ messages in thread
From: Arnd Bergmann @ 2018-08-20 11:19 UTC (permalink / raw)
  To: Rafael Wysocki
  Cc: linux-pci, Bjorn Helgaas, Linux Kernel Mailing List,
	Christoph Hellwig, Lorenzo Pieralisi, Benjamin Herrenschmidt,
	linuxppc-dev, ACPI Devel Maling List

On Mon, Aug 20, 2018 at 10:23 AM Rafael J. Wysocki <rafael@kernel.org> wrote:
> On Fri, Aug 17, 2018 at 12:33 PM Arnd Bergmann <arnd@arndb.de> wrote:
> > @@ -909,8 +881,7 @@ struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
> >         int ret, busnum = root->secondary.start;
> >         struct acpi_device *device = root->device;
> >         int node = acpi_get_node(device->handle);
> > -       struct pci_bus *bus;
> > -       struct pci_host_bridge *host_bridge;
> > +       struct pci_host_bridge *bridge;
>
> Why "bridge" and not "host" or even something to stand for "root complex"?
>
> Or maybe it can still be "host_bridge"?

I did this for consistency with the naming in drivers/pci/probe.c,
which always declares the local variable as 'struct pci_host_bridge *bridge'.
It's easy to change here if you feel strongly about it (I don't).

        Arnd

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [RFC 07/15] PCI/ACPI: clean up acpi_pci_root_create()
  2018-08-20 11:19     ` Arnd Bergmann
@ 2018-08-20 11:24       ` Rafael J. Wysocki
  2018-08-20 11:36         ` Arnd Bergmann
  0 siblings, 1 reply; 28+ messages in thread
From: Rafael J. Wysocki @ 2018-08-20 11:24 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Rafael J. Wysocki, Linux PCI, Bjorn Helgaas,
	Linux Kernel Mailing List, Christoph Hellwig, Lorenzo Pieralisi,
	Benjamin Herrenschmidt, linuxppc-dev, ACPI Devel Maling List

On Mon, Aug 20, 2018 at 1:20 PM Arnd Bergmann <arnd@arndb.de> wrote:
>
> On Mon, Aug 20, 2018 at 10:23 AM Rafael J. Wysocki <rafael@kernel.org> wrote:
> > On Fri, Aug 17, 2018 at 12:33 PM Arnd Bergmann <arnd@arndb.de> wrote:
> > > @@ -909,8 +881,7 @@ struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
> > >         int ret, busnum = root->secondary.start;
> > >         struct acpi_device *device = root->device;
> > >         int node = acpi_get_node(device->handle);
> > > -       struct pci_bus *bus;
> > > -       struct pci_host_bridge *host_bridge;
> > > +       struct pci_host_bridge *bridge;
> >
> > Why "bridge" and not "host" or even something to stand for "root complex"?
> >
> > Or maybe it can still be "host_bridge"?
>
> I did this for consistency with the naming in drivers/pci/probe.c,
> which always declares the local variable as 'struct pci_host_bridge *bridge'.
> It's easy to change here if you feel strongly about it (I don't).

I would leave host_bridge here.  It would make the patch smaller too I think.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [RFC 08/15] x86: PCI: clean up pcibios_scan_root()
  2018-08-20 11:16     ` Arnd Bergmann
@ 2018-08-20 11:26       ` Rafael J. Wysocki
  0 siblings, 0 replies; 28+ messages in thread
From: Rafael J. Wysocki @ 2018-08-20 11:26 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Rafael J. Wysocki, Linux PCI, Bjorn Helgaas,
	Linux Kernel Mailing List, Christoph Hellwig, Lorenzo Pieralisi,
	Benjamin Herrenschmidt, linuxppc-dev, ACPI Devel Maling List

On Mon, Aug 20, 2018 at 1:17 PM Arnd Bergmann <arnd@arndb.de> wrote:
>
> On Mon, Aug 20, 2018 at 10:31 AM Rafael J. Wysocki <rafael@kernel.org> wrote:
> > On Fri, Aug 17, 2018 at 12:32 PM Arnd Bergmann <arnd@arndb.de> wrote:
>
> > > -static struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
> > > -               struct pci_ops *ops, void *sysdata, struct list_head *resources)
> > > +void pcibios_scan_root(int busnum)
> > >  {
> > > +       struct pci_sysdata *sd;
> > >         struct pci_host_bridge *bridge;
> > >         int error;
> > >
> > > -       bridge = pci_alloc_host_bridge(0);
> > > -       if (!bridge)
> > > -               return NULL;
> > > +       bridge = pci_alloc_host_bridge(sizeof(sd));
> > > +       if (!bridge) {
> > > +               printk(KERN_ERR "PCI: OOM, skipping PCI bus %02x\n", busnum);
> > > +               return;
> > > +       }
> > > +       sd = pci_host_bridge_priv(bridge);
> >
> > This looks fishy, as bridge->private is not set at this point AFAICS,
> > unless one of the previous patches changes that.
>
> bridge->private what comes after the bridge structure, and it's allocated
> by pci_alloc_host_bridge() passing the size of the structure we want
> for this private area.

I see, sorry for the noise.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [RFC 07/15] PCI/ACPI: clean up acpi_pci_root_create()
  2018-08-20 11:24       ` Rafael J. Wysocki
@ 2018-08-20 11:36         ` Arnd Bergmann
  0 siblings, 0 replies; 28+ messages in thread
From: Arnd Bergmann @ 2018-08-20 11:36 UTC (permalink / raw)
  To: Rafael Wysocki
  Cc: linux-pci, Bjorn Helgaas, Linux Kernel Mailing List,
	Christoph Hellwig, Lorenzo Pieralisi, Benjamin Herrenschmidt,
	linuxppc-dev, ACPI Devel Maling List

On Mon, Aug 20, 2018 at 1:24 PM Rafael J. Wysocki <rafael@kernel.org> wrote:
>
> On Mon, Aug 20, 2018 at 1:20 PM Arnd Bergmann <arnd@arndb.de> wrote:
> >
> > On Mon, Aug 20, 2018 at 10:23 AM Rafael J. Wysocki <rafael@kernel.org> wrote:
> > > On Fri, Aug 17, 2018 at 12:33 PM Arnd Bergmann <arnd@arndb.de> wrote:
> > > > @@ -909,8 +881,7 @@ struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
> > > >         int ret, busnum = root->secondary.start;
> > > >         struct acpi_device *device = root->device;
> > > >         int node = acpi_get_node(device->handle);
> > > > -       struct pci_bus *bus;
> > > > -       struct pci_host_bridge *host_bridge;
> > > > +       struct pci_host_bridge *bridge;
> > >
> > > Why "bridge" and not "host" or even something to stand for "root complex"?
> > >
> > > Or maybe it can still be "host_bridge"?
> >
> > I did this for consistency with the naming in drivers/pci/probe.c,
> > which always declares the local variable as 'struct pci_host_bridge *bridge'.
> > It's easy to change here if you feel strongly about it (I don't).
>
> I would leave host_bridge here.  It would make the patch smaller too I think.

Ok, I've changed my local copy as you suggested now.

      Arnd

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [RFC 00/15] PCI: turn some __weak functions into callbacks
  2018-08-17 10:26 [RFC 00/15] PCI: turn some __weak functions into callbacks Arnd Bergmann
                   ` (14 preceding siblings ...)
  2018-08-17 10:26 ` [RFC 15/15] PCI: make pcibios_add_bus/remove_bus callbacks Arnd Bergmann
@ 2018-08-21  6:14 ` Christoph Hellwig
  2018-08-21 10:07   ` Arnd Bergmann
  2018-08-21 11:30   ` David Woodhouse
  2018-10-02 20:59 ` Bjorn Helgaas
  16 siblings, 2 replies; 28+ messages in thread
From: Christoph Hellwig @ 2018-08-21  6:14 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-pci, Bjorn Helgaas, linux-kernel, Christoph Hellwig,
	Lorenzo Pieralisi, Benjamin Herrenschmidt, linuxppc-dev,
	linux-acpi

On Fri, Aug 17, 2018 at 12:26:30PM +0200, Arnd Bergmann wrote:
> Hi Bjorn and others,
> 
> Triggered by Christoph's patches, I had another go at converting
> all of the remaining pci host bridge implementations to be based
> on pci_alloc_host_bridge and a separate registration function.

I really like the idea behind this series.

> I'm adding a bit of duplication into the less maintained code
> here, but it makes everything more consistent, and gives an
> easy place to hook up callback functions etc.

I wonder if there is a way to avoid some of that by adding a few
more helpers, but even without the helpers that approach looks
ok to me.

Do you have a git tree somewhere to play around with the changes?

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [RFC 00/15] PCI: turn some __weak functions into callbacks
  2018-08-21  6:14 ` [RFC 00/15] PCI: turn some __weak functions into callbacks Christoph Hellwig
@ 2018-08-21 10:07   ` Arnd Bergmann
  2018-08-21 11:30   ` David Woodhouse
  1 sibling, 0 replies; 28+ messages in thread
From: Arnd Bergmann @ 2018-08-21 10:07 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: linux-pci, Bjorn Helgaas, Linux Kernel Mailing List,
	Lorenzo Pieralisi, Benjamin Herrenschmidt, linuxppc-dev,
	ACPI Devel Maling List

On Tue, Aug 21, 2018 at 8:14 AM Christoph Hellwig <hch@infradead.org> wrote:
>
> On Fri, Aug 17, 2018 at 12:26:30PM +0200, Arnd Bergmann wrote:
> > Hi Bjorn and others,
> >
> > Triggered by Christoph's patches, I had another go at converting
> > all of the remaining pci host bridge implementations to be based
> > on pci_alloc_host_bridge and a separate registration function.
>
> I really like the idea behind this series.
>
> > I'm adding a bit of duplication into the less maintained code
> > here, but it makes everything more consistent, and gives an
> > easy place to hook up callback functions etc.
>
> I wonder if there is a way to avoid some of that by adding a few
> more helpers, but even without the helpers that approach looks
> ok to me.

Ok, thanks for taking a first look.

One core part that gets duplicated a lot (also in existing drivers)
is the chunk that could be handled by this:

int pci_host_bridge_init(struct pci_host_bridge *bridge,
                   struct device *parent, int bus,
                   struct pci_ops *ops, void *sysdata,
                   struct list_head *resource_list)
{
       if (resources)
              list_splice_init(resources, &bridge->windows);
       bridge->dev.parent = parent;
       bridge->sysdata = sysdata;
       bridge->busnr = bus;
       bridge->ops = ops;
}

That would probably help, but we should think carefully about
the set of fields that we want pass here, specifically because the
idea of splitting the probing into two parts was to avoid having
to come up with a new interface every time that list changes
due to some rework.

For instance, the numa node is something that might get passed
here, and if we decide to split out the operations into a separate
pci_host_bridge_ops structure, the pointer to that would also
be something we'd want to pass this way.

> Do you have a git tree somewhere to play around with the changes?

I now uploaded it (with fixes incorporated) to

https://git.kernel.org/pub/scm/linux/kernel/git/arnd/playground.git
pci-probe-rework

       arnd

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [RFC 00/15] PCI: turn some __weak functions into callbacks
  2018-08-21  6:14 ` [RFC 00/15] PCI: turn some __weak functions into callbacks Christoph Hellwig
  2018-08-21 10:07   ` Arnd Bergmann
@ 2018-08-21 11:30   ` David Woodhouse
  2018-08-21 13:14     ` Christoph Hellwig
  1 sibling, 1 reply; 28+ messages in thread
From: David Woodhouse @ 2018-08-21 11:30 UTC (permalink / raw)
  To: Christoph Hellwig, Arnd Bergmann
  Cc: linux-pci, Bjorn Helgaas, linux-kernel, Lorenzo Pieralisi,
	Benjamin Herrenschmidt, linuxppc-dev, linux-acpi

[-- Attachment #1: Type: text/plain, Size: 490 bytes --]

On Mon, 2018-08-20 at 23:14 -0700, Christoph Hellwig wrote:
> On Fri, Aug 17, 2018 at 12:26:30PM +0200, Arnd Bergmann wrote:
> > Hi Bjorn and others,
> > 
> > Triggered by Christoph's patches, I had another go at converting
> > all of the remaining pci host bridge implementations to be based
> > on pci_alloc_host_bridge and a separate registration function.
> 
> I really like the idea behind this series.

Hm... are you turning direct calls into retpolined indirect calls?


[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 5213 bytes --]

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [RFC 00/15] PCI: turn some __weak functions into callbacks
  2018-08-21 11:30   ` David Woodhouse
@ 2018-08-21 13:14     ` Christoph Hellwig
  0 siblings, 0 replies; 28+ messages in thread
From: Christoph Hellwig @ 2018-08-21 13:14 UTC (permalink / raw)
  To: David Woodhouse
  Cc: Christoph Hellwig, Arnd Bergmann, linux-pci, Bjorn Helgaas,
	linux-kernel, Lorenzo Pieralisi, Benjamin Herrenschmidt,
	linuxppc-dev, linux-acpi

On Tue, Aug 21, 2018 at 12:30:50PM +0100, David Woodhouse wrote:
> On Mon, 2018-08-20 at 23:14 -0700, Christoph Hellwig wrote:
> > On Fri, Aug 17, 2018 at 12:26:30PM +0200, Arnd Bergmann wrote:
> > > Hi Bjorn and others,
> > > 
> > > Triggered by Christoph's patches, I had another go at converting
> > > all of the remaining pci host bridge implementations to be based
> > > on pci_alloc_host_bridge and a separate registration function.
> > 
> > I really like the idea behind this series.
> 
> Hm... are you turning direct calls into retpolined indirect calls?

He does.  But not anywhere near the fast path.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [RFC 00/15] PCI: turn some __weak functions into callbacks
  2018-08-17 10:26 [RFC 00/15] PCI: turn some __weak functions into callbacks Arnd Bergmann
                   ` (15 preceding siblings ...)
  2018-08-21  6:14 ` [RFC 00/15] PCI: turn some __weak functions into callbacks Christoph Hellwig
@ 2018-10-02 20:59 ` Bjorn Helgaas
  16 siblings, 0 replies; 28+ messages in thread
From: Bjorn Helgaas @ 2018-10-02 20:59 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-pci, Bjorn Helgaas, linux-kernel, Christoph Hellwig,
	Lorenzo Pieralisi, Benjamin Herrenschmidt, linuxppc-dev,
	linux-acpi

On Fri, Aug 17, 2018 at 12:26:30PM +0200, Arnd Bergmann wrote:
> Hi Bjorn and others,
> 
> Triggered by Christoph's patches, I had another go at converting
> all of the remaining pci host bridge implementations to be based
> on pci_alloc_host_bridge and a separate registration function.
> 
> This is made possible through work from Lorenzo and others to
> convert many of the existing drivers, as well as the removal
> of some of the older architectures that nobody used.
> 
> I'm adding a bit of duplication into the less maintained code
> here, but it makes everything more consistent, and gives an
> easy place to hook up callback functions etc.
> 
> The three parts of this series are:
> 
> a) push up the registration into the callers (this is where
>    code gets added)
> b) clean up some of the more common host bridge
>    implementations again to integrate that code better.
>    This could be done for the rest as well, or we could just
>    leave them alone.
> c) start moving the __weak functions into callbacks in
>    pci_host_bridge. This is intentionally incomplete, since
>    it is a lot of work to do it for all those functions,
>    and I want to get consensus on the approach first, as well
>    as maybe get other developers to help out with the rest.
> 
> Please have a look.
> 
>        Arnd
> 
> [1] https://lore.kernel.org/lkml/4288331.jNpl6KXlNO@wuerfel/
> [2] https://patchwork.kernel.org/patch/10555657/
> 
> Arnd Bergmann (15):
>   PCI: clean up legacy host bridge scan functions
>   PCI: move pci_scan_bus into callers
>   PCI: move pci_scan_root_bus into callers
>   PCI: export pci_register_host_bridge
>   PCI: move pci_create_root_bus into callers
>   powerpc/pci: fold pci_create_root_bus into pcibios_scan_phb
>   PCI/ACPI: clean up acpi_pci_root_create()
>   x86: PCI: clean up pcibios_scan_root()
>   PCI: xenfront: clean up pcifront_scan_root()
>   sparc/PCI: simplify pci_scan_one_pbm
>   PCI: hyperv: convert to pci_scan_root_bus_bridge
>   PCI: make pcibios_bus_add_device() a callback function
>   PCI: turn pcibios_alloc_irq into a callback
>   PCI: make pcibios_root_bridge_prepare a callback
>   PCI: make pcibios_add_bus/remove_bus callbacks
> 
>  arch/arm64/kernel/pci.c               |  40 ++-----
>  arch/ia64/pci/pci.c                   |  25 +----
>  arch/ia64/sn/kernel/io_init.c         |  27 +++++
>  arch/microblaze/pci/pci-common.c      |  27 +++++
>  arch/powerpc/include/asm/pci-bridge.h |   3 +
>  arch/powerpc/kernel/pci-common.c      |  60 +++++------
>  arch/s390/pci/pci.c                   |  30 +++++-
>  arch/sh/drivers/pci/pci.c             |   1 +
>  arch/sh/drivers/pci/pcie-sh7786.c     |   3 +-
>  arch/sh/include/asm/pci.h             |   2 +
>  arch/sparc/kernel/pci.c               |  40 ++++---
>  arch/sparc/kernel/pcic.c              |  35 ++++++
>  arch/x86/pci/acpi.c                   |  15 +--
>  arch/x86/pci/common.c                 |  42 ++++----
>  arch/xtensa/kernel/pci.c              |  27 +++++
>  drivers/acpi/pci_root.c               |  43 +++++---
>  drivers/parisc/dino.c                 |  28 +++++
>  drivers/parisc/lba_pci.c              |  28 +++++
>  drivers/pci/bus.c                     |   8 +-
>  drivers/pci/controller/pci-hyperv.c   |  47 ++++----
>  drivers/pci/controller/vmd.c          |  30 +++++-
>  drivers/pci/hotplug/ibmphp_core.c     |  35 ++++++
>  drivers/pci/pci-driver.c              |  13 ++-
>  drivers/pci/probe.c                   | 150 +++++++++-----------------
>  drivers/pci/xen-pcifront.c            |  40 +++----
>  include/linux/acpi.h                  |   2 +
>  include/linux/pci.h                   |  17 ++-
>  27 files changed, 514 insertions(+), 304 deletions(-)

Sorry for the late response to this.

I think I'm generally on-board with this.  I admit I'm a little
hesitant about adding 200 lines of code when this is really more
"cleanup" than new functionality, but I think a lot of that is because
this series contains costs (e.g., duplicating code) for everybody but
only has the corresponding benefits for a few (ACPI, x86, xenfront).
Those cases are much closer to parity in terms of lines added/removed.

I saw some minor comments that suggested you had some updates, so I'll
watch for an updated posting.

Bjorn

^ permalink raw reply	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2018-10-02 20:59 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-08-17 10:26 [RFC 00/15] PCI: turn some __weak functions into callbacks Arnd Bergmann
2018-08-17 10:26 ` [RFC 01/15] PCI: clean up legacy host bridge scan functions Arnd Bergmann
2018-08-17 10:26 ` [RFC 02/15] PCI: move pci_scan_bus into callers Arnd Bergmann
2018-08-17 10:26 ` [RFC 03/15] PCI: move pci_scan_root_bus " Arnd Bergmann
2018-08-17 10:26 ` [RFC 04/15] PCI: export pci_register_host_bridge Arnd Bergmann
2018-08-17 10:26 ` [RFC 05/15] PCI: move pci_create_root_bus into callers Arnd Bergmann
2018-08-17 10:26 ` [RFC 06/15] powerpc/pci: fold pci_create_root_bus into pcibios_scan_phb Arnd Bergmann
2018-08-17 10:26 ` [RFC 07/15] PCI/ACPI: clean up acpi_pci_root_create() Arnd Bergmann
2018-08-20  8:23   ` Rafael J. Wysocki
2018-08-20 11:19     ` Arnd Bergmann
2018-08-20 11:24       ` Rafael J. Wysocki
2018-08-20 11:36         ` Arnd Bergmann
2018-08-17 10:26 ` [RFC 08/15] x86: PCI: clean up pcibios_scan_root() Arnd Bergmann
2018-08-20  8:31   ` Rafael J. Wysocki
2018-08-20 11:16     ` Arnd Bergmann
2018-08-20 11:26       ` Rafael J. Wysocki
2018-08-17 10:26 ` [RFC 09/15] PCI: xenfront: clean up pcifront_scan_root() Arnd Bergmann
2018-08-17 10:26 ` [RFC 10/15] sparc/PCI: simplify pci_scan_one_pbm Arnd Bergmann
2018-08-17 10:26 ` [RFC 11/15] PCI: hyperv: convert to pci_scan_root_bus_bridge Arnd Bergmann
2018-08-17 10:26 ` [RFC 12/15] PCI: make pcibios_bus_add_device() a callback function Arnd Bergmann
2018-08-17 10:26 ` [RFC 13/15] PCI: turn pcibios_alloc_irq into a callback Arnd Bergmann
2018-08-17 10:26 ` [RFC 14/15] PCI: make pcibios_root_bridge_prepare " Arnd Bergmann
2018-08-17 10:26 ` [RFC 15/15] PCI: make pcibios_add_bus/remove_bus callbacks Arnd Bergmann
2018-08-21  6:14 ` [RFC 00/15] PCI: turn some __weak functions into callbacks Christoph Hellwig
2018-08-21 10:07   ` Arnd Bergmann
2018-08-21 11:30   ` David Woodhouse
2018-08-21 13:14     ` Christoph Hellwig
2018-10-02 20:59 ` Bjorn Helgaas

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).