aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/pseries/pci_dlpar.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms/pseries/pci_dlpar.c')
-rw-r--r--arch/powerpc/platforms/pseries/pci_dlpar.c64
1 files changed, 48 insertions, 16 deletions
diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c
index bdaa8aabdaa6..44abdeb9ca03 100644
--- a/arch/powerpc/platforms/pseries/pci_dlpar.c
+++ b/arch/powerpc/platforms/pseries/pci_dlpar.c
@@ -27,6 +27,7 @@
27 27
28#include <linux/pci.h> 28#include <linux/pci.h>
29#include <asm/pci-bridge.h> 29#include <asm/pci-bridge.h>
30#include <asm/ppc-pci.h>
30 31
31static struct pci_bus * 32static struct pci_bus *
32find_bus_among_children(struct pci_bus *bus, 33find_bus_among_children(struct pci_bus *bus,
@@ -106,6 +107,8 @@ pcibios_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus)
106 } 107 }
107 } 108 }
108 } 109 }
110
111 eeh_add_device_tree_late(bus);
109} 112}
110EXPORT_SYMBOL_GPL(pcibios_fixup_new_pci_devices); 113EXPORT_SYMBOL_GPL(pcibios_fixup_new_pci_devices);
111 114
@@ -114,7 +117,6 @@ pcibios_pci_config_bridge(struct pci_dev *dev)
114{ 117{
115 u8 sec_busno; 118 u8 sec_busno;
116 struct pci_bus *child_bus; 119 struct pci_bus *child_bus;
117 struct pci_dev *child_dev;
118 120
119 /* Get busno of downstream bus */ 121 /* Get busno of downstream bus */
120 pci_read_config_byte(dev, PCI_SECONDARY_BUS, &sec_busno); 122 pci_read_config_byte(dev, PCI_SECONDARY_BUS, &sec_busno);
@@ -129,10 +131,6 @@ pcibios_pci_config_bridge(struct pci_dev *dev)
129 131
130 pci_scan_child_bus(child_bus); 132 pci_scan_child_bus(child_bus);
131 133
132 list_for_each_entry(child_dev, &child_bus->devices, bus_list) {
133 eeh_add_device_late(child_dev);
134 }
135
136 /* Fixup new pci devices without touching bus struct */ 134 /* Fixup new pci devices without touching bus struct */
137 pcibios_fixup_new_pci_devices(child_bus, 0); 135 pcibios_fixup_new_pci_devices(child_bus, 0);
138 136
@@ -160,18 +158,52 @@ pcibios_add_pci_devices(struct pci_bus * bus)
160 158
161 eeh_add_device_tree_early(dn); 159 eeh_add_device_tree_early(dn);
162 160
163 /* pci_scan_slot should find all children */ 161 if (_machine == PLATFORM_PSERIES_LPAR) {
164 slotno = PCI_SLOT(PCI_DN(dn->child)->devfn); 162 /* use ofdt-based probe */
165 num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0)); 163 of_scan_bus(dn, bus);
166 if (num) { 164 if (!list_empty(&bus->devices)) {
167 pcibios_fixup_new_pci_devices(bus, 1); 165 pcibios_fixup_new_pci_devices(bus, 0);
168 pci_bus_add_devices(bus); 166 pci_bus_add_devices(bus);
169 } 167 }
168 } else {
169 /* use legacy probe */
170 slotno = PCI_SLOT(PCI_DN(dn->child)->devfn);
171 num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
172 if (num) {
173 pcibios_fixup_new_pci_devices(bus, 1);
174 pci_bus_add_devices(bus);
175 }
170 176
171 list_for_each_entry(dev, &bus->devices, bus_list) { 177 list_for_each_entry(dev, &bus->devices, bus_list)
172 eeh_add_device_late (dev); 178 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
173 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) 179 pcibios_pci_config_bridge(dev);
174 pcibios_pci_config_bridge(dev);
175 } 180 }
176} 181}
177EXPORT_SYMBOL_GPL(pcibios_add_pci_devices); 182EXPORT_SYMBOL_GPL(pcibios_add_pci_devices);
183
184struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn)
185{
186 struct pci_controller *phb;
187 int primary;
188
189 primary = list_empty(&hose_list);
190 phb = pcibios_alloc_controller(dn);
191 if (!phb)
192 return NULL;
193 setup_phb(dn, phb);
194 pci_process_bridge_OF_ranges(phb, dn, 0);
195
196 pci_setup_phb_io_dynamic(phb, primary);
197
198 pci_devs_phb_init_dynamic(phb);
199
200 if (dn->child)
201 eeh_add_device_tree_early(dn);
202
203 scan_phb(phb);
204 pcibios_fixup_new_pci_devices(phb->bus, 0);
205 pci_bus_add_devices(phb->bus);
206
207 return phb;
208}
209EXPORT_SYMBOL_GPL(init_phb_dynamic);