xref: /openbmc/linux/drivers/acpi/acpica/utstate.c (revision 95857638)
195857638SErik Schmauss // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
295b482a8SLen Brown /*******************************************************************************
395b482a8SLen Brown  *
495b482a8SLen Brown  * Module Name: utstate - state object support procedures
595b482a8SLen Brown  *
695b482a8SLen Brown  ******************************************************************************/
795b482a8SLen Brown 
895b482a8SLen Brown #include <acpi/acpi.h>
9e2f7a777SLen Brown #include "accommon.h"
1095b482a8SLen Brown 
1195b482a8SLen Brown #define _COMPONENT          ACPI_UTILITIES
1295b482a8SLen Brown ACPI_MODULE_NAME("utstate")
1395b482a8SLen Brown 
1495b482a8SLen Brown /*******************************************************************************
1595b482a8SLen Brown  *
1695b482a8SLen Brown  * FUNCTION:    acpi_ut_push_generic_state
1795b482a8SLen Brown  *
1895b482a8SLen Brown  * PARAMETERS:  list_head           - Head of the state stack
19ba494beeSBob Moore  *              state               - State object to push
2095b482a8SLen Brown  *
2195b482a8SLen Brown  * RETURN:      None
2295b482a8SLen Brown  *
2395b482a8SLen Brown  * DESCRIPTION: Push a state object onto a state stack
2495b482a8SLen Brown  *
2595b482a8SLen Brown  ******************************************************************************/
2695b482a8SLen Brown void
acpi_ut_push_generic_state(union acpi_generic_state ** list_head,union acpi_generic_state * state)2795b482a8SLen Brown acpi_ut_push_generic_state(union acpi_generic_state **list_head,
2895b482a8SLen Brown 			   union acpi_generic_state *state)
2995b482a8SLen Brown {
300e770b32SBob Moore 	ACPI_FUNCTION_ENTRY();
3195b482a8SLen Brown 
3295b482a8SLen Brown 	/* Push the state object onto the front of the list (stack) */
3395b482a8SLen Brown 
3495b482a8SLen Brown 	state->common.next = *list_head;
3595b482a8SLen Brown 	*list_head = state;
360e770b32SBob Moore 	return;
3795b482a8SLen Brown }
3895b482a8SLen Brown 
3995b482a8SLen Brown /*******************************************************************************
4095b482a8SLen Brown  *
4195b482a8SLen Brown  * FUNCTION:    acpi_ut_pop_generic_state
4295b482a8SLen Brown  *
4395b482a8SLen Brown  * PARAMETERS:  list_head           - Head of the state stack
4495b482a8SLen Brown  *
4595b482a8SLen Brown  * RETURN:      The popped state object
4695b482a8SLen Brown  *
4795b482a8SLen Brown  * DESCRIPTION: Pop a state object from a state stack
4895b482a8SLen Brown  *
4995b482a8SLen Brown  ******************************************************************************/
5095b482a8SLen Brown 
acpi_ut_pop_generic_state(union acpi_generic_state ** list_head)5195b482a8SLen Brown union acpi_generic_state *acpi_ut_pop_generic_state(union acpi_generic_state
5295b482a8SLen Brown 						    **list_head)
5395b482a8SLen Brown {
5495b482a8SLen Brown 	union acpi_generic_state *state;
5595b482a8SLen Brown 
560e770b32SBob Moore 	ACPI_FUNCTION_ENTRY();
5795b482a8SLen Brown 
5895b482a8SLen Brown 	/* Remove the state object at the head of the list (stack) */
5995b482a8SLen Brown 
6095b482a8SLen Brown 	state = *list_head;
6195b482a8SLen Brown 	if (state) {
6295b482a8SLen Brown 
6395b482a8SLen Brown 		/* Update the list head */
6495b482a8SLen Brown 
6595b482a8SLen Brown 		*list_head = state->common.next;
6695b482a8SLen Brown 	}
6795b482a8SLen Brown 
680e770b32SBob Moore 	return (state);
6995b482a8SLen Brown }
7095b482a8SLen Brown 
7195b482a8SLen Brown /*******************************************************************************
7295b482a8SLen Brown  *
7395b482a8SLen Brown  * FUNCTION:    acpi_ut_create_generic_state
7495b482a8SLen Brown  *
7595b482a8SLen Brown  * PARAMETERS:  None
7695b482a8SLen Brown  *
7795b482a8SLen Brown  * RETURN:      The new state object. NULL on failure.
7895b482a8SLen Brown  *
7995b482a8SLen Brown  * DESCRIPTION: Create a generic state object. Attempt to obtain one from
8095b482a8SLen Brown  *              the global state cache;  If none available, create a new one.
8195b482a8SLen Brown  *
8295b482a8SLen Brown  ******************************************************************************/
8395b482a8SLen Brown 
acpi_ut_create_generic_state(void)8495b482a8SLen Brown union acpi_generic_state *acpi_ut_create_generic_state(void)
8595b482a8SLen Brown {
8695b482a8SLen Brown 	union acpi_generic_state *state;
8795b482a8SLen Brown 
8895b482a8SLen Brown 	ACPI_FUNCTION_ENTRY();
8995b482a8SLen Brown 
9095b482a8SLen Brown 	state = acpi_os_acquire_object(acpi_gbl_state_cache);
9195b482a8SLen Brown 	if (state) {
9295b482a8SLen Brown 
9395b482a8SLen Brown 		/* Initialize */
9495b482a8SLen Brown 		state->common.descriptor_type = ACPI_DESC_TYPE_STATE;
9595b482a8SLen Brown 	}
9695b482a8SLen Brown 
9795b482a8SLen Brown 	return (state);
9895b482a8SLen Brown }
9995b482a8SLen Brown 
10095b482a8SLen Brown /*******************************************************************************
10195b482a8SLen Brown  *
10295b482a8SLen Brown  * FUNCTION:    acpi_ut_create_thread_state
10395b482a8SLen Brown  *
10495b482a8SLen Brown  * PARAMETERS:  None
10595b482a8SLen Brown  *
10695b482a8SLen Brown  * RETURN:      New Thread State. NULL on failure
10795b482a8SLen Brown  *
10895b482a8SLen Brown  * DESCRIPTION: Create a "Thread State" - a flavor of the generic state used
10995b482a8SLen Brown  *              to track per-thread info during method execution
11095b482a8SLen Brown  *
11195b482a8SLen Brown  ******************************************************************************/
11295b482a8SLen Brown 
acpi_ut_create_thread_state(void)11395b482a8SLen Brown struct acpi_thread_state *acpi_ut_create_thread_state(void)
11495b482a8SLen Brown {
11595b482a8SLen Brown 	union acpi_generic_state *state;
11695b482a8SLen Brown 
1170e770b32SBob Moore 	ACPI_FUNCTION_ENTRY();
11895b482a8SLen Brown 
11995b482a8SLen Brown 	/* Create the generic state object */
12095b482a8SLen Brown 
12195b482a8SLen Brown 	state = acpi_ut_create_generic_state();
12295b482a8SLen Brown 	if (!state) {
1230e770b32SBob Moore 		return (NULL);
12495b482a8SLen Brown 	}
12595b482a8SLen Brown 
12695b482a8SLen Brown 	/* Init fields specific to the update struct */
12795b482a8SLen Brown 
12895b482a8SLen Brown 	state->common.descriptor_type = ACPI_DESC_TYPE_STATE_THREAD;
12995b482a8SLen Brown 	state->thread.thread_id = acpi_os_get_thread_id();
13095b482a8SLen Brown 
13195b482a8SLen Brown 	/* Check for invalid thread ID - zero is very bad, it will break things */
13295b482a8SLen Brown 
13395b482a8SLen Brown 	if (!state->thread.thread_id) {
13495b482a8SLen Brown 		ACPI_ERROR((AE_INFO, "Invalid zero ID from AcpiOsGetThreadId"));
13595b482a8SLen Brown 		state->thread.thread_id = (acpi_thread_id) 1;
13695b482a8SLen Brown 	}
13795b482a8SLen Brown 
1380e770b32SBob Moore 	return ((struct acpi_thread_state *)state);
13995b482a8SLen Brown }
14095b482a8SLen Brown 
14195b482a8SLen Brown /*******************************************************************************
14295b482a8SLen Brown  *
14395b482a8SLen Brown  * FUNCTION:    acpi_ut_create_update_state
14495b482a8SLen Brown  *
145ba494beeSBob Moore  * PARAMETERS:  object          - Initial Object to be installed in the state
146ba494beeSBob Moore  *              action          - Update action to be performed
14795b482a8SLen Brown  *
14895b482a8SLen Brown  * RETURN:      New state object, null on failure
14995b482a8SLen Brown  *
15095b482a8SLen Brown  * DESCRIPTION: Create an "Update State" - a flavor of the generic state used
15195b482a8SLen Brown  *              to update reference counts and delete complex objects such
15295b482a8SLen Brown  *              as packages.
15395b482a8SLen Brown  *
15495b482a8SLen Brown  ******************************************************************************/
15595b482a8SLen Brown 
acpi_ut_create_update_state(union acpi_operand_object * object,u16 action)15695b482a8SLen Brown union acpi_generic_state *acpi_ut_create_update_state(union acpi_operand_object
15795b482a8SLen Brown 						      *object, u16 action)
15895b482a8SLen Brown {
15995b482a8SLen Brown 	union acpi_generic_state *state;
16095b482a8SLen Brown 
1610e770b32SBob Moore 	ACPI_FUNCTION_ENTRY();
16295b482a8SLen Brown 
16395b482a8SLen Brown 	/* Create the generic state object */
16495b482a8SLen Brown 
16595b482a8SLen Brown 	state = acpi_ut_create_generic_state();
16695b482a8SLen Brown 	if (!state) {
1670e770b32SBob Moore 		return (NULL);
16895b482a8SLen Brown 	}
16995b482a8SLen Brown 
17095b482a8SLen Brown 	/* Init fields specific to the update struct */
17195b482a8SLen Brown 
17295b482a8SLen Brown 	state->common.descriptor_type = ACPI_DESC_TYPE_STATE_UPDATE;
17395b482a8SLen Brown 	state->update.object = object;
17495b482a8SLen Brown 	state->update.value = action;
1750e770b32SBob Moore 	return (state);
17695b482a8SLen Brown }
17795b482a8SLen Brown 
17895b482a8SLen Brown /*******************************************************************************
17995b482a8SLen Brown  *
18095b482a8SLen Brown  * FUNCTION:    acpi_ut_create_pkg_state
18195b482a8SLen Brown  *
182ba494beeSBob Moore  * PARAMETERS:  object          - Initial Object to be installed in the state
183ba494beeSBob Moore  *              action          - Update action to be performed
18495b482a8SLen Brown  *
18595b482a8SLen Brown  * RETURN:      New state object, null on failure
18695b482a8SLen Brown  *
18795b482a8SLen Brown  * DESCRIPTION: Create a "Package State"
18895b482a8SLen Brown  *
18995b482a8SLen Brown  ******************************************************************************/
19095b482a8SLen Brown 
acpi_ut_create_pkg_state(void * internal_object,void * external_object,u32 index)19195b482a8SLen Brown union acpi_generic_state *acpi_ut_create_pkg_state(void *internal_object,
19295b482a8SLen Brown 						   void *external_object,
193a62a7117SBob Moore 						   u32 index)
19495b482a8SLen Brown {
19595b482a8SLen Brown 	union acpi_generic_state *state;
19695b482a8SLen Brown 
1970e770b32SBob Moore 	ACPI_FUNCTION_ENTRY();
19895b482a8SLen Brown 
19995b482a8SLen Brown 	/* Create the generic state object */
20095b482a8SLen Brown 
20195b482a8SLen Brown 	state = acpi_ut_create_generic_state();
20295b482a8SLen Brown 	if (!state) {
2030e770b32SBob Moore 		return (NULL);
20495b482a8SLen Brown 	}
20595b482a8SLen Brown 
20695b482a8SLen Brown 	/* Init fields specific to the update struct */
20795b482a8SLen Brown 
20895b482a8SLen Brown 	state->common.descriptor_type = ACPI_DESC_TYPE_STATE_PACKAGE;
20995b482a8SLen Brown 	state->pkg.source_object = (union acpi_operand_object *)internal_object;
21095b482a8SLen Brown 	state->pkg.dest_object = external_object;
21195b482a8SLen Brown 	state->pkg.index = index;
21295b482a8SLen Brown 	state->pkg.num_packages = 1;
2131fad8738SBob Moore 
2140e770b32SBob Moore 	return (state);
21595b482a8SLen Brown }
21695b482a8SLen Brown 
21795b482a8SLen Brown /*******************************************************************************
21895b482a8SLen Brown  *
21995b482a8SLen Brown  * FUNCTION:    acpi_ut_create_control_state
22095b482a8SLen Brown  *
22195b482a8SLen Brown  * PARAMETERS:  None
22295b482a8SLen Brown  *
22395b482a8SLen Brown  * RETURN:      New state object, null on failure
22495b482a8SLen Brown  *
22595b482a8SLen Brown  * DESCRIPTION: Create a "Control State" - a flavor of the generic state used
22695b482a8SLen Brown  *              to support nested IF/WHILE constructs in the AML.
22795b482a8SLen Brown  *
22895b482a8SLen Brown  ******************************************************************************/
22995b482a8SLen Brown 
acpi_ut_create_control_state(void)23095b482a8SLen Brown union acpi_generic_state *acpi_ut_create_control_state(void)
23195b482a8SLen Brown {
23295b482a8SLen Brown 	union acpi_generic_state *state;
23395b482a8SLen Brown 
2340e770b32SBob Moore 	ACPI_FUNCTION_ENTRY();
23595b482a8SLen Brown 
23695b482a8SLen Brown 	/* Create the generic state object */
23795b482a8SLen Brown 
23895b482a8SLen Brown 	state = acpi_ut_create_generic_state();
23995b482a8SLen Brown 	if (!state) {
2400e770b32SBob Moore 		return (NULL);
24195b482a8SLen Brown 	}
24295b482a8SLen Brown 
24395b482a8SLen Brown 	/* Init fields specific to the control struct */
24495b482a8SLen Brown 
24595b482a8SLen Brown 	state->common.descriptor_type = ACPI_DESC_TYPE_STATE_CONTROL;
24695b482a8SLen Brown 	state->common.state = ACPI_CONTROL_CONDITIONAL_EXECUTING;
2471fad8738SBob Moore 
2480e770b32SBob Moore 	return (state);
24995b482a8SLen Brown }
25095b482a8SLen Brown 
25195b482a8SLen Brown /*******************************************************************************
25295b482a8SLen Brown  *
25395b482a8SLen Brown  * FUNCTION:    acpi_ut_delete_generic_state
25495b482a8SLen Brown  *
255ba494beeSBob Moore  * PARAMETERS:  state               - The state object to be deleted
25695b482a8SLen Brown  *
25795b482a8SLen Brown  * RETURN:      None
25895b482a8SLen Brown  *
25995b482a8SLen Brown  * DESCRIPTION: Release a state object to the state cache. NULL state objects
26095b482a8SLen Brown  *              are ignored.
26195b482a8SLen Brown  *
26295b482a8SLen Brown  ******************************************************************************/
26395b482a8SLen Brown 
acpi_ut_delete_generic_state(union acpi_generic_state * state)26495b482a8SLen Brown void acpi_ut_delete_generic_state(union acpi_generic_state *state)
26595b482a8SLen Brown {
2660e770b32SBob Moore 	ACPI_FUNCTION_ENTRY();
26795b482a8SLen Brown 
26895b482a8SLen Brown 	/* Ignore null state */
26995b482a8SLen Brown 
27095b482a8SLen Brown 	if (state) {
27195b482a8SLen Brown 		(void)acpi_os_release_object(acpi_gbl_state_cache, state);
27295b482a8SLen Brown 	}
2731fad8738SBob Moore 
2740e770b32SBob Moore 	return;
27595b482a8SLen Brown }
276