diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2011-04-10 21:19:09 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2011-06-07 19:08:40 -0400 |
commit | 3d5fe5a65af9c0b609d6e26b8d63fe5923c4e512 (patch) | |
tree | 8c6a31cd4614212ffe0821ccc2435413a5b76dc9 /arch | |
parent | bf13a6fa09b8db7f1fd59b5e2ed3674a89a6a25c (diff) |
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: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
Tested-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/kernel/devicetree.c | 60 |
1 files changed, 18 insertions, 42 deletions
diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c index 690bc8461835..d23f7af43679 100644 --- a/arch/x86/kernel/devicetree.c +++ b/arch/x86/kernel/devicetree.c | |||
@@ -123,6 +123,24 @@ static int __init add_bus_probe(void) | |||
123 | module_init(add_bus_probe); | 123 | module_init(add_bus_probe); |
124 | 124 | ||
125 | #ifdef CONFIG_PCI | 125 | #ifdef CONFIG_PCI |
126 | struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus) | ||
127 | { | ||
128 | struct device_node *np; | ||
129 | |||
130 | for_each_node_by_type(np, "pci") { | ||
131 | const void *prop; | ||
132 | unsigned int bus_min; | ||
133 | |||
134 | prop = of_get_property(np, "bus-range", NULL); | ||
135 | if (!prop) | ||
136 | continue; | ||
137 | bus_min = be32_to_cpup(prop); | ||
138 | if (bus->number == bus_min) | ||
139 | return np; | ||
140 | } | ||
141 | return NULL; | ||
142 | } | ||
143 | |||
126 | static int x86_of_pci_irq_enable(struct pci_dev *dev) | 144 | static int x86_of_pci_irq_enable(struct pci_dev *dev) |
127 | { | 145 | { |
128 | struct of_irq oirq; | 146 | struct of_irq oirq; |
@@ -154,50 +172,8 @@ static void x86_of_pci_irq_disable(struct pci_dev *dev) | |||
154 | 172 | ||
155 | void __cpuinit x86_of_pci_init(void) | 173 | void __cpuinit x86_of_pci_init(void) |
156 | { | 174 | { |
157 | struct device_node *np; | ||
158 | |||
159 | pcibios_enable_irq = x86_of_pci_irq_enable; | 175 | pcibios_enable_irq = x86_of_pci_irq_enable; |
160 | pcibios_disable_irq = x86_of_pci_irq_disable; | 176 | pcibios_disable_irq = x86_of_pci_irq_disable; |
161 | |||
162 | for_each_node_by_type(np, "pci") { | ||
163 | const void *prop; | ||
164 | struct pci_bus *bus; | ||
165 | unsigned int bus_min; | ||
166 | struct device_node *child; | ||
167 | |||
168 | prop = of_get_property(np, "bus-range", NULL); | ||
169 | if (!prop) | ||
170 | continue; | ||
171 | bus_min = be32_to_cpup(prop); | ||
172 | |||
173 | bus = pci_find_bus(0, bus_min); | ||
174 | if (!bus) { | ||
175 | printk(KERN_ERR "Can't find a node for bus %s.\n", | ||
176 | np->full_name); | ||
177 | continue; | ||
178 | } | ||
179 | |||
180 | if (bus->self) | ||
181 | bus->self->dev.of_node = np; | ||
182 | else | ||
183 | bus->dev.of_node = np; | ||
184 | |||
185 | for_each_child_of_node(np, child) { | ||
186 | struct pci_dev *dev; | ||
187 | u32 devfn; | ||
188 | |||
189 | prop = of_get_property(child, "reg", NULL); | ||
190 | if (!prop) | ||
191 | continue; | ||
192 | |||
193 | devfn = (be32_to_cpup(prop) >> 8) & 0xff; | ||
194 | dev = pci_get_slot(bus, devfn); | ||
195 | if (!dev) | ||
196 | continue; | ||
197 | dev->dev.of_node = child; | ||
198 | pci_dev_put(dev); | ||
199 | } | ||
200 | } | ||
201 | } | 177 | } |
202 | #endif | 178 | #endif |
203 | 179 | ||