powerpc/powernv: Clear PAPR error injection registers
[firefly-linux-kernel-4.4.55.git] / arch / powerpc / platforms / powernv / eeh-ioda.c
index 22609f23f4556eb5adfa5d5f13cb50a0b031eec9..d6fb90b32525e39abb69c8c80b848c9893ca9c65 100644 (file)
@@ -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))