diff options
Diffstat (limited to 'arch/powerpc/kernel/pci-hotplug.c')
-rw-r--r-- | arch/powerpc/kernel/pci-hotplug.c | 49 |
1 files changed, 24 insertions, 25 deletions
diff --git a/arch/powerpc/kernel/pci-hotplug.c b/arch/powerpc/kernel/pci-hotplug.c index 3f608800c06b..c1e17ae68a08 100644 --- a/arch/powerpc/kernel/pci-hotplug.c +++ b/arch/powerpc/kernel/pci-hotplug.c | |||
@@ -22,45 +22,40 @@ | |||
22 | #include <asm/eeh.h> | 22 | #include <asm/eeh.h> |
23 | 23 | ||
24 | /** | 24 | /** |
25 | * __pcibios_remove_pci_devices - remove all devices under this bus | 25 | * pcibios_release_device - release PCI device |
26 | * @dev: PCI device | ||
27 | * | ||
28 | * The function is called before releasing the indicated PCI device. | ||
29 | */ | ||
30 | void pcibios_release_device(struct pci_dev *dev) | ||
31 | { | ||
32 | eeh_remove_device(dev); | ||
33 | } | ||
34 | |||
35 | /** | ||
36 | * pcibios_remove_pci_devices - remove all devices under this bus | ||
26 | * @bus: the indicated PCI bus | 37 | * @bus: the indicated PCI bus |
27 | * @purge_pe: destroy the PE on removal of PCI devices | ||
28 | * | 38 | * |
29 | * Remove all of the PCI devices under this bus both from the | 39 | * Remove all of the PCI devices under this bus both from the |
30 | * linux pci device tree, and from the powerpc EEH address cache. | 40 | * linux pci device tree, and from the powerpc EEH address cache. |
31 | * By default, the corresponding PE will be destroied during the | ||
32 | * normal PCI hotplug path. For PCI hotplug during EEH recovery, | ||
33 | * the corresponding PE won't be destroied and deallocated. | ||
34 | */ | 41 | */ |
35 | void __pcibios_remove_pci_devices(struct pci_bus *bus, int purge_pe) | 42 | void pcibios_remove_pci_devices(struct pci_bus *bus) |
36 | { | 43 | { |
37 | struct pci_dev *dev, *tmp; | 44 | struct pci_dev *dev, *tmp; |
38 | struct pci_bus *child_bus; | 45 | struct pci_bus *child_bus; |
39 | 46 | ||
40 | /* First go down child busses */ | 47 | /* First go down child busses */ |
41 | list_for_each_entry(child_bus, &bus->children, node) | 48 | list_for_each_entry(child_bus, &bus->children, node) |
42 | __pcibios_remove_pci_devices(child_bus, purge_pe); | 49 | pcibios_remove_pci_devices(child_bus); |
43 | 50 | ||
44 | pr_debug("PCI: Removing devices on bus %04x:%02x\n", | 51 | pr_debug("PCI: Removing devices on bus %04x:%02x\n", |
45 | pci_domain_nr(bus), bus->number); | 52 | pci_domain_nr(bus), bus->number); |
46 | list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) { | 53 | list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) { |
47 | pr_debug(" * Removing %s...\n", pci_name(dev)); | 54 | pr_debug(" Removing %s...\n", pci_name(dev)); |
48 | eeh_remove_bus_device(dev, purge_pe); | ||
49 | pci_stop_and_remove_bus_device(dev); | 55 | pci_stop_and_remove_bus_device(dev); |
50 | } | 56 | } |
51 | } | 57 | } |
52 | 58 | ||
53 | /** | ||
54 | * pcibios_remove_pci_devices - remove all devices under this bus | ||
55 | * @bus: the indicated PCI bus | ||
56 | * | ||
57 | * Remove all of the PCI devices under this bus both from the | ||
58 | * linux pci device tree, and from the powerpc EEH address cache. | ||
59 | */ | ||
60 | void pcibios_remove_pci_devices(struct pci_bus *bus) | ||
61 | { | ||
62 | __pcibios_remove_pci_devices(bus, 1); | ||
63 | } | ||
64 | EXPORT_SYMBOL_GPL(pcibios_remove_pci_devices); | 59 | EXPORT_SYMBOL_GPL(pcibios_remove_pci_devices); |
65 | 60 | ||
66 | /** | 61 | /** |
@@ -76,7 +71,7 @@ EXPORT_SYMBOL_GPL(pcibios_remove_pci_devices); | |||
76 | */ | 71 | */ |
77 | void pcibios_add_pci_devices(struct pci_bus * bus) | 72 | void pcibios_add_pci_devices(struct pci_bus * bus) |
78 | { | 73 | { |
79 | int slotno, num, mode, pass, max; | 74 | int slotno, mode, pass, max; |
80 | struct pci_dev *dev; | 75 | struct pci_dev *dev; |
81 | struct device_node *dn = pci_bus_to_OF_node(bus); | 76 | struct device_node *dn = pci_bus_to_OF_node(bus); |
82 | 77 | ||
@@ -90,11 +85,15 @@ void pcibios_add_pci_devices(struct pci_bus * bus) | |||
90 | /* use ofdt-based probe */ | 85 | /* use ofdt-based probe */ |
91 | of_rescan_bus(dn, bus); | 86 | of_rescan_bus(dn, bus); |
92 | } else if (mode == PCI_PROBE_NORMAL) { | 87 | } else if (mode == PCI_PROBE_NORMAL) { |
93 | /* use legacy probe */ | 88 | /* |
89 | * Use legacy probe. In the partial hotplug case, we | ||
90 | * probably have grandchildren devices unplugged. So | ||
91 | * we don't check the return value from pci_scan_slot() in | ||
92 | * order for fully rescan all the way down to pick them up. | ||
93 | * They can have been removed during partial hotplug. | ||
94 | */ | ||
94 | slotno = PCI_SLOT(PCI_DN(dn->child)->devfn); | 95 | slotno = PCI_SLOT(PCI_DN(dn->child)->devfn); |
95 | num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0)); | 96 | pci_scan_slot(bus, PCI_DEVFN(slotno, 0)); |
96 | if (!num) | ||
97 | return; | ||
98 | pcibios_setup_bus_devices(bus); | 97 | pcibios_setup_bus_devices(bus); |
99 | max = bus->busn_res.start; | 98 | max = bus->busn_res.start; |
100 | for (pass = 0; pass < 2; pass++) { | 99 | for (pass = 0; pass < 2; pass++) { |