return ret;
 }
 
+#ifdef CONFIG_PCI_IOV
+int pseries_send_allow_unfreeze(struct pci_dn *pdn,
+                               u16 *vf_pe_array, int cur_vfs)
+{
+       int rc;
+       int ibm_allow_unfreeze = rtas_token("ibm,open-sriov-allow-unfreeze");
+       unsigned long buid, addr;
+
+       addr = rtas_config_addr(pdn->busno, pdn->devfn, 0);
+       buid = pdn->phb->buid;
+       spin_lock(&rtas_data_buf_lock);
+       memcpy(rtas_data_buf, vf_pe_array, RTAS_DATA_BUF_SIZE);
+       rc = rtas_call(ibm_allow_unfreeze, 5, 1, NULL,
+                      addr,
+                      BUID_HI(buid),
+                      BUID_LO(buid),
+                      rtas_data_buf, cur_vfs * sizeof(u16));
+       spin_unlock(&rtas_data_buf_lock);
+       if (rc)
+               pr_warn("%s: Failed to allow unfreeze for PHB#%x-PE#%lx, rc=%x\n",
+                       __func__,
+                       pdn->phb->global_number, addr, rc);
+       return rc;
+}
+
+static int pseries_call_allow_unfreeze(struct eeh_dev *edev)
+{
+       struct pci_dn *pdn, *tmp, *parent, *physfn_pdn;
+       int cur_vfs = 0, rc = 0, vf_index, bus, devfn;
+       u16 *vf_pe_array;
+
+       vf_pe_array = kzalloc(RTAS_DATA_BUF_SIZE, GFP_KERNEL);
+       if (!vf_pe_array)
+               return -ENOMEM;
+       if (pci_num_vf(edev->physfn ? edev->physfn : edev->pdev)) {
+               if (edev->pdev->is_physfn) {
+                       cur_vfs = pci_num_vf(edev->pdev);
+                       pdn = eeh_dev_to_pdn(edev);
+                       parent = pdn->parent;
+                       for (vf_index = 0; vf_index < cur_vfs; vf_index++)
+                               vf_pe_array[vf_index] =
+                                       cpu_to_be16(pdn->pe_num_map[vf_index]);
+                       rc = pseries_send_allow_unfreeze(pdn, vf_pe_array,
+                                                        cur_vfs);
+                       pdn->last_allow_rc = rc;
+                       for (vf_index = 0; vf_index < cur_vfs; vf_index++) {
+                               list_for_each_entry_safe(pdn, tmp,
+                                                        &parent->child_list,
+                                                        list) {
+                                       bus = pci_iov_virtfn_bus(edev->pdev,
+                                                                vf_index);
+                                       devfn = pci_iov_virtfn_devfn(edev->pdev,
+                                                                    vf_index);
+                                       if (pdn->busno != bus ||
+                                           pdn->devfn != devfn)
+                                               continue;
+                                       pdn->last_allow_rc = rc;
+                               }
+                       }
+               } else {
+                       pdn = pci_get_pdn(edev->pdev);
+                       vf_pe_array[0] = cpu_to_be16(pdn->pe_number);
+                       physfn_pdn = pci_get_pdn(edev->physfn);
+                       rc = pseries_send_allow_unfreeze(physfn_pdn,
+                                                        vf_pe_array, 1);
+                       pdn->last_allow_rc = rc;
+               }
+       }
+
+       kfree(vf_pe_array);
+       return rc;
+}
+
+static int pseries_notify_resume(struct pci_dn *pdn)
+{
+       struct eeh_dev *edev = pdn_to_eeh_dev(pdn);
+
+       if (!edev)
+               return -EEXIST;
+
+       if (rtas_token("ibm,open-sriov-allow-unfreeze")
+           == RTAS_UNKNOWN_SERVICE)
+               return -EINVAL;
+
+       if (edev->pdev->is_physfn || edev->pdev->is_virtfn)
+               return pseries_call_allow_unfreeze(edev);
+
+       return 0;
+}
+#endif
+
 static struct eeh_ops pseries_eeh_ops = {
        .name                   = "pseries",
        .init                   = pseries_eeh_init,
        .read_config            = pseries_eeh_read_config,
        .write_config           = pseries_eeh_write_config,
        .next_error             = NULL,
-       .restore_config         = pseries_eeh_restore_config
+       .restore_config         = pseries_eeh_restore_config,
+#ifdef CONFIG_PCI_IOV
+       .notify_resume          = pseries_notify_resume
+#endif
 };
 
 /**