static int ibm_read_slot_reset_state;
 static int ibm_read_slot_reset_state2;
 static int ibm_slot_error_detail;
-static int ibm_get_config_addr_info;
-static int ibm_get_config_addr_info2;
 static int ibm_configure_bridge;
 static int ibm_configure_pe;
 
        }
 }
 
-#define EEH_ENABLE 1
-
-struct eeh_early_enable_info {
-       unsigned int buid_hi;
-       unsigned int buid_lo;
-};
-
-/**
- * eeh_get_pe_addr - Retrieve PE address with given BDF address
- * @config_addr: BDF address
- * @info: BUID of the associated PHB
- *
- * There're 2 kinds of addresses existing in EEH core components:
- * BDF address and PE address. Besides, there has dedicated platform
- * dependent function call to retrieve the PE address according to
- * the given BDF address. Further more, we prefer PE address on BDF
- * address in EEH core components.
- */
-static int eeh_get_pe_addr(int config_addr,
-                        struct eeh_early_enable_info *info)
-{
-       unsigned int rets[3];
-       int ret;
-
-       /* Use latest config-addr token on power6 */
-       if (ibm_get_config_addr_info2 != RTAS_UNKNOWN_SERVICE) {
-               /* Make sure we have a PE in hand */
-               ret = rtas_call(ibm_get_config_addr_info2, 4, 2, rets,
-                       config_addr, info->buid_hi, info->buid_lo, 1);
-               if (ret || (rets[0]==0))
-                       return 0;
-
-               ret = rtas_call(ibm_get_config_addr_info2, 4, 2, rets,
-                       config_addr, info->buid_hi, info->buid_lo, 0);
-               if (ret)
-                       return 0;
-               return rets[0];
-       }
-
-       /* Use older config-addr token on power5 */
-       if (ibm_get_config_addr_info != RTAS_UNKNOWN_SERVICE) {
-               ret = rtas_call(ibm_get_config_addr_info, 4, 2, rets,
-                       config_addr, info->buid_hi, info->buid_lo, 0);
-               if (ret)
-                       return 0;
-               return rets[0];
-       }
-       return 0;
-}
-
 /**
  * eeh_early_enable - Early enable EEH on the indicated device
  * @dn: device node
 static void *eeh_early_enable(struct device_node *dn, void *data)
 {
        unsigned int rets[3];
-       struct eeh_early_enable_info *info = data;
        int ret;
        const u32 *class_code = of_get_property(dn, "class-code", NULL);
        const u32 *vendor_id = of_get_property(dn, "vendor-id", NULL);
                        /* If the newer, better, ibm,get-config-addr-info is supported, 
                         * then use that instead.
                         */
-                       pdn->eeh_pe_config_addr = eeh_get_pe_addr(pdn->eeh_config_addr, info);
+                       pdn->eeh_pe_config_addr = eeh_ops->get_pe_addr(dn);
 
                        /* Some older systems (Power4) allow the
                         * ibm,set-eeh-option call to succeed even on nodes
 void __init eeh_init(void)
 {
        struct device_node *phb, *np;
-       struct eeh_early_enable_info info;
        int ret;
 
        /* call platform initialization function */
        ibm_read_slot_reset_state2 = rtas_token("ibm,read-slot-reset-state2");
        ibm_read_slot_reset_state = rtas_token("ibm,read-slot-reset-state");
        ibm_slot_error_detail = rtas_token("ibm,slot-error-detail");
-       ibm_get_config_addr_info = rtas_token("ibm,get-config-addr-info");
-       ibm_get_config_addr_info2 = rtas_token("ibm,get-config-addr-info2");
        ibm_configure_bridge = rtas_token("ibm,configure-bridge");
        ibm_configure_pe = rtas_token("ibm,configure-pe");
 
                if (buid == 0 || PCI_DN(phb) == NULL)
                        continue;
 
-               info.buid_lo = BUID_LO(buid);
-               info.buid_hi = BUID_HI(buid);
-               traverse_pci_devices(phb, eeh_early_enable, &info);
+               traverse_pci_devices(phb, eeh_early_enable, NULL);
        }
 
        if (eeh_subsystem_enabled)
 static void eeh_add_device_early(struct device_node *dn)
 {
        struct pci_controller *phb;
-       struct eeh_early_enable_info info;
 
        if (!dn || !PCI_DN(dn))
                return;
        if (NULL == phb || 0 == phb->buid)
                return;
 
-       info.buid_hi = BUID_HI(phb->buid);
-       info.buid_lo = BUID_LO(phb->buid);
-       eeh_early_enable(dn, &info);
+       eeh_early_enable(dn, NULL);
 }
 
 /**
 
  */
 static int pseries_eeh_get_pe_addr(struct device_node *dn)
 {
-       return 0;
+       struct pci_dn *pdn;
+       int ret = 0;
+       int rets[3];
+
+       pdn = PCI_DN(dn);
+
+       if (ibm_get_config_addr_info2 != RTAS_UNKNOWN_SERVICE) {
+               /*
+                * First of all, we need to make sure there has one PE
+                * associated with the device. Otherwise, PE address is
+                * meaningless.
+                */
+               ret = rtas_call(ibm_get_config_addr_info2, 4, 2, rets,
+                               pdn->eeh_config_addr, BUID_HI(pdn->phb->buid),
+                               BUID_LO(pdn->phb->buid), 1);
+               if (ret || (rets[0] == 0))
+                       return 0;
+
+               /* Retrieve the associated PE config address */
+               ret = rtas_call(ibm_get_config_addr_info2, 4, 2, rets,
+                               pdn->eeh_config_addr, BUID_HI(pdn->phb->buid),
+                               BUID_LO(pdn->phb->buid), 0);
+               if (ret) {
+                       pr_warning("%s: Failed to get PE address for %s\n",
+                               __func__, dn->full_name);
+                       return 0;
+               }
+
+               return rets[0];
+       }
+
+       if (ibm_get_config_addr_info != RTAS_UNKNOWN_SERVICE) {
+               ret = rtas_call(ibm_get_config_addr_info, 4, 2, rets,
+                               pdn->eeh_config_addr, BUID_HI(pdn->phb->buid),
+                               BUID_LO(pdn->phb->buid), 0);
+               if (ret) {
+                       pr_warning("%s: Failed to get PE address for %s\n",
+                               __func__, dn->full_name);
+                       return 0;
+               }
+
+               return rets[0];
+       }
+
+       return ret;
 }
 
 /**