In pnv_pci_reset_secondary_bus(), we should issue fundamental reset if any one subordinate device of the specified is requesting that. Otherwise, the device might not come up after the reset.
Signed-off-by: Gavin Shan <gws...@linux.vnet.ibm.com> --- arch/powerpc/platforms/powernv/eeh-powernv.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c index c69b6a1..ab8b93e 100644 --- a/arch/powerpc/platforms/powernv/eeh-powernv.c +++ b/arch/powerpc/platforms/powernv/eeh-powernv.c @@ -878,9 +878,28 @@ static int pnv_eeh_bridge_reset(struct pci_dev *dev, int option) return 0; } +static int pnv_pci_dev_reset_type(struct pci_dev *pdev, void *data) +{ + int *freset = data; + + /* + * Stop the iteration immediately if there has any one + * PCI device requesting fundamental reset. + */ + *freset |= pdev->needs_freset; + return *freset; +} + void pnv_pci_reset_secondary_bus(struct pci_dev *dev) { - pnv_eeh_bridge_reset(dev, EEH_RESET_HOT); + int option, freset = 0; + + if (dev->subordinate) + pci_walk_bus(dev->subordinate, + pnv_pci_dev_reset_type, &freset); + + option = freset ? EEH_RESET_FUNDAMENTAL : EEH_RESET_HOT; + pnv_eeh_bridge_reset(dev, option); pnv_eeh_bridge_reset(dev, EEH_RESET_DEACTIVATE); } -- 2.1.0 _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev