diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index 01fcf1fa0f666afa6efd9c31247c2961ff335941..ec48c9433ae507cd5e61157adbc0c50551a9f1ee 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -200,12 +200,40 @@ static int reset_slot(struct hotplug_slot *hotplug_slot, int probe)
 	return pciehp_reset_slot(slot, probe);
 }
 
+/**
+ * pciehp_check_presence() - synthesize event if presence has changed
+ *
+ * On probe and resume, an explicit presence check is necessary to bring up an
+ * occupied slot or bring down an unoccupied slot.  This can't be triggered by
+ * events in the Slot Status register, they may be stale and are therefore
+ * cleared.  Secondly, sending an interrupt for "events that occur while
+ * interrupt generation is disabled [when] interrupt generation is subsequently
+ * enabled" is optional per PCIe r4.0, sec 6.7.3.4.
+ */
+static void pciehp_check_presence(struct controller *ctrl)
+{
+	struct slot *slot = ctrl->slot;
+	u8 occupied;
+
+	down_read(&ctrl->reset_lock);
+	mutex_lock(&slot->lock);
+
+	pciehp_get_adapter_status(slot, &occupied);
+	if ((occupied && (slot->state == OFF_STATE ||
+			  slot->state == BLINKINGON_STATE)) ||
+	    (!occupied && (slot->state == ON_STATE ||
+			   slot->state == BLINKINGOFF_STATE)))
+		pciehp_request(ctrl, PCI_EXP_SLTSTA_PDC);
+
+	mutex_unlock(&slot->lock);
+	up_read(&ctrl->reset_lock);
+}
+
 static int pciehp_probe(struct pcie_device *dev)
 {
 	int rc;
 	struct controller *ctrl;
 	struct slot *slot;
-	u8 occupied, poweron;
 
 	/* If this is not a "hotplug" service, we have no business here. */
 	if (dev->service != PCIE_PORT_SERVICE_HP)
@@ -250,21 +278,7 @@ static int pciehp_probe(struct pcie_device *dev)
 		goto err_out_shutdown_notification;
 	}
 
-	/* Check if slot is occupied */
-	down_read(&ctrl->reset_lock);
-	mutex_lock(&slot->lock);
-	pciehp_get_adapter_status(slot, &occupied);
-	pciehp_get_power_status(slot, &poweron);
-	if ((occupied && (slot->state == OFF_STATE ||
-			  slot->state == BLINKINGON_STATE)) ||
-	    (!occupied && (slot->state == ON_STATE ||
-			   slot->state == BLINKINGOFF_STATE)))
-		pciehp_request(ctrl, PCI_EXP_SLTSTA_PDC);
-	/* If empty slot's power status is on, turn power off */
-	if (!occupied && poweron && POWER_CTRL(ctrl))
-		pciehp_power_off_slot(slot);
-	mutex_unlock(&slot->lock);
-	up_read(&ctrl->reset_lock);
+	pciehp_check_presence(ctrl);
 
 	return 0;
 
@@ -311,22 +325,9 @@ static int pciehp_resume_noirq(struct pcie_device *dev)
 
 static int pciehp_resume(struct pcie_device *dev)
 {
-	struct controller *ctrl;
-	struct slot *slot;
-	u8 status;
-
-	ctrl = get_service_data(dev);
-	slot = ctrl->slot;
+	struct controller *ctrl = get_service_data(dev);
 
-	/* Check if slot is occupied */
-	pciehp_get_adapter_status(slot, &status);
-	mutex_lock(&slot->lock);
-	if ((status && (slot->state == OFF_STATE ||
-			slot->state == BLINKINGON_STATE)) ||
-	    (!status && (slot->state == ON_STATE ||
-			 slot->state == BLINKINGOFF_STATE)))
-		pciehp_request(ctrl, PCI_EXP_SLTSTA_PDC);
-	mutex_unlock(&slot->lock);
+	pciehp_check_presence(ctrl);
 
 	return 0;
 }
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 6f7de0819c88272d73dbedad8d183d20cbe446f1..5b15e76f3564f7baac8da4c922399c2948609f91 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -856,6 +856,7 @@ struct controller *pcie_init(struct pcie_device *dev)
 {
 	struct controller *ctrl;
 	u32 slot_cap, link_cap;
+	u8 occupied, poweron;
 	struct pci_dev *pdev = dev->port;
 
 	ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL);
@@ -910,6 +911,19 @@ struct controller *pcie_init(struct pcie_device *dev)
 	if (pcie_init_slot(ctrl))
 		goto abort_ctrl;
 
+	/*
+	 * If empty slot's power status is on, turn power off.  The IRQ isn't
+	 * requested yet, so avoid triggering a notification with this command.
+	 */
+	if (POWER_CTRL(ctrl)) {
+		pciehp_get_adapter_status(ctrl->slot, &occupied);
+		pciehp_get_power_status(ctrl->slot, &poweron);
+		if (!occupied && poweron) {
+			pcie_disable_notification(ctrl);
+			pciehp_power_off_slot(ctrl->slot);
+		}
+	}
+
 	return ctrl;
 
 abort_ctrl: