aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2007-05-15 02:19:36 -0400
committerPaul Mackerras <paulus@samba.org>2007-05-17 07:11:14 -0400
commitde821204dbd0a967f77213daf7b89070a65e7523 (patch)
tree08113c00d59352db02d0487ddba614ffe9627f3c /arch
parent017e3c53f116d6a0741a21624924528dc9f98418 (diff)
[POWERPC] Fix IO space on PCI buses created from of_platform
This changes the way of_platform_pci creates PCI host bridges such that it uses request_phb_iospace() for mapping the IO ports, instead of using the dynamic hotplug stuff. That guarantees the IO space stays within the 2GB limit and thus doesn't break half of the legacy drivers around. Fixes a couple of warnings due to missing IO space while at it. This patch is a temporary workaround for 2.6.22 before a more complete rewrite of IO mappings is merged in 2.6.23 Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/kernel/of_platform.c10
-rw-r--r--arch/powerpc/kernel/pci_64.c23
2 files changed, 28 insertions, 5 deletions
diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c
index 84c34d979a88..d501c23e5159 100644
--- a/arch/powerpc/kernel/of_platform.c
+++ b/arch/powerpc/kernel/of_platform.c
@@ -427,11 +427,13 @@ static int __devinit of_pci_phb_probe(struct of_device *dev,
427 /* Process "ranges" property */ 427 /* Process "ranges" property */
428 pci_process_bridge_OF_ranges(phb, dev->node, 0); 428 pci_process_bridge_OF_ranges(phb, dev->node, 0);
429 429
430 /* Setup IO space. 430 /* Setup IO space. We use the non-dynamic version of that code here,
431 * This will not work properly for ISA IOs, something needs to be done 431 * which doesn't quite support unplugging. Next kernel release will
432 * about it if we ever generalize that way of probing PCI brigdes 432 * have a better fix for this.
433 * Note also that we don't do ISA, this will also be fixed with a
434 * more massive rework.
433 */ 435 */
434 pci_setup_phb_io_dynamic(phb, 0); 436 pci_setup_phb_io(phb, 0);
435 437
436 /* Init pci_dn data structures */ 438 /* Init pci_dn data structures */
437 pci_devs_phb_init_dynamic(phb); 439 pci_devs_phb_init_dynamic(phb);
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index b0409e19b1c1..249cca27a9b8 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -41,6 +41,7 @@
41 41
42unsigned long pci_probe_only = 1; 42unsigned long pci_probe_only = 1;
43int pci_assign_all_buses = 0; 43int pci_assign_all_buses = 0;
44static int pci_initial_scan_done;
44 45
45static void fixup_resource(struct resource *res, struct pci_dev *dev); 46static void fixup_resource(struct resource *res, struct pci_dev *dev);
46static void do_bus_setup(struct pci_bus *bus); 47static void do_bus_setup(struct pci_bus *bus);
@@ -604,6 +605,8 @@ static int __init pcibios_init(void)
604 /* map in PCI I/O space */ 605 /* map in PCI I/O space */
605 phbs_remap_io(); 606 phbs_remap_io();
606 607
608 pci_initial_scan_done = 1;
609
607 printk(KERN_DEBUG "PCI: Probing PCI hardware done\n"); 610 printk(KERN_DEBUG "PCI: Probing PCI hardware done\n");
608 611
609 return 0; 612 return 0;
@@ -1042,13 +1045,16 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
1042 } 1045 }
1043} 1046}
1044 1047
1045void __init pci_setup_phb_io(struct pci_controller *hose, int primary) 1048void __devinit pci_setup_phb_io(struct pci_controller *hose, int primary)
1046{ 1049{
1047 unsigned long size = hose->pci_io_size; 1050 unsigned long size = hose->pci_io_size;
1048 unsigned long io_virt_offset; 1051 unsigned long io_virt_offset;
1049 struct resource *res; 1052 struct resource *res;
1050 struct device_node *isa_dn; 1053 struct device_node *isa_dn;
1051 1054
1055 if (size == 0)
1056 return;
1057
1052 hose->io_base_virt = reserve_phb_iospace(size); 1058 hose->io_base_virt = reserve_phb_iospace(size);
1053 DBG("phb%d io_base_phys 0x%lx io_base_virt 0x%lx\n", 1059 DBG("phb%d io_base_phys 0x%lx io_base_virt 0x%lx\n",
1054 hose->global_number, hose->io_base_phys, 1060 hose->global_number, hose->io_base_phys,
@@ -1069,6 +1075,15 @@ void __init pci_setup_phb_io(struct pci_controller *hose, int primary)
1069 res = &hose->io_resource; 1075 res = &hose->io_resource;
1070 res->start += io_virt_offset; 1076 res->start += io_virt_offset;
1071 res->end += io_virt_offset; 1077 res->end += io_virt_offset;
1078
1079 /* If this is called after the initial PCI scan, then we need to
1080 * proceed to IO mappings now
1081 */
1082 if (pci_initial_scan_done)
1083 __ioremap_explicit(hose->io_base_phys,
1084 (unsigned long)hose->io_base_virt,
1085 hose->pci_io_size,
1086 _PAGE_NO_CACHE | _PAGE_GUARDED);
1072} 1087}
1073 1088
1074void __devinit pci_setup_phb_io_dynamic(struct pci_controller *hose, 1089void __devinit pci_setup_phb_io_dynamic(struct pci_controller *hose,
@@ -1078,6 +1093,9 @@ void __devinit pci_setup_phb_io_dynamic(struct pci_controller *hose,
1078 unsigned long io_virt_offset; 1093 unsigned long io_virt_offset;
1079 struct resource *res; 1094 struct resource *res;
1080 1095
1096 if (size == 0)
1097 return;
1098
1081 hose->io_base_virt = __ioremap(hose->io_base_phys, size, 1099 hose->io_base_virt = __ioremap(hose->io_base_phys, size,
1082 _PAGE_NO_CACHE | _PAGE_GUARDED); 1100 _PAGE_NO_CACHE | _PAGE_GUARDED);
1083 DBG("phb%d io_base_phys 0x%lx io_base_virt 0x%lx\n", 1101 DBG("phb%d io_base_phys 0x%lx io_base_virt 0x%lx\n",
@@ -1106,6 +1124,9 @@ static int get_bus_io_range(struct pci_bus *bus, unsigned long *start_phys,
1106 /* Root Bus */ 1124 /* Root Bus */
1107 res = &hose->io_resource; 1125 res = &hose->io_resource;
1108 1126
1127 if (res->end == 0 && res->start == 0)
1128 return 1;
1129
1109 *start_virt = pci_io_base + res->start; 1130 *start_virt = pci_io_base + res->start;
1110 *start_phys = *start_virt + hose->io_base_phys 1131 *start_phys = *start_virt + hose->io_base_phys
1111 - (unsigned long) hose->io_base_virt; 1132 - (unsigned long) hose->io_base_virt;