summaryrefslogtreecommitdiff
path: root/arch/powerpc/kernel/pci-hotplug.c
diff options
context:
space:
mode:
authorGavin Shan <shangw@linux.vnet.ibm.com>2013-07-24 10:24:57 +0800
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2013-07-24 14:18:48 +1000
commitab444ec97e8bd65fff9d489b9a409fc03979268b (patch)
treec0462b0cf66b6c400d4fb45bba635535ab8a2806 /arch/powerpc/kernel/pci-hotplug.c
parent9feed42e93d2625db86423cedf8b4b2bed00779e (diff)
powerpc/pci: Partial tree hotplug support
When EEH error happens to one specific PE, the device drivers of its attached EEH devices (PCI devices) are checked to see the further action: reset with complete hotplug, or reset without hotplug. However, that's not enough for those PCI devices whose drivers can't support EEH, or those PCI devices without driver. So we need do so-called "partial hotplug" on basis of PCI devices. In the situation, part of PCI devices of the specific PE are unplugged and plugged again after PE reset. The patch changes pcibios_add_pci_devices() so that it can support full hotplug and so-called "partial" hotplug based on device-tree or real hardware. It's notable that pci_of_scan.c has been changed for a bit in order to support the "partial" hotplug based on dev-tree. Most of the generic code already supports that, we just need to plumb it properly on our side. Signed-off-by: Gavin Shan <shangw@linux.vnet.ibm.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/kernel/pci-hotplug.c')
-rw-r--r--arch/powerpc/kernel/pci-hotplug.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/arch/powerpc/kernel/pci-hotplug.c b/arch/powerpc/kernel/pci-hotplug.c
index fc0831d4971f..c1e17ae68a08 100644
--- a/arch/powerpc/kernel/pci-hotplug.c
+++ b/arch/powerpc/kernel/pci-hotplug.c
@@ -71,7 +71,7 @@ EXPORT_SYMBOL_GPL(pcibios_remove_pci_devices);
*/
void pcibios_add_pci_devices(struct pci_bus * bus)
{
- int slotno, num, mode, pass, max;
+ int slotno, mode, pass, max;
struct pci_dev *dev;
struct device_node *dn = pci_bus_to_OF_node(bus);
@@ -85,11 +85,15 @@ void pcibios_add_pci_devices(struct pci_bus * bus)
/* use ofdt-based probe */
of_rescan_bus(dn, bus);
} else if (mode == PCI_PROBE_NORMAL) {
- /* use legacy probe */
+ /*
+ * Use legacy probe. In the partial hotplug case, we
+ * probably have grandchildren devices unplugged. So
+ * we don't check the return value from pci_scan_slot() in
+ * order for fully rescan all the way down to pick them up.
+ * They can have been removed during partial hotplug.
+ */
slotno = PCI_SLOT(PCI_DN(dn->child)->devfn);
- num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
- if (!num)
- return;
+ pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
pcibios_setup_bus_devices(bus);
max = bus->busn_res.start;
for (pass = 0; pass < 2; pass++) {