diff options
author | Mike Yoknis <mike.yoknis@hp.com> | 2012-11-07 17:52:20 -0500 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2012-11-07 17:52:20 -0500 |
commit | b4873931cc8c934a9893d5962bde97aca23be983 (patch) | |
tree | f78f75073bb64a52c9f141dfe1715af75d89aa3c /arch/x86/pci | |
parent | 8f0d8163b50e01f398b14bcd4dc039ac5ab18d64 (diff) |
x86/PCI: Allow x86 platforms to use translation offsets
The memory range descriptors in the _CRS control method contain an address
translation offset for host bridges. This value is used to translate
addresses across the bridge. The support to use _TRA values is present for
other architectures but not for X86 platforms.
For existing X86 platforms the _TRA value is zero. Non-zero _TRA values
are expected on future X86 platforms. This change will register that value
with the resource.
Signed-off-by: Mike Yoknis <mike.yoknis@hp.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Diffstat (limited to 'arch/x86/pci')
-rw-r--r-- | arch/x86/pci/acpi.c | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index 192397c98606..9cecffc72e63 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c | |||
@@ -12,6 +12,7 @@ struct pci_root_info { | |||
12 | char name[16]; | 12 | char name[16]; |
13 | unsigned int res_num; | 13 | unsigned int res_num; |
14 | struct resource *res; | 14 | struct resource *res; |
15 | resource_size_t *res_offset; | ||
15 | struct pci_sysdata sd; | 16 | struct pci_sysdata sd; |
16 | #ifdef CONFIG_PCI_MMCONFIG | 17 | #ifdef CONFIG_PCI_MMCONFIG |
17 | bool mcfg_added; | 18 | bool mcfg_added; |
@@ -305,6 +306,7 @@ setup_resource(struct acpi_resource *acpi_res, void *data) | |||
305 | res->flags = flags; | 306 | res->flags = flags; |
306 | res->start = start; | 307 | res->start = start; |
307 | res->end = end; | 308 | res->end = end; |
309 | info->res_offset[info->res_num] = addr.translation_offset; | ||
308 | 310 | ||
309 | if (!pci_use_crs) { | 311 | if (!pci_use_crs) { |
310 | dev_printk(KERN_DEBUG, &info->bridge->dev, | 312 | dev_printk(KERN_DEBUG, &info->bridge->dev, |
@@ -374,7 +376,8 @@ static void add_resources(struct pci_root_info *info, | |||
374 | "ignoring host bridge window %pR (conflicts with %s %pR)\n", | 376 | "ignoring host bridge window %pR (conflicts with %s %pR)\n", |
375 | res, conflict->name, conflict); | 377 | res, conflict->name, conflict); |
376 | else | 378 | else |
377 | pci_add_resource(resources, res); | 379 | pci_add_resource_offset(resources, res, |
380 | info->res_offset[i]); | ||
378 | } | 381 | } |
379 | } | 382 | } |
380 | 383 | ||
@@ -382,6 +385,8 @@ static void free_pci_root_info_res(struct pci_root_info *info) | |||
382 | { | 385 | { |
383 | kfree(info->res); | 386 | kfree(info->res); |
384 | info->res = NULL; | 387 | info->res = NULL; |
388 | kfree(info->res_offset); | ||
389 | info->res_offset = NULL; | ||
385 | info->res_num = 0; | 390 | info->res_num = 0; |
386 | } | 391 | } |
387 | 392 | ||
@@ -432,10 +437,20 @@ probe_pci_root_info(struct pci_root_info *info, struct acpi_device *device, | |||
432 | return; | 437 | return; |
433 | 438 | ||
434 | size = sizeof(*info->res) * info->res_num; | 439 | size = sizeof(*info->res) * info->res_num; |
435 | info->res_num = 0; | ||
436 | info->res = kzalloc(size, GFP_KERNEL); | 440 | info->res = kzalloc(size, GFP_KERNEL); |
437 | if (!info->res) | 441 | if (!info->res) { |
442 | info->res_num = 0; | ||
443 | return; | ||
444 | } | ||
445 | |||
446 | size = sizeof(*info->res_offset) * info->res_num; | ||
447 | info->res_num = 0; | ||
448 | info->res_offset = kzalloc(size, GFP_KERNEL); | ||
449 | if (!info->res_offset) { | ||
450 | kfree(info->res); | ||
451 | info->res = NULL; | ||
438 | return; | 452 | return; |
453 | } | ||
439 | 454 | ||
440 | acpi_walk_resources(device->handle, METHOD_NAME__CRS, setup_resource, | 455 | acpi_walk_resources(device->handle, METHOD_NAME__CRS, setup_resource, |
441 | info); | 456 | info); |