This converts pnv_eeh_poll() to pnv_pci_poll() in order to:

   * Return linux error code other than OPAL error code.
   * The return value from last OPAL call, requested delay, is
     passed to pnv_pci_poll() and delay accordingly. Thus one
     call to opal_pci_poll() is saved.
   * More information (e.g. PCI slot power status) is returned
     if the last argument isn't NULL.

Signed-off-by: Gavin Shan <gws...@linux.vnet.ibm.com>
---
 arch/powerpc/platforms/powernv/eeh-powernv.c | 47 ++++++----------------------
 arch/powerpc/platforms/powernv/pci.c         | 21 +++++++++++++
 arch/powerpc/platforms/powernv/pci.h         |  1 +
 3 files changed, 31 insertions(+), 38 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c 
b/arch/powerpc/platforms/powernv/eeh-powernv.c
index 4ae48ff..e664542 100644
--- a/arch/powerpc/platforms/powernv/eeh-powernv.c
+++ b/arch/powerpc/platforms/powernv/eeh-powernv.c
@@ -745,28 +745,11 @@ static int pnv_eeh_get_state(struct eeh_pe *pe, int 
*delay)
        return ret;
 }
 
-static s64 pnv_eeh_poll(uint64_t id)
-{
-       s64 rc = OPAL_HARDWARE;
-
-       while (1) {
-               rc = opal_pci_poll(id, NULL);
-               if (rc <= 0)
-                       break;
-
-               if (system_state < SYSTEM_RUNNING)
-                       udelay(1000 * rc);
-               else
-                       msleep(rc);
-       }
-
-       return rc;
-}
-
 int pnv_eeh_phb_reset(struct pci_controller *hose, int option)
 {
        struct pnv_phb *phb = hose->private_data;
        s64 rc = OPAL_HARDWARE;
+       int ret;
 
        pr_debug("%s: Reset PHB#%x, option=%d\n",
                 __func__, hose->global_number, option);
@@ -781,8 +764,6 @@ int pnv_eeh_phb_reset(struct pci_controller *hose, int 
option)
                rc = opal_pci_reset(phb->opal_id,
                                    OPAL_RESET_PHB_COMPLETE,
                                    OPAL_DEASSERT_RESET);
-       if (rc < 0)
-               goto out;
 
        /*
         * Poll state of the PHB until the request is done
@@ -790,24 +771,22 @@ int pnv_eeh_phb_reset(struct pci_controller *hose, int 
option)
         * reset followed by hot reset on root bus. So we also
         * need the PCI bus settlement delay.
         */
-       rc = pnv_eeh_poll(phb->opal_id);
-       if (option == EEH_RESET_DEACTIVATE) {
+       ret = pnv_pci_poll(phb->opal_id, rc, NULL);
+       if (option == EEH_RESET_DEACTIVATE && !ret) {
                if (system_state < SYSTEM_RUNNING)
                        udelay(1000 * EEH_PE_RST_SETTLE_TIME);
                else
                        msleep(EEH_PE_RST_SETTLE_TIME);
        }
-out:
-       if (rc != OPAL_SUCCESS)
-               return -EIO;
 
-       return 0;
+       return ret;
 }
 
 static int pnv_eeh_root_reset(struct pci_controller *hose, int option)
 {
        struct pnv_phb *phb = hose->private_data;
        s64 rc = OPAL_HARDWARE;
+       int ret;
 
        pr_debug("%s: Reset PHB#%x, option=%d\n",
                 __func__, hose->global_number, option);
@@ -829,18 +808,13 @@ static int pnv_eeh_root_reset(struct pci_controller 
*hose, int option)
                rc = opal_pci_reset(phb->opal_id,
                                    OPAL_RESET_PCI_HOT,
                                    OPAL_DEASSERT_RESET);
-       if (rc < 0)
-               goto out;
 
        /* Poll state of the PHB until the request is done */
-       rc = pnv_eeh_poll(phb->opal_id);
-       if (option == EEH_RESET_DEACTIVATE)
+       ret = pnv_pci_poll(phb->opal_id, rc, NULL);
+       if (option == EEH_RESET_DEACTIVATE && !ret)
                msleep(EEH_PE_RST_SETTLE_TIME);
-out:
-       if (rc != OPAL_SUCCESS)
-               return -EIO;
 
-       return 0;
+       return ret;
 }
 
 static int __pnv_eeh_bridge_reset(struct pci_dev *dev, int option)
@@ -930,10 +904,7 @@ static int pnv_eeh_bridge_reset(struct pci_dev *pdev, int 
option)
        phb = hose->private_data;
        id |= (pdev->bus->number << 24) | (pdev->devfn << 16) | phb->opal_id;
        rc = opal_pci_reset(id, scope, OPAL_ASSERT_RESET);
-       if (rc > 0)
-               rc = pnv_eeh_poll(id);
-
-       return (rc == OPAL_SUCCESS) ? 0 : -EIO;
+       return pnv_pci_poll(id, rc, NULL);
 }
 
 static void pnv_eeh_wait_for_pending(struct pci_dn *pdn, int pos,
diff --git a/arch/powerpc/platforms/powernv/pci.c 
b/arch/powerpc/platforms/powernv/pci.c
index 6c350a2..801e3e8 100644
--- a/arch/powerpc/platforms/powernv/pci.c
+++ b/arch/powerpc/platforms/powernv/pci.c
@@ -44,6 +44,27 @@
 #define cfg_dbg(fmt...)        do { } while(0)
 //#define cfg_dbg(fmt...)      printk(fmt)
 
+int pnv_pci_poll(uint64_t id, int64_t rval, uint8_t *pval)
+{
+       while (rval > 0) {
+               if (system_state < SYSTEM_RUNNING)
+                       udelay(1000 * rval);
+               else
+                       msleep(rval);
+
+               rval = opal_pci_poll(id, pval);
+       }
+
+       /*
+        * The caller expects to retrieve additional information
+        * if the last argument is valid.
+        */
+       if (rval == OPAL_SUCCESS && pval)
+               rval = opal_pci_poll(id, pval);
+
+       return rval ? -EIO : 0;
+}
+
 #ifdef CONFIG_PCI_MSI
 int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
 {
diff --git a/arch/powerpc/platforms/powernv/pci.h 
b/arch/powerpc/platforms/powernv/pci.h
index 2058f06..99d2da6 100644
--- a/arch/powerpc/platforms/powernv/pci.h
+++ b/arch/powerpc/platforms/powernv/pci.h
@@ -214,6 +214,7 @@ extern int pnv_tce_xchg(struct iommu_table *tbl, long index,
                unsigned long *hpa, enum dma_data_direction *direction);
 extern unsigned long pnv_tce_get(struct iommu_table *tbl, long index);
 
+int pnv_pci_poll(uint64_t id, int64_t rval, uint8_t *pval);
 void pnv_pci_dump_phb_diag_data(struct pci_controller *hose,
                                unsigned char *log_buff);
 int pnv_pci_cfg_read(struct pci_dn *pdn,
-- 
2.1.0

_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Reply via email to