diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h
index 901b1543b869..2925055e8546 100644
--- a/drivers/acpi/acpica/aclocal.h
+++ b/drivers/acpi/acpica/aclocal.h
@@ -10,6 +10,8 @@
 #ifndef __ACLOCAL_H__
 #define __ACLOCAL_H__
 
+#include <linux/wait.h>
+
 /* acpisrc:struct_defs -- for acpisrc conversion */
 
 #define ACPI_SERIALIZED                 0xFF
@@ -471,6 +473,7 @@ struct acpi_gpe_register_info {
 	u8 enable_for_run;	/* GPEs to keep enabled when running */
 	u8 mask_for_run;	/* GPEs to keep masked when running */
 	u8 enable_mask;		/* Current mask of enabled GPEs */
+	wait_queue_head_t wake_mask_wq;	/* Waitqueue to sync disabling wakeup mask bit */
 };
 
 /*
diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c
index a6bb480d631c..3bfb08b5b0a9 100644
--- a/drivers/acpi/acpica/evgpe.c
+++ b/drivers/acpi/acpica/evgpe.c
@@ -355,6 +355,7 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info *gpe_xrupt_list)
 	acpi_cpu_flags flags;
 	u32 i;
 	u32 j;
+	u8 gpe_can_wake;
 
 	ACPI_FUNCTION_NAME(ev_gpe_detect);
 
@@ -408,6 +409,8 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info *gpe_xrupt_list)
 				continue;
 			}
 
+			gpe_can_wake = 0;
+
 			/* Now look at the individual GPEs in this byte register */
 
 			for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {
@@ -420,6 +423,7 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info *gpe_xrupt_list)
 						ACPI_GPE_REGISTER_WIDTH) + j];
 				gpe_number =
 				    j + gpe_register_info->base_gpe_number;
+				gpe_can_wake |= gpe_event_info->flags & ACPI_GPE_CAN_WAKE;
 				acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
 				int_status |=
 				    acpi_ev_detect_gpe(gpe_device,
@@ -427,6 +431,10 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info *gpe_xrupt_list)
 						       gpe_number);
 				flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
 			}
+
+			/* Notify the wakeup GPE event has been processed */
+			if (gpe_register_info->enable_for_wake && gpe_can_wake)
+				wake_up(&gpe_register_info->wake_mask_wq);
 		}
 
 		gpe_block = gpe_block->next;
diff --git a/drivers/acpi/acpica/evxfgpe.c b/drivers/acpi/acpica/evxfgpe.c
index 340947e412bb..16eac034abfa 100644
--- a/drivers/acpi/acpica/evxfgpe.c
+++ b/drivers/acpi/acpica/evxfgpe.c
@@ -17,6 +17,9 @@
 #define _COMPONENT          ACPI_EVENTS
 ACPI_MODULE_NAME("evxfgpe")
 
