aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2005-11-15 00:05:33 -0500
committerPaul Mackerras <paulus@samba.org>2005-11-15 21:29:46 -0500
commitb5166cc252190be80465f3b4f050e4a0310f71af (patch)
tree565d11c2ea25d1553489d6c8a9b4d2c00e110288 /arch/powerpc/platforms
parentf9e4ec57c66586d0c165ed9373efaf9e329d5766 (diff)
[PATCH] powerpc: pci_64 fixes & cleanups
I discovered that in some cases (PowerMac for example) we wouldn't properly map the PCI IO space on recent kernels. In addition, the code for initializing PCI host bridges was scattered all over the place with some duplication between platforms. This patch fixes the problem and does a small cleanup by creating a pcibios_alloc_controller() in pci_64.c that is similar to the one in pci_32.c (just takes an additional device node argument) that takes care of all the grunt allocation and initialisation work. It should work for both boot time and dynamically allocated PHBs. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/platforms')
-rw-r--r--arch/powerpc/platforms/iseries/pci.c3
-rw-r--r--arch/powerpc/platforms/maple/pci.c16
-rw-r--r--arch/powerpc/platforms/powermac/pci.c62
3 files changed, 34 insertions, 47 deletions
diff --git a/arch/powerpc/platforms/iseries/pci.c b/arch/powerpc/platforms/iseries/pci.c
index 4b75131773a6..dafc518fbb83 100644
--- a/arch/powerpc/platforms/iseries/pci.c
+++ b/arch/powerpc/platforms/iseries/pci.c
@@ -244,10 +244,9 @@ unsigned long __init find_and_init_phbs(void)
244 if (ret == 0) { 244 if (ret == 0) {
245 printk("bus %d appears to exist\n", bus); 245 printk("bus %d appears to exist\n", bus);
246 246
247 phb = (struct pci_controller *)kmalloc(sizeof(struct pci_controller), GFP_KERNEL); 247 phb = pcibios_alloc_controller(NULL);
248 if (phb == NULL) 248 if (phb == NULL)
249 return -ENOMEM; 249 return -ENOMEM;
250 pci_setup_pci_controller(phb);
251 250
252 phb->pci_mem_offset = phb->local_number = bus; 251 phb->pci_mem_offset = phb->local_number = bus;
253 phb->first_busno = bus; 252 phb->first_busno = bus;
diff --git a/arch/powerpc/platforms/maple/pci.c b/arch/powerpc/platforms/maple/pci.c
index 895aeb3f75d0..f40451da037c 100644
--- a/arch/powerpc/platforms/maple/pci.c
+++ b/arch/powerpc/platforms/maple/pci.c
@@ -326,26 +326,12 @@ static int __init add_bridge(struct device_node *dev)
326 dev->full_name); 326 dev->full_name);
327 } 327 }
328 328
329 hose = alloc_bootmem(sizeof(struct pci_controller)); 329 hose = pcibios_alloc_controller(dev);
330 if (hose == NULL) 330 if (hose == NULL)
331 return -ENOMEM; 331 return -ENOMEM;
332 pci_setup_pci_controller(hose);
333
334 hose->arch_data = dev;
335 hose->first_busno = bus_range ? bus_range[0] : 0; 332 hose->first_busno = bus_range ? bus_range[0] : 0;
336 hose->last_busno = bus_range ? bus_range[1] : 0xff; 333 hose->last_busno = bus_range ? bus_range[1] : 0xff;
337 334
338 of_prop = alloc_bootmem(sizeof(struct property) +
339 sizeof(hose->global_number));
340 if (of_prop) {
341 memset(of_prop, 0, sizeof(struct property));
342 of_prop->name = "linux,pci-domain";
343 of_prop->length = sizeof(hose->global_number);
344 of_prop->value = (unsigned char *)&of_prop[1];
345 memcpy(of_prop->value, &hose->global_number, sizeof(hose->global_number));
346 prom_add_property(dev, of_prop);
347 }
348
349 disp_name = NULL; 335 disp_name = NULL;
350 if (device_is_compatible(dev, "u3-agp")) { 336 if (device_is_compatible(dev, "u3-agp")) {
351 setup_u3_agp(hose); 337 setup_u3_agp(hose);
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c
index dfd41b9781a9..443be526cde7 100644
--- a/arch/powerpc/platforms/powermac/pci.c
+++ b/arch/powerpc/platforms/powermac/pci.c
@@ -640,15 +640,16 @@ static void __init setup_u3_ht(struct pci_controller* hose)
640 * the reg address cell, we shall fix that by killing struct 640 * the reg address cell, we shall fix that by killing struct
641 * reg_property and using some accessor functions instead 641 * reg_property and using some accessor functions instead
642 */ 642 */
643 hose->cfg_data = (volatile unsigned char *)ioremap(0xf2000000, 0x02000000); 643 hose->cfg_data = (volatile unsigned char *)ioremap(0xf2000000,
644 0x02000000);
644 645
645 /* 646 /*
646 * /ht node doesn't expose a "ranges" property, so we "remove" regions that 647 * /ht node doesn't expose a "ranges" property, so we "remove"
647 * have been allocated to AGP. So far, this version of the code doesn't assign 648 * regions that have been allocated to AGP. So far, this version of
648 * any of the 0xfxxxxxxx "fine" memory regions to /ht. 649 * the code doesn't assign any of the 0xfxxxxxxx "fine" memory regions
649 * We need to fix that sooner or later by either parsing all child "ranges" 650 * to /ht. We need to fix that sooner or later by either parsing all
650 * properties or figuring out the U3 address space decoding logic and 651 * child "ranges" properties or figuring out the U3 address space
651 * then read its configuration register (if any). 652 * decoding logic and then read its configuration register (if any).
652 */ 653 */
653 hose->io_base_phys = 0xf4000000; 654 hose->io_base_phys = 0xf4000000;
654 hose->pci_io_size = 0x00400000; 655 hose->pci_io_size = 0x00400000;
@@ -671,10 +672,10 @@ static void __init setup_u3_ht(struct pci_controller* hose)
671 return; 672 return;
672 } 673 }
673 674
674 /* We "remove" the AGP resources from the resources allocated to HT, that 675 /* We "remove" the AGP resources from the resources allocated to HT,
675 * is we create "holes". However, that code does assumptions that so far 676 * that is we create "holes". However, that code does assumptions
676 * happen to be true (cross fingers...), typically that resources in the 677 * that so far happen to be true (cross fingers...), typically that
677 * AGP node are properly ordered 678 * resources in the AGP node are properly ordered
678 */ 679 */
679 cur = 0; 680 cur = 0;
680 for (i=0; i<3; i++) { 681 for (i=0; i<3; i++) {
@@ -684,23 +685,30 @@ static void __init setup_u3_ht(struct pci_controller* hose)
684 /* We don't care about "fine" resources */ 685 /* We don't care about "fine" resources */
685 if (res->start >= 0xf0000000) 686 if (res->start >= 0xf0000000)
686 continue; 687 continue;
687 /* Check if it's just a matter of "shrinking" us in one direction */ 688 /* Check if it's just a matter of "shrinking" us in one
689 * direction
690 */
688 if (hose->mem_resources[cur].start == res->start) { 691 if (hose->mem_resources[cur].start == res->start) {
689 DBG("U3/HT: shrink start of %d, %08lx -> %08lx\n", 692 DBG("U3/HT: shrink start of %d, %08lx -> %08lx\n",
690 cur, hose->mem_resources[cur].start, res->end + 1); 693 cur, hose->mem_resources[cur].start,
694 res->end + 1);
691 hose->mem_resources[cur].start = res->end + 1; 695 hose->mem_resources[cur].start = res->end + 1;
692 continue; 696 continue;
693 } 697 }
694 if (hose->mem_resources[cur].end == res->end) { 698 if (hose->mem_resources[cur].end == res->end) {
695 DBG("U3/HT: shrink end of %d, %08lx -> %08lx\n", 699 DBG("U3/HT: shrink end of %d, %08lx -> %08lx\n",
696 cur, hose->mem_resources[cur].end, res->start - 1); 700 cur, hose->mem_resources[cur].end,
701 res->start - 1);
697 hose->mem_resources[cur].end = res->start - 1; 702 hose->mem_resources[cur].end = res->start - 1;
698 continue; 703 continue;
699 } 704 }
700 /* No, it's not the case, we need a hole */ 705 /* No, it's not the case, we need a hole */
701 if (cur == 2) { 706 if (cur == 2) {
702 /* not enough resources for a hole, we drop part of the range */ 707 /* not enough resources for a hole, we drop part
703 printk(KERN_WARNING "Running out of resources for /ht host !\n"); 708 * of the range
709 */
710 printk(KERN_WARNING "Running out of resources"
711 " for /ht host !\n");
704 hose->mem_resources[cur].end = res->start - 1; 712 hose->mem_resources[cur].end = res->start - 1;
705 continue; 713 continue;
706 } 714 }
@@ -714,17 +722,6 @@ static void __init setup_u3_ht(struct pci_controller* hose)
714 hose->mem_resources[cur-1].end = res->start - 1; 722 hose->mem_resources[cur-1].end = res->start - 1;
715 } 723 }
716} 724}
717
718/* XXX this needs to be converged between ppc32 and ppc64... */
719static struct pci_controller * __init pcibios_alloc_controller(void)
720{
721 struct pci_controller *hose;
722
723 hose = alloc_bootmem(sizeof(struct pci_controller));
724 if (hose)
725 pci_setup_pci_controller(hose);
726 return hose;
727}
728#endif 725#endif
729 726
730/* 727/*
@@ -756,11 +753,16 @@ static int __init add_bridge(struct device_node *dev)
756#endif 753#endif
757 bus_range = (int *) get_property(dev, "bus-range", &len); 754 bus_range = (int *) get_property(dev, "bus-range", &len);
758 if (bus_range == NULL || len < 2 * sizeof(int)) { 755 if (bus_range == NULL || len < 2 * sizeof(int)) {
759 printk(KERN_WARNING "Can't get bus-range for %s, assume bus 0\n", 756 printk(KERN_WARNING "Can't get bus-range for %s, assume"
760 dev->full_name); 757 " bus 0\n", dev->full_name);
761 } 758 }
762 759
760 /* XXX Different prototypes, to be merged */
761#ifdef CONFIG_PPC64
762 hose = pcibios_alloc_controller(dev);
763#else
763 hose = pcibios_alloc_controller(); 764 hose = pcibios_alloc_controller();
765#endif
764 if (!hose) 766 if (!hose)
765 return -ENOMEM; 767 return -ENOMEM;
766 hose->arch_data = dev; 768 hose->arch_data = dev;
@@ -768,7 +770,7 @@ static int __init add_bridge(struct device_node *dev)
768 hose->last_busno = bus_range ? bus_range[1] : 0xff; 770 hose->last_busno = bus_range ? bus_range[1] : 0xff;
769 771
770 disp_name = NULL; 772 disp_name = NULL;
771#ifdef CONFIG_POWER4 773#ifdef CONFIG_PPC64
772 if (device_is_compatible(dev, "u3-agp")) { 774 if (device_is_compatible(dev, "u3-agp")) {
773 setup_u3_agp(hose); 775 setup_u3_agp(hose);
774 disp_name = "U3-AGP"; 776 disp_name = "U3-AGP";