From d9df1b5da17cd328301def1d2ae2c2df35f3823c Mon Sep 17 00:00:00 2001 From: Gavin Shan Date: Tue, 30 Sep 2014 12:38:58 +1000 Subject: [PATCH] powerpc/powernv: Clear PAPR error injection registers The frozen state on one specific PE is probably caused by error injection, which is done with help of PAPR error injection registers. According to the hardware spec, those registers should be cleared automatically after one-shot frozen PE. However, that's not always true, at least on P7IOC of Firebird-L. So we have to clear them before doing PE reset to avoid recursive EEH errors at recovery stage. Signed-off-by: Gavin Shan Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/powernv/eeh-ioda.c | 25 +++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/arch/powerpc/platforms/powernv/eeh-ioda.c b/arch/powerpc/platforms/powernv/eeh-ioda.c index 22609f23f455..d6fb90b32525 100644 --- a/arch/powerpc/platforms/powernv/eeh-ioda.c +++ b/arch/powerpc/platforms/powernv/eeh-ioda.c @@ -682,6 +682,31 @@ static int ioda_eeh_reset(struct eeh_pe *pe, int option) if (pe->type & EEH_PE_PHB) { ret = ioda_eeh_phb_reset(hose, option); } else { + struct pnv_phb *phb; + s64 rc; + + /* + * The frozen PE might be caused by PAPR error injection + * registers, which are expected to be cleared after hitting + * frozen PE as stated in the hardware spec. Unfortunately, + * that's not true on P7IOC. So we have to clear it manually + * to avoid recursive EEH errors during recovery. + */ + phb = hose->private_data; + if (phb->model == PNV_PHB_MODEL_P7IOC && + (option == EEH_RESET_HOT || + option == EEH_RESET_FUNDAMENTAL)) { + rc = opal_pci_reset(phb->opal_id, + OPAL_PHB_ERROR, + OPAL_ASSERT_RESET); + if (rc != OPAL_SUCCESS) { + pr_warn("%s: Failure %lld clearing " + "error injection registers\n", + __func__, rc); + return -EIO; + } + } + bus = eeh_pe_bus_get(pe); if (pci_is_root_bus(bus) || pci_is_root_bus(bus->parent))