diff options
Diffstat (limited to 'arch/powerpc/kernel/pci_64.c')
-rw-r--r-- | arch/powerpc/kernel/pci_64.c | 118 |
1 files changed, 12 insertions, 106 deletions
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index b9619b9e5e02..794359d8686b 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c | |||
@@ -91,85 +91,6 @@ static void fixup_broken_pcnet32(struct pci_dev* dev) | |||
91 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TRIDENT, PCI_ANY_ID, fixup_broken_pcnet32); | 91 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TRIDENT, PCI_ANY_ID, fixup_broken_pcnet32); |
92 | 92 | ||
93 | 93 | ||
94 | /* | ||
95 | * We need to avoid collisions with `mirrored' VGA ports | ||
96 | * and other strange ISA hardware, so we always want the | ||
97 | * addresses to be allocated in the 0x000-0x0ff region | ||
98 | * modulo 0x400. | ||
99 | * | ||
100 | * Why? Because some silly external IO cards only decode | ||
101 | * the low 10 bits of the IO address. The 0x00-0xff region | ||
102 | * is reserved for motherboard devices that decode all 16 | ||
103 | * bits, so it's ok to allocate at, say, 0x2800-0x28ff, | ||
104 | * but we want to try to avoid allocating at 0x2900-0x2bff | ||
105 | * which might have be mirrored at 0x0100-0x03ff.. | ||
106 | */ | ||
107 | void pcibios_align_resource(void *data, struct resource *res, | ||
108 | resource_size_t size, resource_size_t align) | ||
109 | { | ||
110 | struct pci_dev *dev = data; | ||
111 | struct pci_controller *hose = pci_bus_to_host(dev->bus); | ||
112 | resource_size_t start = res->start; | ||
113 | unsigned long alignto; | ||
114 | |||
115 | if (res->flags & IORESOURCE_IO) { | ||
116 | unsigned long offset = (unsigned long)hose->io_base_virt - | ||
117 | _IO_BASE; | ||
118 | /* Make sure we start at our min on all hoses */ | ||
119 | if (start - offset < PCIBIOS_MIN_IO) | ||
120 | start = PCIBIOS_MIN_IO + offset; | ||
121 | |||
122 | /* | ||
123 | * Put everything into 0x00-0xff region modulo 0x400 | ||
124 | */ | ||
125 | if (start & 0x300) | ||
126 | start = (start + 0x3ff) & ~0x3ff; | ||
127 | |||
128 | } else if (res->flags & IORESOURCE_MEM) { | ||
129 | /* Make sure we start at our min on all hoses */ | ||
130 | if (start - hose->pci_mem_offset < PCIBIOS_MIN_MEM) | ||
131 | start = PCIBIOS_MIN_MEM + hose->pci_mem_offset; | ||
132 | |||
133 | /* Align to multiple of size of minimum base. */ | ||
134 | alignto = max(0x1000UL, align); | ||
135 | start = ALIGN(start, alignto); | ||
136 | } | ||
137 | |||
138 | res->start = start; | ||
139 | } | ||
140 | |||
141 | void __devinit pcibios_claim_one_bus(struct pci_bus *b) | ||
142 | { | ||
143 | struct pci_dev *dev; | ||
144 | struct pci_bus *child_bus; | ||
145 | |||
146 | list_for_each_entry(dev, &b->devices, bus_list) { | ||
147 | int i; | ||
148 | |||
149 | for (i = 0; i < PCI_NUM_RESOURCES; i++) { | ||
150 | struct resource *r = &dev->resource[i]; | ||
151 | |||
152 | if (r->parent || !r->start || !r->flags) | ||
153 | continue; | ||
154 | pci_claim_resource(dev, i); | ||
155 | } | ||
156 | } | ||
157 | |||
158 | list_for_each_entry(child_bus, &b->children, node) | ||
159 | pcibios_claim_one_bus(child_bus); | ||
160 | } | ||
161 | #ifdef CONFIG_HOTPLUG | ||
162 | EXPORT_SYMBOL_GPL(pcibios_claim_one_bus); | ||
163 | #endif | ||
164 | |||
165 | static void __init pcibios_claim_of_setup(void) | ||
166 | { | ||
167 | struct pci_bus *b; | ||
168 | |||
169 | list_for_each_entry(b, &pci_root_buses, node) | ||
170 | pcibios_claim_one_bus(b); | ||
171 | } | ||
172 | |||
173 | static u32 get_int_prop(struct device_node *np, const char *name, u32 def) | 94 | static u32 get_int_prop(struct device_node *np, const char *name, u32 def) |
174 | { | 95 | { |
175 | const u32 *prop; | 96 | const u32 *prop; |
@@ -440,6 +361,7 @@ void __devinit scan_phb(struct pci_controller *hose) | |||
440 | 361 | ||
441 | DBG("Scanning PHB %s\n", node ? node->full_name : "<NO NAME>"); | 362 | DBG("Scanning PHB %s\n", node ? node->full_name : "<NO NAME>"); |
442 | 363 | ||
364 | /* Create an empty bus for the toplevel */ | ||
443 | bus = pci_create_bus(hose->parent, hose->first_busno, hose->ops, node); | 365 | bus = pci_create_bus(hose->parent, hose->first_busno, hose->ops, node); |
444 | if (bus == NULL) { | 366 | if (bus == NULL) { |
445 | printk(KERN_ERR "Failed to create bus for PCI domain %04x\n", | 367 | printk(KERN_ERR "Failed to create bus for PCI domain %04x\n", |
@@ -449,26 +371,16 @@ void __devinit scan_phb(struct pci_controller *hose) | |||
449 | bus->secondary = hose->first_busno; | 371 | bus->secondary = hose->first_busno; |
450 | hose->bus = bus; | 372 | hose->bus = bus; |
451 | 373 | ||
374 | /* Get some IO space for the new PHB */ | ||
452 | pcibios_map_io_space(bus); | 375 | pcibios_map_io_space(bus); |
453 | 376 | ||
377 | /* Wire up PHB bus resources */ | ||
454 | bus->resource[0] = res = &hose->io_resource; | 378 | bus->resource[0] = res = &hose->io_resource; |
455 | if (res->flags && request_resource(&ioport_resource, res)) { | 379 | for (i = 0; i < 3; ++i) |
456 | printk(KERN_ERR "Failed to request PCI IO region " | 380 | bus->resource[i+1] = &hose->mem_resources[i]; |
457 | "on PCI domain %04x\n", hose->global_number); | ||
458 | DBG("res->start = 0x%016lx, res->end = 0x%016lx\n", | ||
459 | res->start, res->end); | ||
460 | } | ||
461 | |||
462 | for (i = 0; i < 3; ++i) { | ||
463 | res = &hose->mem_resources[i]; | ||
464 | bus->resource[i+1] = res; | ||
465 | if (res->flags && request_resource(&iomem_resource, res)) | ||
466 | printk(KERN_ERR "Failed to request PCI memory region " | ||
467 | "on PCI domain %04x\n", hose->global_number); | ||
468 | } | ||
469 | 381 | ||
382 | /* Get probe mode and perform scan */ | ||
470 | mode = PCI_PROBE_NORMAL; | 383 | mode = PCI_PROBE_NORMAL; |
471 | |||
472 | if (node && ppc_md.pci_probe_mode) | 384 | if (node && ppc_md.pci_probe_mode) |
473 | mode = ppc_md.pci_probe_mode(bus); | 385 | mode = ppc_md.pci_probe_mode(bus); |
474 | DBG(" probe mode: %d\n", mode); | 386 | DBG(" probe mode: %d\n", mode); |
@@ -485,12 +397,15 @@ static int __init pcibios_init(void) | |||
485 | { | 397 | { |
486 | struct pci_controller *hose, *tmp; | 398 | struct pci_controller *hose, *tmp; |
487 | 399 | ||
400 | printk(KERN_INFO "PCI: Probing PCI hardware\n"); | ||
401 | |||
488 | /* For now, override phys_mem_access_prot. If we need it, | 402 | /* For now, override phys_mem_access_prot. If we need it, |
489 | * later, we may move that initialization to each ppc_md | 403 | * later, we may move that initialization to each ppc_md |
490 | */ | 404 | */ |
491 | ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot; | 405 | ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot; |
492 | 406 | ||
493 | printk(KERN_DEBUG "PCI: Probing PCI hardware\n"); | 407 | if (pci_probe_only) |
408 | ppc_pci_flags |= PPC_PCI_PROBE_ONLY; | ||
494 | 409 | ||
495 | /* Scan all of the recorded PCI controllers. */ | 410 | /* Scan all of the recorded PCI controllers. */ |
496 | list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { | 411 | list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { |
@@ -498,17 +413,8 @@ static int __init pcibios_init(void) | |||
498 | pci_bus_add_devices(hose->bus); | 413 | pci_bus_add_devices(hose->bus); |
499 | } | 414 | } |
500 | 415 | ||
501 | if (pci_probe_only) | 416 | /* Call common code to handle resource allocation */ |
502 | pcibios_claim_of_setup(); | 417 | pcibios_resource_survey(); |
503 | else | ||
504 | /* FIXME: `else' will be removed when | ||
505 | pci_assign_unassigned_resources() is able to work | ||
506 | correctly with [partially] allocated PCI tree. */ | ||
507 | pci_assign_unassigned_resources(); | ||
508 | |||
509 | /* Call machine dependent final fixup */ | ||
510 | if (ppc_md.pcibios_fixup) | ||
511 | ppc_md.pcibios_fixup(); | ||
512 | 418 | ||
513 | printk(KERN_DEBUG "PCI: Probing PCI hardware done\n"); | 419 | printk(KERN_DEBUG "PCI: Probing PCI hardware done\n"); |
514 | 420 | ||