]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/suse-2.6.27.25/patches.arch/ppc-powerpc-debug-pci-hotplug.patch
Revert "Disable build of xen kernel."
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.arch / ppc-powerpc-debug-pci-hotplug.patch
1 Subject: Fix DLPAR
2 From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
3 References: 439491
4
5 Signed-off-by: Olaf Hering <olh@suse.de>
6 ---
7 arch/powerpc/include/asm/pci-bridge.h | 4
8 arch/powerpc/include/asm/pci.h | 10 +
9 arch/powerpc/kernel/pci-common.c | 124 ++++++++++++----------
10 arch/powerpc/kernel/pci_32.c | 6 -
11 arch/powerpc/kernel/pci_64.c | 27 +++-
12 arch/powerpc/kernel/rtas_pci.c | 48 --------
13 arch/powerpc/platforms/pseries/eeh.c | 44 ++++---
14 arch/powerpc/platforms/pseries/pci_dlpar.c | 163 +++++++++++++++--------------
15 drivers/pci/hotplug/rpadlpar_core.c | 49 +++++---
16 drivers/pci/hotplug/rpaphp_slot.c | 4
17 10 files changed, 245 insertions(+), 234 deletions(-)
18
19 --- a/arch/powerpc/include/asm/pci-bridge.h
20 +++ b/arch/powerpc/include/asm/pci-bridge.h
21 @@ -234,9 +234,7 @@ extern void pcibios_remove_pci_devices(s
22
23 /** Discover new pci devices under this bus, and add them */
24 extern void pcibios_add_pci_devices(struct pci_bus *bus);
25 -extern void pcibios_fixup_new_pci_devices(struct pci_bus *bus);
26 -
27 -extern int pcibios_remove_root_bus(struct pci_controller *phb);
28 +extern void pcibios_finish_adding_new_bus(struct pci_bus *bus);
29
30 static inline struct pci_controller *pci_bus_to_host(const struct pci_bus *bus)
31 {
32 --- a/arch/powerpc/include/asm/pci.h
33 +++ b/arch/powerpc/include/asm/pci.h
34 @@ -201,6 +201,7 @@ extern void pcibios_allocate_bus_resourc
35 extern void pcibios_resource_survey(void);
36
37 extern struct pci_controller *init_phb_dynamic(struct device_node *dn);
38 +extern int remove_phb_dynamic(struct pci_controller *phb);
39
40 extern struct pci_dev *of_create_pci_dev(struct device_node *node,
41 struct pci_bus *bus, int devfn);
42 @@ -208,7 +209,8 @@ extern struct pci_dev *of_create_pci_dev
43 extern void of_scan_pci_bridge(struct device_node *node,
44 struct pci_dev *dev);
45
46 -extern void of_scan_bus(struct device_node *node, struct pci_bus *bus);
47 +extern void of_scan_bus(struct device_node *node, struct pci_bus *bus,
48 + int rescan_existing);
49
50 extern int pci_read_irq_line(struct pci_dev *dev);
51
52 @@ -223,8 +225,10 @@ extern void pci_resource_to_user(const s
53 const struct resource *rsrc,
54 resource_size_t *start, resource_size_t *end);
55
56 -extern void pcibios_do_bus_setup(struct pci_bus *bus);
57 -extern void pcibios_fixup_of_probed_bus(struct pci_bus *bus);
58 +extern void pcibios_do_bus_setup_self(struct pci_bus *bus);
59 +extern void pcibios_do_bus_setup_devices(struct pci_bus *bus);
60 +extern void pcibios_fixup_bus_self(struct pci_bus *bus);
61 +extern void pcibios_fixup_bus_devices(struct pci_bus *bus);
62
63 #endif /* __KERNEL__ */
64 #endif /* __ASM_POWERPC_PCI_H */
65 --- a/arch/powerpc/kernel/pci_32.c
66 +++ b/arch/powerpc/kernel/pci_32.c
67 @@ -418,7 +418,7 @@ static int __init pcibios_init(void)
68
69 subsys_initcall(pcibios_init);
70
71 -void __devinit pcibios_do_bus_setup(struct pci_bus *bus)
72 +void __devinit pcibios_do_bus_setup_self(struct pci_bus *bus)
73 {
74 struct pci_controller *hose = (struct pci_controller *) bus->sysdata;
75 unsigned long io_offset;
76 @@ -459,6 +459,10 @@ void __devinit pcibios_do_bus_setup(stru
77 }
78 }
79
80 +void __devinit pcibios_do_bus_setup_devices(struct pci_bus *bus)
81 +{
82 +}
83 +
84 /* the next one is stolen from the alpha port... */
85 void __init
86 pcibios_update_irq(struct pci_dev *dev, int irq)
87 --- a/arch/powerpc/kernel/pci_64.c
88 +++ b/arch/powerpc/kernel/pci_64.c
89 @@ -225,14 +225,16 @@ struct pci_dev *of_create_pci_dev(struct
90 EXPORT_SYMBOL(of_create_pci_dev);
91
92 void __devinit of_scan_bus(struct device_node *node,
93 - struct pci_bus *bus)
94 + struct pci_bus *bus,
95 + int rescan_existing)
96 {
97 struct device_node *child;
98 const u32 *reg;
99 int reglen, devfn;
100 struct pci_dev *dev;
101
102 - DBG("of_scan_bus(%s) bus no %d... \n", node->full_name, bus->number);
103 + DBG("of_scan_bus(%s) %s bus no %d... \n", node->full_name,
104 + rescan_existing ? "existing" : "new", bus->number);
105
106 /* Scan direct children */
107 for_each_child_of_node(node, child) {
108 @@ -249,8 +251,12 @@ void __devinit of_scan_bus(struct device
109 DBG(" dev header type: %x\n", dev->hdr_type);
110 }
111
112 - /* Ally all fixups */
113 - pcibios_fixup_of_probed_bus(bus);
114 + /* Apply all fixups necessary. We don't fixup the bus "self"
115 + * for an existing bridge that is being rescanned
116 + */
117 + if (!rescan_existing)
118 + pcibios_fixup_bus_self(bus);
119 + pcibios_fixup_bus_devices(bus);
120
121 /* Now scan child busses */
122 list_for_each_entry(dev, &bus->devices, bus_list) {
123 @@ -346,7 +352,7 @@ void __devinit of_scan_pci_bridge(struct
124 DBG(" probe mode: %d\n", mode);
125
126 if (mode == PCI_PROBE_DEVTREE)
127 - of_scan_bus(node, bus);
128 + of_scan_bus(node, bus, 0);
129 else if (mode == PCI_PROBE_NORMAL)
130 pci_scan_child_bus(bus);
131 }
132 @@ -396,7 +402,7 @@ void __devinit scan_phb(struct pci_contr
133 DBG(" probe mode: %d\n", mode);
134 if (mode == PCI_PROBE_DEVTREE) {
135 bus->subordinate = hose->last_busno;
136 - of_scan_bus(node, bus);
137 + of_scan_bus(node, bus, 0);
138 }
139
140 if (mode == PCI_PROBE_NORMAL)
141 @@ -568,12 +574,15 @@ void __devinit pcibios_setup_new_device(
142 }
143 EXPORT_SYMBOL(pcibios_setup_new_device);
144
145 -void __devinit pcibios_do_bus_setup(struct pci_bus *bus)
146 +void __devinit pcibios_do_bus_setup_self(struct pci_bus *bus)
147 {
148 - struct pci_dev *dev;
149 -
150 if (ppc_md.pci_dma_bus_setup)
151 ppc_md.pci_dma_bus_setup(bus);
152 +}
153 +
154 +void __devinit pcibios_do_bus_setup_devices(struct pci_bus *bus)
155 +{
156 + struct pci_dev *dev;
157
158 list_for_each_entry(dev, &bus->devices, bus_list)
159 pcibios_setup_new_device(dev);
160 --- a/arch/powerpc/kernel/pci-common.c
161 +++ b/arch/powerpc/kernel/pci-common.c
162 @@ -789,63 +789,78 @@ static void __devinit pcibios_fixup_reso
163 }
164 DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources);
165
166 -static void __devinit __pcibios_fixup_bus(struct pci_bus *bus)
167 +void __devinit pcibios_fixup_bus_self(struct pci_bus *bus)
168 {
169 struct pci_controller *hose = pci_bus_to_host(bus);
170 struct pci_dev *dev = bus->self;
171 + struct resource *res;
172 + int i;
173
174 - pr_debug("PCI: Fixup bus %d (%s)\n", bus->number, dev ? pci_name(dev) : "PHB");
175 + pr_debug("PCI: Fixup bus resources %d (%s)\n",
176 + bus->number, dev ? pci_name(dev) : "PHB");
177
178 /* Fixup PCI<->PCI bridges. Host bridges are handled separately, for
179 * now differently between 32 and 64 bits.
180 */
181 - if (dev != NULL) {
182 - struct resource *res;
183 - int i;
184 -
185 - for (i = 0; i < PCI_BUS_NUM_RESOURCES; ++i) {
186 - if ((res = bus->resource[i]) == NULL)
187 - continue;
188 - if (!res->flags)
189 - continue;
190 - if (i >= 3 && bus->self->transparent)
191 - continue;
192 - /* On PowerMac, Apple leaves bridge windows open over
193 - * an inaccessible region of memory space (0...fffff)
194 - * which is somewhat bogus, but that's what they think
195 - * means disabled...
196 - *
197 - * We clear those to force them to be reallocated later
198 - *
199 - * We detect such regions by the fact that the base is
200 - * equal to the pci_mem_offset of the host bridge and
201 - * their size is smaller than 1M.
202 - */
203 - if (res->flags & IORESOURCE_MEM &&
204 - res->start == hose->pci_mem_offset &&
205 - res->end < 0x100000) {
206 - printk(KERN_INFO
207 - "PCI: Closing bogus Apple Firmware"
208 - " region %d on bus 0x%02x\n",
209 - i, bus->number);
210 - res->flags = 0;
211 - continue;
212 - }
213 + if (dev == NULL)
214 + goto host_bridge;
215
216 - pr_debug("PCI:%s Bus rsrc %d %016llx-%016llx [%x] fixup...\n",
217 - pci_name(dev), i,
218 - (unsigned long long)res->start,\
219 - (unsigned long long)res->end,
220 - (unsigned int)res->flags);
221 + for (i = 0; i < PCI_BUS_NUM_RESOURCES; ++i) {
222 + if ((res = bus->resource[i]) == NULL)
223 + continue;
224 + if (!res->flags)
225 + continue;
226 + if (i >= 3 && bus->self->transparent)
227 + continue;
228
229 - fixup_resource(res, dev);
230 + /* On PowerMac, Apple leaves bridge windows open over
231 + * an inaccessible region of memory space (0...fffff)
232 + * which is somewhat bogus, but that's what they think
233 + * means disabled...
234 + *
235 + * We clear those to force them to be reallocated later
236 + *
237 + * We detect such regions by the fact that the base is
238 + * equal to the pci_mem_offset of the host bridge and
239 + * their size is smaller than 1M.
240 + */
241 + if (res->flags & IORESOURCE_MEM &&
242 + res->start == hose->pci_mem_offset &&
243 + res->end < 0x100000) {
244 + printk(KERN_INFO
245 + "PCI: Closing bogus Apple Firmware"
246 + " region %d on bus 0x%02x\n",
247 + i, bus->number);
248 + res->flags = 0;
249 + continue;
250 }
251 +
252 + pr_debug("PCI:%s Bus rsrc %d %016llx-%016llx [%x] fixup...\n",
253 + pci_name(dev), i,
254 + (unsigned long long)res->start,\
255 + (unsigned long long)res->end,
256 + (unsigned int)res->flags);
257 +
258 + fixup_resource(res, dev);
259 }
260
261 +host_bridge:
262 +
263 + /* Additional setup that is different between 32 and 64 bits for now */
264 + pcibios_do_bus_setup_self(bus);
265 +}
266 +
267 +void __devinit pcibios_fixup_bus_devices(struct pci_bus *bus)
268 +{
269 + struct pci_dev *dev = bus->self;
270 +
271 + pr_debug("PCI: Fixup bus devices %d (%s)\n",
272 + bus->number, dev ? pci_name(dev) : "PHB");
273 +
274 /* Additional setup that is different between 32 and 64 bits for now */
275 - pcibios_do_bus_setup(bus);
276 + pcibios_do_bus_setup_devices(bus);
277
278 - /* Platform specific bus fixups */
279 + /* Platform specific bus fixups (XXX Get rid of these !) */
280 if (ppc_md.pcibios_fixup_bus)
281 ppc_md.pcibios_fixup_bus(bus);
282
283 @@ -864,19 +879,11 @@ void __devinit pcibios_fixup_bus(struct
284 */
285 if (bus->self != NULL)
286 pci_read_bridge_bases(bus);
287 - __pcibios_fixup_bus(bus);
288 + pcibios_fixup_bus_self(bus);
289 + pcibios_fixup_bus_devices(bus);
290 }
291 EXPORT_SYMBOL(pcibios_fixup_bus);
292
293 -/* When building a bus from the OF tree rather than probing, we need a
294 - * slightly different version of the fixup which doesn't read the
295 - * bridge bases using config space accesses
296 - */
297 -void __devinit pcibios_fixup_of_probed_bus(struct pci_bus *bus)
298 -{
299 - __pcibios_fixup_bus(bus);
300 -}
301 -
302 static int skip_isa_ioresource_align(struct pci_dev *dev)
303 {
304 if ((ppc_pci_flags & PPC_PCI_CAN_SKIP_ISA_ALIGN) &&
305 @@ -992,9 +999,12 @@ void pcibios_allocate_bus_resources(stru
306 int i;
307 struct resource *res, *pr;
308
309 + DBG("PCI: Allocating bus resources for %04x:%02x...\n",
310 + pci_domain_nr(bus), bus->number);
311 +
312 for (i = 0; i < PCI_BUS_NUM_RESOURCES; ++i) {
313 if ((res = bus->resource[i]) == NULL || !res->flags
314 - || res->start > res->end)
315 + || res->start > res->end || res->parent)
316 continue;
317 if (bus->parent == NULL)
318 pr = (res->flags & IORESOURCE_IO) ?
319 @@ -1047,6 +1057,7 @@ clear_resource:
320 list_for_each_entry(b, &bus->children, node)
321 pcibios_allocate_bus_resources(b);
322 }
323 +EXPORT_SYMBOL_GPL(pcibios_allocate_bus_resources);
324
325 static inline void __devinit alloc_resource(struct pci_dev *dev, int idx)
326 {
327 @@ -1157,6 +1168,13 @@ void __devinit pcibios_claim_one_bus(str
328
329 if (r->parent || !r->start || !r->flags)
330 continue;
331 +
332 + DBG("PCI: Claiming %s: Resource %d: %016llx..%016llx [%x]\n",
333 + pci_name(dev), i,
334 + (unsigned long long)r->start,
335 + (unsigned long long)r->end,
336 + (unsigned int)r->flags);
337 +
338 pci_claim_resource(dev, i);
339 }
340 }
341 --- a/arch/powerpc/kernel/rtas_pci.c
342 +++ b/arch/powerpc/kernel/rtas_pci.c
343 @@ -301,51 +301,3 @@ void __init find_and_init_phbs(void)
344 #endif /* CONFIG_PPC32 */
345 }
346 }
347 -
348 -/* RPA-specific bits for removing PHBs */
349 -int pcibios_remove_root_bus(struct pci_controller *phb)
350 -{
351 - struct pci_bus *b = phb->bus;
352 - struct resource *res;
353 - int rc, i;
354 -
355 - res = b->resource[0];
356 - if (!res->flags) {
357 - printk(KERN_ERR "%s: no IO resource for PHB %s\n", __func__,
358 - b->name);
359 - return 1;
360 - }
361 -
362 - rc = pcibios_unmap_io_space(b);
363 - if (rc) {
364 - printk(KERN_ERR "%s: failed to unmap IO on bus %s\n",
365 - __func__, b->name);
366 - return 1;
367 - }
368 -
369 - if (release_resource(res)) {
370 - printk(KERN_ERR "%s: failed to release IO on bus %s\n",
371 - __func__, b->name);
372 - return 1;
373 - }
374 -
375 - for (i = 1; i < 3; ++i) {
376 - res = b->resource[i];
377 - if (!res->flags && i == 0) {
378 - printk(KERN_ERR "%s: no MEM resource for PHB %s\n",
379 - __func__, b->name);
380 - return 1;
381 - }
382 - if (res->flags && release_resource(res)) {
383 - printk(KERN_ERR
384 - "%s: failed to release IO %d on bus %s\n",
385 - __func__, i, b->name);
386 - return 1;
387 - }
388 - }
389 -
390 - pcibios_free_controller(phb);
391 -
392 - return 0;
393 -}
394 -EXPORT_SYMBOL(pcibios_remove_root_bus);
395 --- a/arch/powerpc/platforms/pseries/eeh.c
396 +++ b/arch/powerpc/platforms/pseries/eeh.c
397 @@ -21,6 +21,8 @@
398 * Please address comments and feedback to Linas Vepstas <linas@austin.ibm.com>
399 */
400
401 +#undef DEBUG
402 +
403 #include <linux/delay.h>
404 #include <linux/init.h>
405 #include <linux/list.h>
406 @@ -488,10 +490,8 @@ int eeh_dn_check_failure(struct device_n
407 if (!(pdn->eeh_mode & EEH_MODE_SUPPORTED) ||
408 pdn->eeh_mode & EEH_MODE_NOCHECK) {
409 ignored_check++;
410 -#ifdef DEBUG
411 - printk ("EEH:ignored check (%x) for %s %s\n",
412 - pdn->eeh_mode, pci_name (dev), dn->full_name);
413 -#endif
414 + pr_debug("EEH: Ignored check (%x) for %s %s\n",
415 + pdn->eeh_mode, pci_name (dev), dn->full_name);
416 return 0;
417 }
418
419 @@ -1014,10 +1014,9 @@ static void *early_enable_eeh(struct dev
420 eeh_subsystem_enabled = 1;
421 pdn->eeh_mode |= EEH_MODE_SUPPORTED;
422
423 -#ifdef DEBUG
424 - printk(KERN_DEBUG "EEH: %s: eeh enabled, config=%x pe_config=%x\n",
425 - dn->full_name, pdn->eeh_config_addr, pdn->eeh_pe_config_addr);
426 -#endif
427 + pr_debug("EEH: %s: eeh enabled, config=%x pe_config=%x\n",
428 + dn->full_name, pdn->eeh_config_addr,
429 + pdn->eeh_pe_config_addr);
430 } else {
431
432 /* This device doesn't support EEH, but it may have an
433 @@ -1161,13 +1160,17 @@ static void eeh_add_device_late(struct p
434 if (!dev || !eeh_subsystem_enabled)
435 return;
436
437 -#ifdef DEBUG
438 - printk(KERN_DEBUG "EEH: adding device %s\n", pci_name(dev));
439 -#endif
440 + pr_debug("EEH: Adding device %s\n", pci_name(dev));
441
442 - pci_dev_get (dev);
443 dn = pci_device_to_OF_node(dev);
444 pdn = PCI_DN(dn);
445 + if (pdn->pcidev == dev) {
446 + pr_debug("EEH: Already referenced !\n");
447 + return;
448 + }
449 + WARN_ON(pdn->pcidev);
450 +
451 + pci_dev_get (dev);
452 pdn->pcidev = dev;
453
454 pci_addr_cache_insert_device(dev);
455 @@ -1206,17 +1209,18 @@ static void eeh_remove_device(struct pci
456 return;
457
458 /* Unregister the device with the EEH/PCI address search system */
459 -#ifdef DEBUG
460 - printk(KERN_DEBUG "EEH: remove device %s\n", pci_name(dev));
461 -#endif
462 - pci_addr_cache_remove_device(dev);
463 - eeh_sysfs_remove_device(dev);
464 + pr_debug("EEH: Removing device %s\n", pci_name(dev));
465
466 dn = pci_device_to_OF_node(dev);
467 - if (PCI_DN(dn)->pcidev) {
468 - PCI_DN(dn)->pcidev = NULL;
469 - pci_dev_put (dev);
470 + if (PCI_DN(dn)->pcidev == NULL) {
471 + pr_debug("EEH: Not referenced !\n");
472 + return;
473 }
474 + PCI_DN(dn)->pcidev = NULL;
475 + pci_dev_put (dev);
476 +
477 + pci_addr_cache_remove_device(dev);
478 + eeh_sysfs_remove_device(dev);
479 }
480
481 void eeh_remove_bus_device(struct pci_dev *dev)
482 --- a/arch/powerpc/platforms/pseries/pci_dlpar.c
483 +++ b/arch/powerpc/platforms/pseries/pci_dlpar.c
484 @@ -25,6 +25,8 @@
485 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
486 */
487
488 +#undef DEBUG
489 +
490 #include <linux/pci.h>
491 #include <asm/pci-bridge.h>
492 #include <asm/ppc-pci.h>
493 @@ -69,73 +71,41 @@ EXPORT_SYMBOL_GPL(pcibios_find_pci_bus);
494 * Remove all of the PCI devices under this bus both from the
495 * linux pci device tree, and from the powerpc EEH address cache.
496 */
497 -void
498 -pcibios_remove_pci_devices(struct pci_bus *bus)
499 +void pcibios_remove_pci_devices(struct pci_bus *bus)
500 {
501 struct pci_dev *dev, *tmp;
502 + struct pci_bus *child_bus;
503
504 + /* First go down child busses */
505 + list_for_each_entry(child_bus, &bus->children, node)
506 + pcibios_remove_pci_devices(child_bus);
507 +
508 + pr_debug("PCI: Removing devices on bus %04x:%02x\n",
509 + pci_domain_nr(bus), bus->number);
510 list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) {
511 + pr_debug(" * Removing %s...\n", pci_name(dev));
512 eeh_remove_bus_device(dev);
513 pci_remove_bus_device(dev);
514 }
515 }
516 EXPORT_SYMBOL_GPL(pcibios_remove_pci_devices);
517
518 -/* Must be called before pci_bus_add_devices */
519 -void
520 -pcibios_fixup_new_pci_devices(struct pci_bus *bus)
521 -{
522 - struct pci_dev *dev;
523 -
524 - list_for_each_entry(dev, &bus->devices, bus_list) {
525 - /* Skip already-added devices */
526 - if (!dev->is_added) {
527 - int i;
528 -
529 - /* Fill device archdata and setup iommu table */
530 - pcibios_setup_new_device(dev);
531 -
532 - pci_read_irq_line(dev);
533 - for (i = 0; i < PCI_NUM_RESOURCES; i++) {
534 - struct resource *r = &dev->resource[i];
535 -
536 - if (r->parent || !r->start || !r->flags)
537 - continue;
538 - pci_claim_resource(dev, i);
539 - }
540 - }
541 - }
542 -}
543 -EXPORT_SYMBOL_GPL(pcibios_fixup_new_pci_devices);
544 -
545 -static int
546 -pcibios_pci_config_bridge(struct pci_dev *dev)
547 +void pcibios_finish_adding_new_bus(struct pci_bus *bus)
548 {
549 - u8 sec_busno;
550 - struct pci_bus *child_bus;
551 -
552 - /* Get busno of downstream bus */
553 - pci_read_config_byte(dev, PCI_SECONDARY_BUS, &sec_busno);
554 + pr_debug("PCI: Finishing adding hotplug bus %04x:%02x\n",
555 + pci_domain_nr(bus), bus->number);
556
557 - /* Add to children of PCI bridge dev->bus */
558 - child_bus = pci_add_new_bus(dev->bus, dev, sec_busno);
559 - if (!child_bus) {
560 - printk (KERN_ERR "%s: could not add second bus\n", __func__);
561 - return -EIO;
562 - }
563 - sprintf(child_bus->name, "PCI Bus #%02x", child_bus->number);
564 -
565 - pci_scan_child_bus(child_bus);
566 + /* Allocate bus and devices resources */
567 + pcibios_allocate_bus_resources(bus);
568 + pcibios_claim_one_bus(bus);
569
570 - /* Fixup new pci devices */
571 - pcibios_fixup_new_pci_devices(child_bus);
572 + /* Add new devices to global lists. Register in proc, sysfs. */
573 + pci_bus_add_devices(bus);
574
575 - /* Make the discovered devices available */
576 - pci_bus_add_devices(child_bus);
577 -
578 - eeh_add_device_tree_late(child_bus);
579 - return 0;
580 + /* Fixup EEH */
581 + eeh_add_device_tree_late(bus);
582 }
583 +EXPORT_SYMBOL_GPL(pcibios_finish_adding_new_bus);
584
585 /**
586 * pcibios_add_pci_devices - adds new pci devices to bus
587 @@ -147,10 +117,9 @@ pcibios_pci_config_bridge(struct pci_dev
588 * is how this routine differs from other, similar pcibios
589 * routines.)
590 */
591 -void
592 -pcibios_add_pci_devices(struct pci_bus * bus)
593 +void pcibios_add_pci_devices(struct pci_bus * bus)
594 {
595 - int slotno, num, mode;
596 + int slotno, num, mode, pass, max;
597 struct pci_dev *dev;
598 struct device_node *dn = pci_bus_to_OF_node(bus);
599
600 @@ -162,25 +131,24 @@ pcibios_add_pci_devices(struct pci_bus *
601
602 if (mode == PCI_PROBE_DEVTREE) {
603 /* use ofdt-based probe */
604 - of_scan_bus(dn, bus);
605 - if (!list_empty(&bus->devices)) {
606 - pcibios_fixup_new_pci_devices(bus);
607 - pci_bus_add_devices(bus);
608 - eeh_add_device_tree_late(bus);
609 - }
610 + of_scan_bus(dn, bus, 1);
611 + if (!list_empty(&bus->devices))
612 + pcibios_finish_adding_new_bus(bus);
613 } else if (mode == PCI_PROBE_NORMAL) {
614 /* use legacy probe */
615 slotno = PCI_SLOT(PCI_DN(dn->child)->devfn);
616 num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
617 - if (num) {
618 - pcibios_fixup_new_pci_devices(bus);
619 - pci_bus_add_devices(bus);
620 - eeh_add_device_tree_late(bus);
621 + if (!num)
622 + return;
623 + pcibios_fixup_bus_devices(bus);
624 + max = bus->secondary;
625 + for (pass=0; pass < 2; pass++)
626 + list_for_each_entry(dev, &bus->devices, bus_list) {
627 + if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
628 + dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
629 + max = pci_scan_bridge(bus, dev, max, pass);
630 }
631 -
632 - list_for_each_entry(dev, &bus->devices, bus_list)
633 - if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
634 - pcibios_pci_config_bridge(dev);
635 + pcibios_finish_adding_new_bus(bus);
636 }
637 }
638 EXPORT_SYMBOL_GPL(pcibios_add_pci_devices);
639 @@ -189,7 +157,8 @@ struct pci_controller * __devinit init_p
640 {
641 struct pci_controller *phb;
642 int primary;
643 - struct pci_bus *b;
644 +
645 + pr_debug("PCI: Initializing new hotplug PHB %s\n", dn->full_name);
646
647 primary = list_empty(&hose_list);
648 phb = pcibios_alloc_controller(dn);
649 @@ -204,11 +173,57 @@ struct pci_controller * __devinit init_p
650 eeh_add_device_tree_early(dn);
651
652 scan_phb(phb);
653 - pcibios_allocate_bus_resources(phb->bus);
654 - pcibios_fixup_new_pci_devices(phb->bus);
655 - pci_bus_add_devices(phb->bus);
656 - eeh_add_device_tree_late(phb->bus);
657 + pcibios_finish_adding_new_bus(phb->bus);
658
659 return phb;
660 }
661 EXPORT_SYMBOL_GPL(init_phb_dynamic);
662 +
663 +
664 +
665 +
666 +/* RPA-specific bits for removing PHBs */
667 +int remove_phb_dynamic(struct pci_controller *phb)
668 +{
669 + struct pci_bus *b = phb->bus;
670 + struct resource *res;
671 + int rc, i;
672 +
673 + pr_debug("PCI: Removing PHB %04x:%02x... \n", pci_domain_nr(b), b->number);
674 +
675 + /* We -know- there aren't any child devices anymore at this stage
676 + * and thus, we can safely unmap the IO space as it's not in use
677 + */
678 + res = &phb->io_resource;
679 + if (res->flags & IORESOURCE_IO) {
680 + rc = pcibios_unmap_io_space(b);
681 + if (rc) {
682 + printk(KERN_ERR "%s: failed to unmap IO on bus %s\n",
683 + __func__, b->name);
684 + return 1;
685 + }
686 + }
687 +
688 + /* Unregister the bridge device from sysfs and remove the PCI bus */
689 + device_unregister(b->bridge);
690 + phb->bus = NULL;
691 + pci_remove_bus(b);
692 +
693 + /* Now release the IO resource */
694 + if (res->flags & IORESOURCE_IO)
695 + release_resource(res);
696 +
697 + /* Release memory resources */
698 + for (i = 0; i < 3; ++i) {
699 + res = &phb->mem_resources[i];
700 + if (!(res->flags & IORESOURCE_MEM))
701 + continue;
702 + release_resource(res);
703 + }
704 +
705 + /* Free pci_controller data structure */
706 + pcibios_free_controller(phb);
707 +
708 + return 0;
709 +}
710 +EXPORT_SYMBOL_GPL(remove_phb_dynamic);
711 --- a/drivers/pci/hotplug/rpadlpar_core.c
712 +++ b/drivers/pci/hotplug/rpadlpar_core.c
713 @@ -14,6 +14,8 @@
714 * as published by the Free Software Foundation; either version
715 * 2 of the License, or (at your option) any later version.
716 */
717 +#undef DEBUG
718 +
719 #include <linux/init.h>
720 #include <linux/pci.h>
721 #include <linux/string.h>
722 @@ -155,16 +157,15 @@ static void dlpar_pci_add_bus(struct dev
723 dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
724 of_scan_pci_bridge(dn, dev);
725
726 - pcibios_fixup_new_pci_devices(dev->subordinate);
727 -
728 - /* Claim new bus resources */
729 - pcibios_claim_one_bus(dev->bus);
730 -
731 /* Map IO space for child bus, which may or may not succeed */
732 pcibios_map_io_space(dev->subordinate);
733
734 - /* Add new devices to global lists. Register in proc, sysfs. */
735 - pci_bus_add_devices(phb->bus);
736 + /* Finish adding it : resource allocation, adding devices, etc...
737 + * Note that we need to perform the finish pass on the -parent-
738 + * bus of the EADS bridge so the bridge device itself gets
739 + * properly added
740 + */
741 + pcibios_finish_adding_new_bus(phb->bus);
742 }
743
744 static int dlpar_add_pci_slot(char *drc_name, struct device_node *dn)
745 @@ -206,22 +207,19 @@ static int dlpar_add_pci_slot(char *drc_
746 static int dlpar_remove_root_bus(struct pci_controller *phb)
747 {
748 struct pci_bus *phb_bus;
749 - int rc;
750
751 phb_bus = phb->bus;
752 + pr_debug("PCI: -> removing root bus %04x:%02x\n",
753 + pci_domain_nr(phb_bus), phb_bus->number);
754 +
755 + /* We cannot to remove a root bus that has children */
756 if (!(list_empty(&phb_bus->children) &&
757 list_empty(&phb_bus->devices))) {
758 + pr_debug("PCI: PHB removal failed, bus not empty !\n");
759 return -EBUSY;
760 }
761
762 - rc = pcibios_remove_root_bus(phb);
763 - if (rc)
764 - return -EIO;
765 -
766 - device_unregister(phb_bus->bridge);
767 - pci_remove_bus(phb_bus);
768 -
769 - return 0;
770 + return remove_phb_dynamic(phb);
771 }
772
773 static int dlpar_remove_phb(char *drc_name, struct device_node *dn)
774 @@ -233,6 +231,8 @@ static int dlpar_remove_phb(char *drc_na
775 if (!pcibios_find_pci_bus(dn))
776 return -EINVAL;
777
778 + pr_debug("PCI: Removing PHB %s...\n", dn->full_name);
779 +
780 /* If pci slot is hotplugable, use hotplug to remove it */
781 slot = find_php_slot(dn);
782 if (slot) {
783 @@ -378,25 +378,36 @@ int dlpar_remove_pci_slot(char *drc_name
784 if (!bus)
785 return -EINVAL;
786
787 - /* If pci slot is hotplugable, use hotplug to remove it */
788 + pr_debug("PCI: Removing PCI slot below EADS bridge %s\n",
789 + bus->self ? pci_name(bus->self) : "<!PHB!>");
790 +
791 + /* If pci slot is hotplugable, remove hotplug data structures */
792 slot = find_php_slot(dn);
793 if (slot) {
794 + pr_debug("PCI: Removing hotplug slot for %04x:%02x...\n",
795 + pci_domain_nr(bus), bus->number);
796 if (rpaphp_deregister_slot(slot)) {
797 printk(KERN_ERR
798 "%s: unable to remove hotplug slot %s\n",
799 __func__, drc_name);
800 return -EIO;
801 }
802 - } else
803 - pcibios_remove_pci_devices(bus);
804 + }
805 +
806 + /* Remove all devices below slot */
807 + pcibios_remove_pci_devices(bus);
808
809 + /* Unmap PCI IO space */
810 if (pcibios_unmap_io_space(bus)) {
811 printk(KERN_ERR "%s: failed to unmap bus range\n",
812 __func__);
813 return -ERANGE;
814 }
815
816 + /* Remove the EADS bridge device itself */
817 BUG_ON(!bus->self);
818 + pr_debug("PCI: Now removing bridge device %s\n", pci_name(bus->self));
819 + eeh_remove_bus_device(bus->self);
820 pci_remove_bus_device(bus->self);
821 return 0;
822 }
823 --- a/drivers/pci/hotplug/rpaphp_slot.c
824 +++ b/drivers/pci/hotplug/rpaphp_slot.c
825 @@ -145,9 +145,5 @@ int rpaphp_register_slot(struct slot *sl
826 list_add(&slot->rpaphp_slot_list, &rpaphp_slot_head);
827 info("Slot [%s] registered\n", slot->name);
828 return 0;
829 -
830 -sysfs_fail:
831 - pci_hp_deregister(php_slot);
832 - return retval;
833 }
834