diff options
Diffstat (limited to 'arch/ia64/pci/pci.c')
-rw-r--r-- | arch/ia64/pci/pci.c | 70 |
1 files changed, 43 insertions, 27 deletions
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index 88641e5095b5..54d9ed444e4a 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c | |||
@@ -33,8 +33,6 @@ | |||
33 | #include <asm/hw_irq.h> | 33 | #include <asm/hw_irq.h> |
34 | 34 | ||
35 | 35 | ||
36 | static int pci_routeirq; | ||
37 | |||
38 | /* | 36 | /* |
39 | * Low-level SAL-based PCI configuration access functions. Note that SAL | 37 | * Low-level SAL-based PCI configuration access functions. Note that SAL |
40 | * calls are already serialized (via sal_lock), so we don't need another | 38 | * calls are already serialized (via sal_lock), so we don't need another |
@@ -139,24 +137,8 @@ static void acpi_map_iosapics(void) | |||
139 | static int __init | 137 | static int __init |
140 | pci_acpi_init (void) | 138 | pci_acpi_init (void) |
141 | { | 139 | { |
142 | struct pci_dev *dev = NULL; | ||
143 | |||
144 | printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n"); | ||
145 | |||
146 | acpi_map_iosapics(); | 140 | acpi_map_iosapics(); |
147 | 141 | ||
148 | if (pci_routeirq) { | ||
149 | /* | ||
150 | * PCI IRQ routing is set up by pci_enable_device(), but we | ||
151 | * also do it here in case there are still broken drivers that | ||
152 | * don't use pci_enable_device(). | ||
153 | */ | ||
154 | printk(KERN_INFO "PCI: Routing interrupts for all devices because \"pci=routeirq\" specified\n"); | ||
155 | for_each_pci_dev(dev) | ||
156 | acpi_pci_irq_enable(dev); | ||
157 | } else | ||
158 | printk(KERN_INFO "PCI: If a device doesn't work, try \"pci=routeirq\". If it helps, post a report\n"); | ||
159 | |||
160 | return 0; | 142 | return 0; |
161 | } | 143 | } |
162 | 144 | ||
@@ -175,6 +157,7 @@ alloc_pci_controller (int seg) | |||
175 | 157 | ||
176 | memset(controller, 0, sizeof(*controller)); | 158 | memset(controller, 0, sizeof(*controller)); |
177 | controller->segment = seg; | 159 | controller->segment = seg; |
160 | controller->node = -1; | ||
178 | return controller; | 161 | return controller; |
179 | } | 162 | } |
180 | 163 | ||
@@ -306,6 +289,7 @@ pci_acpi_scan_root(struct acpi_device *device, int domain, int bus) | |||
306 | unsigned int windows = 0; | 289 | unsigned int windows = 0; |
307 | struct pci_bus *pbus; | 290 | struct pci_bus *pbus; |
308 | char *name; | 291 | char *name; |
292 | int pxm; | ||
309 | 293 | ||
310 | controller = alloc_pci_controller(domain); | 294 | controller = alloc_pci_controller(domain); |
311 | if (!controller) | 295 | if (!controller) |
@@ -313,10 +297,16 @@ pci_acpi_scan_root(struct acpi_device *device, int domain, int bus) | |||
313 | 297 | ||
314 | controller->acpi_handle = device->handle; | 298 | controller->acpi_handle = device->handle; |
315 | 299 | ||
300 | pxm = acpi_get_pxm(controller->acpi_handle); | ||
301 | #ifdef CONFIG_NUMA | ||
302 | if (pxm >= 0) | ||
303 | controller->node = pxm_to_nid_map[pxm]; | ||
304 | #endif | ||
305 | |||
316 | acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_window, | 306 | acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_window, |
317 | &windows); | 307 | &windows); |
318 | controller->window = kmalloc(sizeof(*controller->window) * windows, | 308 | controller->window = kmalloc_node(sizeof(*controller->window) * windows, |
319 | GFP_KERNEL); | 309 | GFP_KERNEL, controller->node); |
320 | if (!controller->window) | 310 | if (!controller->window) |
321 | goto out2; | 311 | goto out2; |
322 | 312 | ||
@@ -330,7 +320,7 @@ pci_acpi_scan_root(struct acpi_device *device, int domain, int bus) | |||
330 | acpi_walk_resources(device->handle, METHOD_NAME__CRS, add_window, | 320 | acpi_walk_resources(device->handle, METHOD_NAME__CRS, add_window, |
331 | &info); | 321 | &info); |
332 | 322 | ||
333 | pbus = pci_scan_bus(bus, &pci_root_ops, controller); | 323 | pbus = pci_scan_bus_parented(NULL, bus, &pci_root_ops, controller); |
334 | if (pbus) | 324 | if (pbus) |
335 | pcibios_setup_root_windows(pbus, controller); | 325 | pcibios_setup_root_windows(pbus, controller); |
336 | 326 | ||
@@ -391,6 +381,25 @@ void pcibios_bus_to_resource(struct pci_dev *dev, | |||
391 | res->end = region->end + offset; | 381 | res->end = region->end + offset; |
392 | } | 382 | } |
393 | 383 | ||
384 | static int __devinit is_valid_resource(struct pci_dev *dev, int idx) | ||
385 | { | ||
386 | unsigned int i, type_mask = IORESOURCE_IO | IORESOURCE_MEM; | ||
387 | struct resource *devr = &dev->resource[idx]; | ||
388 | |||
389 | if (!dev->bus) | ||
390 | return 0; | ||
391 | for (i=0; i<PCI_BUS_NUM_RESOURCES; i++) { | ||
392 | struct resource *busr = dev->bus->resource[i]; | ||
393 | |||
394 | if (!busr || ((busr->flags ^ devr->flags) & type_mask)) | ||
395 | continue; | ||
396 | if ((devr->start) && (devr->start >= busr->start) && | ||
397 | (devr->end <= busr->end)) | ||
398 | return 1; | ||
399 | } | ||
400 | return 0; | ||
401 | } | ||
402 | |||
394 | static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev) | 403 | static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev) |
395 | { | 404 | { |
396 | struct pci_bus_region region; | 405 | struct pci_bus_region region; |
@@ -404,7 +413,8 @@ static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev) | |||
404 | region.start = dev->resource[i].start; | 413 | region.start = dev->resource[i].start; |
405 | region.end = dev->resource[i].end; | 414 | region.end = dev->resource[i].end; |
406 | pcibios_bus_to_resource(dev, &dev->resource[i], ®ion); | 415 | pcibios_bus_to_resource(dev, &dev->resource[i], ®ion); |
407 | pci_claim_resource(dev, i); | 416 | if ((is_valid_resource(dev, i))) |
417 | pci_claim_resource(dev, i); | ||
408 | } | 418 | } |
409 | } | 419 | } |
410 | 420 | ||
@@ -416,6 +426,10 @@ pcibios_fixup_bus (struct pci_bus *b) | |||
416 | { | 426 | { |
417 | struct pci_dev *dev; | 427 | struct pci_dev *dev; |
418 | 428 | ||
429 | if (b->self) { | ||
430 | pci_read_bridge_bases(b); | ||
431 | pcibios_fixup_device_resources(b->self); | ||
432 | } | ||
419 | list_for_each_entry(dev, &b->devices, bus_list) | 433 | list_for_each_entry(dev, &b->devices, bus_list) |
420 | pcibios_fixup_device_resources(dev); | 434 | pcibios_fixup_device_resources(dev); |
421 | 435 | ||
@@ -436,18 +450,24 @@ pcibios_enable_resources (struct pci_dev *dev, int mask) | |||
436 | u16 cmd, old_cmd; | 450 | u16 cmd, old_cmd; |
437 | int idx; | 451 | int idx; |
438 | struct resource *r; | 452 | struct resource *r; |
453 | unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM; | ||
439 | 454 | ||
440 | if (!dev) | 455 | if (!dev) |
441 | return -EINVAL; | 456 | return -EINVAL; |
442 | 457 | ||
443 | pci_read_config_word(dev, PCI_COMMAND, &cmd); | 458 | pci_read_config_word(dev, PCI_COMMAND, &cmd); |
444 | old_cmd = cmd; | 459 | old_cmd = cmd; |
445 | for (idx=0; idx<6; idx++) { | 460 | for (idx=0; idx<PCI_NUM_RESOURCES; idx++) { |
446 | /* Only set up the desired resources. */ | 461 | /* Only set up the desired resources. */ |
447 | if (!(mask & (1 << idx))) | 462 | if (!(mask & (1 << idx))) |
448 | continue; | 463 | continue; |
449 | 464 | ||
450 | r = &dev->resource[idx]; | 465 | r = &dev->resource[idx]; |
466 | if (!(r->flags & type_mask)) | ||
467 | continue; | ||
468 | if ((idx == PCI_ROM_RESOURCE) && | ||
469 | (!(r->flags & IORESOURCE_ROM_ENABLE))) | ||
470 | continue; | ||
451 | if (!r->start && r->end) { | 471 | if (!r->start && r->end) { |
452 | printk(KERN_ERR | 472 | printk(KERN_ERR |
453 | "PCI: Device %s not available because of resource collisions\n", | 473 | "PCI: Device %s not available because of resource collisions\n", |
@@ -459,8 +479,6 @@ pcibios_enable_resources (struct pci_dev *dev, int mask) | |||
459 | if (r->flags & IORESOURCE_MEM) | 479 | if (r->flags & IORESOURCE_MEM) |
460 | cmd |= PCI_COMMAND_MEMORY; | 480 | cmd |= PCI_COMMAND_MEMORY; |
461 | } | 481 | } |
462 | if (dev->resource[PCI_ROM_RESOURCE].start) | ||
463 | cmd |= PCI_COMMAND_MEMORY; | ||
464 | if (cmd != old_cmd) { | 482 | if (cmd != old_cmd) { |
465 | printk("PCI: Enabling device %s (%04x -> %04x)\n", pci_name(dev), old_cmd, cmd); | 483 | printk("PCI: Enabling device %s (%04x -> %04x)\n", pci_name(dev), old_cmd, cmd); |
466 | pci_write_config_word(dev, PCI_COMMAND, cmd); | 484 | pci_write_config_word(dev, PCI_COMMAND, cmd); |
@@ -500,8 +518,6 @@ pcibios_align_resource (void *data, struct resource *res, | |||
500 | char * __init | 518 | char * __init |
501 | pcibios_setup (char *str) | 519 | pcibios_setup (char *str) |
502 | { | 520 | { |
503 | if (!strcmp(str, "routeirq")) | ||
504 | pci_routeirq = 1; | ||
505 | return NULL; | 521 | return NULL; |
506 | } | 522 | } |
507 | 523 | ||