diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-11 21:50:26 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-11 21:50:26 -0500 |
commit | 7b67e751479d50b7f84d1a3cc5216eed5e534b66 (patch) | |
tree | a1a6746857cf65f04dde739fe271bf4143d55eaf /arch/x86/pci/acpi.c | |
parent | 9f13a1fd452f11c18004ba2422a6384b424ec8a9 (diff) | |
parent | 76ccc297018d25d55b789bbd508861ef1e2cdb0c (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.c | 75 |
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 | ||
27 | static int __init set_nouse_crs(const struct dmi_system_id *id) | ||
28 | { | ||
29 | pci_use_crs = false; | ||
30 | return 0; | ||
31 | } | ||
32 | |||
27 | static const struct dmi_system_id pci_use_crs_table[] __initconst = { | 33 | static 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 | ||
268 | static void | 311 | static void |
269 | get_current_resources(struct acpi_device *device, int busnum, | 312 | get_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 | ||
302 | name_alloc_fail: | 342 | name_alloc_fail: |
303 | kfree(info.res); | 343 | kfree(info.res); |
304 | res_alloc_fail: | ||
305 | return; | ||
306 | } | 344 | } |
307 | 345 | ||
308 | 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) |
@@ -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, |