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++) { |
