Merge tag 'v3.10.56' into update
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / acpi / acpica / evregion.c
index 6555e350fc1fe21087cea7e219a9c4b170d70e25..8fab9262d98afc68e07c6fdf7794850b2ebd20d6 100644 (file)
@@ -141,6 +141,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
        union acpi_operand_object *region_obj2;
        void *region_context = NULL;
        struct acpi_connection_info *context;
+       acpi_physical_address address;
 
        ACPI_FUNCTION_TRACE(ev_address_space_dispatch);
 
@@ -235,25 +236,23 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
        /* We have everything we need, we can invoke the address space handler */
 
        handler = handler_desc->address_space.handler;
-
-       ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
-                         "Handler %p (@%p) Address %8.8X%8.8X [%s]\n",
-                         &region_obj->region.handler->address_space, handler,
-                         ACPI_FORMAT_NATIVE_UINT(region_obj->region.address +
-                                                 region_offset),
-                         acpi_ut_get_region_name(region_obj->region.
-                                                 space_id)));
+       address = (region_obj->region.address + region_offset);
 
        /*
         * Special handling for generic_serial_bus and general_purpose_io:
         * There are three extra parameters that must be passed to the
         * handler via the context:
-        *   1) Connection buffer, a resource template from Connection() op.
-        *   2) Length of the above buffer.
-        *   3) Actual access length from the access_as() op.
+        *   1) Connection buffer, a resource template from Connection() op
+        *   2) Length of the above buffer
+        *   3) Actual access length from the access_as() op
+        *
+        * In addition, for general_purpose_io, the Address and bit_width fields
+        * are defined as follows:
+        *   1) Address is the pin number index of the field (bit offset from
+        *      the previous Connection)
+        *   2) bit_width is the actual bit length of the field (number of pins)
         */
-       if (((region_obj->region.space_id == ACPI_ADR_SPACE_GSBUS) ||
-            (region_obj->region.space_id == ACPI_ADR_SPACE_GPIO)) &&
+       if ((region_obj->region.space_id == ACPI_ADR_SPACE_GSBUS) &&
            context && field_obj) {
 
                /* Get the Connection (resource_template) buffer */
@@ -262,6 +261,24 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
                context->length = field_obj->field.resource_length;
                context->access_length = field_obj->field.access_length;
        }
+       if ((region_obj->region.space_id == ACPI_ADR_SPACE_GPIO) &&
+           context && field_obj) {
+
+               /* Get the Connection (resource_template) buffer */
+
+               context->connection = field_obj->field.resource_buffer;
+               context->length = field_obj->field.resource_length;
+               context->access_length = field_obj->field.access_length;
+               address = field_obj->field.pin_number_index;
+               bit_width = field_obj->field.bit_length;
+       }
+
+       ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
+                         "Handler %p (@%p) Address %8.8X%8.8X [%s]\n",
+                         &region_obj->region.handler->address_space, handler,
+                         ACPI_FORMAT_NATIVE_UINT(address),
+                         acpi_ut_get_region_name(region_obj->region.
+                                                 space_id)));
 
        if (!(handler_desc->address_space.handler_flags &
              ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
@@ -275,9 +292,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
 
        /* Call the handler */
 
-       status = handler(function,
-                        (region_obj->region.address + region_offset),
-                        bit_width, value, context,
+       status = handler(function, address, bit_width, value, context,
                         region_obj2->extra.region_context);
 
        if (ACPI_FAILURE(status)) {