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.c118
1 files changed, 23 insertions, 95 deletions
diff --git a/drivers/acpi/namespace/nsalloc.c b/drivers/acpi/namespace/nsalloc.c
index 9b871f38b61b..dc3f0739a46b 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_MEM_CALLOCATE(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
@@ -100,7 +94,7 @@ void acpi_ns_delete_node(struct acpi_namespace_node *node)
100 struct acpi_namespace_node *prev_node; 94 struct acpi_namespace_node *prev_node;
101 struct acpi_namespace_node *next_node; 95 struct acpi_namespace_node *next_node;
102 96
103 ACPI_FUNCTION_TRACE_PTR("ns_delete_node", node); 97 ACPI_FUNCTION_TRACE_PTR(ns_delete_node, node);
104 98
105 parent_node = acpi_ns_get_parent_node(node); 99 parent_node = acpi_ns_get_parent_node(node);
106 100
@@ -115,6 +109,7 @@ void acpi_ns_delete_node(struct acpi_namespace_node *node)
115 } 109 }
116 110
117 if (prev_node) { 111 if (prev_node) {
112
118 /* Node is not first child, unlink it */ 113 /* Node is not first child, unlink it */
119 114
120 prev_node->peer = next_node->peer; 115 prev_node->peer = next_node->peer;
@@ -125,6 +120,7 @@ void acpi_ns_delete_node(struct acpi_namespace_node *node)
125 /* Node is first child (has no previous peer) */ 120 /* Node is first child (has no previous peer) */
126 121
127 if (next_node->flags & ANOBJ_END_OF_PEER_LIST) { 122 if (next_node->flags & ANOBJ_END_OF_PEER_LIST) {
123
128 /* No peers at all */ 124 /* No peers at all */
129 125
130 parent_node->child = NULL; 126 parent_node->child = NULL;
@@ -137,10 +133,10 @@ void acpi_ns_delete_node(struct acpi_namespace_node *node)
137 ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_freed++); 133 ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_freed++);
138 134
139 /* 135 /*
140 * Detach an object if there is one then delete the node 136 * Detach an object if there is one, then delete the node
141 */ 137 */
142 acpi_ns_detach_object(node); 138 acpi_ns_detach_object(node);
143 ACPI_MEM_FREE(node); 139 (void)acpi_os_release_object(acpi_gbl_namespace_cache, node);
144 return_VOID; 140 return_VOID;
145} 141}
146 142
@@ -171,7 +167,7 @@ void acpi_ns_install_node(struct acpi_walk_state *walk_state, struct acpi_namesp
171 acpi_owner_id owner_id = 0; 167 acpi_owner_id owner_id = 0;
172 struct acpi_namespace_node *child_node; 168 struct acpi_namespace_node *child_node;
173 169
174 ACPI_FUNCTION_TRACE("ns_install_node"); 170 ACPI_FUNCTION_TRACE(ns_install_node);
175 171
176 /* 172 /*
177 * Get the owner ID from the Walk state 173 * Get the owner ID from the Walk state
@@ -216,14 +212,6 @@ void acpi_ns_install_node(struct acpi_walk_state *walk_state, struct acpi_namesp
216 acpi_ut_get_type_name(parent_node->type), 212 acpi_ut_get_type_name(parent_node->type),
217 parent_node)); 213 parent_node));
218 214
219 /*
220 * Increment the reference count(s) of all parents up to
221 * the root!
222 */
223 while ((node = acpi_ns_get_parent_node(node)) != NULL) {
224 node->reference_count++;
225 }
226
227 return_VOID; 215 return_VOID;
228} 216}
229 217
@@ -244,10 +232,9 @@ void acpi_ns_delete_children(struct acpi_namespace_node *parent_node)
244{ 232{
245 struct acpi_namespace_node *child_node; 233 struct acpi_namespace_node *child_node;
246 struct acpi_namespace_node *next_node; 234 struct acpi_namespace_node *next_node;
247 struct acpi_namespace_node *node;
248 u8 flags; 235 u8 flags;
249 236
250 ACPI_FUNCTION_TRACE_PTR("ns_delete_children", parent_node); 237 ACPI_FUNCTION_TRACE_PTR(ns_delete_children, parent_node);
251 238
252 if (!parent_node) { 239 if (!parent_node) {
253 return_VOID; 240 return_VOID;
@@ -264,6 +251,7 @@ void acpi_ns_delete_children(struct acpi_namespace_node *parent_node)
264 * Deallocate all children at this level 251 * Deallocate all children at this level
265 */ 252 */
266 do { 253 do {
254
267 /* Get the things we need */ 255 /* Get the things we need */
268 256
269 next_node = child_node->peer; 257 next_node = child_node->peer;
@@ -289,26 +277,10 @@ void acpi_ns_delete_children(struct acpi_namespace_node *parent_node)
289 */ 277 */
290 acpi_ns_detach_object(child_node); 278 acpi_ns_detach_object(child_node);
291 279
292 /*
293 * Decrement the reference count(s) of all parents up to
294 * the root! (counts were incremented when the node was created)
295 */
296 node = child_node;
297 while ((node = acpi_ns_get_parent_node(node)) != NULL) {
298 node->reference_count--;
299 }
300
301 /* There should be only one reference remaining on this node */
302
303 if (child_node->reference_count != 1) {
304 ACPI_WARNING((AE_INFO,
305 "Existing references (%d) on node being deleted (%p)",
306 child_node->reference_count, child_node));
307 }
308
309 /* Now we can delete the node */ 280 /* Now we can delete the node */
310 281
311 ACPI_MEM_FREE(child_node); 282 (void)acpi_os_release_object(acpi_gbl_namespace_cache,
283 child_node);
312 284
313 /* And move on to the next child in the list */ 285 /* And move on to the next child in the list */
314 286
@@ -341,7 +313,7 @@ void acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_node)
341 struct acpi_namespace_node *child_node = NULL; 313 struct acpi_namespace_node *child_node = NULL;
342 u32 level = 1; 314 u32 level = 1;
343 315
344 ACPI_FUNCTION_TRACE("ns_delete_namespace_subtree"); 316 ACPI_FUNCTION_TRACE(ns_delete_namespace_subtree);
345 317
346 if (!parent_node) { 318 if (!parent_node) {
347 return_VOID; 319 return_VOID;
@@ -352,11 +324,14 @@ void acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_node)
352 * to where we started. 324 * to where we started.
353 */ 325 */
354 while (level > 0) { 326 while (level > 0) {
327
355 /* Get the next node in this scope (NULL if none) */ 328 /* Get the next node in this scope (NULL if none) */
356 329
357 child_node = acpi_ns_get_next_node(ACPI_TYPE_ANY, parent_node, 330 child_node =
358 child_node); 331 acpi_ns_get_next_node(ACPI_TYPE_ANY, parent_node,
332 child_node);
359 if (child_node) { 333 if (child_node) {
334
360 /* Found a child node - detach any attached object */ 335 /* Found a child node - detach any attached object */
361 336
362 acpi_ns_detach_object(child_node); 337 acpi_ns_detach_object(child_node);
@@ -401,55 +376,6 @@ void acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_node)
401 376
402/******************************************************************************* 377/*******************************************************************************
403 * 378 *
404 * FUNCTION: acpi_ns_remove_reference
405 *
406 * PARAMETERS: Node - Named node whose reference count is to be
407 * decremented
408 *
409 * RETURN: None.
410 *
411 * DESCRIPTION: Remove a Node reference. Decrements the reference count
412 * of all parent Nodes up to the root. Any node along
413 * the way that reaches zero references is freed.
414 *
415 ******************************************************************************/
416
417static void acpi_ns_remove_reference(struct acpi_namespace_node *node)
418{
419 struct acpi_namespace_node *parent_node;
420 struct acpi_namespace_node *this_node;
421
422 ACPI_FUNCTION_ENTRY();
423
424 /*
425 * Decrement the reference count(s) of this node and all
426 * nodes up to the root, Delete anything with zero remaining references.
427 */
428 this_node = node;
429 while (this_node) {
430 /* Prepare to move up to parent */
431
432 parent_node = acpi_ns_get_parent_node(this_node);
433
434 /* Decrement the reference count on this node */
435
436 this_node->reference_count--;
437
438 /* Delete the node if no more references */
439
440 if (!this_node->reference_count) {
441 /* Delete all children and delete the node */
442
443 acpi_ns_delete_children(this_node);
444 acpi_ns_delete_node(this_node);
445 }
446
447 this_node = parent_node;
448 }
449}
450
451/*******************************************************************************
452 *
453 * FUNCTION: acpi_ns_delete_namespace_by_owner 379 * FUNCTION: acpi_ns_delete_namespace_by_owner
454 * 380 *
455 * PARAMETERS: owner_id - All nodes with this owner will be deleted 381 * PARAMETERS: owner_id - All nodes with this owner will be deleted
@@ -469,15 +395,15 @@ void acpi_ns_delete_namespace_by_owner(acpi_owner_id owner_id)
469 u32 level; 395 u32 level;
470 struct acpi_namespace_node *parent_node; 396 struct acpi_namespace_node *parent_node;
471 397
472 ACPI_FUNCTION_TRACE_U32("ns_delete_namespace_by_owner", owner_id); 398 ACPI_FUNCTION_TRACE_U32(ns_delete_namespace_by_owner, owner_id);
473 399
474 if (owner_id == 0) { 400 if (owner_id == 0) {
475 return_VOID; 401 return_VOID;
476 } 402 }
477 403
404 deletion_node = NULL;
478 parent_node = acpi_gbl_root_node; 405 parent_node = acpi_gbl_root_node;
479 child_node = NULL; 406 child_node = NULL;
480 deletion_node = NULL;
481 level = 1; 407 level = 1;
482 408
483 /* 409 /*
@@ -494,12 +420,14 @@ void acpi_ns_delete_namespace_by_owner(acpi_owner_id owner_id)
494 child_node); 420 child_node);
495 421
496 if (deletion_node) { 422 if (deletion_node) {
497 acpi_ns_remove_reference(deletion_node); 423 acpi_ns_delete_children(deletion_node);
424 acpi_ns_delete_node(deletion_node);
498 deletion_node = NULL; 425 deletion_node = NULL;
499 } 426 }
500 427
501 if (child_node) { 428 if (child_node) {
502 if (child_node->owner_id == owner_id) { 429 if (child_node->owner_id == owner_id) {
430
503 /* Found a matching child node - detach any attached object */ 431 /* Found a matching child node - detach any attached object */
504 432
505 acpi_ns_detach_object(child_node); 433 acpi_ns_detach_object(child_node);