aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/pci
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /arch/ia64/pci
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'arch/ia64/pci')
-rw-r--r--arch/ia64/pci/fixup.c6
-rw-r--r--arch/ia64/pci/pci.c147
2 files changed, 114 insertions, 39 deletions
diff --git a/arch/ia64/pci/fixup.c b/arch/ia64/pci/fixup.c
index 5dc969dd4ac..f5959c0c181 100644
--- a/arch/ia64/pci/fixup.c
+++ b/arch/ia64/pci/fixup.c
@@ -24,14 +24,14 @@
24 * video device at this point. 24 * video device at this point.
25 */ 25 */
26 26
27static void pci_fixup_video(struct pci_dev *pdev) 27static void __devinit pci_fixup_video(struct pci_dev *pdev)
28{ 28{
29 struct pci_dev *bridge; 29 struct pci_dev *bridge;
30 struct pci_bus *bus; 30 struct pci_bus *bus;
31 u16 config; 31 u16 config;
32 32
33 if ((strcmp(ia64_platform_name, "dig") != 0) 33 if ((strcmp(platform_name, "dig") != 0)
34 && (strcmp(ia64_platform_name, "hpzx1") != 0)) 34 && (strcmp(platform_name, "hpzx1") != 0))
35 return; 35 return;
36 /* Maybe, this machine supports legacy memory map. */ 36 /* Maybe, this machine supports legacy memory map. */
37 37
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index 55b72ad5732..aa2533ae7e9 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -20,10 +20,10 @@
20#include <linux/slab.h> 20#include <linux/slab.h>
21#include <linux/spinlock.h> 21#include <linux/spinlock.h>
22#include <linux/bootmem.h> 22#include <linux/bootmem.h>
23#include <linux/export.h>
24 23
25#include <asm/machvec.h> 24#include <asm/machvec.h>
26#include <asm/page.h> 25#include <asm/page.h>
26#include <asm/system.h>
27#include <asm/io.h> 27#include <asm/io.h>
28#include <asm/sal.h> 28#include <asm/sal.h>
29#include <asm/smp.h> 29#include <asm/smp.h>
@@ -116,7 +116,8 @@ struct pci_ops pci_root_ops = {
116 116
117/* Called by ACPI when it finds a new root bus. */ 117/* Called by ACPI when it finds a new root bus. */
118 118
119static struct pci_controller *alloc_pci_controller(int seg) 119static struct pci_controller * __devinit
120alloc_pci_controller (int seg)
120{ 121{
121 struct pci_controller *controller; 122 struct pci_controller *controller;
122 123
@@ -132,7 +133,6 @@ static struct pci_controller *alloc_pci_controller(int seg)
132struct pci_root_info { 133struct pci_root_info {
133 struct acpi_device *bridge; 134 struct acpi_device *bridge;
134 struct pci_controller *controller; 135 struct pci_controller *controller;
135 struct list_head resources;
136 char *name; 136 char *name;
137}; 137};
138 138
@@ -164,8 +164,8 @@ new_space (u64 phys_base, int sparse)
164 return i; 164 return i;
165} 165}
166 166
167static u64 add_io_space(struct pci_root_info *info, 167static u64 __devinit
168 struct acpi_resource_address64 *addr) 168add_io_space (struct pci_root_info *info, struct acpi_resource_address64 *addr)
169{ 169{
170 struct resource *resource; 170 struct resource *resource;
171 char *name; 171 char *name;
@@ -225,8 +225,8 @@ out:
225 return ~0; 225 return ~0;
226} 226}
227 227
228static acpi_status resource_to_window(struct acpi_resource *resource, 228static acpi_status __devinit resource_to_window(struct acpi_resource *resource,
229 struct acpi_resource_address64 *addr) 229 struct acpi_resource_address64 *addr)
230{ 230{
231 acpi_status status; 231 acpi_status status;
232 232
@@ -248,7 +248,8 @@ static acpi_status resource_to_window(struct acpi_resource *resource,
248 return AE_ERROR; 248 return AE_ERROR;
249} 249}
250 250
251static acpi_status count_window(struct acpi_resource *resource, void *data) 251static acpi_status __devinit
252count_window (struct acpi_resource *resource, void *data)
252{ 253{
253 unsigned int *windows = (unsigned int *) data; 254 unsigned int *windows = (unsigned int *) data;
254 struct acpi_resource_address64 addr; 255 struct acpi_resource_address64 addr;
@@ -261,7 +262,7 @@ static acpi_status count_window(struct acpi_resource *resource, void *data)
261 return AE_OK; 262 return AE_OK;
262} 263}
263 264
264static acpi_status add_window(struct acpi_resource *res, void *data) 265static __devinit acpi_status add_window(struct acpi_resource *res, void *data)
265{ 266{
266 struct pci_root_info *info = data; 267 struct pci_root_info *info = data;
267 struct pci_window *window; 268 struct pci_window *window;
@@ -293,6 +294,7 @@ static acpi_status add_window(struct acpi_resource *res, void *data)
293 window->resource.flags = flags; 294 window->resource.flags = flags;
294 window->resource.start = addr.minimum + offset; 295 window->resource.start = addr.minimum + offset;
295 window->resource.end = window->resource.start + addr.address_length - 1; 296 window->resource.end = window->resource.start + addr.address_length - 1;
297 window->resource.child = NULL;
296 window->offset = offset; 298 window->offset = offset;
297 299
298 if (insert_resource(root, &window->resource)) { 300 if (insert_resource(root, &window->resource)) {
@@ -312,24 +314,34 @@ static acpi_status add_window(struct acpi_resource *res, void *data)
312 &window->resource); 314 &window->resource);
313 } 315 }
314 316
315 /* HP's firmware has a hack to work around a Windows bug.
316 * Ignore these tiny memory ranges */
317 if (!((window->resource.flags & IORESOURCE_MEM) &&
318 (window->resource.end - window->resource.start < 16)))
319 pci_add_resource_offset(&info->resources, &window->resource,
320 window->offset);
321
322 return AE_OK; 317 return AE_OK;
323} 318}
324 319
325struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) 320static void __devinit
321pcibios_setup_root_windows(struct pci_bus *bus, struct pci_controller *ctrl)
322{
323 int i;
324
325 pci_bus_remove_resources(bus);
326 for (i = 0; i < ctrl->windows; i++) {
327 struct resource *res = &ctrl->window[i].resource;
328 /* HP's firmware has a hack to work around a Windows bug.
329 * Ignore these tiny memory ranges */
330 if ((res->flags & IORESOURCE_MEM) &&
331 (res->end - res->start < 16))
332 continue;
333 pci_bus_add_resource(bus, res, 0);
334 }
335}
336
337struct pci_bus * __devinit
338pci_acpi_scan_root(struct acpi_pci_root *root)
326{ 339{
327 struct acpi_device *device = root->device; 340 struct acpi_device *device = root->device;
328 int domain = root->segment; 341 int domain = root->segment;
329 int bus = root->secondary.start; 342 int bus = root->secondary.start;
330 struct pci_controller *controller; 343 struct pci_controller *controller;
331 unsigned int windows = 0; 344 unsigned int windows = 0;
332 struct pci_root_info info;
333 struct pci_bus *pbus; 345 struct pci_bus *pbus;
334 char *name; 346 char *name;
335 int pxm; 347 int pxm;
@@ -346,14 +358,13 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
346 controller->node = pxm_to_node(pxm); 358 controller->node = pxm_to_node(pxm);
347#endif 359#endif
348 360
349 INIT_LIST_HEAD(&info.resources);
350 /* insert busn resource at first */
351 pci_add_resource(&info.resources, &root->secondary);
352 acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_window, 361 acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_window,
353 &windows); 362 &windows);
354 if (windows) { 363 if (windows) {
364 struct pci_root_info info;
365
355 controller->window = 366 controller->window =
356 kzalloc_node(sizeof(*controller->window) * windows, 367 kmalloc_node(sizeof(*controller->window) * windows,
357 GFP_KERNEL, controller->node); 368 GFP_KERNEL, controller->node);
358 if (!controller->window) 369 if (!controller->window)
359 goto out2; 370 goto out2;
@@ -375,14 +386,8 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
375 * should handle the case here, but it appears that IA64 hasn't 386 * should handle the case here, but it appears that IA64 hasn't
376 * such quirk. So we just ignore the case now. 387 * such quirk. So we just ignore the case now.
377 */ 388 */
378 pbus = pci_create_root_bus(NULL, bus, &pci_root_ops, controller, 389 pbus = pci_scan_bus_parented(NULL, bus, &pci_root_ops, controller);
379 &info.resources);
380 if (!pbus) {
381 pci_free_resource_list(&info.resources);
382 return NULL;
383 }
384 390
385 pci_scan_child_bus(pbus);
386 return pbus; 391 return pbus;
387 392
388out3: 393out3:
@@ -393,7 +398,55 @@ out1:
393 return NULL; 398 return NULL;
394} 399}
395 400
396static int is_valid_resource(struct pci_dev *dev, int idx) 401void pcibios_resource_to_bus(struct pci_dev *dev,
402 struct pci_bus_region *region, struct resource *res)
403{
404 struct pci_controller *controller = PCI_CONTROLLER(dev);
405 unsigned long offset = 0;
406 int i;
407
408 for (i = 0; i < controller->windows; i++) {
409 struct pci_window *window = &controller->window[i];
410 if (!(window->resource.flags & res->flags))
411 continue;
412 if (window->resource.start > res->start)
413 continue;
414 if (window->resource.end < res->end)
415 continue;
416 offset = window->offset;
417 break;
418 }
419
420 region->start = res->start - offset;
421 region->end = res->end - offset;
422}
423EXPORT_SYMBOL(pcibios_resource_to_bus);
424
425void pcibios_bus_to_resource(struct pci_dev *dev,
426 struct resource *res, struct pci_bus_region *region)
427{
428 struct pci_controller *controller = PCI_CONTROLLER(dev);
429 unsigned long offset = 0;
430 int i;
431
432 for (i = 0; i < controller->windows; i++) {
433 struct pci_window *window = &controller->window[i];
434 if (!(window->resource.flags & res->flags))
435 continue;
436 if (window->resource.start - window->offset > region->start)
437 continue;
438 if (window->resource.end - window->offset < region->end)
439 continue;
440 offset = window->offset;
441 break;
442 }
443
444 res->start = region->start + offset;
445 res->end = region->end + offset;
446}
447EXPORT_SYMBOL(pcibios_bus_to_resource);
448
449static int __devinit is_valid_resource(struct pci_dev *dev, int idx)
397{ 450{
398 unsigned int i, type_mask = IORESOURCE_IO | IORESOURCE_MEM; 451 unsigned int i, type_mask = IORESOURCE_IO | IORESOURCE_MEM;
399 struct resource *devr = &dev->resource[idx], *busr; 452 struct resource *devr = &dev->resource[idx], *busr;
@@ -411,25 +464,30 @@ static int is_valid_resource(struct pci_dev *dev, int idx)
411 return 0; 464 return 0;
412} 465}
413 466
414static void pcibios_fixup_resources(struct pci_dev *dev, int start, int limit) 467static void __devinit
468pcibios_fixup_resources(struct pci_dev *dev, int start, int limit)
415{ 469{
470 struct pci_bus_region region;
416 int i; 471 int i;
417 472
418 for (i = start; i < limit; i++) { 473 for (i = start; i < limit; i++) {
419 if (!dev->resource[i].flags) 474 if (!dev->resource[i].flags)
420 continue; 475 continue;
476 region.start = dev->resource[i].start;
477 region.end = dev->resource[i].end;
478 pcibios_bus_to_resource(dev, &dev->resource[i], &region);
421 if ((is_valid_resource(dev, i))) 479 if ((is_valid_resource(dev, i)))
422 pci_claim_resource(dev, i); 480 pci_claim_resource(dev, i);
423 } 481 }
424} 482}
425 483
426void pcibios_fixup_device_resources(struct pci_dev *dev) 484void __devinit pcibios_fixup_device_resources(struct pci_dev *dev)
427{ 485{
428 pcibios_fixup_resources(dev, 0, PCI_BRIDGE_RESOURCES); 486 pcibios_fixup_resources(dev, 0, PCI_BRIDGE_RESOURCES);
429} 487}
430EXPORT_SYMBOL_GPL(pcibios_fixup_device_resources); 488EXPORT_SYMBOL_GPL(pcibios_fixup_device_resources);
431 489
432static void pcibios_fixup_bridge_resources(struct pci_dev *dev) 490static void __devinit pcibios_fixup_bridge_resources(struct pci_dev *dev)
433{ 491{
434 pcibios_fixup_resources(dev, PCI_BRIDGE_RESOURCES, PCI_NUM_RESOURCES); 492 pcibios_fixup_resources(dev, PCI_BRIDGE_RESOURCES, PCI_NUM_RESOURCES);
435} 493}
@@ -437,22 +495,30 @@ static void pcibios_fixup_bridge_resources(struct pci_dev *dev)
437/* 495/*
438 * Called after each bus is probed, but before its children are examined. 496 * Called after each bus is probed, but before its children are examined.
439 */ 497 */
440void pcibios_fixup_bus(struct pci_bus *b) 498void __devinit
499pcibios_fixup_bus (struct pci_bus *b)
441{ 500{
442 struct pci_dev *dev; 501 struct pci_dev *dev;
443 502
444 if (b->self) { 503 if (b->self) {
445 pci_read_bridge_bases(b); 504 pci_read_bridge_bases(b);
446 pcibios_fixup_bridge_resources(b->self); 505 pcibios_fixup_bridge_resources(b->self);
506 } else {
507 pcibios_setup_root_windows(b, b->sysdata);
447 } 508 }
448 list_for_each_entry(dev, &b->devices, bus_list) 509 list_for_each_entry(dev, &b->devices, bus_list)
449 pcibios_fixup_device_resources(dev); 510 pcibios_fixup_device_resources(dev);
450 platform_pci_fixup_bus(b); 511 platform_pci_fixup_bus(b);
512
513 return;
451} 514}
452 515
453void pcibios_set_master (struct pci_dev *dev) 516void __devinit
517pcibios_update_irq (struct pci_dev *dev, int irq)
454{ 518{
455 /* No special bus mastering setup handling */ 519 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
520
521 /* ??? FIXME -- record old value for shutdown. */
456} 522}
457 523
458int 524int
@@ -484,6 +550,15 @@ pcibios_align_resource (void *data, const struct resource *res,
484 return res->start; 550 return res->start;
485} 551}
486 552
553/*
554 * PCI BIOS setup, always defaults to SAL interface
555 */
556char * __init
557pcibios_setup (char *str)
558{
559 return str;
560}
561
487int 562int
488pci_mmap_page_range (struct pci_dev *dev, struct vm_area_struct *vma, 563pci_mmap_page_range (struct pci_dev *dev, struct vm_area_struct *vma,
489 enum pci_mmap_state mmap_state, int write_combine) 564 enum pci_mmap_state mmap_state, int write_combine)