aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/pci/acpi.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-01-11 21:50:26 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-01-11 21:50:26 -0500
commit7b67e751479d50b7f84d1a3cc5216eed5e534b66 (patch)
treea1a6746857cf65f04dde739fe271bf4143d55eaf /arch/x86/pci/acpi.c
parent9f13a1fd452f11c18004ba2422a6384b424ec8a9 (diff)
parent76ccc297018d25d55b789bbd508861ef1e2cdb0c (diff)
Merge branch 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci
* 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci: (80 commits) x86/PCI: Expand the x86_msi_ops to have a restore MSIs. PCI: Increase resource array mask bit size in pcim_iomap_regions() PCI: DEVICE_COUNT_RESOURCE should be equal to PCI_NUM_RESOURCES PCI: pci_ids: add device ids for STA2X11 device (aka ConneXT) PNP: work around Dell 1536/1546 BIOS MMCONFIG bug that breaks USB x86/PCI: amd: factor out MMCONFIG discovery PCI: Enable ATS at the device state restore PCI: msi: fix imbalanced refcount of msi irq sysfs objects PCI: kconfig: English typo in pci/pcie/Kconfig PCI/PM/Runtime: make PCI traces quieter PCI: remove pci_create_bus() xtensa/PCI: convert to pci_scan_root_bus() for correct root bus resources x86/PCI: convert to pci_create_root_bus() and pci_scan_root_bus() x86/PCI: use pci_scan_bus() instead of pci_scan_bus_parented() x86/PCI: read Broadcom CNB20LE host bridge info before PCI scan sparc32, leon/PCI: convert to pci_scan_root_bus() for correct root bus resources sparc/PCI: convert to pci_create_root_bus() sh/PCI: convert to pci_scan_root_bus() for correct root bus resources powerpc/PCI: convert to pci_create_root_bus() powerpc/PCI: split PHB part out of pcibios_map_io_space() ... Fix up conflicts in drivers/pci/msi.c and include/linux/pci_regs.h due to the same patches being applied in other branches.
Diffstat (limited to 'arch/x86/pci/acpi.c')
-rw-r--r--arch/x86/pci/acpi.c75
1 files changed, 59 insertions, 16 deletions
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c
index 404f21a3ff9e..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
@@ -24,6 +24,12 @@ static int __init set_use_crs(const struct dmi_system_id *id)
24 return 0; 24 return 0;
25} 25}
26 26
27static int __init set_nouse_crs(const struct dmi_system_id *id)
28{
29 pci_use_crs = false;
30 return 0;
31}
32
27static const struct dmi_system_id pci_use_crs_table[] __initconst = { 33static const struct dmi_system_id pci_use_crs_table[] __initconst = {
28 /* http://bugzilla.kernel.org/show_bug.cgi?id=14183 */ 34 /* http://bugzilla.kernel.org/show_bug.cgi?id=14183 */
29 { 35 {
@@ -54,6 +60,29 @@ static const struct dmi_system_id pci_use_crs_table[] __initconst = {
54 DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."), 60 DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."),
55 }, 61 },
56 }, 62 },
63
64 /* Now for the blacklist.. */
65
66 /* https://bugzilla.redhat.com/show_bug.cgi?id=769657 */
67 {
68 .callback = set_nouse_crs,
69 .ident = "Dell Studio 1557",
70 .matches = {
71 DMI_MATCH(DMI_BOARD_VENDOR, "Dell Inc."),
72 DMI_MATCH(DMI_PRODUCT_NAME, "Studio 1557"),
73 DMI_MATCH(DMI_BIOS_VERSION, "A09"),
74 },
75 },
76 /* https://bugzilla.redhat.com/show_bug.cgi?id=769657 */
77 {
78 .callback = set_nouse_crs,
79 .ident = "Thinkpad SL510",
80 .matches = {
81 DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
82 DMI_MATCH(DMI_BOARD_NAME, "2847DFG"),
83 DMI_MATCH(DMI_BIOS_VERSION, "6JET85WW (1.43 )"),
84 },
85 },
57 {} 86 {}
58}; 87};
59 88
@@ -149,7 +178,7 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
149 struct acpi_resource_address64 addr; 178 struct acpi_resource_address64 addr;
150 acpi_status status; 179 acpi_status status;
151 unsigned long flags; 180 unsigned long flags;
152 u64 start, end; 181 u64 start, orig_end, end;
153 182
154 status = resource_to_addr(acpi_res, &addr); 183 status = resource_to_addr(acpi_res, &addr);
155 if (!ACPI_SUCCESS(status)) 184 if (!ACPI_SUCCESS(status))
@@ -165,7 +194,21 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
165 return AE_OK; 194 return AE_OK;
166 195
167 start = addr.minimum + addr.translation_offset; 196 start = addr.minimum + addr.translation_offset;
168 end = addr.maximum + addr.translation_offset; 197 orig_end = end = addr.maximum + addr.translation_offset;
198
199 /* Exclude non-addressable range or non-addressable portion of range */
200 end = min(end, (u64)iomem_resource.end);
201 if (end <= start) {
202 dev_info(&info->bridge->dev,
203 "host bridge window [%#llx-%#llx] "
204 "(ignored, not CPU addressable)\n", start, orig_end);
205 return AE_OK;
206 } else if (orig_end != end) {
207 dev_info(&info->bridge->dev,
208 "host bridge window [%#llx-%#llx] "
209 "([%#llx-%#llx] ignored, not CPU addressable)\n",
210 start, orig_end, end + 1, orig_end);
211 }
169 212
170 res = &info->res[info->res_num]; 213 res = &info->res[info->res_num];
171 res->name = info->name; 214 res->name = info->name;
@@ -261,23 +304,20 @@ static void add_resources(struct pci_root_info *info)
261 "ignoring host bridge window %pR (conflicts with %s %pR)\n", 304 "ignoring host bridge window %pR (conflicts with %s %pR)\n",
262 res, conflict->name, conflict); 305 res, conflict->name, conflict);
263 else 306 else
264 pci_bus_add_resource(info->bus, res, 0); 307 pci_add_resource(info->resources, res);
265 } 308 }
266} 309}
267 310
268static void 311static void
269get_current_resources(struct acpi_device *device, int busnum, 312get_current_resources(struct acpi_device *device, int busnum,
270 int domain, struct pci_bus *bus) 313 int domain, struct list_head *resources)
271{ 314{
272 struct pci_root_info info; 315 struct pci_root_info info;
273 size_t size; 316 size_t size;
274 317
275 if (pci_use_crs)
276 pci_bus_remove_resources(bus);
277
278 info.bridge = device; 318 info.bridge = device;
279 info.bus = bus;
280 info.res_num = 0; 319 info.res_num = 0;
320 info.resources = resources;
281 acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_resource, 321 acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_resource,
282 &info); 322 &info);
283 if (!info.res_num) 323 if (!info.res_num)
@@ -286,7 +326,7 @@ get_current_resources(struct acpi_device *device, int busnum,
286 size = sizeof(*info.res) * info.res_num; 326 size = sizeof(*info.res) * info.res_num;
287 info.res = kmalloc(size, GFP_KERNEL); 327 info.res = kmalloc(size, GFP_KERNEL);
288 if (!info.res) 328 if (!info.res)
289 goto res_alloc_fail; 329 return;
290 330
291 info.name = kasprintf(GFP_KERNEL, "PCI Bus %04x:%02x", domain, busnum); 331 info.name = kasprintf(GFP_KERNEL, "PCI Bus %04x:%02x", domain, busnum);
292 if (!info.name) 332 if (!info.name)
@@ -301,8 +341,6 @@ get_current_resources(struct acpi_device *device, int busnum,
301 341
302name_alloc_fail: 342name_alloc_fail:
303 kfree(info.res); 343 kfree(info.res);
304res_alloc_fail:
305 return;
306} 344}
307 345
308struct 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)
@@ -310,6 +348,7 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root)
310 struct acpi_device *device = root->device; 348 struct acpi_device *device = root->device;
311 int domain = root->segment; 349 int domain = root->segment;
312 int busnum = root->secondary.start; 350 int busnum = root->secondary.start;
351 LIST_HEAD(resources);
313 struct pci_bus *bus; 352 struct pci_bus *bus;
314 struct pci_sysdata *sd; 353 struct pci_sysdata *sd;
315 int node; 354 int node;
@@ -364,11 +403,15 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root)
364 memcpy(bus->sysdata, sd, sizeof(*sd)); 403 memcpy(bus->sysdata, sd, sizeof(*sd));
365 kfree(sd); 404 kfree(sd);
366 } else { 405 } else {
367 bus = pci_create_bus(NULL, busnum, &pci_root_ops, sd); 406 get_current_resources(device, busnum, domain, &resources);
368 if (bus) { 407 if (list_empty(&resources))
369 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)
370 bus->subordinate = pci_scan_child_bus(bus); 412 bus->subordinate = pci_scan_child_bus(bus);
371 } 413 else
414 pci_free_resource_list(&resources);
372 } 415 }
373 416
374 /* 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,