diff options
author | Yijing Wang <wangyijing@huawei.com> | 2013-06-06 15:34:48 +0800 |
---|---|---|
committer | Tony Luck <tony.luck@intel.com> | 2013-06-18 09:44:10 -0700 |
commit | 5cd7595dea8d54d93124cfc4faec103ce56ab03d (patch) | |
tree | 2c0fb4985707e51283f4fac48c7079dbed0be6df /arch/ia64 | |
parent | 2ead66b5472542d82f31c3b6418b23ace3dac87d (diff) | |
download | blackbird-op-linux-5cd7595dea8d54d93124cfc4faec103ce56ab03d.tar.gz blackbird-op-linux-5cd7595dea8d54d93124cfc4faec103ce56ab03d.zip |
PCI/IA64: embed pci hostbridge resources into pci_root_info
Currently, pcibios_resource_to_bus() and pcibios_bus_to_resource()
functions use pci_host_bridge to translate bus side address from/to
cpu side address. The pci_window in pci_controller never be used again.
So we remove pci_window in pci_controller and embed hostbridge resource
into pci_root_info. Bjorn suggested to implement hostbridge resources
release in IA64 like in X86, this patch is to prepare for that.
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Thierry Reding <thierry.reding@avionic-design.de>
Cc: linux-ia64@vger.kernel.org
Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'arch/ia64')
-rw-r--r-- | arch/ia64/include/asm/pci.h | 9 | ||||
-rw-r--r-- | arch/ia64/pci/pci.c | 65 |
2 files changed, 38 insertions, 36 deletions
diff --git a/arch/ia64/include/asm/pci.h b/arch/ia64/include/asm/pci.h index 5e04b591e423..a7ebe5f97e63 100644 --- a/arch/ia64/include/asm/pci.h +++ b/arch/ia64/include/asm/pci.h @@ -89,23 +89,16 @@ extern int pci_mmap_legacy_page_range(struct pci_bus *bus, #define pci_legacy_read platform_pci_legacy_read #define pci_legacy_write platform_pci_legacy_write -struct pci_window { - struct resource resource; - u64 offset; -}; - struct pci_controller { void *acpi_handle; void *iommu; int segment; int node; /* nearest node with memory or -1 for global allocation */ - unsigned int windows; - struct pci_window *window; - void *platform_data; }; + #define PCI_CONTROLLER(busdev) ((struct pci_controller *) busdev->sysdata) #define pci_domain_nr(busdev) (PCI_CONTROLLER(busdev)->segment) diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index de1474ff0bc5..82eb8b2a4f1d 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c @@ -134,6 +134,9 @@ struct pci_root_info { struct acpi_device *bridge; struct pci_controller *controller; struct list_head resources; + struct resource *res; + resource_size_t *res_offset; + unsigned int res_num; char *name; }; @@ -265,7 +268,7 @@ static acpi_status count_window(struct acpi_resource *resource, void *data) static acpi_status add_window(struct acpi_resource *res, void *data) { struct pci_root_info *info = data; - struct pci_window *window; + struct resource *resource; struct acpi_resource_address64 addr; acpi_status status; unsigned long flags, offset = 0; @@ -289,37 +292,36 @@ static acpi_status add_window(struct acpi_resource *res, void *data) } else return AE_OK; - window = &info->controller->window[info->controller->windows++]; - window->resource.name = info->name; - window->resource.flags = flags; - window->resource.start = addr.minimum + offset; - window->resource.end = window->resource.start + addr.address_length - 1; - window->offset = offset; + resource = &info->res[info->res_num]; + resource->name = info->name; + resource->flags = flags; + resource->start = addr.minimum + offset; + resource->end = resource->start + addr.address_length - 1; + info->res_offset[info->res_num] = offset; - if (insert_resource(root, &window->resource)) { + if (insert_resource(root, resource)) { dev_err(&info->bridge->dev, "can't allocate host bridge window %pR\n", - &window->resource); + resource); } else { if (offset) dev_info(&info->bridge->dev, "host bridge window %pR " "(PCI address [%#llx-%#llx])\n", - &window->resource, - window->resource.start - offset, - window->resource.end - offset); + resource, + resource->start - offset, + resource->end - offset); else dev_info(&info->bridge->dev, - "host bridge window %pR\n", - &window->resource); + "host bridge window %pR\n", resource); } - /* HP's firmware has a hack to work around a Windows bug. * Ignore these tiny memory ranges */ - if (!((window->resource.flags & IORESOURCE_MEM) && - (window->resource.end - window->resource.start < 16))) - pci_add_resource_offset(&info->resources, &window->resource, - window->offset); + if (!((resource->flags & IORESOURCE_MEM) && + (resource->end - resource->start < 16))) + pci_add_resource_offset(&info->resources, resource, + info->res_offset[info->res_num]); + info->res_num++; return AE_OK; } @@ -329,7 +331,6 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) int domain = root->segment; int bus = root->secondary.start; struct pci_controller *controller; - unsigned int windows = 0; struct pci_root_info info; struct pci_bus *pbus; char *name; @@ -351,22 +352,29 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) /* insert busn resource at first */ pci_add_resource(&info.resources, &root->secondary); acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_window, - &windows); - if (windows) { - controller->window = - kzalloc_node(sizeof(*controller->window) * windows, + &info.res_num); + if (info.res_num) { + info.res = + kzalloc_node(sizeof(*info.res) * info.res_num, GFP_KERNEL, controller->node); - if (!controller->window) + if (!info.res) goto out2; + info.res_offset = + kzalloc_node(sizeof(*info.res_offset) * info.res_num, + GFP_KERNEL, controller->node); + if (!info.res_offset) + goto out3; + name = kmalloc(16, GFP_KERNEL); if (!name) - goto out3; + goto out4; sprintf(name, "PCI Bus %04x:%02x", domain, bus); info.bridge = device; info.controller = controller; info.name = name; + info.res_num = 0; acpi_walk_resources(device->handle, METHOD_NAME__CRS, add_window, &info); } @@ -385,9 +393,10 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) pci_scan_child_bus(pbus); return pbus; - +out4: + kfree(info.res_offset); out3: - kfree(controller->window); + kfree(info.res); out2: kfree(controller); out1: |