aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica/nsalloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/acpica/nsalloc.c')
-rw-r--r--drivers/acpi/acpica/nsalloc.c94
1 files changed, 41 insertions, 53 deletions
diff --git a/drivers/acpi/acpica/nsalloc.c b/drivers/acpi/acpica/nsalloc.c
index 982269c1fa48..1e5ff803d9ad 100644
--- a/drivers/acpi/acpica/nsalloc.c
+++ b/drivers/acpi/acpica/nsalloc.c
@@ -159,7 +159,7 @@ void acpi_ns_remove_node(struct acpi_namespace_node *node)
159 159
160 ACPI_FUNCTION_TRACE_PTR(ns_remove_node, node); 160 ACPI_FUNCTION_TRACE_PTR(ns_remove_node, node);
161 161
162 parent_node = acpi_ns_get_parent_node(node); 162 parent_node = node->parent;
163 163
164 prev_node = NULL; 164 prev_node = NULL;
165 next_node = parent_node->child; 165 next_node = parent_node->child;
@@ -168,29 +168,20 @@ void acpi_ns_remove_node(struct acpi_namespace_node *node)
168 168
169 while (next_node != node) { 169 while (next_node != node) {
170 prev_node = next_node; 170 prev_node = next_node;
171 next_node = prev_node->peer; 171 next_node = next_node->peer;
172 } 172 }
173 173
174 if (prev_node) { 174 if (prev_node) {
175 175
176 /* Node is not first child, unlink it */ 176 /* Node is not first child, unlink it */
177 177
178 prev_node->peer = next_node->peer; 178 prev_node->peer = node->peer;
179 if (next_node->flags & ANOBJ_END_OF_PEER_LIST) {
180 prev_node->flags |= ANOBJ_END_OF_PEER_LIST;
181 }
182 } else { 179 } else {
183 /* Node is first child (has no previous peer) */ 180 /*
184 181 * Node is first child (has no previous peer).
185 if (next_node->flags & ANOBJ_END_OF_PEER_LIST) { 182 * Link peer list to parent
186 183 */
187 /* No peers at all */ 184 parent_node->child = node->peer;
188
189 parent_node->child = NULL;
190 } else { /* Link peer list to parent */
191
192 parent_node->child = next_node->peer;
193 }
194 } 185 }
195 186
196 /* Delete the node and any attached objects */ 187 /* Delete the node and any attached objects */
@@ -228,33 +219,42 @@ void acpi_ns_install_node(struct acpi_walk_state *walk_state, struct acpi_namesp
228 219
229 ACPI_FUNCTION_TRACE(ns_install_node); 220 ACPI_FUNCTION_TRACE(ns_install_node);
230 221
231 /*
232 * Get the owner ID from the Walk state. The owner ID is used to track
233 * table deletion and deletion of objects created by methods.
234 */
235 if (walk_state) { 222 if (walk_state) {
223 /*
224 * Get the owner ID from the Walk state. The owner ID is used to
225 * track table deletion and deletion of objects created by methods.
226 */
236 owner_id = walk_state->owner_id; 227 owner_id = walk_state->owner_id;
228
229 if ((walk_state->method_desc) &&
230 (parent_node != walk_state->method_node)) {
231 /*
232 * A method is creating a new node that is not a child of the
233 * method (it is non-local). Mark the executing method as having
234 * modified the namespace. This is used for cleanup when the
235 * method exits.
236 */
237 walk_state->method_desc->method.flags |=
238 AOPOBJ_MODIFIED_NAMESPACE;
239 }
237 } 240 }
238 241
239 /* Link the new entry into the parent and existing children */ 242 /* Link the new entry into the parent and existing children */
240 243
244 node->peer = NULL;
245 node->parent = parent_node;
241 child_node = parent_node->child; 246 child_node = parent_node->child;
247
242 if (!child_node) { 248 if (!child_node) {
243 parent_node->child = node; 249 parent_node->child = node;
244 node->flags |= ANOBJ_END_OF_PEER_LIST;
245 node->peer = parent_node;
246 } else { 250 } else {
247 while (!(child_node->flags & ANOBJ_END_OF_PEER_LIST)) { 251 /* Add node to the end of the peer list */
252
253 while (child_node->peer) {
248 child_node = child_node->peer; 254 child_node = child_node->peer;
249 } 255 }
250 256
251 child_node->peer = node; 257 child_node->peer = node;
252
253 /* Clear end-of-list flag */
254
255 child_node->flags &= ~ANOBJ_END_OF_PEER_LIST;
256 node->flags |= ANOBJ_END_OF_PEER_LIST;
257 node->peer = parent_node;
258 } 258 }
259 259
260 /* Init the new entry */ 260 /* Init the new entry */
@@ -288,9 +288,8 @@ void acpi_ns_install_node(struct acpi_walk_state *walk_state, struct acpi_namesp
288 288
289void acpi_ns_delete_children(struct acpi_namespace_node *parent_node) 289void acpi_ns_delete_children(struct acpi_namespace_node *parent_node)
290{ 290{
291 struct acpi_namespace_node *child_node;
292 struct acpi_namespace_node *next_node; 291 struct acpi_namespace_node *next_node;
293 u8 flags; 292 struct acpi_namespace_node *node_to_delete;
294 293
295 ACPI_FUNCTION_TRACE_PTR(ns_delete_children, parent_node); 294 ACPI_FUNCTION_TRACE_PTR(ns_delete_children, parent_node);
296 295
@@ -298,37 +297,26 @@ void acpi_ns_delete_children(struct acpi_namespace_node *parent_node)
298 return_VOID; 297 return_VOID;
299 } 298 }
300 299
301 /* If no children, all done! */
302
303 child_node = parent_node->child;
304 if (!child_node) {
305 return_VOID;
306 }
307
308 /* Deallocate all children at this level */ 300 /* Deallocate all children at this level */
309 301
310 do { 302 next_node = parent_node->child;
311 303 while (next_node) {
312 /* Get the things we need */
313
314 next_node = child_node->peer;
315 flags = child_node->flags;
316 304
317 /* Grandchildren should have all been deleted already */ 305 /* Grandchildren should have all been deleted already */
318 306
319 if (child_node->child) { 307 if (next_node->child) {
320 ACPI_ERROR((AE_INFO, "Found a grandchild! P=%p C=%p", 308 ACPI_ERROR((AE_INFO, "Found a grandchild! P=%p C=%p",
321 parent_node, child_node)); 309 parent_node, next_node));
322 } 310 }
323 311
324 /* 312 /*
325 * Delete this child node and move on to the next child in the list. 313 * Delete this child node and move on to the next child in the list.
326 * No need to unlink the node since we are deleting the entire branch. 314 * No need to unlink the node since we are deleting the entire branch.
327 */ 315 */
328 acpi_ns_delete_node(child_node); 316 node_to_delete = next_node;
329 child_node = next_node; 317 next_node = next_node->peer;
330 318 acpi_ns_delete_node(node_to_delete);
331 } while (!(flags & ANOBJ_END_OF_PEER_LIST)); 319 };
332 320
333 /* Clear the parent's child pointer */ 321 /* Clear the parent's child pointer */
334 322
@@ -405,7 +393,7 @@ void acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_node)
405 393
406 /* Move up the tree to the grandparent */ 394 /* Move up the tree to the grandparent */
407 395
408 parent_node = acpi_ns_get_parent_node(parent_node); 396 parent_node = parent_node->parent;
409 } 397 }
410 } 398 }
411 399
@@ -510,7 +498,7 @@ void acpi_ns_delete_namespace_by_owner(acpi_owner_id owner_id)
510 498
511 /* Move up the tree to the grandparent */ 499 /* Move up the tree to the grandparent */
512 500
513 parent_node = acpi_ns_get_parent_node(parent_node); 501 parent_node = parent_node->parent;
514 } 502 }
515 } 503 }
516 504