gic: make sure ProcessorSleep bit clear successfully

GICR_WAKER.ProcessorSleep can only be set to zero when:
— GICR_WAKER.Sleep bit[0] == 0.
— GICR_WAKER.Quiescent bit[31] == 0.

On some platforms, when system reboot with GIC in sleep
mode but with power ON, such as on NXP's i.MX8QM, Linux
kernel enters suspend but could be requested to reboot,
and GIC is in sleep mode and it is inside a power domain
which is ON in this scenario, when CPU reset, the GIC
driver trys to set CORE's redistributor interface to awake,
with GICR_WAKER.Sleep bit[0] and GICR_WAKER.Quiescent bit[31]
both set, the ProcessorSleep bit[1] will never be clear
and cause system hang.

This patch makes sure GICR_WAKER.Sleep bit[0] and
GICR_WAKER.Quiescent bit[31] are both zeor before clearing
ProcessorSleep bit[1].

Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
(cherry picked from commit 4436f3a49a47a778d7a30afb6ef2b0ef3f1f21c5)
diff --git a/drivers/arm/gic/v3/gicv3_helpers.c b/drivers/arm/gic/v3/gicv3_helpers.c
index c12a4b6..bd513a0 100644
--- a/drivers/arm/gic/v3/gicv3_helpers.c
+++ b/drivers/arm/gic/v3/gicv3_helpers.c
@@ -12,6 +12,7 @@
 #include <interrupt_props.h>
 #include "../common/gic_common_private.h"
 #include "gicv3_private.h"
+#include "arm_gicv3_common.h"
 
 /*
  * Accessor to read the GIC Distributor IGRPMODR corresponding to the
@@ -282,6 +283,19 @@
 	 */
 	assert((gicr_read_waker(gicr_base) & WAKER_CA_BIT) != 0U);
 
+	/*
+	 * ProcessorSleep bit can ONLY be set to zero when
+	 * Quiescent bit and Sleep bit are both zero, so
+	 * need to make sure Quiescent bit and Sleep bit
+	 * are zero before clearing ProcessorSleep bit.
+	 */
+	if (gicr_read_waker(gicr_base) & WAKER_QSC_BIT) {
+		gicr_write_waker(gicr_base, gicr_read_waker(gicr_base) & ~WAKER_SL_BIT);
+		/* Wait till the WAKER_QSC_BIT changes to 0 */
+		while ((gicr_read_waker(gicr_base) & WAKER_QSC_BIT) != 0U)
+			;
+	}
+
 	/* Mark the connected core as awake */
 	gicr_write_waker(gicr_base, gicr_read_waker(gicr_base) & ~WAKER_PS_BIT);