powerpc/powernv: Drop PHB operation get_state()
authorGavin Shan <gwshan@linux.vnet.ibm.com>
Mon, 16 Feb 2015 03:45:45 +0000 (14:45 +1100)
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>
Mon, 16 Mar 2015 23:31:19 +0000 (10:31 +1100)
The patch drops PHB EEH operation get_state() and merges its logic
to eeh_ops::get_state().

Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
arch/powerpc/platforms/powernv/eeh-ioda.c
arch/powerpc/platforms/powernv/eeh-powernv.c
arch/powerpc/platforms/powernv/pci.h

index 349c0830f535a999e7afd246b4810e97d3cdc48f..dc34c36805dc71bcae91a5828d2f97a7325df53f 100644 (file)
@@ -46,173 +46,6 @@ static void ioda_eeh_phb_diag(struct eeh_pe *pe)
                        __func__, pe->phb->global_number, rc);
 }
 
-static int ioda_eeh_get_phb_state(struct eeh_pe *pe)
-{
-       struct pnv_phb *phb = pe->phb->private_data;
-       u8 fstate;
-       __be16 pcierr;
-       s64 rc;
-       int result = 0;
-
-       rc = opal_pci_eeh_freeze_status(phb->opal_id,
-                                       pe->addr,
-                                       &fstate,
-                                       &pcierr,
-                                       NULL);
-       if (rc != OPAL_SUCCESS) {
-               pr_warn("%s: Failure %lld getting PHB#%x state\n",
-                       __func__, rc, phb->hose->global_number);
-               return EEH_STATE_NOT_SUPPORT;
-       }
-
-       /*
-        * Check PHB state. If the PHB is frozen for the
-        * first time, to dump the PHB diag-data.
-        */
-       if (be16_to_cpu(pcierr) != OPAL_EEH_PHB_ERROR) {
-               result = (EEH_STATE_MMIO_ACTIVE  |
-                         EEH_STATE_DMA_ACTIVE   |
-                         EEH_STATE_MMIO_ENABLED |
-                         EEH_STATE_DMA_ENABLED);
-       } else if (!(pe->state & EEH_PE_ISOLATED)) {
-               eeh_pe_state_mark(pe, EEH_PE_ISOLATED);
-               ioda_eeh_phb_diag(pe);
-
-               if (eeh_has_flag(EEH_EARLY_DUMP_LOG))
-                       pnv_pci_dump_phb_diag_data(pe->phb, pe->data);
-       }
-
-       return result;
-}
-
-static int ioda_eeh_get_pe_state(struct eeh_pe *pe)
-{
-       struct pnv_phb *phb = pe->phb->private_data;
-       u8 fstate;
-       __be16 pcierr;
-       s64 rc;
-       int result;
-
-       /*
-        * We don't clobber hardware frozen state until PE
-        * reset is completed. In order to keep EEH core
-        * moving forward, we have to return operational
-        * state during PE reset.
-        */
-       if (pe->state & EEH_PE_RESET) {
-               result = (EEH_STATE_MMIO_ACTIVE  |
-                         EEH_STATE_DMA_ACTIVE   |
-                         EEH_STATE_MMIO_ENABLED |
-                         EEH_STATE_DMA_ENABLED);
-               return result;
-       }
-
-       /*
-        * Fetch PE state from hardware. If the PHB
-        * supports compound PE, let it handle that.
-        */
-       if (phb->get_pe_state) {
-               fstate = phb->get_pe_state(phb, pe->addr);
-       } else {
-               rc = opal_pci_eeh_freeze_status(phb->opal_id,
-                                               pe->addr,
-                                               &fstate,
-                                               &pcierr,
-                                               NULL);
-               if (rc != OPAL_SUCCESS) {
-                       pr_warn("%s: Failure %lld getting PHB#%x-PE%x state\n",
-                               __func__, rc, phb->hose->global_number, pe->addr);
-                       return EEH_STATE_NOT_SUPPORT;
-               }
-       }
-
-       /* Figure out state */
-       switch (fstate) {
-       case OPAL_EEH_STOPPED_NOT_FROZEN:
-               result = (EEH_STATE_MMIO_ACTIVE  |
-                         EEH_STATE_DMA_ACTIVE   |
-                         EEH_STATE_MMIO_ENABLED |
-                         EEH_STATE_DMA_ENABLED);
-               break;
-       case OPAL_EEH_STOPPED_MMIO_FREEZE:
-               result = (EEH_STATE_DMA_ACTIVE |
-                         EEH_STATE_DMA_ENABLED);
-               break;
-       case OPAL_EEH_STOPPED_DMA_FREEZE:
-               result = (EEH_STATE_MMIO_ACTIVE |
-                         EEH_STATE_MMIO_ENABLED);
-               break;
-       case OPAL_EEH_STOPPED_MMIO_DMA_FREEZE:
-               result = 0;
-               break;
-       case OPAL_EEH_STOPPED_RESET:
-               result = EEH_STATE_RESET_ACTIVE;
-               break;
-       case OPAL_EEH_STOPPED_TEMP_UNAVAIL:
-               result = EEH_STATE_UNAVAILABLE;
-               break;
-       case OPAL_EEH_STOPPED_PERM_UNAVAIL:
-               result = EEH_STATE_NOT_SUPPORT;
-               break;
-       default:
-               result = EEH_STATE_NOT_SUPPORT;
-               pr_warn("%s: Invalid PHB#%x-PE#%x state %x\n",
-                       __func__, phb->hose->global_number,
-                       pe->addr, fstate);
-       }
-
-       /*
-        * If PHB supports compound PE, to freeze all
-        * slave PEs for consistency.
-        *
-        * If the PE is switching to frozen state for the
-        * first time, to dump the PHB diag-data.
-        */
-       if (!(result & EEH_STATE_NOT_SUPPORT) &&
-           !(result & EEH_STATE_UNAVAILABLE) &&
-           !(result & EEH_STATE_MMIO_ACTIVE) &&
-           !(result & EEH_STATE_DMA_ACTIVE)  &&
-           !(pe->state & EEH_PE_ISOLATED)) {
-               if (phb->freeze_pe)
-                       phb->freeze_pe(phb, pe->addr);
-
-               eeh_pe_state_mark(pe, EEH_PE_ISOLATED);
-               ioda_eeh_phb_diag(pe);
-
-               if (eeh_has_flag(EEH_EARLY_DUMP_LOG))
-                       pnv_pci_dump_phb_diag_data(pe->phb, pe->data);
-       }
-
-       return result;
-}
-
-/**
- * ioda_eeh_get_state - Retrieve the state of PE
- * @pe: EEH PE
- *
- * The PE's state should be retrieved from the PEEV, PEST
- * IODA tables. Since the OPAL has exported the function
- * to do it, it'd better to use that.
- */
-static int ioda_eeh_get_state(struct eeh_pe *pe)
-{
-       struct pnv_phb *phb = pe->phb->private_data;
-
-       /* Sanity check on PE number. PHB PE should have 0 */
-       if (pe->addr < 0 ||
-           pe->addr >= phb->ioda.total_pe) {
-               pr_warn("%s: PHB#%x-PE#%x out of range [0, %x]\n",
-                       __func__, phb->hose->global_number,
-                       pe->addr, phb->ioda.total_pe);
-               return EEH_STATE_NOT_SUPPORT;
-       }
-
-       if (pe->type & EEH_PE_PHB)
-               return ioda_eeh_get_phb_state(pe);
-
-       return ioda_eeh_get_pe_state(pe);
-}
-
 static s64 ioda_eeh_phb_poll(struct pnv_phb *phb)
 {
        s64 rc = OPAL_HARDWARE;
@@ -759,7 +592,7 @@ static int ioda_eeh_next_error(struct eeh_pe **pe)
                                        break;
 
                                /* Frozen parent PE ? */
-                               state = ioda_eeh_get_state(parent_pe);
+                               state = eeh_ops->get_state(parent_pe, NULL);
                                if (state > 0 &&
                                    (state & active_flags) != active_flags)
                                        *pe = parent_pe;
@@ -786,7 +619,6 @@ static int ioda_eeh_next_error(struct eeh_pe **pe)
 }
 
 struct pnv_eeh_ops ioda_eeh_ops = {
-       .get_state              = ioda_eeh_get_state,
        .reset                  = ioda_eeh_reset,
        .next_error             = ioda_eeh_next_error
 };
