diff options
Diffstat (limited to 'drivers/acpi/namespace/nsalloc.c')
-rw-r--r-- | drivers/acpi/namespace/nsalloc.c | 104 |
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 |
48 | ACPI_MODULE_NAME("nsalloc") | 48 | ACPI_MODULE_NAME("nsalloc") |
49 | 49 | ||
50 | /* Local prototypes */ | ||
51 | static 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 | |||
65 | struct acpi_namespace_node *acpi_ns_create_node(u32 name) | 61 | struct 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 | |||
422 | static 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 | ||