ACPICA: Namespace: Add support to allow overriding objects
authorLv Zheng <lv.zheng@intel.com>
Wed, 1 Jul 2015 06:44:17 +0000 (14:44 +0800)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Wed, 1 Jul 2015 21:17:54 +0000 (23:17 +0200)
ACPICA commit 6084e34e44565c6293f446c0202b5e59b055e351

This patch adds an "NamespaceOverride" flag in struct acpi_walk_state, and allows
namespace objects to be overridden when this flag is set. Lv Zheng.

Link: https://github.com/acpica/acpica/commit/6084e34e
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
drivers/acpi/acpica/acnamesp.h
drivers/acpi/acpica/acstruct.h
drivers/acpi/acpica/dswload.c
drivers/acpi/acpica/nsaccess.c
drivers/acpi/acpica/nssearch.c

index 952fbe0b7231a79c62f463bd36e8bce596c8c478..0dd088290d80588fa1e4f7545c70d712e8b7c86c 100644 (file)
@@ -66,6 +66,7 @@
 #define ACPI_NS_PREFIX_IS_SCOPE     0x10
 #define ACPI_NS_EXTERNAL            0x20
 #define ACPI_NS_TEMPORARY           0x40
+#define ACPI_NS_OVERRIDE_IF_FOUND   0x80
 
 /* Flags for acpi_ns_walk_namespace */
 
index 87c7860b3394b483dd3c0fe6c039e1d589682d65..44997ca02ae26a59f4e2efe0992d6c80dbcc32b7 100644 (file)
@@ -82,6 +82,7 @@ struct acpi_walk_state {
        u8 return_used;
        u8 scope_depth;
        u8 pass_number;         /* Parse pass during table load */
+       u8 namespace_override;  /* Override existing objects */
        u8 result_size;         /* Total elements for the result stack */
        u8 result_count;        /* Current number of occupied elements of result stack */
        u32 aml_offset;
index 843942fb4be501c8dcc3d15ced1729a152489011..845ff44919c3713f8725f08daff16d9b9679e338 100644 (file)
@@ -315,10 +315,19 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state,
                flags = ACPI_NS_NO_UPSEARCH;
                if ((walk_state->opcode != AML_SCOPE_OP) &&
                    (!(walk_state->parse_flags & ACPI_PARSE_DEFERRED_OP))) {
-                       flags |= ACPI_NS_ERROR_IF_FOUND;
-                       ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
-                                         "[%s] Cannot already exist\n",
-                                         acpi_ut_get_type_name(object_type)));
+                       if (walk_state->namespace_override) {
+                               flags |= ACPI_NS_OVERRIDE_IF_FOUND;
+                               ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
+                                                 "[%s] Override allowed\n",
+                                                 acpi_ut_get_type_name
+                                                 (object_type)));
+                       } else {
+                               flags |= ACPI_NS_ERROR_IF_FOUND;
+                               ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
+                                                 "[%s] Cannot already exist\n",
+                                                 acpi_ut_get_type_name
+                                                 (object_type)));
+                       }
                } else {
                        ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
                                          "[%s] Both Find or Create allowed\n",
index 24fa19a76d704102b89ada50aa836dbf95d0171e..19ad0b5993d58583516f3f7941c45f7c46ebfeb1 100644 (file)
@@ -304,7 +304,9 @@ acpi_ns_lookup(union acpi_generic_state *scope_info,
                return_ACPI_STATUS(AE_BAD_PARAMETER);
        }
 
-       local_flags = flags & ~(ACPI_NS_ERROR_IF_FOUND | ACPI_NS_SEARCH_PARENT);
+       local_flags = flags &
+           ~(ACPI_NS_ERROR_IF_FOUND | ACPI_NS_OVERRIDE_IF_FOUND |
+             ACPI_NS_SEARCH_PARENT);
        *return_node = ACPI_ENTRY_NOT_FOUND;
        acpi_gbl_ns_lookup_count++;
 
@@ -547,6 +549,12 @@ acpi_ns_lookup(union acpi_generic_state *scope_info,
                        if (flags & ACPI_NS_ERROR_IF_FOUND) {
                                local_flags |= ACPI_NS_ERROR_IF_FOUND;
                        }
+
+                       /* Set override flag according to caller */
+
+                       if (flags & ACPI_NS_OVERRIDE_IF_FOUND) {
+                               local_flags |= ACPI_NS_OVERRIDE_IF_FOUND;
+                       }
                }
 
                /* Extract one ACPI name from the front of the pathname */
index 4a9d4a66016e51eefcb851979489bb871edab2a2..47fbe5b335247c97b7a12a1f2e430f49adde2ee6 100644 (file)
@@ -325,8 +325,26 @@ acpi_ns_search_and_enter(u32 target_name,
                 * If we found it AND the request specifies that a find is an error,
                 * return the error
                 */
-               if ((status == AE_OK) && (flags & ACPI_NS_ERROR_IF_FOUND)) {
-                       status = AE_ALREADY_EXISTS;
+               if (status == AE_OK) {
+
+                       /* The node was found in the namespace */
+
+                       /*
+                        * If the namespace override feature is enabled for this node,
+                        * delete any existing node. This can only happen during the
+                        * boot stage, thus it is safe to remove the node here.
+                        */
+                       if (flags & ACPI_NS_OVERRIDE_IF_FOUND) {
+                               acpi_ns_delete_children(*return_node);
+                               acpi_ns_remove_node(*return_node);
+                               *return_node = ACPI_ENTRY_NOT_FOUND;
+                       }
+
+                       /* Return an error if we don't expect to find the object */
+
+                       else if (flags & ACPI_NS_ERROR_IF_FOUND) {
+                               status = AE_ALREADY_EXISTS;
+                       }
                }
 #ifdef ACPI_ASL_COMPILER
                if (*return_node && (*return_node)->type == ACPI_TYPE_ANY) {