diff options
author | Yinghai Lu <yinghai@kernel.org> | 2012-11-04 00:39:26 -0400 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2013-01-07 17:58:16 -0500 |
commit | 83edc87ce8b284a3d60ab8072e55041c76a68277 (patch) | |
tree | ef8b9a395f563d97e433245d293d92a93d50ac96 /arch/x86 | |
parent | c7f4bbc92feee2986212ef3b42c806e2257197dc (diff) |
x86/PCI: Allocate resources on a per-bus basis for hot-adding root buses
Previously pcibios_allocate_resources() allocated resources at boot-time
for all PCI devices using for_each_pci_dev(). This patch changes
pcibios_allocate_resources() so we can specify a bus, so we can do
similar allocation when hot-adding a root bus.
[bhelgaas: changelog]
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/pci/i386.c | 38 |
1 files changed, 25 insertions, 13 deletions
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c index 5817cf235d9a..84696ed1f0e9 100644 --- a/arch/x86/pci/i386.c +++ b/arch/x86/pci/i386.c | |||
@@ -215,16 +215,15 @@ static void __init pcibios_allocate_bridge_resources(struct pci_dev *dev) | |||
215 | } | 215 | } |
216 | } | 216 | } |
217 | 217 | ||
218 | static void __init pcibios_allocate_bus_resources(struct list_head *bus_list) | 218 | static void __init pcibios_allocate_bus_resources(struct pci_bus *bus) |
219 | { | 219 | { |
220 | struct pci_bus *bus; | 220 | struct pci_bus *child; |
221 | 221 | ||
222 | /* Depth-First Search on bus tree */ | 222 | /* Depth-First Search on bus tree */ |
223 | list_for_each_entry(bus, bus_list, node) { | 223 | if (bus->self) |
224 | if (bus->self) | 224 | pcibios_allocate_bridge_resources(bus->self); |
225 | pcibios_allocate_bridge_resources(bus->self); | 225 | list_for_each_entry(child, &bus->children, node) |
226 | pcibios_allocate_bus_resources(&bus->children); | 226 | pcibios_allocate_bus_resources(child); |
227 | } | ||
228 | } | 227 | } |
229 | 228 | ||
230 | struct pci_check_idx_range { | 229 | struct pci_check_idx_range { |
@@ -285,12 +284,18 @@ static void __init pcibios_allocate_dev_resources(struct pci_dev *dev, int pass) | |||
285 | } | 284 | } |
286 | } | 285 | } |
287 | 286 | ||
288 | static void __init pcibios_allocate_resources(int pass) | 287 | static void __init pcibios_allocate_resources(struct pci_bus *bus, int pass) |
289 | { | 288 | { |
290 | struct pci_dev *dev = NULL; | 289 | struct pci_dev *dev; |
290 | struct pci_bus *child; | ||
291 | 291 | ||
292 | for_each_pci_dev(dev) | 292 | list_for_each_entry(dev, &bus->devices, bus_list) { |
293 | pcibios_allocate_dev_resources(dev, pass); | 293 | pcibios_allocate_dev_resources(dev, pass); |
294 | |||
295 | child = dev->subordinate; | ||
296 | if (child) | ||
297 | pcibios_allocate_resources(child, pass); | ||
298 | } | ||
294 | } | 299 | } |
295 | 300 | ||
296 | static int __init pcibios_assign_resources(void) | 301 | static int __init pcibios_assign_resources(void) |
@@ -323,10 +328,17 @@ static int __init pcibios_assign_resources(void) | |||
323 | 328 | ||
324 | void __init pcibios_resource_survey(void) | 329 | void __init pcibios_resource_survey(void) |
325 | { | 330 | { |
331 | struct pci_bus *bus; | ||
332 | |||
326 | DBG("PCI: Allocating resources\n"); | 333 | DBG("PCI: Allocating resources\n"); |
327 | pcibios_allocate_bus_resources(&pci_root_buses); | 334 | |
328 | pcibios_allocate_resources(0); | 335 | list_for_each_entry(bus, &pci_root_buses, node) |
329 | pcibios_allocate_resources(1); | 336 | pcibios_allocate_bus_resources(bus); |
337 | |||
338 | list_for_each_entry(bus, &pci_root_buses, node) | ||
339 | pcibios_allocate_resources(bus, 0); | ||
340 | list_for_each_entry(bus, &pci_root_buses, node) | ||
341 | pcibios_allocate_resources(bus, 1); | ||
330 | 342 | ||
331 | e820_reserve_resources_late(); | 343 | e820_reserve_resources_late(); |
332 | /* | 344 | /* |