diff options
Diffstat (limited to 'arch/powerpc/kernel/pci-common.c')
-rw-r--r-- | arch/powerpc/kernel/pci-common.c | 300 |
1 files changed, 191 insertions, 109 deletions
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index f36936d9fda3..2538030954d8 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c | |||
@@ -37,13 +37,7 @@ | |||
37 | #include <asm/machdep.h> | 37 | #include <asm/machdep.h> |
38 | #include <asm/ppc-pci.h> | 38 | #include <asm/ppc-pci.h> |
39 | #include <asm/firmware.h> | 39 | #include <asm/firmware.h> |
40 | 40 | #include <asm/eeh.h> | |
41 | #ifdef DEBUG | ||
42 | #include <asm/udbg.h> | ||
43 | #define DBG(fmt...) printk(fmt) | ||
44 | #else | ||
45 | #define DBG(fmt...) | ||
46 | #endif | ||
47 | 41 | ||
48 | static DEFINE_SPINLOCK(hose_spinlock); | 42 | static DEFINE_SPINLOCK(hose_spinlock); |
49 | 43 | ||
@@ -53,8 +47,9 @@ static int global_phb_number; /* Global phb counter */ | |||
53 | /* ISA Memory physical address */ | 47 | /* ISA Memory physical address */ |
54 | resource_size_t isa_mem_base; | 48 | resource_size_t isa_mem_base; |
55 | 49 | ||
56 | /* Default PCI flags is 0 */ | 50 | /* Default PCI flags is 0 on ppc32, modified at boot on ppc64 */ |
57 | unsigned int ppc_pci_flags; | 51 | unsigned int ppc_pci_flags = 0; |
52 | |||
58 | 53 | ||
59 | static struct dma_mapping_ops *pci_dma_ops; | 54 | static struct dma_mapping_ops *pci_dma_ops; |
60 | 55 | ||
@@ -165,8 +160,6 @@ EXPORT_SYMBOL(pci_domain_nr); | |||
165 | */ | 160 | */ |
166 | struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node) | 161 | struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node) |
167 | { | 162 | { |
168 | if (!have_of) | ||
169 | return NULL; | ||
170 | while(node) { | 163 | while(node) { |
171 | struct pci_controller *hose, *tmp; | 164 | struct pci_controller *hose, *tmp; |
172 | list_for_each_entry_safe(hose, tmp, &hose_list, list_node) | 165 | list_for_each_entry_safe(hose, tmp, &hose_list, list_node) |
@@ -208,26 +201,6 @@ char __devinit *pcibios_setup(char *str) | |||
208 | return str; | 201 | return str; |
209 | } | 202 | } |
210 | 203 | ||
211 | void __devinit pcibios_setup_new_device(struct pci_dev *dev) | ||
212 | { | ||
213 | struct dev_archdata *sd = &dev->dev.archdata; | ||
214 | |||
215 | sd->of_node = pci_device_to_OF_node(dev); | ||
216 | |||
217 | DBG("PCI: device %s OF node: %s\n", pci_name(dev), | ||
218 | sd->of_node ? sd->of_node->full_name : "<none>"); | ||
219 | |||
220 | sd->dma_ops = pci_dma_ops; | ||
221 | #ifdef CONFIG_PPC32 | ||
222 | sd->dma_data = (void *)PCI_DRAM_OFFSET; | ||
223 | #endif | ||
224 | set_dev_node(&dev->dev, pcibus_to_node(dev->bus)); | ||
225 | |||
226 | if (ppc_md.pci_dma_dev_setup) | ||
227 | ppc_md.pci_dma_dev_setup(dev); | ||
228 | } | ||
229 | EXPORT_SYMBOL(pcibios_setup_new_device); | ||
230 | |||
231 | /* | 204 | /* |
232 | * Reads the interrupt pin to determine if interrupt is use by card. | 205 | * Reads the interrupt pin to determine if interrupt is use by card. |
233 | * If the interrupt is used, then gets the interrupt line from the | 206 | * If the interrupt is used, then gets the interrupt line from the |
@@ -252,7 +225,7 @@ int pci_read_irq_line(struct pci_dev *pci_dev) | |||
252 | return -1; | 225 | return -1; |
253 | #endif | 226 | #endif |
254 | 227 | ||
255 | DBG("Try to map irq for %s...\n", pci_name(pci_dev)); | 228 | pr_debug("PCI: Try to map irq for %s...\n", pci_name(pci_dev)); |
256 | 229 | ||
257 | #ifdef DEBUG | 230 | #ifdef DEBUG |
258 | memset(&oirq, 0xff, sizeof(oirq)); | 231 | memset(&oirq, 0xff, sizeof(oirq)); |
@@ -276,26 +249,26 @@ int pci_read_irq_line(struct pci_dev *pci_dev) | |||
276 | line == 0xff || line == 0) { | 249 | line == 0xff || line == 0) { |
277 | return -1; | 250 | return -1; |
278 | } | 251 | } |
279 | DBG(" -> no map ! Using line %d (pin %d) from PCI config\n", | 252 | pr_debug(" No map ! Using line %d (pin %d) from PCI config\n", |
280 | line, pin); | 253 | line, pin); |
281 | 254 | ||
282 | virq = irq_create_mapping(NULL, line); | 255 | virq = irq_create_mapping(NULL, line); |
283 | if (virq != NO_IRQ) | 256 | if (virq != NO_IRQ) |
284 | set_irq_type(virq, IRQ_TYPE_LEVEL_LOW); | 257 | set_irq_type(virq, IRQ_TYPE_LEVEL_LOW); |
285 | } else { | 258 | } else { |
286 | DBG(" -> got one, spec %d cells (0x%08x 0x%08x...) on %s\n", | 259 | pr_debug(" Got one, spec %d cells (0x%08x 0x%08x...) on %s\n", |
287 | oirq.size, oirq.specifier[0], oirq.specifier[1], | 260 | oirq.size, oirq.specifier[0], oirq.specifier[1], |
288 | oirq.controller->full_name); | 261 | oirq.controller->full_name); |
289 | 262 | ||
290 | virq = irq_create_of_mapping(oirq.controller, oirq.specifier, | 263 | virq = irq_create_of_mapping(oirq.controller, oirq.specifier, |
291 | oirq.size); | 264 | oirq.size); |
292 | } | 265 | } |
293 | if(virq == NO_IRQ) { | 266 | if(virq == NO_IRQ) { |
294 | DBG(" -> failed to map !\n"); | 267 | pr_debug(" Failed to map !\n"); |
295 | return -1; | 268 | return -1; |
296 | } | 269 | } |
297 | 270 | ||
298 | DBG(" -> mapped to linux irq %d\n", virq); | 271 | pr_debug(" Mapped to linux irq %d\n", virq); |
299 | 272 | ||
300 | pci_dev->irq = virq; | 273 | pci_dev->irq = virq; |
301 | 274 | ||
@@ -397,13 +370,10 @@ static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp, | |||
397 | } | 370 | } |
398 | 371 | ||
399 | /* XXX would be nice to have a way to ask for write-through */ | 372 | /* XXX would be nice to have a way to ask for write-through */ |
400 | prot |= _PAGE_NO_CACHE; | ||
401 | if (write_combine) | 373 | if (write_combine) |
402 | prot &= ~_PAGE_GUARDED; | 374 | return pgprot_noncached_wc(prot); |
403 | else | 375 | else |
404 | prot |= _PAGE_GUARDED; | 376 | return pgprot_noncached(prot); |
405 | |||
406 | return __pgprot(prot); | ||
407 | } | 377 | } |
408 | 378 | ||
409 | /* | 379 | /* |
@@ -414,19 +384,17 @@ static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp, | |||
414 | pgprot_t pci_phys_mem_access_prot(struct file *file, | 384 | pgprot_t pci_phys_mem_access_prot(struct file *file, |
415 | unsigned long pfn, | 385 | unsigned long pfn, |
416 | unsigned long size, | 386 | unsigned long size, |
417 | pgprot_t protection) | 387 | pgprot_t prot) |
418 | { | 388 | { |
419 | struct pci_dev *pdev = NULL; | 389 | struct pci_dev *pdev = NULL; |
420 | struct resource *found = NULL; | 390 | struct resource *found = NULL; |
421 | unsigned long prot = pgprot_val(protection); | ||
422 | resource_size_t offset = ((resource_size_t)pfn) << PAGE_SHIFT; | 391 | resource_size_t offset = ((resource_size_t)pfn) << PAGE_SHIFT; |
423 | int i; | 392 | int i; |
424 | 393 | ||
425 | if (page_is_ram(pfn)) | 394 | if (page_is_ram(pfn)) |
426 | return __pgprot(prot); | 395 | return prot; |
427 | |||
428 | prot |= _PAGE_NO_CACHE | _PAGE_GUARDED; | ||
429 | 396 | ||
397 | prot = pgprot_noncached(prot); | ||
430 | for_each_pci_dev(pdev) { | 398 | for_each_pci_dev(pdev) { |
431 | for (i = 0; i <= PCI_ROM_RESOURCE; i++) { | 399 | for (i = 0; i <= PCI_ROM_RESOURCE; i++) { |
432 | struct resource *rp = &pdev->resource[i]; | 400 | struct resource *rp = &pdev->resource[i]; |
@@ -447,14 +415,14 @@ pgprot_t pci_phys_mem_access_prot(struct file *file, | |||
447 | } | 415 | } |
448 | if (found) { | 416 | if (found) { |
449 | if (found->flags & IORESOURCE_PREFETCH) | 417 | if (found->flags & IORESOURCE_PREFETCH) |
450 | prot &= ~_PAGE_GUARDED; | 418 | prot = pgprot_noncached_wc(prot); |
451 | pci_dev_put(pdev); | 419 | pci_dev_put(pdev); |
452 | } | 420 | } |
453 | 421 | ||
454 | DBG("non-PCI map for %llx, prot: %lx\n", | 422 | pr_debug("PCI: Non-PCI map for %llx, prot: %lx\n", |
455 | (unsigned long long)offset, prot); | 423 | (unsigned long long)offset, pgprot_val(prot)); |
456 | 424 | ||
457 | return __pgprot(prot); | 425 | return prot; |
458 | } | 426 | } |
459 | 427 | ||
460 | 428 | ||
@@ -610,8 +578,7 @@ int pci_mmap_legacy_page_range(struct pci_bus *bus, | |||
610 | pr_debug(" -> mapping phys %llx\n", (unsigned long long)offset); | 578 | pr_debug(" -> mapping phys %llx\n", (unsigned long long)offset); |
611 | 579 | ||
612 | vma->vm_pgoff = offset >> PAGE_SHIFT; | 580 | vma->vm_pgoff = offset >> PAGE_SHIFT; |
613 | vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) | 581 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); |
614 | | _PAGE_NO_CACHE | _PAGE_GUARDED); | ||
615 | return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, | 582 | return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, |
616 | vma->vm_end - vma->vm_start, | 583 | vma->vm_end - vma->vm_start, |
617 | vma->vm_page_prot); | 584 | vma->vm_page_prot); |
@@ -853,15 +820,12 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose, | |||
853 | int pci_proc_domain(struct pci_bus *bus) | 820 | int pci_proc_domain(struct pci_bus *bus) |
854 | { | 821 | { |
855 | struct pci_controller *hose = pci_bus_to_host(bus); | 822 | struct pci_controller *hose = pci_bus_to_host(bus); |
856 | #ifdef CONFIG_PPC64 | 823 | |
857 | return hose->buid != 0; | ||
858 | #else | ||
859 | if (!(ppc_pci_flags & PPC_PCI_ENABLE_PROC_DOMAINS)) | 824 | if (!(ppc_pci_flags & PPC_PCI_ENABLE_PROC_DOMAINS)) |
860 | return 0; | 825 | return 0; |
861 | if (ppc_pci_flags & PPC_PCI_COMPAT_DOMAIN_0) | 826 | if (ppc_pci_flags & PPC_PCI_COMPAT_DOMAIN_0) |
862 | return hose->global_number != 0; | 827 | return hose->global_number != 0; |
863 | return 1; | 828 | return 1; |
864 | #endif | ||
865 | } | 829 | } |
866 | 830 | ||
867 | void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, | 831 | void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, |
@@ -1083,27 +1047,50 @@ static void __devinit pcibios_fixup_bridge(struct pci_bus *bus) | |||
1083 | } | 1047 | } |
1084 | } | 1048 | } |
1085 | 1049 | ||
1086 | static void __devinit __pcibios_fixup_bus(struct pci_bus *bus) | 1050 | void __devinit pcibios_setup_bus_self(struct pci_bus *bus) |
1087 | { | 1051 | { |
1088 | struct pci_dev *dev = bus->self; | 1052 | /* Fix up the bus resources for P2P bridges */ |
1089 | 1053 | if (bus->self != NULL) | |
1090 | pr_debug("PCI: Fixup bus %d (%s)\n", bus->number, dev ? pci_name(dev) : "PHB"); | ||
1091 | |||
1092 | /* Fixup PCI<->PCI bridges. Host bridges are handled separately, for | ||
1093 | * now differently between 32 and 64 bits. | ||
1094 | */ | ||
1095 | if (dev != NULL) | ||
1096 | pcibios_fixup_bridge(bus); | 1054 | pcibios_fixup_bridge(bus); |
1097 | 1055 | ||
1098 | /* Additional setup that is different between 32 and 64 bits for now */ | 1056 | /* Platform specific bus fixups. This is currently only used |
1099 | pcibios_do_bus_setup(bus); | 1057 | * by fsl_pci and I'm hoping to get rid of it at some point |
1100 | 1058 | */ | |
1101 | /* Platform specific bus fixups */ | ||
1102 | if (ppc_md.pcibios_fixup_bus) | 1059 | if (ppc_md.pcibios_fixup_bus) |
1103 | ppc_md.pcibios_fixup_bus(bus); | 1060 | ppc_md.pcibios_fixup_bus(bus); |
1104 | 1061 | ||
1105 | /* Read default IRQs and fixup if necessary */ | 1062 | /* Setup bus DMA mappings */ |
1063 | if (ppc_md.pci_dma_bus_setup) | ||
1064 | ppc_md.pci_dma_bus_setup(bus); | ||
1065 | } | ||
1066 | |||
1067 | void __devinit pcibios_setup_bus_devices(struct pci_bus *bus) | ||
1068 | { | ||
1069 | struct pci_dev *dev; | ||
1070 | |||
1071 | pr_debug("PCI: Fixup bus devices %d (%s)\n", | ||
1072 | bus->number, bus->self ? pci_name(bus->self) : "PHB"); | ||
1073 | |||
1106 | list_for_each_entry(dev, &bus->devices, bus_list) { | 1074 | list_for_each_entry(dev, &bus->devices, bus_list) { |
1075 | struct dev_archdata *sd = &dev->dev.archdata; | ||
1076 | |||
1077 | /* Setup OF node pointer in archdata */ | ||
1078 | sd->of_node = pci_device_to_OF_node(dev); | ||
1079 | |||
1080 | /* Fixup NUMA node as it may not be setup yet by the generic | ||
1081 | * code and is needed by the DMA init | ||
1082 | */ | ||
1083 | set_dev_node(&dev->dev, pcibus_to_node(dev->bus)); | ||
1084 | |||
1085 | /* Hook up default DMA ops */ | ||
1086 | sd->dma_ops = pci_dma_ops; | ||
1087 | sd->dma_data = (void *)PCI_DRAM_OFFSET; | ||
1088 | |||
1089 | /* Additional platform DMA/iommu setup */ | ||
1090 | if (ppc_md.pci_dma_dev_setup) | ||
1091 | ppc_md.pci_dma_dev_setup(dev); | ||
1092 | |||
1093 | /* Read default IRQs and fixup if necessary */ | ||
1107 | pci_read_irq_line(dev); | 1094 | pci_read_irq_line(dev); |
1108 | if (ppc_md.pci_irq_fixup) | 1095 | if (ppc_md.pci_irq_fixup) |
1109 | ppc_md.pci_irq_fixup(dev); | 1096 | ppc_md.pci_irq_fixup(dev); |
@@ -1113,22 +1100,19 @@ static void __devinit __pcibios_fixup_bus(struct pci_bus *bus) | |||
1113 | void __devinit pcibios_fixup_bus(struct pci_bus *bus) | 1100 | void __devinit pcibios_fixup_bus(struct pci_bus *bus) |
1114 | { | 1101 | { |
1115 | /* When called from the generic PCI probe, read PCI<->PCI bridge | 1102 | /* When called from the generic PCI probe, read PCI<->PCI bridge |
1116 | * bases before proceeding | 1103 | * bases. This is -not- called when generating the PCI tree from |
1104 | * the OF device-tree. | ||
1117 | */ | 1105 | */ |
1118 | if (bus->self != NULL) | 1106 | if (bus->self != NULL) |
1119 | pci_read_bridge_bases(bus); | 1107 | pci_read_bridge_bases(bus); |
1120 | __pcibios_fixup_bus(bus); | ||
1121 | } | ||
1122 | EXPORT_SYMBOL(pcibios_fixup_bus); | ||
1123 | 1108 | ||
1124 | /* When building a bus from the OF tree rather than probing, we need a | 1109 | /* Now fixup the bus bus */ |
1125 | * slightly different version of the fixup which doesn't read the | 1110 | pcibios_setup_bus_self(bus); |
1126 | * bridge bases using config space accesses | 1111 | |
1127 | */ | 1112 | /* Now fixup devices on that bus */ |
1128 | void __devinit pcibios_fixup_of_probed_bus(struct pci_bus *bus) | 1113 | pcibios_setup_bus_devices(bus); |
1129 | { | ||
1130 | __pcibios_fixup_bus(bus); | ||
1131 | } | 1114 | } |
1115 | EXPORT_SYMBOL(pcibios_fixup_bus); | ||
1132 | 1116 | ||
1133 | static int skip_isa_ioresource_align(struct pci_dev *dev) | 1117 | static int skip_isa_ioresource_align(struct pci_dev *dev) |
1134 | { | 1118 | { |
@@ -1198,10 +1182,10 @@ static int __init reparent_resources(struct resource *parent, | |||
1198 | *pp = NULL; | 1182 | *pp = NULL; |
1199 | for (p = res->child; p != NULL; p = p->sibling) { | 1183 | for (p = res->child; p != NULL; p = p->sibling) { |
1200 | p->parent = res; | 1184 | p->parent = res; |
1201 | DBG(KERN_INFO "PCI: reparented %s [%llx..%llx] under %s\n", | 1185 | pr_debug("PCI: Reparented %s [%llx..%llx] under %s\n", |
1202 | p->name, | 1186 | p->name, |
1203 | (unsigned long long)p->start, | 1187 | (unsigned long long)p->start, |
1204 | (unsigned long long)p->end, res->name); | 1188 | (unsigned long long)p->end, res->name); |
1205 | } | 1189 | } |
1206 | return 0; | 1190 | return 0; |
1207 | } | 1191 | } |
@@ -1245,9 +1229,12 @@ void pcibios_allocate_bus_resources(struct pci_bus *bus) | |||
1245 | int i; | 1229 | int i; |
1246 | struct resource *res, *pr; | 1230 | struct resource *res, *pr; |
1247 | 1231 | ||
1232 | pr_debug("PCI: Allocating bus resources for %04x:%02x...\n", | ||
1233 | pci_domain_nr(bus), bus->number); | ||
1234 | |||
1248 | for (i = 0; i < PCI_BUS_NUM_RESOURCES; ++i) { | 1235 | for (i = 0; i < PCI_BUS_NUM_RESOURCES; ++i) { |
1249 | if ((res = bus->resource[i]) == NULL || !res->flags | 1236 | if ((res = bus->resource[i]) == NULL || !res->flags |
1250 | || res->start > res->end) | 1237 | || res->start > res->end || res->parent) |
1251 | continue; | 1238 | continue; |
1252 | if (bus->parent == NULL) | 1239 | if (bus->parent == NULL) |
1253 | pr = (res->flags & IORESOURCE_IO) ? | 1240 | pr = (res->flags & IORESOURCE_IO) ? |
@@ -1271,14 +1258,14 @@ void pcibios_allocate_bus_resources(struct pci_bus *bus) | |||
1271 | } | 1258 | } |
1272 | } | 1259 | } |
1273 | 1260 | ||
1274 | DBG("PCI: %s (bus %d) bridge rsrc %d: %016llx-%016llx " | 1261 | pr_debug("PCI: %s (bus %d) bridge rsrc %d: %016llx-%016llx " |
1275 | "[0x%x], parent %p (%s)\n", | 1262 | "[0x%x], parent %p (%s)\n", |
1276 | bus->self ? pci_name(bus->self) : "PHB", | 1263 | bus->self ? pci_name(bus->self) : "PHB", |
1277 | bus->number, i, | 1264 | bus->number, i, |
1278 | (unsigned long long)res->start, | 1265 | (unsigned long long)res->start, |
1279 | (unsigned long long)res->end, | 1266 | (unsigned long long)res->end, |
1280 | (unsigned int)res->flags, | 1267 | (unsigned int)res->flags, |
1281 | pr, (pr && pr->name) ? pr->name : "nil"); | 1268 | pr, (pr && pr->name) ? pr->name : "nil"); |
1282 | 1269 | ||
1283 | if (pr && !(pr->flags & IORESOURCE_UNSET)) { | 1270 | if (pr && !(pr->flags & IORESOURCE_UNSET)) { |
1284 | if (request_resource(pr, res) == 0) | 1271 | if (request_resource(pr, res) == 0) |
@@ -1305,11 +1292,11 @@ static inline void __devinit alloc_resource(struct pci_dev *dev, int idx) | |||
1305 | { | 1292 | { |
1306 | struct resource *pr, *r = &dev->resource[idx]; | 1293 | struct resource *pr, *r = &dev->resource[idx]; |
1307 | 1294 | ||
1308 | DBG("PCI: Allocating %s: Resource %d: %016llx..%016llx [%x]\n", | 1295 | pr_debug("PCI: Allocating %s: Resource %d: %016llx..%016llx [%x]\n", |
1309 | pci_name(dev), idx, | 1296 | pci_name(dev), idx, |
1310 | (unsigned long long)r->start, | 1297 | (unsigned long long)r->start, |
1311 | (unsigned long long)r->end, | 1298 | (unsigned long long)r->end, |
1312 | (unsigned int)r->flags); | 1299 | (unsigned int)r->flags); |
1313 | 1300 | ||
1314 | pr = pci_find_parent_resource(dev, r); | 1301 | pr = pci_find_parent_resource(dev, r); |
1315 | if (!pr || (pr->flags & IORESOURCE_UNSET) || | 1302 | if (!pr || (pr->flags & IORESOURCE_UNSET) || |
@@ -1317,10 +1304,11 @@ static inline void __devinit alloc_resource(struct pci_dev *dev, int idx) | |||
1317 | printk(KERN_WARNING "PCI: Cannot allocate resource region %d" | 1304 | printk(KERN_WARNING "PCI: Cannot allocate resource region %d" |
1318 | " of device %s, will remap\n", idx, pci_name(dev)); | 1305 | " of device %s, will remap\n", idx, pci_name(dev)); |
1319 | if (pr) | 1306 | if (pr) |
1320 | DBG("PCI: parent is %p: %016llx-%016llx [%x]\n", pr, | 1307 | pr_debug("PCI: parent is %p: %016llx-%016llx [%x]\n", |
1321 | (unsigned long long)pr->start, | 1308 | pr, |
1322 | (unsigned long long)pr->end, | 1309 | (unsigned long long)pr->start, |
1323 | (unsigned int)pr->flags); | 1310 | (unsigned long long)pr->end, |
1311 | (unsigned int)pr->flags); | ||
1324 | /* We'll assign a new address later */ | 1312 | /* We'll assign a new address later */ |
1325 | r->flags |= IORESOURCE_UNSET; | 1313 | r->flags |= IORESOURCE_UNSET; |
1326 | r->end -= r->start; | 1314 | r->end -= r->start; |
@@ -1358,7 +1346,8 @@ static void __init pcibios_allocate_resources(int pass) | |||
1358 | * but keep it unregistered. | 1346 | * but keep it unregistered. |
1359 | */ | 1347 | */ |
1360 | u32 reg; | 1348 | u32 reg; |
1361 | DBG("PCI: Switching off ROM of %s\n", pci_name(dev)); | 1349 | pr_debug("PCI: Switching off ROM of %s\n", |
1350 | pci_name(dev)); | ||
1362 | r->flags &= ~IORESOURCE_ROM_ENABLE; | 1351 | r->flags &= ~IORESOURCE_ROM_ENABLE; |
1363 | pci_read_config_dword(dev, dev->rom_base_reg, ®); | 1352 | pci_read_config_dword(dev, dev->rom_base_reg, ®); |
1364 | pci_write_config_dword(dev, dev->rom_base_reg, | 1353 | pci_write_config_dword(dev, dev->rom_base_reg, |
@@ -1383,7 +1372,7 @@ void __init pcibios_resource_survey(void) | |||
1383 | } | 1372 | } |
1384 | 1373 | ||
1385 | if (!(ppc_pci_flags & PPC_PCI_PROBE_ONLY)) { | 1374 | if (!(ppc_pci_flags & PPC_PCI_PROBE_ONLY)) { |
1386 | DBG("PCI: Assigning unassigned resouces...\n"); | 1375 | pr_debug("PCI: Assigning unassigned resouces...\n"); |
1387 | pci_assign_unassigned_resources(); | 1376 | pci_assign_unassigned_resources(); |
1388 | } | 1377 | } |
1389 | 1378 | ||
@@ -1393,9 +1382,11 @@ void __init pcibios_resource_survey(void) | |||
1393 | } | 1382 | } |
1394 | 1383 | ||
1395 | #ifdef CONFIG_HOTPLUG | 1384 | #ifdef CONFIG_HOTPLUG |
1396 | /* This is used by the pSeries hotplug driver to allocate resource | 1385 | |
1386 | /* This is used by the PCI hotplug driver to allocate resource | ||
1397 | * of newly plugged busses. We can try to consolidate with the | 1387 | * of newly plugged busses. We can try to consolidate with the |
1398 | * rest of the code later, for now, keep it as-is | 1388 | * rest of the code later, for now, keep it as-is as our main |
1389 | * resource allocation function doesn't deal with sub-trees yet. | ||
1399 | */ | 1390 | */ |
1400 | void __devinit pcibios_claim_one_bus(struct pci_bus *bus) | 1391 | void __devinit pcibios_claim_one_bus(struct pci_bus *bus) |
1401 | { | 1392 | { |
@@ -1410,6 +1401,14 @@ void __devinit pcibios_claim_one_bus(struct pci_bus *bus) | |||
1410 | 1401 | ||
1411 | if (r->parent || !r->start || !r->flags) | 1402 | if (r->parent || !r->start || !r->flags) |
1412 | continue; | 1403 | continue; |
1404 | |||
1405 | pr_debug("PCI: Claiming %s: " | ||
1406 | "Resource %d: %016llx..%016llx [%x]\n", | ||
1407 | pci_name(dev), i, | ||
1408 | (unsigned long long)r->start, | ||
1409 | (unsigned long long)r->end, | ||
1410 | (unsigned int)r->flags); | ||
1411 | |||
1413 | pci_claim_resource(dev, i); | 1412 | pci_claim_resource(dev, i); |
1414 | } | 1413 | } |
1415 | } | 1414 | } |
@@ -1418,6 +1417,31 @@ void __devinit pcibios_claim_one_bus(struct pci_bus *bus) | |||
1418 | pcibios_claim_one_bus(child_bus); | 1417 | pcibios_claim_one_bus(child_bus); |
1419 | } | 1418 | } |
1420 | EXPORT_SYMBOL_GPL(pcibios_claim_one_bus); | 1419 | EXPORT_SYMBOL_GPL(pcibios_claim_one_bus); |
1420 | |||
1421 | |||
1422 | /* pcibios_finish_adding_to_bus | ||
1423 | * | ||
1424 | * This is to be called by the hotplug code after devices have been | ||
1425 | * added to a bus, this include calling it for a PHB that is just | ||
1426 | * being added | ||
1427 | */ | ||
1428 | void pcibios_finish_adding_to_bus(struct pci_bus *bus) | ||
1429 | { | ||
1430 | pr_debug("PCI: Finishing adding to hotplug bus %04x:%02x\n", | ||
1431 | pci_domain_nr(bus), bus->number); | ||
1432 | |||
1433 | /* Allocate bus and devices resources */ | ||
1434 | pcibios_allocate_bus_resources(bus); | ||
1435 | pcibios_claim_one_bus(bus); | ||
1436 | |||
1437 | /* Add new devices to global lists. Register in proc, sysfs. */ | ||
1438 | pci_bus_add_devices(bus); | ||
1439 | |||
1440 | /* Fixup EEH */ | ||
1441 | eeh_add_device_tree_late(bus); | ||
1442 | } | ||
1443 | EXPORT_SYMBOL_GPL(pcibios_finish_adding_to_bus); | ||
1444 | |||
1421 | #endif /* CONFIG_HOTPLUG */ | 1445 | #endif /* CONFIG_HOTPLUG */ |
1422 | 1446 | ||
1423 | int pcibios_enable_device(struct pci_dev *dev, int mask) | 1447 | int pcibios_enable_device(struct pci_dev *dev, int mask) |
@@ -1428,3 +1452,61 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) | |||
1428 | 1452 | ||
1429 | return pci_enable_resources(dev, mask); | 1453 | return pci_enable_resources(dev, mask); |
1430 | } | 1454 | } |
1455 | |||
1456 | void __devinit pcibios_setup_phb_resources(struct pci_controller *hose) | ||
1457 | { | ||
1458 | struct pci_bus *bus = hose->bus; | ||
1459 | struct resource *res; | ||
1460 | int i; | ||
1461 | |||
1462 | /* Hookup PHB IO resource */ | ||
1463 | bus->resource[0] = res = &hose->io_resource; | ||
1464 | |||
1465 | if (!res->flags) { | ||
1466 | printk(KERN_WARNING "PCI: I/O resource not set for host" | ||
1467 | " bridge %s (domain %d)\n", | ||
1468 | hose->dn->full_name, hose->global_number); | ||
1469 | #ifdef CONFIG_PPC32 | ||
1470 | /* Workaround for lack of IO resource only on 32-bit */ | ||
1471 | res->start = (unsigned long)hose->io_base_virt - isa_io_base; | ||
1472 | res->end = res->start + IO_SPACE_LIMIT; | ||
1473 | res->flags = IORESOURCE_IO; | ||
1474 | #endif /* CONFIG_PPC32 */ | ||
1475 | } | ||
1476 | |||
1477 | pr_debug("PCI: PHB IO resource = %016llx-%016llx [%lx]\n", | ||
1478 | (unsigned long long)res->start, | ||
1479 | (unsigned long long)res->end, | ||
1480 | (unsigned long)res->flags); | ||
1481 | |||
1482 | /* Hookup PHB Memory resources */ | ||
1483 | for (i = 0; i < 3; ++i) { | ||
1484 | res = &hose->mem_resources[i]; | ||
1485 | if (!res->flags) { | ||
1486 | if (i > 0) | ||
1487 | continue; | ||
1488 | printk(KERN_ERR "PCI: Memory resource 0 not set for " | ||
1489 | "host bridge %s (domain %d)\n", | ||
1490 | hose->dn->full_name, hose->global_number); | ||
1491 | #ifdef CONFIG_PPC32 | ||
1492 | /* Workaround for lack of MEM resource only on 32-bit */ | ||
1493 | res->start = hose->pci_mem_offset; | ||
1494 | res->end = (resource_size_t)-1LL; | ||
1495 | res->flags = IORESOURCE_MEM; | ||
1496 | #endif /* CONFIG_PPC32 */ | ||
1497 | } | ||
1498 | bus->resource[i+1] = res; | ||
1499 | |||
1500 | pr_debug("PCI: PHB MEM resource %d = %016llx-%016llx [%lx]\n", i, | ||
1501 | (unsigned long long)res->start, | ||
1502 | (unsigned long long)res->end, | ||
1503 | (unsigned long)res->flags); | ||
1504 | } | ||
1505 | |||
1506 | pr_debug("PCI: PHB MEM offset = %016llx\n", | ||
1507 | (unsigned long long)hose->pci_mem_offset); | ||
1508 | pr_debug("PCI: PHB IO offset = %08lx\n", | ||
1509 | (unsigned long)hose->io_base_virt - _IO_BASE); | ||
1510 | |||
1511 | } | ||
1512 | |||