Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e90a1318 authored by Nathan Fontenot's avatar Nathan Fontenot Committed by Paul Mackerras
Browse files

powerpc/pci: Properly allocate bus resources for hotplug PHBs



Resources for PHB's that are dynamically added to a system are not
properly allocated in the resource tree.

Not having these resources allocated causes an oops when removing
the PHB when we try to release them.

The diff appears a bit messy, this is mainly due to moving everything
one tab to the left in the pcibios_allocate_bus_resources routine.
The functionality change in this routine is only that the
list_for_each_entry() loop is pulled out and moved to the necessary
calling routine.

Signed-off-by: default avatarNathan Fontenot <nfont@austin.ibm.com>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
parent 6098e2ee
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -208,6 +208,8 @@ extern void pcibios_setup_new_device(struct pci_dev *dev);

extern void pcibios_claim_one_bus(struct pci_bus *b);

extern void pcibios_allocate_bus_resources(struct pci_bus *bus);

extern void pcibios_resource_survey(void);

extern struct pci_controller *init_phb_dynamic(struct device_node *dn);
+55 −55
Original line number Diff line number Diff line
@@ -1239,14 +1239,12 @@ static int __init reparent_resources(struct resource *parent,
 *	    as well.
 */

static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
void pcibios_allocate_bus_resources(struct pci_bus *bus)
{
	struct pci_bus *bus;
	struct pci_bus *b;
	int i;
	struct resource *res, *pr;

	/* Depth-First Search on bus tree */
	list_for_each_entry(bus, bus_list, node) {
	for (i = 0; i < PCI_BUS_NUM_RESOURCES; ++i) {
		if ((res = bus->resource[i]) == NULL || !res->flags
		    || res->start > res->end)
@@ -1293,15 +1291,14 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
			if (reparent_resources(pr, res) == 0)
				continue;
		}
			printk(KERN_WARNING
			       "PCI: Cannot allocate resource region "
			       "%d of PCI bridge %d, will remap\n",
			       i, bus->number);
		printk(KERN_WARNING "PCI: Cannot allocate resource region "
		       "%d of PCI bridge %d, will remap\n", i, bus->number);
clear_resource:
		res->flags = 0;
	}
		pcibios_allocate_bus_resources(&bus->children);
	}

	list_for_each_entry(b, &bus->children, node)
		pcibios_allocate_bus_resources(b);
}

static inline void __devinit alloc_resource(struct pci_dev *dev, int idx)
@@ -1372,10 +1369,13 @@ static void __init pcibios_allocate_resources(int pass)

void __init pcibios_resource_survey(void)
{
	struct pci_bus *b;

	/* Allocate and assign resources. If we re-assign everything, then
	 * we skip the allocate phase
	 */
	pcibios_allocate_bus_resources(&pci_root_buses);
	list_for_each_entry(b, &pci_root_buses, node)
		pcibios_allocate_bus_resources(b);

	if (!(ppc_pci_flags & PPC_PCI_REASSIGN_ALL_RSRC)) {
		pcibios_allocate_resources(0);
+2 −0
Original line number Diff line number Diff line
@@ -189,6 +189,7 @@ struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn)
{
	struct pci_controller *phb;
	int primary;
	struct pci_bus *b;

	primary = list_empty(&hose_list);
	phb = pcibios_alloc_controller(dn);
@@ -203,6 +204,7 @@ struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn)
		eeh_add_device_tree_early(dn);

	scan_phb(phb);
	pcibios_allocate_bus_resources(phb->bus);
	pcibios_fixup_new_pci_devices(phb->bus);
	pci_bus_add_devices(phb->bus);
	eeh_add_device_tree_late(phb->bus);