Commit 3d5fe5a6 authored by Benjamin Herrenschmidt's avatar Benjamin Herrenschmidt
Browse files

x86/devicetree: Use generic PCI <-> OF matching



Instead of walking the whole PCI tree to update the of_node's for
PCI busses and devices after the fact, enable the new generic core
code for doing so by providing the proper device nodes for the
PCI host bridges

Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
Acked-by: default avatarGrant Likely <grant.likely@secretlab.ca>
Tested-by: default avatarSebastian Andrzej Siewior <bigeasy@linutronix.de>
parent bf13a6fa
Loading
Loading
Loading
Loading
+18 −42
Original line number Diff line number Diff line
@@ -123,6 +123,24 @@ static int __init add_bus_probe(void)
module_init(add_bus_probe);

#ifdef CONFIG_PCI
struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus)
{
	struct device_node *np;

	for_each_node_by_type(np, "pci") {
		const void *prop;
		unsigned int bus_min;

		prop = of_get_property(np, "bus-range", NULL);
		if (!prop)
			continue;
		bus_min = be32_to_cpup(prop);
		if (bus->number == bus_min)
			return np;
	}
	return NULL;
}

static int x86_of_pci_irq_enable(struct pci_dev *dev)
{
	struct of_irq oirq;
@@ -154,50 +172,8 @@ static void x86_of_pci_irq_disable(struct pci_dev *dev)

void __cpuinit x86_of_pci_init(void)
{
	struct device_node *np;

	pcibios_enable_irq = x86_of_pci_irq_enable;
	pcibios_disable_irq = x86_of_pci_irq_disable;

	for_each_node_by_type(np, "pci") {
		const void *prop;
		struct pci_bus *bus;
		unsigned int bus_min;
		struct device_node *child;

		prop = of_get_property(np, "bus-range", NULL);
		if (!prop)
			continue;
		bus_min = be32_to_cpup(prop);

		bus = pci_find_bus(0, bus_min);
		if (!bus) {
			printk(KERN_ERR "Can't find a node for bus %s.\n",
					np->full_name);
			continue;
		}

		if (bus->self)
			bus->self->dev.of_node = np;
		else
			bus->dev.of_node = np;

		for_each_child_of_node(np, child) {
			struct pci_dev *dev;
			u32 devfn;

			prop = of_get_property(child, "reg", NULL);
			if (!prop)
				continue;

			devfn = (be32_to_cpup(prop) >> 8) & 0xff;
			dev = pci_get_slot(bus, devfn);
			if (!dev)
				continue;
			dev->dev.of_node = child;
			pci_dev_put(dev);
		}
	}
}
#endif