Linux-libre 5.4.48-gnu
[librecmc/linux-libre.git] / drivers / acpi / acpica / nsxfobj.c
1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /*******************************************************************************
3  *
4  * Module Name: nsxfobj - Public interfaces to the ACPI subsystem
5  *                         ACPI Object oriented interfaces
6  *
7  ******************************************************************************/
8
9 #define EXPORT_ACPI_INTERFACES
10
11 #include <acpi/acpi.h>
12 #include "accommon.h"
13 #include "acnamesp.h"
14
15 #define _COMPONENT          ACPI_NAMESPACE
16 ACPI_MODULE_NAME("nsxfobj")
17
18 /*******************************************************************************
19  *
20  * FUNCTION:    acpi_get_type
21  *
22  * PARAMETERS:  handle          - Handle of object whose type is desired
23  *              ret_type        - Where the type will be placed
24  *
25  * RETURN:      Status
26  *
27  * DESCRIPTION: This routine returns the type associatd with a particular handle
28  *
29  ******************************************************************************/
30 acpi_status acpi_get_type(acpi_handle handle, acpi_object_type *ret_type)
31 {
32         struct acpi_namespace_node *node;
33         acpi_status status;
34
35         /* Parameter Validation */
36
37         if (!ret_type) {
38                 return (AE_BAD_PARAMETER);
39         }
40
41         /* Special case for the predefined Root Node (return type ANY) */
42
43         if (handle == ACPI_ROOT_OBJECT) {
44                 *ret_type = ACPI_TYPE_ANY;
45                 return (AE_OK);
46         }
47
48         status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
49         if (ACPI_FAILURE(status)) {
50                 return (status);
51         }
52
53         /* Convert and validate the handle */
54
55         node = acpi_ns_validate_handle(handle);
56         if (!node) {
57                 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
58                 return (AE_BAD_PARAMETER);
59         }
60
61         *ret_type = node->type;
62
63         status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
64         return (status);
65 }
66
67 ACPI_EXPORT_SYMBOL(acpi_get_type)
68
69 /*******************************************************************************
70  *
71  * FUNCTION:    acpi_get_parent
72  *
73  * PARAMETERS:  handle          - Handle of object whose parent is desired
74  *              ret_handle      - Where the parent handle will be placed
75  *
76  * RETURN:      Status
77  *
78  * DESCRIPTION: Returns a handle to the parent of the object represented by
79  *              Handle.
80  *
81  ******************************************************************************/
82 acpi_status acpi_get_parent(acpi_handle handle, acpi_handle *ret_handle)
83 {
84         struct acpi_namespace_node *node;
85         struct acpi_namespace_node *parent_node;
86         acpi_status status;
87
88         if (!ret_handle) {
89                 return (AE_BAD_PARAMETER);
90         }
91
92         /* Special case for the predefined Root Node (no parent) */
93
94         if (handle == ACPI_ROOT_OBJECT) {
95                 return (AE_NULL_ENTRY);
96         }
97
98         status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
99         if (ACPI_FAILURE(status)) {
100                 return (status);
101         }
102
103         /* Convert and validate the handle */
104
105         node = acpi_ns_validate_handle(handle);
106         if (!node) {
107                 status = AE_BAD_PARAMETER;
108                 goto unlock_and_exit;
109         }
110
111         /* Get the parent entry */
112
113         parent_node = node->parent;
114         *ret_handle = ACPI_CAST_PTR(acpi_handle, parent_node);
115
116         /* Return exception if parent is null */
117
118         if (!parent_node) {
119                 status = AE_NULL_ENTRY;
120         }
121
122 unlock_and_exit:
123
124         (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
125         return (status);
126 }
127
128 ACPI_EXPORT_SYMBOL(acpi_get_parent)
129
130 /*******************************************************************************
131  *
132  * FUNCTION:    acpi_get_next_object
133  *
134  * PARAMETERS:  type            - Type of object to be searched for
135  *              parent          - Parent object whose children we are getting
136  *              last_child      - Previous child that was found.
137  *                                The NEXT child will be returned
138  *              ret_handle      - Where handle to the next object is placed
139  *
140  * RETURN:      Status
141  *
142  * DESCRIPTION: Return the next peer object within the namespace. If Handle is
143  *              valid, Scope is ignored. Otherwise, the first object within
144  *              Scope is returned.
145  *
146  ******************************************************************************/
147 acpi_status
148 acpi_get_next_object(acpi_object_type type,
149                      acpi_handle parent,
150                      acpi_handle child, acpi_handle *ret_handle)
151 {
152         acpi_status status;
153         struct acpi_namespace_node *node;
154         struct acpi_namespace_node *parent_node = NULL;
155         struct acpi_namespace_node *child_node = NULL;
156
157         /* Parameter validation */
158
159         if (type > ACPI_TYPE_EXTERNAL_MAX) {
160                 return (AE_BAD_PARAMETER);
161         }
162
163         status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
164         if (ACPI_FAILURE(status)) {
165                 return (status);
166         }
167
168         /* If null handle, use the parent */
169
170         if (!child) {
171
172                 /* Start search at the beginning of the specified scope */
173
174                 parent_node = acpi_ns_validate_handle(parent);
175                 if (!parent_node) {
176                         status = AE_BAD_PARAMETER;
177                         goto unlock_and_exit;
178                 }
179         } else {
180                 /* Non-null handle, ignore the parent */
181                 /* Convert and validate the handle */
182
183                 child_node = acpi_ns_validate_handle(child);
184                 if (!child_node) {
185                         status = AE_BAD_PARAMETER;
186                         goto unlock_and_exit;
187                 }
188         }
189
190         /* Internal function does the real work */
191
192         node = acpi_ns_get_next_node_typed(type, parent_node, child_node);
193         if (!node) {
194                 status = AE_NOT_FOUND;
195                 goto unlock_and_exit;
196         }
197
198         if (ret_handle) {
199                 *ret_handle = ACPI_CAST_PTR(acpi_handle, node);
200         }
201
202 unlock_and_exit:
203
204         (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
205         return (status);
206 }
207
208 ACPI_EXPORT_SYMBOL(acpi_get_next_object)