Skip to content

Commit

Permalink
x86/PCI: Allow x86 platforms to use translation offsets
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Mike Yoknis authored and Bjorn Helgaas committed Nov 7, 2012
1 parent 8f0d816 commit b487393
Showing 1 changed file with 18 additions and 3 deletions.
21 changes: 18 additions & 3 deletions arch/x86/pci/acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ struct pci_root_info {
char name[16];
unsigned int res_num;
struct resource *res;
resource_size_t *res_offset;
struct pci_sysdata sd;
#ifdef CONFIG_PCI_MMCONFIG
bool mcfg_added;
Expand Down Expand Up @@ -305,6 +306,7 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
res->flags = flags;
res->start = start;
res->end = end;
info->res_offset[info->res_num] = addr.translation_offset;

if (!pci_use_crs) {
dev_printk(KERN_DEBUG, &info->bridge->dev,
Expand Down Expand Up @@ -374,14 +376,17 @@ static void add_resources(struct pci_root_info *info,
"ignoring host bridge window %pR (conflicts with %s %pR)\n",
res, conflict->name, conflict);
else
pci_add_resource(resources, res);
pci_add_resource_offset(resources, res,
info->res_offset[i]);
}
}

static void free_pci_root_info_res(struct pci_root_info *info)
{
kfree(info->res);
info->res = NULL;
kfree(info->res_offset);
info->res_offset = NULL;
info->res_num = 0;
}

Expand Down Expand Up @@ -432,10 +437,20 @@ probe_pci_root_info(struct pci_root_info *info, struct acpi_device *device,
return;

size = sizeof(*info->res) * info->res_num;
info->res_num = 0;
info->res = kzalloc(size, GFP_KERNEL);
if (!info->res)
if (!info->res) {
info->res_num = 0;
return;
}

size = sizeof(*info->res_offset) * info->res_num;
info->res_num = 0;
info->res_offset = kzalloc(size, GFP_KERNEL);
if (!info->res_offset) {
kfree(info->res);
info->res = NULL;
return;
}

acpi_walk_resources(device->handle, METHOD_NAME__CRS, setup_resource,
info);
Expand Down

0 comments on commit b487393

Please sign in to comment.