index 2429a23d4802caa477fa5feb4efd8b8836cc8315..127ef0cc7c5b8bae92edcfd87013dd593de2282d 100644 (file)
@@ -478,6 +478,159 @@ static int pnv_eeh_get_pe_addr(struct eeh_pe *pe)
        return pe->addr;
 }
 
+static void pnv_eeh_get_phb_diag(struct eeh_pe *pe)
+{
+       struct pnv_phb *phb = pe->phb->private_data;
+       s64 rc;
+
+       rc = opal_pci_get_phb_diag_data2(phb->opal_id, pe->data,
+                                        PNV_PCI_DIAG_BUF_SIZE);
+       if (rc != OPAL_SUCCESS)
+               pr_warn("%s: Failure %lld getting PHB#%x diag-data\n",
+                       __func__, rc, pe->phb->global_number);
+}
+
+static int pnv_eeh_get_phb_state(struct eeh_pe *pe)
+{
+       struct pnv_phb *phb = pe->phb->private_data;
+       u8 fstate;
+       __be16 pcierr;
+       s64 rc;
+       int result = 0;
+
+       rc = opal_pci_eeh_freeze_status(phb->opal_id,
+                                       pe->addr,
+                                       &fstate,
+                                       &pcierr,
+                                       NULL);
+       if (rc != OPAL_SUCCESS) {
+               pr_warn("%s: Failure %lld getting PHB#%x state\n",
+                       __func__, rc, phb->hose->global_number);
+               return EEH_STATE_NOT_SUPPORT;
+       }
+
+       /*
+        * Check PHB state. If the PHB is frozen for the
+        * first time, to dump the PHB diag-data.
+        */
+       if (be16_to_cpu(pcierr) != OPAL_EEH_PHB_ERROR) {
+               result = (EEH_STATE_MMIO_ACTIVE  |
+                         EEH_STATE_DMA_ACTIVE   |
+                         EEH_STATE_MMIO_ENABLED |
+                         EEH_STATE_DMA_ENABLED);
+       } else if (!(pe->state & EEH_PE_ISOLATED)) {
+               eeh_pe_state_mark(pe, EEH_PE_ISOLATED);
+               pnv_eeh_get_phb_diag(pe);
+
+               if (eeh_has_flag(EEH_EARLY_DUMP_LOG))
+                       pnv_pci_dump_phb_diag_data(pe->phb, pe->data);
+       }
+
+       return result;
+}
+
+static int pnv_eeh_get_pe_state(struct eeh_pe *pe)
+{
+       struct pnv_phb *phb = pe->phb->private_data;
+       u8 fstate;
+       __be16 pcierr;
+       s64 rc;
+       int result;
+
+       /*
+        * We don't clobber hardware frozen state until PE
+        * reset is completed. In order to keep EEH core
+        * moving forward, we have to return operational
+        * state during PE reset.
+        */
+       if (pe->state & EEH_PE_RESET) {
+               result = (EEH_STATE_MMIO_ACTIVE  |
+                         EEH_STATE_DMA_ACTIVE   |
+                         EEH_STATE_MMIO_ENABLED |
+                         EEH_STATE_DMA_ENABLED);
+               return result;
+       }
+
+       /*
+        * Fetch PE state from hardware. If the PHB
+        * supports compound PE, let it handle that.
+        */
+       if (phb->get_pe_state) {
+               fstate = phb->get_pe_state(phb, pe->addr);
+       } else {
+               rc = opal_pci_eeh_freeze_status(phb->opal_id,
+                                               pe->addr,
+                                               &fstate,
+                                               &pcierr,
+                                               NULL);
+               if (rc != OPAL_SUCCESS) {
+                       pr_warn("%s: Failure %lld getting PHB#%x-PE%x state\n",
+                               __func__, rc, phb->hose->global_number,
+                               pe->addr);
+                       return EEH_STATE_NOT_SUPPORT;
+               }
+       }
+
+       /* Figure out state */
+       switch (fstate) {
+       case OPAL_EEH_STOPPED_NOT_FROZEN:
+               result = (EEH_STATE_MMIO_ACTIVE  |
+                         EEH_STATE_DMA_ACTIVE   |
+                         EEH_STATE_MMIO_ENABLED |
+                         EEH_STATE_DMA_ENABLED);
+               break;
+       case OPAL_EEH_STOPPED_MMIO_FREEZE:
+               result = (EEH_STATE_DMA_ACTIVE |
+                         EEH_STATE_DMA_ENABLED);
+               break;
+       case OPAL_EEH_STOPPED_DMA_FREEZE:
+               result = (EEH_STATE_MMIO_ACTIVE |
+                         EEH_STATE_MMIO_ENABLED);
+               break;
+       case OPAL_EEH_STOPPED_MMIO_DMA_FREEZE:
+               result = 0;
+               break;
+       case OPAL_EEH_STOPPED_RESET:
+               result = EEH_STATE_RESET_ACTIVE;
+               break;
+       case OPAL_EEH_STOPPED_TEMP_UNAVAIL:
+               result = EEH_STATE_UNAVAILABLE;
+               break;
+       case OPAL_EEH_STOPPED_PERM_UNAVAIL:
+               result = EEH_STATE_NOT_SUPPORT;
+               break;
+       default:
+               result = EEH_STATE_NOT_SUPPORT;
+               pr_warn("%s: Invalid PHB#%x-PE#%x state %x\n",
+                       __func__, phb->hose->global_number,
+                       pe->addr, fstate);
+       }
+
+       /*
+        * If PHB supports compound PE, to freeze all
+        * slave PEs for consistency.
+        *
+        * If the PE is switching to frozen state for the
+        * first time, to dump the PHB diag-data.
+        */
+       if (!(result & EEH_STATE_NOT_SUPPORT) &&
+           !(result & EEH_STATE_UNAVAILABLE) &&
+           !(result & EEH_STATE_MMIO_ACTIVE) &&
+           !(result & EEH_STATE_DMA_ACTIVE)  &&
+           !(pe->state & EEH_PE_ISOLATED)) {
+               if (phb->freeze_pe)
+                       phb->freeze_pe(phb, pe->addr);
+
+               eeh_pe_state_mark(pe, EEH_PE_ISOLATED);
+               pnv_eeh_get_phb_diag(pe);
+
+               if (eeh_has_flag(EEH_EARLY_DUMP_LOG))
+                       pnv_pci_dump_phb_diag_data(pe->phb, pe->data);
+       }
+
+       return result;
+}
+
 /**
  * pnv_eeh_get_state - Retrieve PE state
  * @pe: EEH PE
@@ -490,24 +643,24 @@ static int pnv_eeh_get_pe_addr(struct eeh_pe *pe)
  */
 static int pnv_eeh_get_state(struct eeh_pe *pe, int *delay)
 {
-       struct pci_controller *hose = pe->phb;
-       struct pnv_phb *phb = hose->private_data;
-       int ret = EEH_STATE_NOT_SUPPORT;
+       int ret;
 
-       if (phb->eeh_ops && phb->eeh_ops->get_state) {
-               ret = phb->eeh_ops->get_state(pe);
+       if (pe->type & EEH_PE_PHB)
+               ret = pnv_eeh_get_phb_state(pe);
+       else
+               ret = pnv_eeh_get_pe_state(pe);
 
-               /*
-                * If the PE state is temporarily unavailable,
-                * to inform the EEH core delay for default
-                * period (1 second)
-                */
-               if (delay) {
-                       *delay = 0;
-                       if (ret & EEH_STATE_UNAVAILABLE)
-                               *delay = 1000;
-               }
-       }
+       if (!delay)
+               return ret;
+
+       /*
+        * If the PE state is temporarily unavailable,
+        * to inform the EEH core delay for default
+        * period (1 second)
+        */
+       *delay = 0;
+       if (ret & EEH_STATE_UNAVAILABLE)
+               *delay = 1000;
 
        return ret;
 }
index 8043dee64a51bff566ffae45c57825d204d7fa58..773a026bfee2d72bab60c370125379d7a991d60d 100644 (file)
@@ -78,7 +78,6 @@ struct pnv_ioda_pe {
 /* IOC dependent EEH operations */
 #ifdef CONFIG_EEH
 struct pnv_eeh_ops {
-       int (*get_state)(struct eeh_pe *pe);
        int (*reset)(struct eeh_pe *pe, int option);
        int (*next_error)(struct eeh_pe **pe);
 };