diff options
author | Bjorn Helgaas <bhelgaas@google.com> | 2011-10-28 18:28:14 -0400 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2012-01-06 15:11:14 -0500 |
commit | 2cd6975a4ff92a75e46240109d01c1daf4682e5d (patch) | |
tree | ec5ca0a025c31e54c5f4c6701dc8c79ce012f820 /arch/x86/pci/acpi.c | |
parent | 46fbade05ca0784ca3c959bd7bf2aae7d81306c2 (diff) |
x86/PCI: convert to pci_create_root_bus() and pci_scan_root_bus()
x86 has two kinds of PCI root bus scanning:
(1) ACPI-based, using _CRS resources. This used pci_create_bus(), not
pci_scan_bus(), because ACPI hotplug needed to split the
pci_bus_add_devices() into a separate host bridge .start() method.
This patch parses the _CRS resources earlier, so we can build a list of
resources and pass it to pci_create_root_bus().
Note that as before, we parse the _CRS even if we aren't going to use
it so we can print it for debugging purposes.
(2) All other, which used either default resources (ioport_resource and
iomem_resource) or information read from the hardware via amd_bus.c or
similar. This used pci_scan_bus().
This patch converts x86_pci_root_bus_res_quirks() (previously called
from pcibios_fixup_bus()) to x86_pci_root_bus_resources(), which builds
a list of resources before we call pci_scan_root_bus().
We also use x86_pci_root_bus_resources() if we have ACPI but are
ignoring _CRS.
CC: Yinghai Lu <yinghai.lu@oracle.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'arch/x86/pci/acpi.c')
-rw-r--r-- | arch/x86/pci/acpi.c | 28 |
1 files changed, 14 insertions, 14 deletions
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index 425500bb24e6..a312e76063a7 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c | |||
@@ -12,7 +12,7 @@ struct pci_root_info { | |||
12 | char *name; | 12 | char *name; |
13 | unsigned int res_num; | 13 | unsigned int res_num; |
14 | struct resource *res; | 14 | struct resource *res; |
15 | struct pci_bus *bus; | 15 | struct list_head *resources; |
16 | int busnum; | 16 | int busnum; |
17 | }; | 17 | }; |
18 | 18 | ||
@@ -304,23 +304,20 @@ static void add_resources(struct pci_root_info *info) | |||
304 | "ignoring host bridge window %pR (conflicts with %s %pR)\n", | 304 | "ignoring host bridge window %pR (conflicts with %s %pR)\n", |
305 | res, conflict->name, conflict); | 305 | res, conflict->name, conflict); |
306 | else | 306 | else |
307 | pci_bus_add_resource(info->bus, res, 0); | 307 | pci_add_resource(info->resources, res); |
308 | } | 308 | } |
309 | } | 309 | } |
310 | 310 | ||
311 | static void | 311 | static void |
312 | get_current_resources(struct acpi_device *device, int busnum, | 312 | get_current_resources(struct acpi_device *device, int busnum, |
313 | int domain, struct pci_bus *bus) | 313 | int domain, struct list_head *resources) |
314 | { | 314 | { |
315 | struct pci_root_info info; | 315 | struct pci_root_info info; |
316 | size_t size; | 316 | size_t size; |
317 | 317 | ||
318 | if (pci_use_crs) | ||
319 | pci_bus_remove_resources(bus); | ||
320 | |||
321 | info.bridge = device; | 318 | info.bridge = device; |
322 | info.bus = bus; | ||
323 | info.res_num = 0; | 319 | info.res_num = 0; |
320 | info.resources = resources; | ||
324 | acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_resource, | 321 | acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_resource, |
325 | &info); | 322 | &info); |
326 | if (!info.res_num) | 323 | if (!info.res_num) |
@@ -329,7 +326,7 @@ get_current_resources(struct acpi_device *device, int busnum, | |||
329 | size = sizeof(*info.res) * info.res_num; | 326 | size = sizeof(*info.res) * info.res_num; |
330 | info.res = kmalloc(size, GFP_KERNEL); | 327 | info.res = kmalloc(size, GFP_KERNEL); |
331 | if (!info.res) | 328 | if (!info.res) |
332 | goto res_alloc_fail; | 329 | return; |
333 | 330 | ||
334 | info.name = kasprintf(GFP_KERNEL, "PCI Bus %04x:%02x", domain, busnum); | 331 | info.name = kasprintf(GFP_KERNEL, "PCI Bus %04x:%02x", domain, busnum); |
335 | if (!info.name) | 332 | if (!info.name) |
@@ -344,8 +341,6 @@ get_current_resources(struct acpi_device *device, int busnum, | |||
344 | 341 | ||
345 | name_alloc_fail: | 342 | name_alloc_fail: |
346 | kfree(info.res); | 343 | kfree(info.res); |
347 | res_alloc_fail: | ||
348 | return; | ||
349 | } | 344 | } |
350 | 345 | ||
351 | struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root) | 346 | struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root) |
@@ -353,6 +348,7 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root) | |||
353 | struct acpi_device *device = root->device; | 348 | struct acpi_device *device = root->device; |
354 | int domain = root->segment; | 349 | int domain = root->segment; |
355 | int busnum = root->secondary.start; | 350 | int busnum = root->secondary.start; |
351 | LIST_HEAD(resources); | ||
356 | struct pci_bus *bus; | 352 | struct pci_bus *bus; |
357 | struct pci_sysdata *sd; | 353 | struct pci_sysdata *sd; |
358 | int node; | 354 | int node; |
@@ -407,11 +403,15 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root) | |||
407 | memcpy(bus->sysdata, sd, sizeof(*sd)); | 403 | memcpy(bus->sysdata, sd, sizeof(*sd)); |
408 | kfree(sd); | 404 | kfree(sd); |
409 | } else { | 405 | } else { |
410 | bus = pci_create_bus(NULL, busnum, &pci_root_ops, sd); | 406 | get_current_resources(device, busnum, domain, &resources); |
411 | if (bus) { | 407 | if (list_empty(&resources)) |
412 | get_current_resources(device, busnum, domain, bus); | 408 | x86_pci_root_bus_resources(busnum, &resources); |
409 | bus = pci_create_root_bus(NULL, busnum, &pci_root_ops, sd, | ||
410 | &resources); | ||
411 | if (bus) | ||
413 | bus->subordinate = pci_scan_child_bus(bus); | 412 | bus->subordinate = pci_scan_child_bus(bus); |
414 | } | 413 | else |
414 | pci_free_resource_list(&resources); | ||
415 | } | 415 | } |
416 | 416 | ||
417 | /* After the PCI-E bus has been walked and all devices discovered, | 417 | /* After the PCI-E bus has been walked and all devices discovered, |