brintos

brintos / linux-shallow public Read only

0
0
Text · 5.7 KiB · a9ba919 Raw
205 lines · c
1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.02/******************************************************************************3 *4 * Name: hwesleep.c - ACPI Hardware Sleep/Wake Support functions for the5 *                    extended FADT-V5 sleep registers.6 *7 * Copyright (C) 2000 - 2023, Intel Corp.8 *9 *****************************************************************************/10 11#include <acpi/acpi.h>12#include "accommon.h"13 14#define _COMPONENT          ACPI_HARDWARE15ACPI_MODULE_NAME("hwesleep")16 17/*******************************************************************************18 *19 * FUNCTION:    acpi_hw_execute_sleep_method20 *21 * PARAMETERS:  method_pathname     - Pathname of method to execute22 *              integer_argument    - Argument to pass to the method23 *24 * RETURN:      None25 *26 * DESCRIPTION: Execute a sleep/wake related method with one integer argument27 *              and no return value.28 *29 ******************************************************************************/30void acpi_hw_execute_sleep_method(char *method_pathname, u32 integer_argument)31{32	struct acpi_object_list arg_list;33	union acpi_object arg;34	acpi_status status;35 36	ACPI_FUNCTION_TRACE(hw_execute_sleep_method);37 38	/* One argument, integer_argument; No return value expected */39 40	arg_list.count = 1;41	arg_list.pointer = &arg;42	arg.type = ACPI_TYPE_INTEGER;43	arg.integer.value = (u64)integer_argument;44 45	status = acpi_evaluate_object(NULL, method_pathname, &arg_list, NULL);46	if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {47		ACPI_EXCEPTION((AE_INFO, status, "While executing method %s",48				method_pathname));49	}50 51	return_VOID;52}53 54/*******************************************************************************55 *56 * FUNCTION:    acpi_hw_extended_sleep57 *58 * PARAMETERS:  sleep_state         - Which sleep state to enter59 *60 * RETURN:      Status61 *62 * DESCRIPTION: Enter a system sleep state via the extended FADT sleep63 *              registers (V5 FADT).64 *              THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED65 *66 ******************************************************************************/67 68acpi_status acpi_hw_extended_sleep(u8 sleep_state)69{70	acpi_status status;71	u8 sleep_control;72	u64 sleep_status;73 74	ACPI_FUNCTION_TRACE(hw_extended_sleep);75 76	/* Extended sleep registers must be valid */77 78	if (!acpi_gbl_FADT.sleep_control.address ||79	    !acpi_gbl_FADT.sleep_status.address) {80		return_ACPI_STATUS(AE_NOT_EXIST);81	}82 83	/* Clear wake status (WAK_STS) */84 85	status = acpi_write((u64)ACPI_X_WAKE_STATUS,86			    &acpi_gbl_FADT.sleep_status);87	if (ACPI_FAILURE(status)) {88		return_ACPI_STATUS(status);89	}90 91	acpi_gbl_system_awake_and_running = FALSE;92 93	/*94	 * Set the SLP_TYP and SLP_EN bits.95	 *96	 * Note: We only use the first value returned by the \_Sx method97	 * (acpi_gbl_sleep_type_a) - As per ACPI specification.98	 */99	ACPI_DEBUG_PRINT((ACPI_DB_INIT,100			  "Entering sleep state [S%u]\n", sleep_state));101 102	sleep_control = ((acpi_gbl_sleep_type_a << ACPI_X_SLEEP_TYPE_POSITION) &103			 ACPI_X_SLEEP_TYPE_MASK) | ACPI_X_SLEEP_ENABLE;104 105	/* Flush caches, as per ACPI specification */106 107	if (sleep_state < ACPI_STATE_S4) {108		ACPI_FLUSH_CPU_CACHE();109	}110 111	status = acpi_os_enter_sleep(sleep_state, sleep_control, 0);112	if (status == AE_CTRL_TERMINATE) {113		return_ACPI_STATUS(AE_OK);114	}115	if (ACPI_FAILURE(status)) {116		return_ACPI_STATUS(status);117	}118 119	status = acpi_write((u64)sleep_control, &acpi_gbl_FADT.sleep_control);120	if (ACPI_FAILURE(status)) {121		return_ACPI_STATUS(status);122	}123 124	/* Wait for transition back to Working State */125 126	do {127		status = acpi_read(&sleep_status, &acpi_gbl_FADT.sleep_status);128		if (ACPI_FAILURE(status)) {129			return_ACPI_STATUS(status);130		}131 132	} while (!(((u8)sleep_status) & ACPI_X_WAKE_STATUS));133 134	return_ACPI_STATUS(AE_OK);135}136 137/*******************************************************************************138 *139 * FUNCTION:    acpi_hw_extended_wake_prep140 *141 * PARAMETERS:  sleep_state         - Which sleep state we just exited142 *143 * RETURN:      Status144 *145 * DESCRIPTION: Perform first part of OS-independent ACPI cleanup after146 *              a sleep. Called with interrupts ENABLED.147 *148 ******************************************************************************/149 150acpi_status acpi_hw_extended_wake_prep(u8 sleep_state)151{152	u8 sleep_type_value;153 154	ACPI_FUNCTION_TRACE(hw_extended_wake_prep);155 156	if (acpi_gbl_sleep_type_a_s0 != ACPI_SLEEP_TYPE_INVALID) {157		sleep_type_value =158		    ((acpi_gbl_sleep_type_a_s0 << ACPI_X_SLEEP_TYPE_POSITION) &159		     ACPI_X_SLEEP_TYPE_MASK);160 161		(void)acpi_write((u64)(sleep_type_value | ACPI_X_SLEEP_ENABLE),162				 &acpi_gbl_FADT.sleep_control);163	}164 165	return_ACPI_STATUS(AE_OK);166}167 168/*******************************************************************************169 *170 * FUNCTION:    acpi_hw_extended_wake171 *172 * PARAMETERS:  sleep_state         - Which sleep state we just exited173 *174 * RETURN:      Status175 *176 * DESCRIPTION: Perform OS-independent ACPI cleanup after a sleep177 *              Called with interrupts ENABLED.178 *179 ******************************************************************************/180 181acpi_status acpi_hw_extended_wake(u8 sleep_state)182{183	ACPI_FUNCTION_TRACE(hw_extended_wake);184 185	/* Ensure enter_sleep_state_prep -> enter_sleep_state ordering */186 187	acpi_gbl_sleep_type_a = ACPI_SLEEP_TYPE_INVALID;188 189	/* Execute the wake methods */190 191	acpi_hw_execute_sleep_method(METHOD_PATHNAME__SST, ACPI_SST_WAKING);192	acpi_hw_execute_sleep_method(METHOD_PATHNAME__WAK, sleep_state);193 194	/*195	 * Some BIOS code assumes that WAK_STS will be cleared on resume196	 * and use it to determine whether the system is rebooting or197	 * resuming. Clear WAK_STS for compatibility.198	 */199	(void)acpi_write((u64)ACPI_X_WAKE_STATUS, &acpi_gbl_FADT.sleep_status);200	acpi_gbl_system_awake_and_running = TRUE;201 202	acpi_hw_execute_sleep_method(METHOD_PATHNAME__SST, ACPI_SST_WORKING);203	return_ACPI_STATUS(AE_OK);204}205