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.c88
1 files changed, 61 insertions, 27 deletions
diff --git a/drivers/acpi/acpica/nsalloc.c b/drivers/acpi/acpica/nsalloc.c
index efc971ab7d65..8a58a1b85aa0 100644
--- a/drivers/acpi/acpica/nsalloc.c
+++ b/drivers/acpi/acpica/nsalloc.c
@@ -96,17 +96,68 @@ struct acpi_namespace_node *acpi_ns_create_node(u32 name)
96 * 96 *
97 * RETURN: None 97 * RETURN: None
98 * 98 *
99 * DESCRIPTION: Delete a namespace node 99 * DESCRIPTION: Delete a namespace node. All node deletions must come through
100 * here. Detaches any attached objects, including any attached
101 * data. If a handler is associated with attached data, it is
102 * invoked before the node is deleted.
100 * 103 *
101 ******************************************************************************/ 104 ******************************************************************************/
102 105
103void acpi_ns_delete_node(struct acpi_namespace_node *node) 106void acpi_ns_delete_node(struct acpi_namespace_node *node)
104{ 107{
108 union acpi_operand_object *obj_desc;
109
110 ACPI_FUNCTION_NAME(ns_delete_node);
111
112 /* Detach an object if there is one */
113
114 acpi_ns_detach_object(node);
115
116 /*
117 * Delete an attached data object if present (an object that was created
118 * and attached via acpi_attach_data). Note: After any normal object is
119 * detached above, the only possible remaining object is a data object.
120 */
121 obj_desc = node->object;
122 if (obj_desc && (obj_desc->common.type == ACPI_TYPE_LOCAL_DATA)) {
123
124 /* Invoke the attached data deletion handler if present */
125
126 if (obj_desc->data.handler) {
127 obj_desc->data.handler(node, obj_desc->data.pointer);
128 }
129
130 acpi_ut_remove_reference(obj_desc);
131 }
132
133 /* Now we can delete the node */
134
135 (void)acpi_os_release_object(acpi_gbl_namespace_cache, node);
136
137 ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_freed++);
138 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "Node %p, Remaining %X\n",
139 node, acpi_gbl_current_node_count));
140}
141
142/*******************************************************************************
143 *
144 * FUNCTION: acpi_ns_remove_node
145 *
146 * PARAMETERS: Node - Node to be removed/deleted
147 *
148 * RETURN: None
149 *
150 * DESCRIPTION: Remove (unlink) and delete a namespace node
151 *
152 ******************************************************************************/
153
154void acpi_ns_remove_node(struct acpi_namespace_node *node)
155{
105 struct acpi_namespace_node *parent_node; 156 struct acpi_namespace_node *parent_node;
106 struct acpi_namespace_node *prev_node; 157 struct acpi_namespace_node *prev_node;
107 struct acpi_namespace_node *next_node; 158 struct acpi_namespace_node *next_node;
108 159
109 ACPI_FUNCTION_TRACE_PTR(ns_delete_node, node); 160 ACPI_FUNCTION_TRACE_PTR(ns_remove_node, node);
110 161
111 parent_node = acpi_ns_get_parent_node(node); 162 parent_node = acpi_ns_get_parent_node(node);
112 163
@@ -142,12 +193,9 @@ void acpi_ns_delete_node(struct acpi_namespace_node *node)
142 } 193 }
143 } 194 }
144 195
145 ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_freed++); 196 /* Delete the node and any attached objects */
146
147 /* Detach an object if there is one, then delete the node */
148 197
149 acpi_ns_detach_object(node); 198 acpi_ns_delete_node(node);
150 (void)acpi_os_release_object(acpi_gbl_namespace_cache, node);
151 return_VOID; 199 return_VOID;
152} 200}
153 201
@@ -273,25 +321,11 @@ void acpi_ns_delete_children(struct acpi_namespace_node *parent_node)
273 parent_node, child_node)); 321 parent_node, child_node));
274 } 322 }
275 323
276 /* Now we can free this child object */ 324 /*
277 325 * Delete this child node and move on to the next child in the list.
278 ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_freed++); 326 * No need to unlink the node since we are deleting the entire branch.
279 327 */
280 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, 328 acpi_ns_delete_node(child_node);
281 "Object %p, Remaining %X\n", child_node,
282 acpi_gbl_current_node_count));
283
284 /* Detach an object if there is one, then free the child node */
285
286 acpi_ns_detach_object(child_node);
287
288 /* Now we can delete the node */
289
290 (void)acpi_os_release_object(acpi_gbl_namespace_cache,
291 child_node);
292
293 /* And move on to the next child in the list */
294
295 child_node = next_node; 329 child_node = next_node;
296 330
297 } while (!(flags & ANOBJ_END_OF_PEER_LIST)); 331 } while (!(flags & ANOBJ_END_OF_PEER_LIST));
@@ -433,7 +467,7 @@ void acpi_ns_delete_namespace_by_owner(acpi_owner_id owner_id)
433 467
434 if (deletion_node) { 468 if (deletion_node) {
435 acpi_ns_delete_children(deletion_node); 469 acpi_ns_delete_children(deletion_node);
436 acpi_ns_delete_node(deletion_node); 470 acpi_ns_remove_node(deletion_node);
437 deletion_node = NULL; 471 deletion_node = NULL;
438 } 472 }
439 473