#define PCI_BUS_RESET_WAIT_MSEC (60*1000)
 
 /* RTAS tokens */
-static int ibm_set_eeh_option;
 static int ibm_set_slot_reset;
 static int ibm_read_slot_reset_state;
 static int ibm_read_slot_reset_state2;
        size_t loglen = 0;
        pci_regs_buf[0] = 0;
 
-       eeh_pci_enable(pdn, EEH_THAW_MMIO);
+       eeh_pci_enable(pdn, EEH_OPT_THAW_MMIO);
        eeh_configure_bridge(pdn);
        eeh_restore_bars(pdn);
        loglen = eeh_gather_pci_data(pdn, pci_regs_buf, EEH_PCI_REGS_LOG_LEN);
  */
 int eeh_pci_enable(struct pci_dn *pdn, int function)
 {
-       int config_addr;
        int rc;
 
-       /* Use PE configuration address, if present */
-       config_addr = pdn->eeh_config_addr;
-       if (pdn->eeh_pe_config_addr)
-               config_addr = pdn->eeh_pe_config_addr;
-
-       rc = rtas_call(ibm_set_eeh_option, 4, 1, NULL,
-                      config_addr,
-                      BUID_HI(pdn->phb->buid),
-                      BUID_LO(pdn->phb->buid),
-                           function);
-
+       rc = eeh_ops->set_option(pdn->node, function);
        if (rc)
                printk(KERN_WARNING "EEH: Unexpected state change %d, err=%d dn=%s\n",
                        function, rc, pdn->node->full_name);
 
        rc = eeh_wait_for_slot_status(pdn, PCI_BUS_RESET_WAIT_MSEC);
-       if ((rc == 4) && (function == EEH_THAW_MMIO))
+       if ((rc == 4) && (function == EEH_OPT_THAW_MMIO))
                return 0;
 
        return rc;
        if (regs) {
                /* First register entry is addr (00BBSS00)  */
                /* Try to enable eeh */
-               ret = rtas_call(ibm_set_eeh_option, 4, 1, NULL,
-                               regs[0], info->buid_hi, info->buid_lo,
-                               EEH_ENABLE);
+               ret = eeh_ops->set_option(dn, EEH_OPT_ENABLE);
 
                enable = 0;
                if (ret == 0) {
        if (np == NULL)
                return;
 
-       ibm_set_eeh_option = rtas_token("ibm,set-eeh-option");
        ibm_set_slot_reset = rtas_token("ibm,set-slot-reset");
        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_configure_bridge = rtas_token("ibm,configure-bridge");
        ibm_configure_pe = rtas_token("ibm,configure-pe");
 
-       if (ibm_set_eeh_option == RTAS_UNKNOWN_SERVICE)
-               return;
-
        eeh_error_buf_size = rtas_token("rtas-error-log-max");
        if (eeh_error_buf_size == RTAS_UNKNOWN_SERVICE) {
                eeh_error_buf_size = 1024;
 
 
        /* If all devices reported they can proceed, then re-enable MMIO */
        if (result == PCI_ERS_RESULT_CAN_RECOVER) {
-               rc = eeh_pci_enable(frozen_pdn, EEH_THAW_MMIO);
+               rc = eeh_pci_enable(frozen_pdn, EEH_OPT_THAW_MMIO);
 
                if (rc < 0)
                        goto hard_fail;
 
        /* If all devices reported they can proceed, then re-enable DMA */
        if (result == PCI_ERS_RESULT_CAN_RECOVER) {
-               rc = eeh_pci_enable(frozen_pdn, EEH_THAW_DMA);
+               rc = eeh_pci_enable(frozen_pdn, EEH_OPT_THAW_DMA);
 
                if (rc < 0)
                        goto hard_fail;
 
  */
 static int pseries_eeh_set_option(struct device_node *dn, int option)
 {
-       return 0;
+       int ret = 0;
+       struct pci_dn *pdn;
+       const u32 *reg;
+       int config_addr;
+
+       pdn = PCI_DN(dn);
+
+       /*
+        * When we're enabling or disabling EEH functioality on
+        * the particular PE, the PE config address is possibly
+        * unavailable. Therefore, we have to figure it out from
+        * the FDT node.
+        */
+       switch (option) {
+       case EEH_OPT_DISABLE:
+       case EEH_OPT_ENABLE:
+               reg = of_get_property(dn, "reg", NULL);
+               config_addr = reg[0];
+               break;
+
+       case EEH_OPT_THAW_MMIO:
+       case EEH_OPT_THAW_DMA:
+               config_addr = pdn->eeh_config_addr;
+               if (pdn->eeh_pe_config_addr)
+                       config_addr = pdn->eeh_pe_config_addr;
+               break;
+
+       default:
+               pr_err("%s: Invalid option %d\n",
+                       __func__, option);
+               return -EINVAL;
+       }
+
+       ret = rtas_call(ibm_set_eeh_option, 4, 1, NULL,
+                       config_addr, BUID_HI(pdn->phb->buid),
+                       BUID_LO(pdn->phb->buid), option);
+
+       return ret;
 }
 
 /**