Subject: [PATCH] PCI, powerpc: Kill pci_root_buses in resources reservations

Replace that with hotplug-safe version iteration.

-v2: add missing put_device found by Yijing Wang <wangyijing@huawei.com>
     also move the handling into the for_each_pci_host_bridge {} to
     make it really hotplug safe, also make the function more readable.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: linuxppc-dev@lists.ozlabs.org

---
 arch/powerpc/kernel/pci-common.c |   13 +++----
 arch/powerpc/kernel/pci_64.c     |   67 +++++++++++++++++++++++----------------
 2 files changed, 46 insertions(+), 34 deletions(-)

Index: linux-2.6/arch/powerpc/kernel/pci-common.c
===================================================================
--- linux-2.6.orig/arch/powerpc/kernel/pci-common.c
+++ linux-2.6/arch/powerpc/kernel/pci-common.c
@@ -1397,11 +1397,11 @@ static void __init pcibios_reserve_legac
 
 void __init pcibios_resource_survey(void)
 {
-	struct pci_bus *b;
+	struct pci_host_bridge *host_bridge = NULL;
 
 	/* Allocate and assign resources */
-	list_for_each_entry(b, &pci_root_buses, node)
-		pcibios_allocate_bus_resources(b);
+	for_each_pci_host_bridge(host_bridge)
+		pcibios_allocate_bus_resources(host_bridge->bus);
 	pcibios_allocate_resources(0);
 	pcibios_allocate_resources(1);
 
@@ -1409,10 +1409,9 @@ void __init pcibios_resource_survey(void
 	 * the low IO area and the VGA memory area if they intersect the
 	 * bus available resources to avoid allocating things on top of them
 	 */
-	if (!pci_has_flag(PCI_PROBE_ONLY)) {
-		list_for_each_entry(b, &pci_root_buses, node)
-			pcibios_reserve_legacy_regions(b);
-	}
+	if (!pci_has_flag(PCI_PROBE_ONLY))
+		for_each_pci_host_bridge(host_bridge)
+			pcibios_reserve_legacy_regions(host_bridge->bus);
 
 	/* Now, if the platform didn't decide to blindly trust the firmware,
 	 * we proceed to assigning things that were left unassigned
Index: linux-2.6/arch/powerpc/kernel/pci_64.c
===================================================================
--- linux-2.6.orig/arch/powerpc/kernel/pci_64.c
+++ linux-2.6/arch/powerpc/kernel/pci_64.c
@@ -207,10 +207,7 @@ void pcibios_setup_phb_io_space(struct p
 long sys_pciconfig_iobase(long which, unsigned long in_bus,
 			  unsigned long in_devfn)
 {
-	struct pci_controller* hose;
-	struct list_head *ln;
-	struct pci_bus *bus = NULL;
-	struct device_node *hose_node;
+	struct pci_host_bridge *host_bridge = NULL;
 
 	/* Argh ! Please forgive me for that hack, but that's the
 	 * simplest way to get existing XFree to not lockup on some
@@ -229,33 +226,49 @@ long sys_pciconfig_iobase(long which, un
 	/* That syscall isn't quite compatible with PCI domains, but it's
 	 * used on pre-domains setup. We return the first match
 	 */
-
-	for (ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) {
-		bus = pci_bus_b(ln);
-		if (in_bus >= bus->number && in_bus <= bus->busn_res.end)
+	for_each_pci_host_bridge(host_bridge) {
+		struct device_node *hose_node;
+		struct pci_controller* hose;
+		struct pci_bus *bus;
+		long ret;
+
+		bus = host_bridge->bus;
+		if (in_bus < bus->number || in_bus > bus->busn_res.end)
+			continue;
+
+		if (!bus->dev.of_node) {
+			put_device(&host_bridge->dev);
+			return -ENODEV;
+		}
+
+		hose_node = bus->dev.of_node;
+		hose = PCI_DN(hose_node)->phb;
+
+		switch (which) {
+		case IOBASE_BRIDGE_NUMBER:
+			ret = (long)hose->first_busno;
 			break;
-		bus = NULL;
-	}
-	if (bus == NULL || bus->dev.of_node == NULL)
-		return -ENODEV;
-
-	hose_node = bus->dev.of_node;
-	hose = PCI_DN(hose_node)->phb;
+		case IOBASE_MEMORY:
+			ret = (long)hose->pci_mem_offset;
+			break;
+		case IOBASE_IO:
+			ret = (long)hose->io_base_phys;
+			break;
+		case IOBASE_ISA_IO:
+			ret = (long)isa_io_base;
+			break;
+		case IOBASE_ISA_MEM:
+			ret = -EINVAL;
+			break;
+		default:
+			ret = -EOPNOTSUPP;
+		}
 
-	switch (which) {
-	case IOBASE_BRIDGE_NUMBER:
-		return (long)hose->first_busno;
-	case IOBASE_MEMORY:
-		return (long)hose->pci_mem_offset;
-	case IOBASE_IO:
-		return (long)hose->io_base_phys;
-	case IOBASE_ISA_IO:
-		return (long)isa_io_base;
-	case IOBASE_ISA_MEM:
-		return -EINVAL;
+		put_device(&host_bridge->dev);
+		return ret;
 	}
 
-	return -EOPNOTSUPP;
+	return -ENODEV;
 }
 
 #ifdef CONFIG_NUMA
