aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/pci
diff options
context:
space:
mode:
authorYijing Wang <wangyijing@huawei.com>2013-06-06 03:34:48 -0400
committerTony Luck <tony.luck@intel.com>2013-06-18 12:44:10 -0400
commit5cd7595dea8d54d93124cfc4faec103ce56ab03d (patch)
tree2c0fb4985707e51283f4fac48c7079dbed0be6df /arch/ia64/pci
parent2ead66b5472542d82f31c3b6418b23ace3dac87d (diff)
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/pci')
-rw-r--r--arch/ia64/pci/pci.c65
1 files changed, 37 insertions, 28 deletions
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 {
134 struct acpi_device *bridge; 134 struct acpi_device *bridge;
135 struct pci_controller *controller; 135 struct pci_controller *controller;
136 struct list_head resources; 136 struct list_head resources;
137 struct resource *res;
138 resource_size_t *res_offset;
139 unsigned int res_num;
137 char *name; 140 char *name;
138}; 141};
139 142
@@ -265,7 +268,7 @@ static acpi_status count_window(struct acpi_resource *resource, void *data)
265static acpi_status add_window(struct acpi_resource *res, void *data) 268static acpi_status add_window(struct acpi_resource *res, void *data)
266{ 269{
267 struct pci_root_info *info = data; 270 struct pci_root_info *info = data;
268 struct pci_window *window; 271 struct resource *resource;
269 struct acpi_resource_address64 addr; 272 struct acpi_resource_address64 addr;
270 acpi_status status; 273 acpi_status status;
271 unsigned long flags, offset = 0; 274 unsigned long flags, offset = 0;
@@ -289,37 +292,36 @@ static acpi_status add_window(struct acpi_resource *res, void *data)
289 } else 292 } else
290 return AE_OK; 293 return AE_OK;
291 294
292 window = &info->controller->window[info->controller->windows++]; 295 resource = &info->res[info->res_num];
293 window->resource.name = info->name; 296 resource->name = info->name;
294 window->resource.flags = flags; 297 resource->flags = flags;
295 window->resource.start = addr.minimum + offset; 298 resource->start = addr.minimum + offset;
296 window->resource.end = window->resource.start + addr.address_length - 1; 299 resource->end = resource->start + addr.address_length - 1;
297 window->offset = offset; 300 info->res_offset[info->res_num] = offset;
298 301
299 if (insert_resource(root, &window->resource)) { 302 if (insert_resource(root, resource)) {
300 dev_err(&info->bridge->dev, 303 dev_err(&info->bridge->dev,
301 "can't allocate host bridge window %pR\n", 304 "can't allocate host bridge window %pR\n",
302 &window->resource); 305 resource);
303 } else { 306 } else {
304 if (offset) 307 if (offset)
305 dev_info(&info->bridge->dev, "host bridge window %pR " 308 dev_info(&info->bridge->dev, "host bridge window %pR "
306 "(PCI address [%#llx-%#llx])\n", 309 "(PCI address [%#llx-%#llx])\n",
307 &window->resource, 310 resource,
308 window->resource.start - offset, 311 resource->start - offset,
309 window->resource.end - offset); 312 resource->end - offset);
310 else 313 else
311 dev_info(&info->bridge->dev, 314 dev_info(&info->bridge->dev,
312 "host bridge window %pR\n", 315 "host bridge window %pR\n", resource);
313 &window->resource);
314 } 316 }
315
316 /* HP's firmware has a hack to work around a Windows bug. 317 /* HP's firmware has a hack to work around a Windows bug.
317 * Ignore these tiny memory ranges */ 318 * Ignore these tiny memory ranges */
318 if (!((window->resource.flags & IORESOURCE_MEM) && 319 if (!((resource->flags & IORESOURCE_MEM) &&
319 (window->resource.end - window->resource.start < 16))) 320 (resource->end - resource->start < 16)))
320 pci_add_resource_offset(&info->resources, &window->resource, 321 pci_add_resource_offset(&info->resources, resource,
321 window->offset); 322 info->res_offset[info->res_num]);
322 323
324 info->res_num++;
323 return AE_OK; 325 return AE_OK;
324} 326}
325 327
@@ -329,7 +331,6 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
329 int domain = root->segment; 331 int domain = root->segment;
330 int bus = root->secondary.start; 332 int bus = root->secondary.start;
331 struct pci_controller *controller; 333 struct pci_controller *controller;
332 unsigned int windows = 0;
333 struct pci_root_info info; 334 struct pci_root_info info;
334 struct pci_bus *pbus; 335 struct pci_bus *pbus;
335 char *name; 336 char *name;
@@ -351,22 +352,29 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
351 /* insert busn resource at first */ 352 /* insert busn resource at first */
352 pci_add_resource(&info.resources, &root->secondary); 353 pci_add_resource(&info.resources, &root->secondary);
353 acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_window, 354 acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_window,
354 &windows); 355 &info.res_num);
355 if (windows) { 356 if (info.res_num) {
356 controller->window = 357 info.res =
357 kzalloc_node(sizeof(*controller->window) * windows, 358 kzalloc_node(sizeof(*info.res) * info.res_num,
358 GFP_KERNEL, controller->node); 359 GFP_KERNEL, controller->node);
359 if (!controller->window) 360 if (!info.res)
360 goto out2; 361 goto out2;
361 362
363 info.res_offset =
364 kzalloc_node(sizeof(*info.res_offset) * info.res_num,
365 GFP_KERNEL, controller->node);
366 if (!info.res_offset)
367 goto out3;
368
362 name = kmalloc(16, GFP_KERNEL); 369 name = kmalloc(16, GFP_KERNEL);
363 if (!name) 370 if (!name)
364 goto out3; 371 goto out4;
365 372
366 sprintf(name, "PCI Bus %04x:%02x", domain, bus); 373 sprintf(name, "PCI Bus %04x:%02x", domain, bus);
367 info.bridge = device; 374 info.bridge = device;
368 info.controller = controller; 375 info.controller = controller;
369 info.name = name; 376 info.name = name;
377 info.res_num = 0;
370 acpi_walk_resources(device->handle, METHOD_NAME__CRS, 378 acpi_walk_resources(device->handle, METHOD_NAME__CRS,
371 add_window, &info); 379 add_window, &info);
372 } 380 }
@@ -385,9 +393,10 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
385 393
386 pci_scan_child_bus(pbus); 394 pci_scan_child_bus(pbus);
387 return pbus; 395 return pbus;
388 396out4:
397 kfree(info.res_offset);
389out3: 398out3:
390 kfree(controller->window); 399 kfree(info.res);
391out2: 400out2:
392 kfree(controller); 401 kfree(controller);
393out1: 402out1: