diff options
Diffstat (limited to 'drivers/acpi/acpica/nsalloc.c')
| -rw-r--r-- | drivers/acpi/acpica/nsalloc.c | 47 | 
1 files changed, 33 insertions, 14 deletions
diff --git a/drivers/acpi/acpica/nsalloc.c b/drivers/acpi/acpica/nsalloc.c index 1e5ff803d9a..607eb9e5150 100644 --- a/drivers/acpi/acpica/nsalloc.c +++ b/drivers/acpi/acpica/nsalloc.c @@ -5,7 +5,7 @@   ******************************************************************************/  /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp.   * All rights reserved.   *   * Redistribution and use in source and binary forms, with or without @@ -52,7 +52,7 @@ ACPI_MODULE_NAME("nsalloc")   *   * FUNCTION:    acpi_ns_create_node   * - * PARAMETERS:  Name            - Name of the new node (4 char ACPI name) + * PARAMETERS:  name            - Name of the new node (4 char ACPI name)   *   * RETURN:      New namespace node (Null on failure)   * @@ -92,7 +92,7 @@ struct acpi_namespace_node *acpi_ns_create_node(u32 name)   *   * FUNCTION:    acpi_ns_delete_node   * - * PARAMETERS:  Node            - Node to be deleted + * PARAMETERS:  node            - Node to be deleted   *   * RETURN:      None   * @@ -106,6 +106,7 @@ struct acpi_namespace_node *acpi_ns_create_node(u32 name)  void acpi_ns_delete_node(struct acpi_namespace_node *node)  {  	union acpi_operand_object *obj_desc; +	union acpi_operand_object *next_desc;  	ACPI_FUNCTION_NAME(ns_delete_node); @@ -114,12 +115,13 @@ void acpi_ns_delete_node(struct acpi_namespace_node *node)  	acpi_ns_detach_object(node);  	/* -	 * Delete an attached data object if present (an object that was created -	 * and attached via acpi_attach_data). Note: After any normal object is -	 * detached above, the only possible remaining object is a data object. +	 * Delete an attached data object list if present (objects that were +	 * attached via acpi_attach_data). Note: After any normal object is +	 * detached above, the only possible remaining object(s) are data +	 * objects, in a linked list.  	 */  	obj_desc = node->object; -	if (obj_desc && (obj_desc->common.type == ACPI_TYPE_LOCAL_DATA)) { +	while (obj_desc && (obj_desc->common.type == ACPI_TYPE_LOCAL_DATA)) {  		/* Invoke the attached data deletion handler if present */ @@ -127,7 +129,15 @@ void acpi_ns_delete_node(struct acpi_namespace_node *node)  			obj_desc->data.handler(node, obj_desc->data.pointer);  		} +		next_desc = obj_desc->common.next_object;  		acpi_ut_remove_reference(obj_desc); +		obj_desc = next_desc; +	} + +	/* Special case for the statically allocated root node */ + +	if (node == acpi_gbl_root_node) { +		return;  	}  	/* Now we can delete the node */ @@ -143,7 +153,7 @@ void acpi_ns_delete_node(struct acpi_namespace_node *node)   *   * FUNCTION:    acpi_ns_remove_node   * - * PARAMETERS:  Node            - Node to be removed/deleted + * PARAMETERS:  node            - Node to be removed/deleted   *   * RETURN:      None   * @@ -196,8 +206,8 @@ void acpi_ns_remove_node(struct acpi_namespace_node *node)   *   * PARAMETERS:  walk_state      - Current state of the walk   *              parent_node     - The parent of the new Node - *              Node            - The new Node to install - *              Type            - ACPI object type of the new Node + *              node            - The new Node to install + *              type            - ACPI object type of the new Node   *   * RETURN:      None   * @@ -234,8 +244,8 @@ void acpi_ns_install_node(struct acpi_walk_state *walk_state, struct acpi_namesp  			 * modified the namespace. This is used for cleanup when the  			 * method exits.  			 */ -			walk_state->method_desc->method.flags |= -			    AOPOBJ_MODIFIED_NAMESPACE; +			walk_state->method_desc->method.info_flags |= +			    ACPI_METHOD_MODIFIED_NAMESPACE;  		}  	} @@ -332,7 +342,7 @@ void acpi_ns_delete_children(struct acpi_namespace_node *parent_node)   *   * RETURN:      None.   * - * DESCRIPTION: Delete a subtree of the namespace.  This includes all objects + * DESCRIPTION: Delete a subtree of the namespace. This includes all objects   *              stored within the subtree.   *   ******************************************************************************/ @@ -341,6 +351,7 @@ void acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_node)  {  	struct acpi_namespace_node *child_node = NULL;  	u32 level = 1; +	acpi_status status;  	ACPI_FUNCTION_TRACE(ns_delete_namespace_subtree); @@ -348,6 +359,13 @@ void acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_node)  		return_VOID;  	} +	/* Lock namespace for possible update */ + +	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); +	if (ACPI_FAILURE(status)) { +		return_VOID; +	} +  	/*  	 * Traverse the tree of objects until we bubble back up  	 * to where we started. @@ -397,6 +415,7 @@ void acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_node)  		}  	} +	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);  	return_VOID;  } @@ -409,7 +428,7 @@ void acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_node)   * RETURN:      Status   *   * DESCRIPTION: Delete entries within the namespace that are owned by a - *              specific ID.  Used to delete entire ACPI tables.  All + *              specific ID. Used to delete entire ACPI tables. All   *              reference counts are updated.   *   * MUTEX:       Locks namespace during deletion walk.  | 
