[acpica] Only use syscall for sleep state 1-4.

Currently we use the zx_system_powerctl syscall for S state transitions
however only transitions to S3 are supported. As transitions to S5
(shutdown) do not require interrupts to be disabled because caches are
lost regardless, we can allow these transitions to go ahead in ACPICA.

Change-Id: I2ec96cb0dd02952d81987be538510015cbb8aab4
diff --git a/source/components/hardware/hwsleep.c b/source/components/hardware/hwsleep.c
index 833450e..f6fd05a 100644
--- a/source/components/hardware/hwsleep.c
+++ b/source/components/hardware/hwsleep.c
@@ -65,10 +65,20 @@
 AcpiHwLegacySleep (
     UINT8                   SleepState)
 {
+    ACPI_BIT_REGISTER_INFO  *SleepTypeRegInfo;
+    ACPI_BIT_REGISTER_INFO  *SleepEnableRegInfo;
+    UINT32                  Pm1aControl;
+    UINT32                  Pm1bControl;
+    UINT32                  InValue;
     ACPI_STATUS             Status;
 
+
     ACPI_FUNCTION_TRACE (HwLegacySleep);
 
+
+    SleepTypeRegInfo = AcpiHwGetBitRegisterInfo (ACPI_BITREG_SLEEP_TYPE);
+    SleepEnableRegInfo = AcpiHwGetBitRegisterInfo (ACPI_BITREG_SLEEP_ENABLE);
+
     /* Clear wake status */
 
     Status = AcpiWriteBitRegister (ACPI_BITREG_WAKE_STATUS,
@@ -100,44 +110,41 @@
         return_ACPI_STATUS (Status);
     }
 
-    /* The upstream ACPICA code expects that AcpiHwLegacySleep() is invoked with interrupts
-     * disabled.  It requires this because the last steps of going to sleep is writing to a few
-     * registers, flushing the caches (so we don't lose data if the caches are dropped), and then
-     * writing to a register to enter the sleep.  If we were to take an interrupt after the cache
-     * flush but before entering sleep, we could have inconsistent memory after waking up.*/
+    /* The upstream ACPICA code expects that AcpiHwLegacySleep() is invoked
+     * with interrupts disabled.  It requires this because the last steps of
+     * going to sleep is writing to a few registers, flushing the caches (so we
+     * don't lose data if the caches are dropped), and then writing to a
+     * register to enter the sleep.  If we were to take an interrupt after the
+     * cache flush but before entering sleep, we could have inconsistent memory
+     * after waking up.*/
 
-    /* In Fuchsia, ACPICA runs in usermode and we don't expose a mechanism for it to disable
-     * interrupts.  To ensure a consistent sleep, we notionally split AcpiHwLegacySleep into two
-     * parts, the first part that doesn't need interrupts disabled which is executed by ACPICA in
-     * usermode, and then the second part that does for which we make a syscall into the kernel to
+    /* In Fuchsia, ACPICA runs in usermode and we don't expose a mechanism for
+     * it to disable interrupts.  For a full shutdown (sleep state 5) this does
+     * not matter as caches are dropped due to power loss regardless.  For any
+     * other sleep state transition, to ensure a consistent sleep, we notionally
+     * split AcpiHwLegacySleep into two parts, the first part that doesn't need
+     * interrupts disabled which is executed by ACPICA in usermode, and then the
+     * second part that does for which we make a syscall into the kernel to
      * execute the final steps. */
 
 #if defined(__Fuchsia__) && !defined(_KERNEL)
-    extern zx_handle_t get_root_resource(void);
+    if (SleepState != 5) {
+        extern zx_handle_t get_root_resource(void);
 
-    zx_system_powerctl_arg_t arg;
-    arg.acpi_transition_s_state.target_s_state = SleepState;
-    arg.acpi_transition_s_state.sleep_type_a = AcpiGbl_SleepTypeA;
-    arg.acpi_transition_s_state.sleep_type_b = AcpiGbl_SleepTypeB;
-    zx_status_t zx_status = zx_system_powerctl(get_root_resource(),
-                                               ZX_SYSTEM_POWERCTL_ACPI_TRANSITION_S_STATE,
-                                               &arg);
-    if (zx_status == ZX_OK) {
-        Status = AE_OK;
-    } else {
-        Status = AE_ERROR;
+        zx_system_powerctl_arg_t arg;
+        arg.acpi_transition_s_state.target_s_state = SleepState;
+        arg.acpi_transition_s_state.sleep_type_a = AcpiGbl_SleepTypeA;
+        arg.acpi_transition_s_state.sleep_type_b = AcpiGbl_SleepTypeB;
+        zx_status_t zx_status = zx_system_powerctl(get_root_resource(), 
+            ZX_SYSTEM_POWERCTL_ACPI_TRANSITION_S_STATE, &arg);
+        if (zx_status == ZX_OK) {
+            Status = AE_OK;
+        } else {
+            Status = AE_ERROR;
+        }
+        return_ACPI_STATUS (Status);
     }
-    return_ACPI_STATUS (Status);
-}
-#else
-    ACPI_BIT_REGISTER_INFO  *SleepTypeRegInfo;
-    ACPI_BIT_REGISTER_INFO  *SleepEnableRegInfo;
-    UINT32                  Pm1aControl;
-    UINT32                  Pm1bControl;
-    UINT32                  InValue;
-
-    SleepTypeRegInfo = AcpiHwGetBitRegisterInfo (ACPI_BITREG_SLEEP_TYPE);
-    SleepEnableRegInfo = AcpiHwGetBitRegisterInfo (ACPI_BITREG_SLEEP_ENABLE);
+#endif
 
     /* Get current value of PM1A control */
 
@@ -239,7 +246,6 @@
     return_ACPI_STATUS (AE_OK);
 }
 
-#endif
 
 /*******************************************************************************
  *