xref: /openbmc/linux/drivers/acpi/acpica/utstate.c (revision a62a7117d91ca83d319566cbe16039f4e9f413c2)
195b482a8SLen Brown /*******************************************************************************
295b482a8SLen Brown  *
395b482a8SLen Brown  * Module Name: utstate - state object support procedures
495b482a8SLen Brown  *
595b482a8SLen Brown  ******************************************************************************/
695b482a8SLen Brown 
795b482a8SLen Brown /*
87735ca0eSBob Moore  * Copyright (C) 2000 - 2017, Intel Corp.
995b482a8SLen Brown  * All rights reserved.
1095b482a8SLen Brown  *
1195b482a8SLen Brown  * Redistribution and use in source and binary forms, with or without
1295b482a8SLen Brown  * modification, are permitted provided that the following conditions
1395b482a8SLen Brown  * are met:
1495b482a8SLen Brown  * 1. Redistributions of source code must retain the above copyright
1595b482a8SLen Brown  *    notice, this list of conditions, and the following disclaimer,
1695b482a8SLen Brown  *    without modification.
1795b482a8SLen Brown  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
1895b482a8SLen Brown  *    substantially similar to the "NO WARRANTY" disclaimer below
1995b482a8SLen Brown  *    ("Disclaimer") and any redistribution must be conditioned upon
2095b482a8SLen Brown  *    including a substantially similar Disclaimer requirement for further
2195b482a8SLen Brown  *    binary redistribution.
2295b482a8SLen Brown  * 3. Neither the names of the above-listed copyright holders nor the names
2395b482a8SLen Brown  *    of any contributors may be used to endorse or promote products derived
2495b482a8SLen Brown  *    from this software without specific prior written permission.
2595b482a8SLen Brown  *
2695b482a8SLen Brown  * Alternatively, this software may be distributed under the terms of the
2795b482a8SLen Brown  * GNU General Public License ("GPL") version 2 as published by the Free
2895b482a8SLen Brown  * Software Foundation.
2995b482a8SLen Brown  *
3095b482a8SLen Brown  * NO WARRANTY
3195b482a8SLen Brown  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
3295b482a8SLen Brown  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3395b482a8SLen Brown  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
3495b482a8SLen Brown  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3595b482a8SLen Brown  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3695b482a8SLen Brown  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3795b482a8SLen Brown  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3895b482a8SLen Brown  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
3995b482a8SLen Brown  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
4095b482a8SLen Brown  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
4195b482a8SLen Brown  * POSSIBILITY OF SUCH DAMAGES.
4295b482a8SLen Brown  */
4395b482a8SLen Brown 
4495b482a8SLen Brown #include <acpi/acpi.h>
45e2f7a777SLen Brown #include "accommon.h"
4695b482a8SLen Brown 
4795b482a8SLen Brown #define _COMPONENT          ACPI_UTILITIES
4895b482a8SLen Brown ACPI_MODULE_NAME("utstate")
4995b482a8SLen Brown 
5095b482a8SLen Brown /*******************************************************************************
5195b482a8SLen Brown  *
5295b482a8SLen Brown  * FUNCTION:    acpi_ut_push_generic_state
5395b482a8SLen Brown  *
5495b482a8SLen Brown  * PARAMETERS:  list_head           - Head of the state stack
55ba494beeSBob Moore  *              state               - State object to push
5695b482a8SLen Brown  *
5795b482a8SLen Brown  * RETURN:      None
5895b482a8SLen Brown  *
5995b482a8SLen Brown  * DESCRIPTION: Push a state object onto a state stack
6095b482a8SLen Brown  *
6195b482a8SLen Brown  ******************************************************************************/
6295b482a8SLen Brown void
6395b482a8SLen Brown acpi_ut_push_generic_state(union acpi_generic_state **list_head,
6495b482a8SLen Brown 			   union acpi_generic_state *state)
6595b482a8SLen Brown {
660e770b32SBob Moore 	ACPI_FUNCTION_ENTRY();
6795b482a8SLen Brown 
6895b482a8SLen Brown 	/* Push the state object onto the front of the list (stack) */
6995b482a8SLen Brown 
7095b482a8SLen Brown 	state->common.next = *list_head;
7195b482a8SLen Brown 	*list_head = state;
720e770b32SBob Moore 	return;
7395b482a8SLen Brown }
7495b482a8SLen Brown 
7595b482a8SLen Brown /*******************************************************************************
7695b482a8SLen Brown  *
7795b482a8SLen Brown  * FUNCTION:    acpi_ut_pop_generic_state
7895b482a8SLen Brown  *
7995b482a8SLen Brown  * PARAMETERS:  list_head           - Head of the state stack
8095b482a8SLen Brown  *
8195b482a8SLen Brown  * RETURN:      The popped state object
8295b482a8SLen Brown  *
8395b482a8SLen Brown  * DESCRIPTION: Pop a state object from a state stack
8495b482a8SLen Brown  *
8595b482a8SLen Brown  ******************************************************************************/
8695b482a8SLen Brown 
8795b482a8SLen Brown union acpi_generic_state *acpi_ut_pop_generic_state(union acpi_generic_state
8895b482a8SLen Brown 						    **list_head)
8995b482a8SLen Brown {
9095b482a8SLen Brown 	union acpi_generic_state *state;
9195b482a8SLen Brown 
920e770b32SBob Moore 	ACPI_FUNCTION_ENTRY();
9395b482a8SLen Brown 
9495b482a8SLen Brown 	/* Remove the state object at the head of the list (stack) */
9595b482a8SLen Brown 
9695b482a8SLen Brown 	state = *list_head;
9795b482a8SLen Brown 	if (state) {
9895b482a8SLen Brown 
9995b482a8SLen Brown 		/* Update the list head */
10095b482a8SLen Brown 
10195b482a8SLen Brown 		*list_head = state->common.next;
10295b482a8SLen Brown 	}
10395b482a8SLen Brown 
1040e770b32SBob Moore 	return (state);
10595b482a8SLen Brown }
10695b482a8SLen Brown 
10795b482a8SLen Brown /*******************************************************************************
10895b482a8SLen Brown  *
10995b482a8SLen Brown  * FUNCTION:    acpi_ut_create_generic_state
11095b482a8SLen Brown  *
11195b482a8SLen Brown  * PARAMETERS:  None
11295b482a8SLen Brown  *
11395b482a8SLen Brown  * RETURN:      The new state object. NULL on failure.
11495b482a8SLen Brown  *
11595b482a8SLen Brown  * DESCRIPTION: Create a generic state object. Attempt to obtain one from
11695b482a8SLen Brown  *              the global state cache;  If none available, create a new one.
11795b482a8SLen Brown  *
11895b482a8SLen Brown  ******************************************************************************/
11995b482a8SLen Brown 
12095b482a8SLen Brown union acpi_generic_state *acpi_ut_create_generic_state(void)
12195b482a8SLen Brown {
12295b482a8SLen Brown 	union acpi_generic_state *state;
12395b482a8SLen Brown 
12495b482a8SLen Brown 	ACPI_FUNCTION_ENTRY();
12595b482a8SLen Brown 
12695b482a8SLen Brown 	state = acpi_os_acquire_object(acpi_gbl_state_cache);
12795b482a8SLen Brown 	if (state) {
12895b482a8SLen Brown 
12995b482a8SLen Brown 		/* Initialize */
13095b482a8SLen Brown 		state->common.descriptor_type = ACPI_DESC_TYPE_STATE;
13195b482a8SLen Brown 	}
13295b482a8SLen Brown 
13395b482a8SLen Brown 	return (state);
13495b482a8SLen Brown }
13595b482a8SLen Brown 
13695b482a8SLen Brown /*******************************************************************************
13795b482a8SLen Brown  *
13895b482a8SLen Brown  * FUNCTION:    acpi_ut_create_thread_state
13995b482a8SLen Brown  *
14095b482a8SLen Brown  * PARAMETERS:  None
14195b482a8SLen Brown  *
14295b482a8SLen Brown  * RETURN:      New Thread State. NULL on failure
14395b482a8SLen Brown  *
14495b482a8SLen Brown  * DESCRIPTION: Create a "Thread State" - a flavor of the generic state used
14595b482a8SLen Brown  *              to track per-thread info during method execution
14695b482a8SLen Brown  *
14795b482a8SLen Brown  ******************************************************************************/
14895b482a8SLen Brown 
14995b482a8SLen Brown struct acpi_thread_state *acpi_ut_create_thread_state(void)
15095b482a8SLen Brown {
15195b482a8SLen Brown 	union acpi_generic_state *state;
15295b482a8SLen Brown 
1530e770b32SBob Moore 	ACPI_FUNCTION_ENTRY();
15495b482a8SLen Brown 
15595b482a8SLen Brown 	/* Create the generic state object */
15695b482a8SLen Brown 
15795b482a8SLen Brown 	state = acpi_ut_create_generic_state();
15895b482a8SLen Brown 	if (!state) {
1590e770b32SBob Moore 		return (NULL);
16095b482a8SLen Brown 	}
16195b482a8SLen Brown 
16295b482a8SLen Brown 	/* Init fields specific to the update struct */
16395b482a8SLen Brown 
16495b482a8SLen Brown 	state->common.descriptor_type = ACPI_DESC_TYPE_STATE_THREAD;
16595b482a8SLen Brown 	state->thread.thread_id = acpi_os_get_thread_id();
16695b482a8SLen Brown 
16795b482a8SLen Brown 	/* Check for invalid thread ID - zero is very bad, it will break things */
16895b482a8SLen Brown 
16995b482a8SLen Brown 	if (!state->thread.thread_id) {
17095b482a8SLen Brown 		ACPI_ERROR((AE_INFO, "Invalid zero ID from AcpiOsGetThreadId"));
17195b482a8SLen Brown 		state->thread.thread_id = (acpi_thread_id) 1;
17295b482a8SLen Brown 	}
17395b482a8SLen Brown 
1740e770b32SBob Moore 	return ((struct acpi_thread_state *)state);
17595b482a8SLen Brown }
17695b482a8SLen Brown 
17795b482a8SLen Brown /*******************************************************************************
17895b482a8SLen Brown  *
17995b482a8SLen Brown  * FUNCTION:    acpi_ut_create_update_state
18095b482a8SLen Brown  *
181ba494beeSBob Moore  * PARAMETERS:  object          - Initial Object to be installed in the state
182ba494beeSBob Moore  *              action          - Update action to be performed
18395b482a8SLen Brown  *
18495b482a8SLen Brown  * RETURN:      New state object, null on failure
18595b482a8SLen Brown  *
18695b482a8SLen Brown  * DESCRIPTION: Create an "Update State" - a flavor of the generic state used
18795b482a8SLen Brown  *              to update reference counts and delete complex objects such
18895b482a8SLen Brown  *              as packages.
18995b482a8SLen Brown  *
19095b482a8SLen Brown  ******************************************************************************/
19195b482a8SLen Brown 
19295b482a8SLen Brown union acpi_generic_state *acpi_ut_create_update_state(union acpi_operand_object
19395b482a8SLen Brown 						      *object, u16 action)
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_UPDATE;
20995b482a8SLen Brown 	state->update.object = object;
21095b482a8SLen Brown 	state->update.value = action;
2110e770b32SBob Moore 	return (state);
21295b482a8SLen Brown }
21395b482a8SLen Brown 
21495b482a8SLen Brown /*******************************************************************************
21595b482a8SLen Brown  *
21695b482a8SLen Brown  * FUNCTION:    acpi_ut_create_pkg_state
21795b482a8SLen Brown  *
218ba494beeSBob Moore  * PARAMETERS:  object          - Initial Object to be installed in the state
219ba494beeSBob Moore  *              action          - Update action to be performed
22095b482a8SLen Brown  *
22195b482a8SLen Brown  * RETURN:      New state object, null on failure
22295b482a8SLen Brown  *
22395b482a8SLen Brown  * DESCRIPTION: Create a "Package State"
22495b482a8SLen Brown  *
22595b482a8SLen Brown  ******************************************************************************/
22695b482a8SLen Brown 
22795b482a8SLen Brown union acpi_generic_state *acpi_ut_create_pkg_state(void *internal_object,
22895b482a8SLen Brown 						   void *external_object,
229*a62a7117SBob Moore 						   u32 index)
23095b482a8SLen Brown {
23195b482a8SLen Brown 	union acpi_generic_state *state;
23295b482a8SLen Brown 
2330e770b32SBob Moore 	ACPI_FUNCTION_ENTRY();
23495b482a8SLen Brown 
23595b482a8SLen Brown 	/* Create the generic state object */
23695b482a8SLen Brown 
23795b482a8SLen Brown 	state = acpi_ut_create_generic_state();
23895b482a8SLen Brown 	if (!state) {
2390e770b32SBob Moore 		return (NULL);
24095b482a8SLen Brown 	}
24195b482a8SLen Brown 
24295b482a8SLen Brown 	/* Init fields specific to the update struct */
24395b482a8SLen Brown 
24495b482a8SLen Brown 	state->common.descriptor_type = ACPI_DESC_TYPE_STATE_PACKAGE;
24595b482a8SLen Brown 	state->pkg.source_object = (union acpi_operand_object *)internal_object;
24695b482a8SLen Brown 	state->pkg.dest_object = external_object;
24795b482a8SLen Brown 	state->pkg.index = index;
24895b482a8SLen Brown 	state->pkg.num_packages = 1;
2491fad8738SBob Moore 
2500e770b32SBob Moore 	return (state);
25195b482a8SLen Brown }
25295b482a8SLen Brown 
25395b482a8SLen Brown /*******************************************************************************
25495b482a8SLen Brown  *
25595b482a8SLen Brown  * FUNCTION:    acpi_ut_create_control_state
25695b482a8SLen Brown  *
25795b482a8SLen Brown  * PARAMETERS:  None
25895b482a8SLen Brown  *
25995b482a8SLen Brown  * RETURN:      New state object, null on failure
26095b482a8SLen Brown  *
26195b482a8SLen Brown  * DESCRIPTION: Create a "Control State" - a flavor of the generic state used
26295b482a8SLen Brown  *              to support nested IF/WHILE constructs in the AML.
26395b482a8SLen Brown  *
26495b482a8SLen Brown  ******************************************************************************/
26595b482a8SLen Brown 
26695b482a8SLen Brown union acpi_generic_state *acpi_ut_create_control_state(void)
26795b482a8SLen Brown {
26895b482a8SLen Brown 	union acpi_generic_state *state;
26995b482a8SLen Brown 
2700e770b32SBob Moore 	ACPI_FUNCTION_ENTRY();
27195b482a8SLen Brown 
27295b482a8SLen Brown 	/* Create the generic state object */
27395b482a8SLen Brown 
27495b482a8SLen Brown 	state = acpi_ut_create_generic_state();
27595b482a8SLen Brown 	if (!state) {
2760e770b32SBob Moore 		return (NULL);
27795b482a8SLen Brown 	}
27895b482a8SLen Brown 
27995b482a8SLen Brown 	/* Init fields specific to the control struct */
28095b482a8SLen Brown 
28195b482a8SLen Brown 	state->common.descriptor_type = ACPI_DESC_TYPE_STATE_CONTROL;
28295b482a8SLen Brown 	state->common.state = ACPI_CONTROL_CONDITIONAL_EXECUTING;
2831fad8738SBob Moore 
2840e770b32SBob Moore 	return (state);
28595b482a8SLen Brown }
28695b482a8SLen Brown 
28795b482a8SLen Brown /*******************************************************************************
28895b482a8SLen Brown  *
28995b482a8SLen Brown  * FUNCTION:    acpi_ut_delete_generic_state
29095b482a8SLen Brown  *
291ba494beeSBob Moore  * PARAMETERS:  state               - The state object to be deleted
29295b482a8SLen Brown  *
29395b482a8SLen Brown  * RETURN:      None
29495b482a8SLen Brown  *
29595b482a8SLen Brown  * DESCRIPTION: Release a state object to the state cache. NULL state objects
29695b482a8SLen Brown  *              are ignored.
29795b482a8SLen Brown  *
29895b482a8SLen Brown  ******************************************************************************/
29995b482a8SLen Brown 
30095b482a8SLen Brown void acpi_ut_delete_generic_state(union acpi_generic_state *state)
30195b482a8SLen Brown {
3020e770b32SBob Moore 	ACPI_FUNCTION_ENTRY();
30395b482a8SLen Brown 
30495b482a8SLen Brown 	/* Ignore null state */
30595b482a8SLen Brown 
30695b482a8SLen Brown 	if (state) {
30795b482a8SLen Brown 		(void)acpi_os_release_object(acpi_gbl_state_cache, state);
30895b482a8SLen Brown 	}
3091fad8738SBob Moore 
3100e770b32SBob Moore 	return;
31195b482a8SLen Brown }
312