+/* How long to wait for the GPE status flag to be set */
+#define ACPI_WAIT_GPE_STATUS_FLAG_MS 500
+
 #if (!ACPI_REDUCED_HARDWARE)	/* Entire module */
 /*******************************************************************************
  *
@@ -242,6 +245,50 @@ acpi_status acpi_set_gpe(acpi_handle gpe_device, u32 gpe_number, u8 action)
 
 ACPI_EXPORT_SYMBOL(acpi_set_gpe)
 
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_init_gpe_wake_wq
+ *
+ * PARAMETERS:  gpe_device          - Parent GPE Device. NULL for GPE0/GPE1
+ *              gpe_number          - GPE level within the GPE block
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Init wake waitqueue for GPE.
+ *
+ ******************************************************************************/
+acpi_status acpi_init_gpe_wake_wq(acpi_handle gpe_device, u32 gpe_number)
+{
+	struct acpi_gpe_event_info *gpe_event_info;
+	struct acpi_gpe_register_info *gpe_register_info;
+	acpi_status status = AE_BAD_PARAMETER;
+	acpi_cpu_flags flags;
+
+	ACPI_FUNCTION_TRACE(acpi_init_gpe_wake_wq);
+
+	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
+
+	/* Ensure that we have a valid GPE number */
+
+	gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
+	if (gpe_event_info) {
+		gpe_register_info = gpe_event_info->register_info;
+		if (gpe_register_info) {
+			init_waitqueue_head(&gpe_register_info->wake_mask_wq);
+			status = AE_OK;
+		} else {
+			ACPI_WARNING((AE_INFO,
+				      "GPE 0x%x doesn't have a register info",
+				      gpe_number));
+			status = AE_NOT_EXIST;
+		}
+	}
+
+	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
+	return_ACPI_STATUS(status);
+}
+ACPI_EXPORT_SYMBOL(acpi_init_gpe_wake_wq)
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_mask_gpe
@@ -637,6 +684,82 @@ acpi_get_gpe_status(acpi_handle gpe_device,
 
 ACPI_EXPORT_SYMBOL(acpi_get_gpe_status)
 
+static u8
+acpi_is_gpe_status_set(acpi_handle gpe_device, u32 gpe_number)
+{
+	acpi_event_status event_status;
+
+	acpi_get_gpe_status(gpe_device, gpe_number, &event_status);
+	return event_status & ACPI_EVENT_FLAG_STATUS_SET;
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_wait_for_gpe_status_flag
+ *
+ * PARAMETERS:  gpe_device          - Parent GPE Device. NULL for GPE0/GPE1
+ *              gpe_number          - GPE level within the GPE block
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Wait for clear the status bit in wakeup mask
+ *
+ ******************************************************************************/
+acpi_status
+acpi_wait_for_gpe_status_flag(acpi_handle gpe_device, u32 gpe_number)
+{
+	acpi_status status = AE_OK;
+	struct acpi_gpe_event_info *gpe_event_info;
+	struct acpi_gpe_register_info *gpe_register_info;
+	acpi_cpu_flags flags;
+	int timeout;
+	int wait_ms;
+
+	ACPI_FUNCTION_TRACE(acpi_wait_for_gpe_status_flag);
+
+	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
+
+	/* Ensure that we have a valid GPE number */
+
+	gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
+	if (!gpe_event_info) {
+		status = AE_BAD_PARAMETER;
+		goto unlock_and_exit;
+	}
+
+	if (!(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) {
+		status = AE_TYPE;
+		goto unlock_and_exit;
+	}
+
+	gpe_register_info = gpe_event_info->register_info;
+	if (!gpe_register_info) {
+		status = AE_NOT_EXIST;
+		goto unlock_and_exit;
+	}
+
+	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
+
+	wait_ms = msecs_to_jiffies(ACPI_WAIT_GPE_STATUS_FLAG_MS);
+	timeout = wait_event_timeout(gpe_register_info->wake_mask_wq,
+				     !acpi_is_gpe_status_set(gpe_device,
+							     gpe_number),
+				     wait_ms);
+	if (timeout == 0) {
+		ACPI_WARNING((AE_INFO,
+			      "Time limit exceeded while waiting for GPE 0x%x status flag",
+			      gpe_number));
+		status = AE_TIME;
+	}
+
+	return_ACPI_STATUS(status);
+
+unlock_and_exit:
+	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
+	return_ACPI_STATUS(status);
+}
+ACPI_EXPORT_SYMBOL(acpi_wait_for_gpe_status_flag)
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_gispatch_gpe
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 42cec8120f18..26ba59545ceb 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -952,6 +952,7 @@ static bool acpi_wakeup_gpe_init(struct acpi_device *device)
 			if (wakeup->sleep_state == ACPI_STATE_S5)
 				wakeup->sleep_state = ACPI_STATE_S4;
 		}
+		acpi_init_gpe_wake_wq(wakeup->gpe_device, wakeup->gpe_number);
 		acpi_mark_gpe_for_wake(wakeup->gpe_device, wakeup->gpe_number);
 		device_set_wakeup_capable(&device->dev, true);
 		return true;
diff --git a/drivers/acpi/wakeup.c b/drivers/acpi/wakeup.c
index b02bf770aead..044429e69f86 100644
--- a/drivers/acpi/wakeup.c
+++ b/drivers/acpi/wakeup.c
@@ -72,6 +72,9 @@ void acpi_disable_wakeup_devices(u8 sleep_state)
 			 || dev->wakeup.prepare_count))
 			continue;
 
+		acpi_wait_for_gpe_status_flag(dev->wakeup.gpe_device,
+					      dev->wakeup.gpe_number);
+
 		acpi_set_gpe_wake_mask(dev->wakeup.gpe_device, dev->wakeup.gpe_number,
 				ACPI_GPE_DISABLE);
 
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
index 67c0b9e734b6..cc4b43caa872 100644
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -728,6 +728,10 @@ ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status
 				acpi_finish_gpe(acpi_handle gpe_device,
 						u32 gpe_number))
 
+ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status
+				acpi_init_gpe_wake_wq(acpi_handle gpe_device,
+						u32 gpe_number))
+
 ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status
 				acpi_mask_gpe(acpi_handle gpe_device,
 					      u32 gpe_number, u8 is_masked))
@@ -741,6 +745,11 @@ ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status
 							parent_device,
 							acpi_handle gpe_device,
 							u32 gpe_number))
+
+ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status
+				 acpi_wait_for_gpe_status_flag(acpi_handle gpe_device,
+							u32 gpe_number))
+
 ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status
 				 acpi_set_gpe_wake_mask(acpi_handle gpe_device,
 							u32 gpe_number,
