1// Copyright 2016 The Fuchsia Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "power.h" 6 7#include <acpica/acpi.h> 8#include <ddk/debug.h> 9#include <zircon/syscalls/system.h> 10 11void poweroff(void) { 12 ACPI_STATUS status = AcpiEnterSleepStatePrep(5); 13 if (status == AE_OK) { 14 AcpiEnterSleepState(5); 15 } 16} 17 18void reboot(void) { 19 AcpiReset(); 20} 21 22zx_status_t suspend_to_ram(void) { 23 zx_status_t status = ZX_OK; 24 25 acpica_enable_noncontested_mode(); 26 27 status = zx_system_powerctl(get_root_resource(), 28 ZX_SYSTEM_POWERCTL_DISABLE_ALL_CPUS_BUT_PRIMARY, NULL); 29 if (status != ZX_OK) { 30 zxlogf(ERROR, "acpi: Failed to shutdown CPUs: %d\n", status); 31 goto cleanup; 32 } 33 34 ACPI_STATUS acpi_status = AcpiEnterSleepStatePrep(3); 35 if (acpi_status != AE_OK) { 36 zxlogf(ERROR, "acpi: Failed to prep enter sleep state: %x\n", acpi_status); 37 // TODO: I think we need to do LeaveSleepState{Prep,} on failure 38 status = ZX_ERR_INTERNAL; 39 goto cleanup; 40 } 41 42 acpi_status = AcpiEnterSleepState(3); 43 if (acpi_status != AE_OK) { 44 status = ZX_ERR_INTERNAL; 45 zxlogf(ERROR, "acpi: Failed to enter sleep state: %x\n", acpi_status); 46 // Continue executing to try to get the system back to where it was 47 } 48 zxlogf(TRACE, "acpi: Woke up from sleep\n"); 49 50 acpi_status = AcpiLeaveSleepStatePrep(3); 51 if (acpi_status != AE_OK) { 52 status = ZX_ERR_INTERNAL; 53 zxlogf(ERROR, "acpi: Failed to prep leave sleep state: %x\n", acpi_status); 54 } 55 56 acpi_status = AcpiLeaveSleepState(3); 57 if (acpi_status != AE_OK) { 58 status = ZX_ERR_INTERNAL; 59 zxlogf(ERROR, "acpi: Failed to leave sleep state: %x\n", acpi_status); 60 } 61 62 zx_status_t status2; 63cleanup: 64 status2 = zx_system_powerctl(get_root_resource(), ZX_SYSTEM_POWERCTL_ENABLE_ALL_CPUS, NULL); 65 if (status2 != ZX_OK) { 66 zxlogf(ERROR, "acpi: Re-enabling all cpus failed: %d\n", status2); 67 } 68 69 acpica_disable_noncontested_mode(); 70 71 zxlogf(INFO, "acpi: Finished processing suspend: %d\n", status); 72 return status; 73} 74