aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/pci/acpi.c
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2011-10-28 18:28:14 -0400
committerJesse Barnes <jbarnes@virtuousgeek.org>2012-01-06 15:11:14 -0500
commit2cd6975a4ff92a75e46240109d01c1daf4682e5d (patch)
treeec5ca0a025c31e54c5f4c6701dc8c79ce012f820 /arch/x86/pci/acpi.c
parent46fbade05ca0784ca3c959bd7bf2aae7d81306c2 (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.c28
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
311static void 311static void
312get_current_resources(struct acpi_device *device, int busnum, 312get_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
345name_alloc_fail: 342name_alloc_fail:
346 kfree(info.res); 343 kfree(info.res);
347res_alloc_fail:
348 return;
349} 344}
350 345
351struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root) 346struct 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,