static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) { struct acpi_gpe_event_info *gpe_event_info = (void *)context; acpi_status status; struct acpi_gpe_event_info local_gpe_event_info; struct acpi_evaluate_info *info; ACPI_FUNCTION_TRACE(ev_asynch_execute_gpe_method); status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); if (ACPI_FAILURE(status)) { return_VOID; } /* Must revalidate the gpe_number/gpe_block */ if (!acpi_ev_valid_gpe_event(gpe_event_info)) { status = acpi_ut_release_mutex(ACPI_MTX_EVENTS); return_VOID; } /* Set the GPE flags for return to enabled state */ (void)acpi_ev_enable_gpe(gpe_event_info, FALSE); /* * Take a snapshot of the GPE info for this level - we copy the info to * prevent a race condition with remove_handler/remove_block. */ ACPI_MEMCPY(&local_gpe_event_info, gpe_event_info, sizeof(struct acpi_gpe_event_info)); status = acpi_ut_release_mutex(ACPI_MTX_EVENTS); if (ACPI_FAILURE(status)) { return_VOID; } /* * Must check for control method type dispatch one more time to avoid a * race with ev_gpe_install_handler */ if ((local_gpe_event_info.flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_METHOD) { /* Allocate the evaluation information block */ info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info)); if (!info) { status = AE_NO_MEMORY; } else { /* * Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the _Lxx/_Exx * control method that corresponds to this GPE */ info->prefix_node = local_gpe_event_info.dispatch.method_node; info->flags = ACPI_IGNORE_RETURN_VALUE; status = acpi_ns_evaluate(info); ACPI_FREE(info); } if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "while evaluating GPE method [%4.4s]", acpi_ut_get_node_name (local_gpe_event_info.dispatch. method_node))); } } /* Defer enabling of GPE until all notify handlers are done */ acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_ev_asynch_enable_gpe, gpe_event_info); return_VOID; }
static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) { struct acpi_gpe_event_info *gpe_event_info = context; acpi_status status; struct acpi_gpe_event_info *local_gpe_event_info; struct acpi_evaluate_info *info; struct acpi_gpe_notify_info *notify; ACPI_FUNCTION_TRACE(ev_asynch_execute_gpe_method); /* Allocate a local GPE block */ local_gpe_event_info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_gpe_event_info)); if (!local_gpe_event_info) { ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY, "while handling a GPE")); return_VOID; } status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); if (ACPI_FAILURE(status)) { ACPI_FREE(local_gpe_event_info); return_VOID; } /* Must revalidate the gpe_number/gpe_block */ if (!acpi_ev_valid_gpe_event(gpe_event_info)) { status = acpi_ut_release_mutex(ACPI_MTX_EVENTS); ACPI_FREE(local_gpe_event_info); return_VOID; } /* * Take a snapshot of the GPE info for this level - we copy the info to * prevent a race condition with remove_handler/remove_block. */ ACPI_MEMCPY(local_gpe_event_info, gpe_event_info, sizeof(struct acpi_gpe_event_info)); status = acpi_ut_release_mutex(ACPI_MTX_EVENTS); if (ACPI_FAILURE(status)) { return_VOID; } /* Do the correct dispatch - normal method or implicit notify */ switch (local_gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) { case ACPI_GPE_DISPATCH_NOTIFY: /* * Implicit notify. * Dispatch a DEVICE_WAKE notify to the appropriate handler. * NOTE: the request is queued for execution after this method * completes. The notify handlers are NOT invoked synchronously * from this thread -- because handlers may in turn run other * control methods. * * June 2012: Expand implicit notify mechanism to support * notifies on multiple device objects. */ notify = local_gpe_event_info->dispatch.notify_list; while (ACPI_SUCCESS(status) && notify) { status = acpi_ev_queue_notify_request(notify->device_node, ACPI_NOTIFY_DEVICE_WAKE); notify = notify->next; } break; case ACPI_GPE_DISPATCH_METHOD: /* Allocate the evaluation information block */ info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info)); if (!info) { status = AE_NO_MEMORY; } else { /* * Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the _Lxx/_Exx * control method that corresponds to this GPE */ info->prefix_node = local_gpe_event_info->dispatch.method_node; info->flags = ACPI_IGNORE_RETURN_VALUE; status = acpi_ns_evaluate(info); ACPI_FREE(info); } if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "while evaluating GPE method [%4.4s]", acpi_ut_get_node_name (local_gpe_event_info->dispatch. method_node))); } break; default: return_VOID; /* Should never happen */ } /* Defer enabling of GPE until all notify handlers are done */ status = acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_ev_asynch_enable_gpe, local_gpe_event_info); if (ACPI_FAILURE(status)) { ACPI_FREE(local_gpe_event_info); } return_VOID; }
static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method ( void *context) { struct acpi_gpe_event_info *gpe_event_info = (void *) context; u32 gpe_number = 0; acpi_status status; struct acpi_gpe_event_info local_gpe_event_info; ACPI_FUNCTION_TRACE ("ev_asynch_execute_gpe_method"); status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS); if (ACPI_FAILURE (status)) { return_VOID; } /* Must revalidate the gpe_number/gpe_block */ if (!acpi_ev_valid_gpe_event (gpe_event_info)) { status = acpi_ut_release_mutex (ACPI_MTX_EVENTS); return_VOID; } /* * Take a snapshot of the GPE info for this level - we copy the * info to prevent a race condition with remove_handler/remove_block. */ ACPI_MEMCPY (&local_gpe_event_info, gpe_event_info, sizeof (struct acpi_gpe_event_info)); status = acpi_ut_release_mutex (ACPI_MTX_EVENTS); if (ACPI_FAILURE (status)) { return_VOID; } if (local_gpe_event_info.method_node) { /* * Invoke the GPE Method (_Lxx, _Exx): * (Evaluate the _Lxx/_Exx control method that corresponds to this GPE.) */ status = acpi_ns_evaluate_by_handle (local_gpe_event_info.method_node, NULL, NULL); if (ACPI_FAILURE (status)) { ACPI_REPORT_ERROR (("%s while evaluating method [%4.4s] for GPE[%2X]\n", acpi_format_exception (status), local_gpe_event_info.method_node->name.ascii, gpe_number)); } } if (local_gpe_event_info.flags & ACPI_EVENT_LEVEL_TRIGGERED) { /* * GPE is level-triggered, we clear the GPE status bit after handling * the event. */ status = acpi_hw_clear_gpe (&local_gpe_event_info); if (ACPI_FAILURE (status)) { return_VOID; } } /* Enable this GPE */ (void) acpi_hw_enable_gpe (&local_gpe_event_info); return_VOID; }
static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method ( void *context) { struct acpi_gpe_event_info *gpe_event_info = (void *) context; u32 gpe_number = 0; acpi_status status; struct acpi_gpe_event_info local_gpe_event_info; struct acpi_parameter_info info; ACPI_FUNCTION_TRACE ("ev_asynch_execute_gpe_method"); status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS); if (ACPI_FAILURE (status)) { return_VOID; } /* Must revalidate the gpe_number/gpe_block */ if (!acpi_ev_valid_gpe_event (gpe_event_info)) { status = acpi_ut_release_mutex (ACPI_MTX_EVENTS); return_VOID; } /* Set the GPE flags for return to enabled state */ (void) acpi_ev_enable_gpe (gpe_event_info, FALSE); /* * Take a snapshot of the GPE info for this level - we copy the * info to prevent a race condition with remove_handler/remove_block. */ ACPI_MEMCPY (&local_gpe_event_info, gpe_event_info, sizeof (struct acpi_gpe_event_info)); status = acpi_ut_release_mutex (ACPI_MTX_EVENTS); if (ACPI_FAILURE (status)) { return_VOID; } /* * Must check for control method type dispatch one more * time to avoid race with ev_gpe_install_handler */ if ((local_gpe_event_info.flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_METHOD) { /* * Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the _Lxx/_Exx * control method that corresponds to this GPE */ info.node = local_gpe_event_info.dispatch.method_node; info.parameters = ACPI_CAST_PTR (union acpi_operand_object *, gpe_event_info); info.parameter_type = ACPI_PARAM_GPE; status = acpi_ns_evaluate_by_handle (&info); if (ACPI_FAILURE (status)) { ACPI_REPORT_ERROR (( "%s while evaluating method [%4.4s] for GPE[%2X]\n", acpi_format_exception (status), acpi_ut_get_node_name (local_gpe_event_info.dispatch.method_node), gpe_number)); } }
static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) { struct acpi_gpe_event_info *gpe_event_info = (void *)context; acpi_status status; struct acpi_gpe_event_info local_gpe_event_info; struct acpi_evaluate_info *info; ACPI_FUNCTION_TRACE(ev_asynch_execute_gpe_method); status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); if (ACPI_FAILURE(status)) { return_VOID; } if (!acpi_ev_valid_gpe_event(gpe_event_info)) { status = acpi_ut_release_mutex(ACPI_MTX_EVENTS); return_VOID; } (void)acpi_ev_enable_gpe(gpe_event_info, FALSE); ACPI_MEMCPY(&local_gpe_event_info, gpe_event_info, sizeof(struct acpi_gpe_event_info)); status = acpi_ut_release_mutex(ACPI_MTX_EVENTS); if (ACPI_FAILURE(status)) { return_VOID; } if ((local_gpe_event_info.flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_METHOD) { info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info)); if (!info) { status = AE_NO_MEMORY; } else { info->prefix_node = local_gpe_event_info.dispatch.method_node; info->flags = ACPI_IGNORE_RETURN_VALUE; status = acpi_ns_evaluate(info); ACPI_FREE(info); } if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "while evaluating GPE method [%4.4s]", acpi_ut_get_node_name (local_gpe_event_info.dispatch. method_node))); } } acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_ev_asynch_enable_gpe, gpe_event_info); return_VOID; }