Re: [PATCH v7 39/50] powerpc/powernv: Fundamental reset in pnv_pci_reset_secondary_bus()
From: Gavin Shan <hidden>
Date: 2015-11-12 06:15:25
Also in:
linux-devicetree, linux-pci
On Thu, Nov 05, 2015 at 12:12:39AM +1100, Gavin Shan wrote:
In pnv_pci_reset_secondary_bus(), we should issue fundamental reset if any one subordinate device of the specified is requesting
^^^^^^^^^^^^^^
the specified bus
I put the note reminding me to admend the changelog in next revision.
quoted hunk ↗ jump to hunk
that. Otherwise, the device might not come up after the reset. Signed-off-by: Gavin Shan <redacted> --- 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