diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/kernel/of_platform.c | 10 | ||||
-rw-r--r-- | arch/powerpc/kernel/pci_64.c | 23 |
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 | ||
42 | unsigned long pci_probe_only = 1; | 42 | unsigned long pci_probe_only = 1; |
43 | int pci_assign_all_buses = 0; | 43 | int pci_assign_all_buses = 0; |
44 | static int pci_initial_scan_done; | ||
44 | 45 | ||
45 | static void fixup_resource(struct resource *res, struct pci_dev *dev); | 46 | static void fixup_resource(struct resource *res, struct pci_dev *dev); |
46 | static void do_bus_setup(struct pci_bus *bus); | 47 | static 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 | ||
1045 | void __init pci_setup_phb_io(struct pci_controller *hose, int primary) | 1048 | void __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 | ||
1074 | void __devinit pci_setup_phb_io_dynamic(struct pci_controller *hose, | 1089 | void __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; |