Linux-libre 5.7.6-gnu
[librecmc/linux-libre.git] / drivers / acpi / acpica / dswscope.c
1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /******************************************************************************
3  *
4  * Module Name: dswscope - Scope stack manipulation
5  *
6  * Copyright (C) 2000 - 2020, Intel Corp.
7  *
8  *****************************************************************************/
9
10 #include <acpi/acpi.h>
11 #include "accommon.h"
12 #include "acdispat.h"
13
14 #define _COMPONENT          ACPI_DISPATCHER
15 ACPI_MODULE_NAME("dswscope")
16
17 /****************************************************************************
18  *
19  * FUNCTION:    acpi_ds_scope_stack_clear
20  *
21  * PARAMETERS:  walk_state      - Current state
22  *
23  * RETURN:      None
24  *
25  * DESCRIPTION: Pop (and free) everything on the scope stack except the
26  *              root scope object (which remains at the stack top.)
27  *
28  ***************************************************************************/
29 void acpi_ds_scope_stack_clear(struct acpi_walk_state *walk_state)
30 {
31         union acpi_generic_state *scope_info;
32
33         ACPI_FUNCTION_NAME(ds_scope_stack_clear);
34
35         while (walk_state->scope_info) {
36
37                 /* Pop a scope off the stack */
38
39                 scope_info = walk_state->scope_info;
40                 walk_state->scope_info = scope_info->scope.next;
41
42                 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
43                                   "Popped object type (%s)\n",
44                                   acpi_ut_get_type_name(scope_info->common.
45                                                         value)));
46
47                 acpi_ut_delete_generic_state(scope_info);
48         }
49 }
50
51 /****************************************************************************
52  *
53  * FUNCTION:    acpi_ds_scope_stack_push
54  *
55  * PARAMETERS:  node            - Name to be made current
56  *              type            - Type of frame being pushed
57  *              walk_state      - Current state
58  *
59  * RETURN:      Status
60  *
61  * DESCRIPTION: Push the current scope on the scope stack, and make the
62  *              passed Node current.
63  *
64  ***************************************************************************/
65
66 acpi_status
67 acpi_ds_scope_stack_push(struct acpi_namespace_node *node,
68                          acpi_object_type type,
69                          struct acpi_walk_state *walk_state)
70 {
71         union acpi_generic_state *scope_info;
72         union acpi_generic_state *old_scope_info;
73
74         ACPI_FUNCTION_TRACE(ds_scope_stack_push);
75
76         if (!node) {
77
78                 /* Invalid scope   */
79
80                 ACPI_ERROR((AE_INFO, "Null scope parameter"));
81                 return_ACPI_STATUS(AE_BAD_PARAMETER);
82         }
83
84         /* Make sure object type is valid */
85
86         if (!acpi_ut_valid_object_type(type)) {
87                 ACPI_WARNING((AE_INFO, "Invalid object type: 0x%X", type));
88         }
89
90         /* Allocate a new scope object */
91
92         scope_info = acpi_ut_create_generic_state();
93         if (!scope_info) {
94                 return_ACPI_STATUS(AE_NO_MEMORY);
95         }
96
97         /* Init new scope object */
98
99         scope_info->common.descriptor_type = ACPI_DESC_TYPE_STATE_WSCOPE;
100         scope_info->scope.node = node;
101         scope_info->common.value = (u16) type;
102
103         walk_state->scope_depth++;
104
105         ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
106                           "[%.2d] Pushed scope ",
107                           (u32) walk_state->scope_depth));
108
109         old_scope_info = walk_state->scope_info;
110         if (old_scope_info) {
111                 ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC,
112                                       "[%4.4s] (%s)",
113                                       acpi_ut_get_node_name(old_scope_info->
114                                                             scope.node),
115                                       acpi_ut_get_type_name(old_scope_info->
116                                                             common.value)));
117         } else {
118                 ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC, ACPI_NAMESPACE_ROOT));
119         }
120
121         ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC,
122                               ", New scope -> [%4.4s] (%s)\n",
123                               acpi_ut_get_node_name(scope_info->scope.node),
124                               acpi_ut_get_type_name(scope_info->common.value)));
125
126         /* Push new scope object onto stack */
127
128         acpi_ut_push_generic_state(&walk_state->scope_info, scope_info);
129         return_ACPI_STATUS(AE_OK);
130 }
131
132 /****************************************************************************
133  *
134  * FUNCTION:    acpi_ds_scope_stack_pop
135  *
136  * PARAMETERS:  walk_state      - Current state
137  *
138  * RETURN:      Status
139  *
140  * DESCRIPTION: Pop the scope stack once.
141  *
142  ***************************************************************************/
143
144 acpi_status acpi_ds_scope_stack_pop(struct acpi_walk_state *walk_state)
145 {
146         union acpi_generic_state *scope_info;
147         union acpi_generic_state *new_scope_info;
148
149         ACPI_FUNCTION_TRACE(ds_scope_stack_pop);
150
151         /*
152          * Pop scope info object off the stack.
153          */
154         scope_info = acpi_ut_pop_generic_state(&walk_state->scope_info);
155         if (!scope_info) {
156                 return_ACPI_STATUS(AE_STACK_UNDERFLOW);
157         }
158
159         walk_state->scope_depth--;
160
161         ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
162                           "[%.2d] Popped scope [%4.4s] (%s), New scope -> ",
163                           (u32) walk_state->scope_depth,
164                           acpi_ut_get_node_name(scope_info->scope.node),
165                           acpi_ut_get_type_name(scope_info->common.value)));
166
167         new_scope_info = walk_state->scope_info;
168         if (new_scope_info) {
169                 ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC, "[%4.4s] (%s)\n",
170                                       acpi_ut_get_node_name(new_scope_info->
171                                                             scope.node),
172                                       acpi_ut_get_type_name(new_scope_info->
173                                                             common.value)));
174         } else {
175                 ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC, "%s\n",
176                                       ACPI_NAMESPACE_ROOT));
177         }
178
179         acpi_ut_delete_generic_state(scope_info);
180         return_ACPI_STATUS(AE_OK);
181 }