diff options
Diffstat (limited to 'drivers/pci/hotplug/rpaphp_pci.c')
-rw-r--r-- | drivers/pci/hotplug/rpaphp_pci.c | 142 |
1 files changed, 1 insertions, 141 deletions
diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c index f16d0f9240ee..1a12ebd10e34 100644 --- a/drivers/pci/hotplug/rpaphp_pci.c +++ b/drivers/pci/hotplug/rpaphp_pci.c | |||
@@ -101,140 +101,6 @@ exit: | |||
101 | return rc; | 101 | return rc; |
102 | } | 102 | } |
103 | 103 | ||
104 | /* Must be called before pci_bus_add_devices */ | ||
105 | void rpaphp_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus) | ||
106 | { | ||
107 | struct pci_dev *dev; | ||
108 | |||
109 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
110 | /* | ||
111 | * Skip already-present devices (which are on the | ||
112 | * global device list.) | ||
113 | */ | ||
114 | if (list_empty(&dev->global_list)) { | ||
115 | int i; | ||
116 | |||
117 | /* Need to setup IOMMU tables */ | ||
118 | ppc_md.iommu_dev_setup(dev); | ||
119 | |||
120 | if(fix_bus) | ||
121 | pcibios_fixup_device_resources(dev, bus); | ||
122 | pci_read_irq_line(dev); | ||
123 | for (i = 0; i < PCI_NUM_RESOURCES; i++) { | ||
124 | struct resource *r = &dev->resource[i]; | ||
125 | |||
126 | if (r->parent || !r->start || !r->flags) | ||
127 | continue; | ||
128 | pci_claim_resource(dev, i); | ||
129 | } | ||
130 | } | ||
131 | } | ||
132 | } | ||
133 | |||
134 | static void rpaphp_eeh_add_bus_device(struct pci_bus *bus) | ||
135 | { | ||
136 | struct pci_dev *dev; | ||
137 | |||
138 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
139 | eeh_add_device_late(dev); | ||
140 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { | ||
141 | struct pci_bus *subbus = dev->subordinate; | ||
142 | if (subbus) | ||
143 | rpaphp_eeh_add_bus_device (subbus); | ||
144 | } | ||
145 | } | ||
146 | } | ||
147 | |||
148 | static int rpaphp_pci_config_bridge(struct pci_dev *dev) | ||
149 | { | ||
150 | u8 sec_busno; | ||
151 | struct pci_bus *child_bus; | ||
152 | struct pci_dev *child_dev; | ||
153 | |||
154 | dbg("Enter %s: BRIDGE dev=%s\n", __FUNCTION__, pci_name(dev)); | ||
155 | |||
156 | /* get busno of downstream bus */ | ||
157 | pci_read_config_byte(dev, PCI_SECONDARY_BUS, &sec_busno); | ||
158 | |||
159 | /* add to children of PCI bridge dev->bus */ | ||
160 | child_bus = pci_add_new_bus(dev->bus, dev, sec_busno); | ||
161 | if (!child_bus) { | ||
162 | err("%s: could not add second bus\n", __FUNCTION__); | ||
163 | return -EIO; | ||
164 | } | ||
165 | sprintf(child_bus->name, "PCI Bus #%02x", child_bus->number); | ||
166 | /* do pci_scan_child_bus */ | ||
167 | pci_scan_child_bus(child_bus); | ||
168 | |||
169 | list_for_each_entry(child_dev, &child_bus->devices, bus_list) { | ||
170 | eeh_add_device_late(child_dev); | ||
171 | } | ||
172 | |||
173 | /* fixup new pci devices without touching bus struct */ | ||
174 | rpaphp_fixup_new_pci_devices(child_bus, 0); | ||
175 | |||
176 | /* Make the discovered devices available */ | ||
177 | pci_bus_add_devices(child_bus); | ||
178 | return 0; | ||
179 | } | ||
180 | |||
181 | void rpaphp_init_new_devs(struct pci_bus *bus) | ||
182 | { | ||
183 | rpaphp_fixup_new_pci_devices(bus, 0); | ||
184 | rpaphp_eeh_add_bus_device(bus); | ||
185 | } | ||
186 | EXPORT_SYMBOL_GPL(rpaphp_init_new_devs); | ||
187 | |||
188 | /***************************************************************************** | ||
189 | rpaphp_pci_config_slot() will configure all devices under the | ||
190 | given slot->dn and return the the first pci_dev. | ||
191 | *****************************************************************************/ | ||
192 | static struct pci_dev * | ||
193 | rpaphp_pci_config_slot(struct pci_bus *bus) | ||
194 | { | ||
195 | struct device_node *dn = pci_bus_to_OF_node(bus); | ||
196 | struct pci_dev *dev = NULL; | ||
197 | int slotno; | ||
198 | int num; | ||
199 | |||
200 | dbg("Enter %s: dn=%s bus=%s\n", __FUNCTION__, dn->full_name, bus->name); | ||
201 | if (!dn || !dn->child) | ||
202 | return NULL; | ||
203 | |||
204 | if (_machine == PLATFORM_PSERIES_LPAR) { | ||
205 | of_scan_bus(dn, bus); | ||
206 | if (list_empty(&bus->devices)) { | ||
207 | err("%s: No new device found\n", __FUNCTION__); | ||
208 | return NULL; | ||
209 | } | ||
210 | |||
211 | rpaphp_init_new_devs(bus); | ||
212 | pci_bus_add_devices(bus); | ||
213 | dev = list_entry(&bus->devices, struct pci_dev, bus_list); | ||
214 | } else { | ||
215 | slotno = PCI_SLOT(PCI_DN(dn->child)->devfn); | ||
216 | |||
217 | /* pci_scan_slot should find all children */ | ||
218 | num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0)); | ||
219 | if (num) { | ||
220 | rpaphp_fixup_new_pci_devices(bus, 1); | ||
221 | pci_bus_add_devices(bus); | ||
222 | } | ||
223 | if (list_empty(&bus->devices)) { | ||
224 | err("%s: No new device found\n", __FUNCTION__); | ||
225 | return NULL; | ||
226 | } | ||
227 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
228 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) | ||
229 | rpaphp_pci_config_bridge(dev); | ||
230 | |||
231 | rpaphp_eeh_add_bus_device(bus); | ||
232 | } | ||
233 | } | ||
234 | |||
235 | return dev; | ||
236 | } | ||
237 | |||
238 | static void print_slot_pci_funcs(struct pci_bus *bus) | 104 | static void print_slot_pci_funcs(struct pci_bus *bus) |
239 | { | 105 | { |
240 | struct device_node *dn; | 106 | struct device_node *dn; |
@@ -253,19 +119,13 @@ static void print_slot_pci_funcs(struct pci_bus *bus) | |||
253 | int rpaphp_config_pci_adapter(struct pci_bus *bus) | 119 | int rpaphp_config_pci_adapter(struct pci_bus *bus) |
254 | { | 120 | { |
255 | struct device_node *dn = pci_bus_to_OF_node(bus); | 121 | struct device_node *dn = pci_bus_to_OF_node(bus); |
256 | struct pci_dev *dev; | ||
257 | int rc = -ENODEV; | 122 | int rc = -ENODEV; |
258 | 123 | ||
259 | dbg("Entry %s: slot[%s]\n", __FUNCTION__, dn->full_name); | 124 | dbg("Entry %s: slot[%s]\n", __FUNCTION__, dn->full_name); |
260 | if (!dn) | 125 | if (!dn) |
261 | goto exit; | 126 | goto exit; |
262 | 127 | ||
263 | eeh_add_device_tree_early(dn); | 128 | pcibios_add_pci_devices(bus); |
264 | dev = rpaphp_pci_config_slot(bus); | ||
265 | if (!dev) { | ||
266 | err("%s: can't find any devices.\n", __FUNCTION__); | ||
267 | goto exit; | ||
268 | } | ||
269 | print_slot_pci_funcs(bus); | 129 | print_slot_pci_funcs(bus); |
270 | rc = 0; | 130 | rc = 0; |
271 | exit: | 131 | exit: |