aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/pci
diff options
context:
space:
mode:
authorMike Yoknis <mike.yoknis@hp.com>2012-11-07 17:52:20 -0500
committerBjorn Helgaas <bhelgaas@google.com>2012-11-07 17:52:20 -0500
commitb4873931cc8c934a9893d5962bde97aca23be983 (patch)
treef78f75073bb64a52c9f141dfe1715af75d89aa3c /arch/x86/pci
parent8f0d8163b50e01f398b14bcd4dc039ac5ab18d64 (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.c21
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);