diff options
Diffstat (limited to 'arch/powerpc/platforms/pseries/pci_dlpar.c')
-rw-r--r-- | arch/powerpc/platforms/pseries/pci_dlpar.c | 64 |
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 | ||
31 | static struct pci_bus * | 32 | static struct pci_bus * |
32 | find_bus_among_children(struct pci_bus *bus, | 33 | find_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 | } |
110 | EXPORT_SYMBOL_GPL(pcibios_fixup_new_pci_devices); | 113 | EXPORT_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 | } |
177 | EXPORT_SYMBOL_GPL(pcibios_add_pci_devices); | 182 | EXPORT_SYMBOL_GPL(pcibios_add_pci_devices); |
183 | |||
184 | struct 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 | } | ||
209 | EXPORT_SYMBOL_GPL(init_phb_dynamic); | ||