- patches.suse/slab-handle-memoryless-nodes-v2a.patch: Refresh.
[linux-flexiantxendom0-3.2.10.git] / drivers / acpi / acpica / evregion.c
index 98c7f9c..5336d91 100644 (file)
 ACPI_MODULE_NAME("evregion")
 
 /* Local prototypes */
+static u8
+acpi_ev_has_default_handler(struct acpi_namespace_node *node,
+                           acpi_adr_space_type space_id);
+
 static acpi_status
 acpi_ev_reg_run(acpi_handle obj_handle,
                u32 level, void *context, void **return_value);
@@ -142,6 +146,50 @@ acpi_status acpi_ev_install_region_handlers(void)
 
 /*******************************************************************************
  *
+ * FUNCTION:    acpi_ev_has_default_handler
+ *
+ * PARAMETERS:  Node                - Namespace node for the device
+ *              space_id            - The address space ID
+ *
+ * RETURN:      TRUE if default handler is installed, FALSE otherwise
+ *
+ * DESCRIPTION: Check if the default handler is installed for the requested
+ *              space ID.
+ *
+ ******************************************************************************/
+
+static u8
+acpi_ev_has_default_handler(struct acpi_namespace_node *node,
+                           acpi_adr_space_type space_id)
+{
+       union acpi_operand_object *obj_desc;
+       union acpi_operand_object *handler_obj;
+
+       /* Must have an existing internal object */
+
+       obj_desc = acpi_ns_get_attached_object(node);
+       if (obj_desc) {
+               handler_obj = obj_desc->device.handler;
+
+               /* Walk the linked list of handlers for this object */
+
+               while (handler_obj) {
+                       if (handler_obj->address_space.space_id == space_id) {
+                               if (handler_obj->address_space.handler_flags &
+                                   ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) {
+                                       return (TRUE);
+                               }
+                       }
+
+                       handler_obj = handler_obj->address_space.next;
+               }
+       }
+
+       return (FALSE);
+}
+
+/*******************************************************************************
+ *
  * FUNCTION:    acpi_ev_initialize_op_regions
  *
  * PARAMETERS:  None
@@ -169,12 +217,18 @@ acpi_status acpi_ev_initialize_op_regions(void)
 
        for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) {
                /*
-                * TBD: Make sure handler is the DEFAULT handler, otherwise
-                * _REG will have already been run.
+                * Make sure the installed handler is the DEFAULT handler. If not the
+                * default, the _REG methods will have already been run (when the
+                * handler was installed)
                 */
-               status = acpi_ev_execute_reg_methods(acpi_gbl_root_node,
-                                                    acpi_gbl_default_address_spaces
-                                                    [i]);
+               if (acpi_ev_has_default_handler(acpi_gbl_root_node,
+                                               acpi_gbl_default_address_spaces
+                                               [i])) {
+                       status =
+                           acpi_ev_execute_reg_methods(acpi_gbl_root_node,
+                                                       acpi_gbl_default_address_spaces
+                                                       [i]);
+               }
        }
 
        (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
@@ -235,23 +289,20 @@ acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function)
         *  connection status 1 for connecting the handler, 0 for disconnecting
         *  the handler (Passed as a parameter)
         */
-       args[0] = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
+       args[0] =
+           acpi_ut_create_integer_object((u64) region_obj->region.space_id);
        if (!args[0]) {
                status = AE_NO_MEMORY;
                goto cleanup1;
        }
 
-       args[1] = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
+       args[1] = acpi_ut_create_integer_object((u64) function);
        if (!args[1]) {
                status = AE_NO_MEMORY;
                goto cleanup2;
        }
 
-       /* Setup the parameter objects */
-
-       args[0]->integer.value = region_obj->region.space_id;
-       args[1]->integer.value = function;
-       args[2] = NULL;
+       args[2] = NULL;         /* Terminate list */
 
        /* Execute the method, no return value */
 
@@ -667,7 +718,7 @@ acpi_ev_install_handler(acpi_handle obj_handle,
 
        /* Convert and validate the device handle */
 
-       node = acpi_ns_map_handle_to_node(obj_handle);
+       node = acpi_ns_validate_handle(obj_handle);
        if (!node) {
                return (AE_BAD_PARAMETER);
        }
@@ -971,8 +1022,8 @@ acpi_ev_install_space_handler(struct acpi_namespace_node * node,
         */
        status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, node, ACPI_UINT32_MAX,
                                        ACPI_NS_WALK_UNLOCK,
-                                       acpi_ev_install_handler, handler_obj,
-                                       NULL);
+                                       acpi_ev_install_handler, NULL,
+                                       handler_obj, NULL);
 
       unlock_and_exit:
        return_ACPI_STATUS(status);
@@ -1008,7 +1059,7 @@ acpi_ev_execute_reg_methods(struct acpi_namespace_node *node,
         */
        status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, node, ACPI_UINT32_MAX,
                                        ACPI_NS_WALK_UNLOCK, acpi_ev_reg_run,
-                                       &space_id, NULL);
+                                       NULL, &space_id, NULL);
 
        return_ACPI_STATUS(status);
 }
@@ -1036,7 +1087,7 @@ acpi_ev_reg_run(acpi_handle obj_handle,
 
        /* Convert and validate the device handle */
 
-       node = acpi_ns_map_handle_to_node(obj_handle);
+       node = acpi_ns_validate_handle(obj_handle);
        if (!node) {
                return (AE_BAD_PARAMETER);
        }