aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/namespace/nsalloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/namespace/nsalloc.c')
-rw-r--r--drivers/acpi/namespace/nsalloc.c104
1 files changed, 11 insertions, 93 deletions
diff --git a/drivers/acpi/namespace/nsalloc.c b/drivers/acpi/namespace/nsalloc.c
index acd4b6732ac4..8b921c96d6a5 100644
--- a/drivers/acpi/namespace/nsalloc.c
+++ b/drivers/acpi/namespace/nsalloc.c
@@ -47,9 +47,6 @@
47#define _COMPONENT ACPI_NAMESPACE 47#define _COMPONENT ACPI_NAMESPACE
48ACPI_MODULE_NAME("nsalloc") 48ACPI_MODULE_NAME("nsalloc")
49 49
50/* Local prototypes */
51static void acpi_ns_remove_reference(struct acpi_namespace_node *node);
52
53/******************************************************************************* 50/*******************************************************************************
54 * 51 *
55 * FUNCTION: acpi_ns_create_node 52 * FUNCTION: acpi_ns_create_node
@@ -61,14 +58,13 @@ static void acpi_ns_remove_reference(struct acpi_namespace_node *node);
61 * DESCRIPTION: Create a namespace node 58 * DESCRIPTION: Create a namespace node
62 * 59 *
63 ******************************************************************************/ 60 ******************************************************************************/
64
65struct acpi_namespace_node *acpi_ns_create_node(u32 name) 61struct acpi_namespace_node *acpi_ns_create_node(u32 name)
66{ 62{
67 struct acpi_namespace_node *node; 63 struct acpi_namespace_node *node;
68 64
69 ACPI_FUNCTION_TRACE("ns_create_node"); 65 ACPI_FUNCTION_TRACE("ns_create_node");
70 66
71 node = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_namespace_node)); 67 node = acpi_os_acquire_object(acpi_gbl_namespace_cache);
72 if (!node) { 68 if (!node) {
73 return_PTR(NULL); 69 return_PTR(NULL);
74 } 70 }
@@ -76,9 +72,7 @@ struct acpi_namespace_node *acpi_ns_create_node(u32 name)
76 ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_allocated++); 72 ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_allocated++);
77 73
78 node->name.integer = name; 74 node->name.integer = name;
79 node->reference_count = 1;
80 ACPI_SET_DESCRIPTOR_TYPE(node, ACPI_DESC_TYPE_NAMED); 75 ACPI_SET_DESCRIPTOR_TYPE(node, ACPI_DESC_TYPE_NAMED);
81
82 return_PTR(node); 76 return_PTR(node);
83} 77}
84 78
@@ -139,10 +133,10 @@ void acpi_ns_delete_node(struct acpi_namespace_node *node)
139 ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_freed++); 133 ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_freed++);
140 134
141 /* 135 /*
142 * Detach an object if there is one then delete the node 136 * Detach an object if there is one, then delete the node
143 */ 137 */
144 acpi_ns_detach_object(node); 138 acpi_ns_detach_object(node);
145 ACPI_FREE(node); 139 (void)acpi_os_release_object(acpi_gbl_namespace_cache, node);
146 return_VOID; 140 return_VOID;
147} 141}
148 142
@@ -217,16 +211,6 @@ void acpi_ns_install_node(struct acpi_walk_state *walk_state, struct acpi_namesp
217 acpi_ut_get_node_name(parent_node), 211 acpi_ut_get_node_name(parent_node),
218 acpi_ut_get_type_name(parent_node->type), 212 acpi_ut_get_type_name(parent_node->type),
219 parent_node)); 213 parent_node));
220
221 /*
222 * Increment the reference count(s) of all parents up to
223 * the root!
224 */
225 while ((node = acpi_ns_get_parent_node(node)) != NULL) {
226 node->reference_count++;
227 }
228
229 return_VOID;
230} 214}
231 215
232/******************************************************************************* 216/*******************************************************************************
@@ -246,7 +230,6 @@ void acpi_ns_delete_children(struct acpi_namespace_node *parent_node)
246{ 230{
247 struct acpi_namespace_node *child_node; 231 struct acpi_namespace_node *child_node;
248 struct acpi_namespace_node *next_node; 232 struct acpi_namespace_node *next_node;
249 struct acpi_namespace_node *node;
250 u8 flags; 233 u8 flags;
251 234
252 ACPI_FUNCTION_TRACE_PTR("ns_delete_children", parent_node); 235 ACPI_FUNCTION_TRACE_PTR("ns_delete_children", parent_node);
@@ -292,26 +275,10 @@ void acpi_ns_delete_children(struct acpi_namespace_node *parent_node)
292 */ 275 */
293 acpi_ns_detach_object(child_node); 276 acpi_ns_detach_object(child_node);
294 277
295 /*
296 * Decrement the reference count(s) of all parents up to
297 * the root! (counts were incremented when the node was created)
298 */
299 node = child_node;
300 while ((node = acpi_ns_get_parent_node(node)) != NULL) {
301 node->reference_count--;
302 }
303
304 /* There should be only one reference remaining on this node */
305
306 if (child_node->reference_count != 1) {
307 ACPI_WARNING((AE_INFO,
308 "Existing references (%d) on node being deleted (%p)",
309 child_node->reference_count, child_node));
310 }
311
312 /* Now we can delete the node */ 278 /* Now we can delete the node */
313 279
314 ACPI_FREE(child_node); 280 (void)acpi_os_release_object(acpi_gbl_namespace_cache,
281 child_node);
315 282
316 /* And move on to the next child in the list */ 283 /* And move on to the next child in the list */
317 284
@@ -358,8 +325,9 @@ void acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_node)
358 325
359 /* Get the next node in this scope (NULL if none) */ 326 /* Get the next node in this scope (NULL if none) */
360 327
361 child_node = acpi_ns_get_next_node(ACPI_TYPE_ANY, parent_node, 328 child_node =
362 child_node); 329 acpi_ns_get_next_node(ACPI_TYPE_ANY, parent_node,
330 child_node);
363 if (child_node) { 331 if (child_node) {
364 332
365 /* Found a child node - detach any attached object */ 333 /* Found a child node - detach any attached object */
@@ -406,57 +374,6 @@ void acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_node)
406 374
407/******************************************************************************* 375/*******************************************************************************
408 * 376 *
409 * FUNCTION: acpi_ns_remove_reference
410 *
411 * PARAMETERS: Node - Named node whose reference count is to be
412 * decremented
413 *
414 * RETURN: None.
415 *
416 * DESCRIPTION: Remove a Node reference. Decrements the reference count
417 * of all parent Nodes up to the root. Any node along
418 * the way that reaches zero references is freed.
419 *
420 ******************************************************************************/
421
422static void acpi_ns_remove_reference(struct acpi_namespace_node *node)
423{
424 struct acpi_namespace_node *parent_node;
425 struct acpi_namespace_node *this_node;
426
427 ACPI_FUNCTION_ENTRY();
428
429 /*
430 * Decrement the reference count(s) of this node and all
431 * nodes up to the root, Delete anything with zero remaining references.
432 */
433 this_node = node;
434 while (this_node) {
435
436 /* Prepare to move up to parent */
437
438 parent_node = acpi_ns_get_parent_node(this_node);
439
440 /* Decrement the reference count on this node */
441
442 this_node->reference_count--;
443
444 /* Delete the node if no more references */
445
446 if (!this_node->reference_count) {
447
448 /* Delete all children and delete the node */
449
450 acpi_ns_delete_children(this_node);
451 acpi_ns_delete_node(this_node);
452 }
453
454 this_node = parent_node;
455 }
456}
457
458/*******************************************************************************
459 *
460 * FUNCTION: acpi_ns_delete_namespace_by_owner 377 * FUNCTION: acpi_ns_delete_namespace_by_owner
461 * 378 *
462 * PARAMETERS: owner_id - All nodes with this owner will be deleted 379 * PARAMETERS: owner_id - All nodes with this owner will be deleted
@@ -482,9 +399,9 @@ void acpi_ns_delete_namespace_by_owner(acpi_owner_id owner_id)
482 return_VOID; 399 return_VOID;
483 } 400 }
484 401
402 deletion_node = NULL;
485 parent_node = acpi_gbl_root_node; 403 parent_node = acpi_gbl_root_node;
486 child_node = NULL; 404 child_node = NULL;
487 deletion_node = NULL;
488 level = 1; 405 level = 1;
489 406
490 /* 407 /*
@@ -501,7 +418,8 @@ void acpi_ns_delete_namespace_by_owner(acpi_owner_id owner_id)
501 child_node); 418 child_node);
502 419
503 if (deletion_node) { 420 if (deletion_node) {
504 acpi_ns_remove_reference(deletion_node); 421 acpi_ns_delete_children(deletion_node);
422 acpi_ns_delete_node(deletion_node);
505 deletion_node = NULL; 423 deletion_node = NULL;
506 } 424 }
507 425