xref: /OK3568_Linux_fs/kernel/drivers/acpi/acpica/utstate.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2*4882a593Smuzhiyun /*******************************************************************************
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Module Name: utstate - state object support procedures
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  ******************************************************************************/
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #include <acpi/acpi.h>
9*4882a593Smuzhiyun #include "accommon.h"
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun #define _COMPONENT          ACPI_UTILITIES
12*4882a593Smuzhiyun ACPI_MODULE_NAME("utstate")
13*4882a593Smuzhiyun 
14*4882a593Smuzhiyun /*******************************************************************************
15*4882a593Smuzhiyun  *
16*4882a593Smuzhiyun  * FUNCTION:    acpi_ut_push_generic_state
17*4882a593Smuzhiyun  *
18*4882a593Smuzhiyun  * PARAMETERS:  list_head           - Head of the state stack
19*4882a593Smuzhiyun  *              state               - State object to push
20*4882a593Smuzhiyun  *
21*4882a593Smuzhiyun  * RETURN:      None
22*4882a593Smuzhiyun  *
23*4882a593Smuzhiyun  * DESCRIPTION: Push a state object onto a state stack
24*4882a593Smuzhiyun  *
25*4882a593Smuzhiyun  ******************************************************************************/
26*4882a593Smuzhiyun void
acpi_ut_push_generic_state(union acpi_generic_state ** list_head,union acpi_generic_state * state)27*4882a593Smuzhiyun acpi_ut_push_generic_state(union acpi_generic_state **list_head,
28*4882a593Smuzhiyun 			   union acpi_generic_state *state)
29*4882a593Smuzhiyun {
30*4882a593Smuzhiyun 	ACPI_FUNCTION_ENTRY();
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun 	/* Push the state object onto the front of the list (stack) */
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun 	state->common.next = *list_head;
35*4882a593Smuzhiyun 	*list_head = state;
36*4882a593Smuzhiyun 	return;
37*4882a593Smuzhiyun }
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun /*******************************************************************************
40*4882a593Smuzhiyun  *
41*4882a593Smuzhiyun  * FUNCTION:    acpi_ut_pop_generic_state
42*4882a593Smuzhiyun  *
43*4882a593Smuzhiyun  * PARAMETERS:  list_head           - Head of the state stack
44*4882a593Smuzhiyun  *
45*4882a593Smuzhiyun  * RETURN:      The popped state object
46*4882a593Smuzhiyun  *
47*4882a593Smuzhiyun  * DESCRIPTION: Pop a state object from a state stack
48*4882a593Smuzhiyun  *
49*4882a593Smuzhiyun  ******************************************************************************/
50*4882a593Smuzhiyun 
acpi_ut_pop_generic_state(union acpi_generic_state ** list_head)51*4882a593Smuzhiyun union acpi_generic_state *acpi_ut_pop_generic_state(union acpi_generic_state
52*4882a593Smuzhiyun 						    **list_head)
53*4882a593Smuzhiyun {
54*4882a593Smuzhiyun 	union acpi_generic_state *state;
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun 	ACPI_FUNCTION_ENTRY();
57*4882a593Smuzhiyun 
58*4882a593Smuzhiyun 	/* Remove the state object at the head of the list (stack) */
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun 	state = *list_head;
61*4882a593Smuzhiyun 	if (state) {
62*4882a593Smuzhiyun 
63*4882a593Smuzhiyun 		/* Update the list head */
64*4882a593Smuzhiyun 
65*4882a593Smuzhiyun 		*list_head = state->common.next;
66*4882a593Smuzhiyun 	}
67*4882a593Smuzhiyun 
68*4882a593Smuzhiyun 	return (state);
69*4882a593Smuzhiyun }
70*4882a593Smuzhiyun 
71*4882a593Smuzhiyun /*******************************************************************************
72*4882a593Smuzhiyun  *
73*4882a593Smuzhiyun  * FUNCTION:    acpi_ut_create_generic_state
74*4882a593Smuzhiyun  *
75*4882a593Smuzhiyun  * PARAMETERS:  None
76*4882a593Smuzhiyun  *
77*4882a593Smuzhiyun  * RETURN:      The new state object. NULL on failure.
78*4882a593Smuzhiyun  *
79*4882a593Smuzhiyun  * DESCRIPTION: Create a generic state object. Attempt to obtain one from
80*4882a593Smuzhiyun  *              the global state cache;  If none available, create a new one.
81*4882a593Smuzhiyun  *
82*4882a593Smuzhiyun  ******************************************************************************/
83*4882a593Smuzhiyun 
acpi_ut_create_generic_state(void)84*4882a593Smuzhiyun union acpi_generic_state *acpi_ut_create_generic_state(void)
85*4882a593Smuzhiyun {
86*4882a593Smuzhiyun 	union acpi_generic_state *state;
87*4882a593Smuzhiyun 
88*4882a593Smuzhiyun 	ACPI_FUNCTION_ENTRY();
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun 	state = acpi_os_acquire_object(acpi_gbl_state_cache);
91*4882a593Smuzhiyun 	if (state) {
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun 		/* Initialize */
94*4882a593Smuzhiyun 		state->common.descriptor_type = ACPI_DESC_TYPE_STATE;
95*4882a593Smuzhiyun 	}
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun 	return (state);
98*4882a593Smuzhiyun }
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun /*******************************************************************************
101*4882a593Smuzhiyun  *
102*4882a593Smuzhiyun  * FUNCTION:    acpi_ut_create_thread_state
103*4882a593Smuzhiyun  *
104*4882a593Smuzhiyun  * PARAMETERS:  None
105*4882a593Smuzhiyun  *
106*4882a593Smuzhiyun  * RETURN:      New Thread State. NULL on failure
107*4882a593Smuzhiyun  *
108*4882a593Smuzhiyun  * DESCRIPTION: Create a "Thread State" - a flavor of the generic state used
109*4882a593Smuzhiyun  *              to track per-thread info during method execution
110*4882a593Smuzhiyun  *
111*4882a593Smuzhiyun  ******************************************************************************/
112*4882a593Smuzhiyun 
acpi_ut_create_thread_state(void)113*4882a593Smuzhiyun struct acpi_thread_state *acpi_ut_create_thread_state(void)
114*4882a593Smuzhiyun {
115*4882a593Smuzhiyun 	union acpi_generic_state *state;
116*4882a593Smuzhiyun 
117*4882a593Smuzhiyun 	ACPI_FUNCTION_ENTRY();
118*4882a593Smuzhiyun 
119*4882a593Smuzhiyun 	/* Create the generic state object */
120*4882a593Smuzhiyun 
121*4882a593Smuzhiyun 	state = acpi_ut_create_generic_state();
122*4882a593Smuzhiyun 	if (!state) {
123*4882a593Smuzhiyun 		return (NULL);
124*4882a593Smuzhiyun 	}
125*4882a593Smuzhiyun 
126*4882a593Smuzhiyun 	/* Init fields specific to the update struct */
127*4882a593Smuzhiyun 
128*4882a593Smuzhiyun 	state->common.descriptor_type = ACPI_DESC_TYPE_STATE_THREAD;
129*4882a593Smuzhiyun 	state->thread.thread_id = acpi_os_get_thread_id();
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun 	/* Check for invalid thread ID - zero is very bad, it will break things */
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun 	if (!state->thread.thread_id) {
134*4882a593Smuzhiyun 		ACPI_ERROR((AE_INFO, "Invalid zero ID from AcpiOsGetThreadId"));
135*4882a593Smuzhiyun 		state->thread.thread_id = (acpi_thread_id) 1;
136*4882a593Smuzhiyun 	}
137*4882a593Smuzhiyun 
138*4882a593Smuzhiyun 	return ((struct acpi_thread_state *)state);
139*4882a593Smuzhiyun }
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun /*******************************************************************************
142*4882a593Smuzhiyun  *
143*4882a593Smuzhiyun  * FUNCTION:    acpi_ut_create_update_state
144*4882a593Smuzhiyun  *
145*4882a593Smuzhiyun  * PARAMETERS:  object          - Initial Object to be installed in the state
146*4882a593Smuzhiyun  *              action          - Update action to be performed
147*4882a593Smuzhiyun  *
148*4882a593Smuzhiyun  * RETURN:      New state object, null on failure
149*4882a593Smuzhiyun  *
150*4882a593Smuzhiyun  * DESCRIPTION: Create an "Update State" - a flavor of the generic state used
151*4882a593Smuzhiyun  *              to update reference counts and delete complex objects such
152*4882a593Smuzhiyun  *              as packages.
153*4882a593Smuzhiyun  *
154*4882a593Smuzhiyun  ******************************************************************************/
155*4882a593Smuzhiyun 
acpi_ut_create_update_state(union acpi_operand_object * object,u16 action)156*4882a593Smuzhiyun union acpi_generic_state *acpi_ut_create_update_state(union acpi_operand_object
157*4882a593Smuzhiyun 						      *object, u16 action)
158*4882a593Smuzhiyun {
159*4882a593Smuzhiyun 	union acpi_generic_state *state;
160*4882a593Smuzhiyun 
161*4882a593Smuzhiyun 	ACPI_FUNCTION_ENTRY();
162*4882a593Smuzhiyun 
163*4882a593Smuzhiyun 	/* Create the generic state object */
164*4882a593Smuzhiyun 
165*4882a593Smuzhiyun 	state = acpi_ut_create_generic_state();
166*4882a593Smuzhiyun 	if (!state) {
167*4882a593Smuzhiyun 		return (NULL);
168*4882a593Smuzhiyun 	}
169*4882a593Smuzhiyun 
170*4882a593Smuzhiyun 	/* Init fields specific to the update struct */
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun 	state->common.descriptor_type = ACPI_DESC_TYPE_STATE_UPDATE;
173*4882a593Smuzhiyun 	state->update.object = object;
174*4882a593Smuzhiyun 	state->update.value = action;
175*4882a593Smuzhiyun 	return (state);
176*4882a593Smuzhiyun }
177*4882a593Smuzhiyun 
178*4882a593Smuzhiyun /*******************************************************************************
179*4882a593Smuzhiyun  *
180*4882a593Smuzhiyun  * FUNCTION:    acpi_ut_create_pkg_state
181*4882a593Smuzhiyun  *
182*4882a593Smuzhiyun  * PARAMETERS:  object          - Initial Object to be installed in the state
183*4882a593Smuzhiyun  *              action          - Update action to be performed
184*4882a593Smuzhiyun  *
185*4882a593Smuzhiyun  * RETURN:      New state object, null on failure
186*4882a593Smuzhiyun  *
187*4882a593Smuzhiyun  * DESCRIPTION: Create a "Package State"
188*4882a593Smuzhiyun  *
189*4882a593Smuzhiyun  ******************************************************************************/
190*4882a593Smuzhiyun 
acpi_ut_create_pkg_state(void * internal_object,void * external_object,u32 index)191*4882a593Smuzhiyun union acpi_generic_state *acpi_ut_create_pkg_state(void *internal_object,
192*4882a593Smuzhiyun 						   void *external_object,
193*4882a593Smuzhiyun 						   u32 index)
194*4882a593Smuzhiyun {
195*4882a593Smuzhiyun 	union acpi_generic_state *state;
196*4882a593Smuzhiyun 
197*4882a593Smuzhiyun 	ACPI_FUNCTION_ENTRY();
198*4882a593Smuzhiyun 
199*4882a593Smuzhiyun 	/* Create the generic state object */
200*4882a593Smuzhiyun 
201*4882a593Smuzhiyun 	state = acpi_ut_create_generic_state();
202*4882a593Smuzhiyun 	if (!state) {
203*4882a593Smuzhiyun 		return (NULL);
204*4882a593Smuzhiyun 	}
205*4882a593Smuzhiyun 
206*4882a593Smuzhiyun 	/* Init fields specific to the update struct */
207*4882a593Smuzhiyun 
208*4882a593Smuzhiyun 	state->common.descriptor_type = ACPI_DESC_TYPE_STATE_PACKAGE;
209*4882a593Smuzhiyun 	state->pkg.source_object = (union acpi_operand_object *)internal_object;
210*4882a593Smuzhiyun 	state->pkg.dest_object = external_object;
211*4882a593Smuzhiyun 	state->pkg.index = index;
212*4882a593Smuzhiyun 	state->pkg.num_packages = 1;
213*4882a593Smuzhiyun 
214*4882a593Smuzhiyun 	return (state);
215*4882a593Smuzhiyun }
216*4882a593Smuzhiyun 
217*4882a593Smuzhiyun /*******************************************************************************
218*4882a593Smuzhiyun  *
219*4882a593Smuzhiyun  * FUNCTION:    acpi_ut_create_control_state
220*4882a593Smuzhiyun  *
221*4882a593Smuzhiyun  * PARAMETERS:  None
222*4882a593Smuzhiyun  *
223*4882a593Smuzhiyun  * RETURN:      New state object, null on failure
224*4882a593Smuzhiyun  *
225*4882a593Smuzhiyun  * DESCRIPTION: Create a "Control State" - a flavor of the generic state used
226*4882a593Smuzhiyun  *              to support nested IF/WHILE constructs in the AML.
227*4882a593Smuzhiyun  *
228*4882a593Smuzhiyun  ******************************************************************************/
229*4882a593Smuzhiyun 
acpi_ut_create_control_state(void)230*4882a593Smuzhiyun union acpi_generic_state *acpi_ut_create_control_state(void)
231*4882a593Smuzhiyun {
232*4882a593Smuzhiyun 	union acpi_generic_state *state;
233*4882a593Smuzhiyun 
234*4882a593Smuzhiyun 	ACPI_FUNCTION_ENTRY();
235*4882a593Smuzhiyun 
236*4882a593Smuzhiyun 	/* Create the generic state object */
237*4882a593Smuzhiyun 
238*4882a593Smuzhiyun 	state = acpi_ut_create_generic_state();
239*4882a593Smuzhiyun 	if (!state) {
240*4882a593Smuzhiyun 		return (NULL);
241*4882a593Smuzhiyun 	}
242*4882a593Smuzhiyun 
243*4882a593Smuzhiyun 	/* Init fields specific to the control struct */
244*4882a593Smuzhiyun 
245*4882a593Smuzhiyun 	state->common.descriptor_type = ACPI_DESC_TYPE_STATE_CONTROL;
246*4882a593Smuzhiyun 	state->common.state = ACPI_CONTROL_CONDITIONAL_EXECUTING;
247*4882a593Smuzhiyun 
248*4882a593Smuzhiyun 	return (state);
249*4882a593Smuzhiyun }
250*4882a593Smuzhiyun 
251*4882a593Smuzhiyun /*******************************************************************************
252*4882a593Smuzhiyun  *
253*4882a593Smuzhiyun  * FUNCTION:    acpi_ut_delete_generic_state
254*4882a593Smuzhiyun  *
255*4882a593Smuzhiyun  * PARAMETERS:  state               - The state object to be deleted
256*4882a593Smuzhiyun  *
257*4882a593Smuzhiyun  * RETURN:      None
258*4882a593Smuzhiyun  *
259*4882a593Smuzhiyun  * DESCRIPTION: Release a state object to the state cache. NULL state objects
260*4882a593Smuzhiyun  *              are ignored.
261*4882a593Smuzhiyun  *
262*4882a593Smuzhiyun  ******************************************************************************/
263*4882a593Smuzhiyun 
acpi_ut_delete_generic_state(union acpi_generic_state * state)264*4882a593Smuzhiyun void acpi_ut_delete_generic_state(union acpi_generic_state *state)
265*4882a593Smuzhiyun {
266*4882a593Smuzhiyun 	ACPI_FUNCTION_ENTRY();
267*4882a593Smuzhiyun 
268*4882a593Smuzhiyun 	/* Ignore null state */
269*4882a593Smuzhiyun 
270*4882a593Smuzhiyun 	if (state) {
271*4882a593Smuzhiyun 		(void)acpi_os_release_object(acpi_gbl_state_cache, state);
272*4882a593Smuzhiyun 	}
273*4882a593Smuzhiyun 
274*4882a593Smuzhiyun 	return;
275*4882a593Smuzhiyun }
276