Skip to content

Commit

Permalink
Merge branch 'gpe-defer' into release
Browse files Browse the repository at this point in the history
  • Loading branch information
Len Brown committed Oct 25, 2010
2 parents 8803080 + a210080 commit 6e04c41
Show file tree
Hide file tree
Showing 13 changed files with 94 additions and 140 deletions.
5 changes: 3 additions & 2 deletions drivers/acpi/acpica/acevents.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,9 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
struct acpi_gpe_block_info **return_gpe_block);

acpi_status
acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device,
struct acpi_gpe_block_info *gpe_block);
acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
struct acpi_gpe_block_info *gpe_block,
void *ignored);

acpi_status acpi_ev_delete_gpe_block(struct acpi_gpe_block_info *gpe_block);

Expand Down
1 change: 1 addition & 0 deletions drivers/acpi/acpica/acglobal.h
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,7 @@ ACPI_EXTERN struct acpi_fixed_event_handler
ACPI_EXTERN struct acpi_gpe_xrupt_info *acpi_gbl_gpe_xrupt_list_head;
ACPI_EXTERN struct acpi_gpe_block_info
*acpi_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS];
ACPI_EXTERN u8 acpi_all_gpes_initialized;

/*****************************************************************************
*
Expand Down
3 changes: 2 additions & 1 deletion drivers/acpi/acpica/aclocal.h
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,7 @@ struct acpi_handler_info {
void *context; /* Context to be passed to handler */
struct acpi_namespace_node *method_node; /* Method node for this GPE level (saved) */
u8 orig_flags; /* Original misc info about this GPE */
u8 orig_enabled; /* Set if the GPE was originally enabled */
};

union acpi_gpe_dispatch_info {
Expand Down Expand Up @@ -457,6 +458,7 @@ struct acpi_gpe_block_info {
u32 register_count; /* Number of register pairs in block */
u16 gpe_count; /* Number of individual GPEs in block */
u8 block_base_number; /* Base GPE number for this block */
u8 initialized; /* If set, the GPE block has been initialized */
};

/* Information about GPE interrupt handlers, one per each interrupt level used for GPEs */
Expand All @@ -473,7 +475,6 @@ struct acpi_gpe_walk_info {
struct acpi_gpe_block_info *gpe_block;
u16 count;
acpi_owner_id owner_id;
u8 enable_this_gpe;
u8 execute_by_owner_id;
};

Expand Down
41 changes: 0 additions & 41 deletions drivers/acpi/acpica/evevent.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,47 +93,6 @@ acpi_status acpi_ev_initialize_events(void)
return_ACPI_STATUS(status);
}

/*******************************************************************************
*
* FUNCTION: acpi_ev_install_fadt_gpes
*
* PARAMETERS: None
*
* RETURN: Status
*
* DESCRIPTION: Completes initialization of the FADT-defined GPE blocks
* (0 and 1). The HW must be fully initialized at this point,
* including global lock support.
*
******************************************************************************/

acpi_status acpi_ev_install_fadt_gpes(void)
{
acpi_status status;

ACPI_FUNCTION_TRACE(ev_install_fadt_gpes);

/* Namespace must be locked */

status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
if (ACPI_FAILURE(status)) {
return (status);
}

/* FADT GPE Block 0 */

(void)acpi_ev_initialize_gpe_block(acpi_gbl_fadt_gpe_device,
acpi_gbl_gpe_fadt_blocks[0]);

/* FADT GPE Block 1 */

(void)acpi_ev_initialize_gpe_block(acpi_gbl_fadt_gpe_device,
acpi_gbl_gpe_fadt_blocks[1]);

(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
return_ACPI_STATUS(AE_OK);
}

/*******************************************************************************
*
* FUNCTION: acpi_ev_install_xrupt_handlers
Expand Down
47 changes: 21 additions & 26 deletions drivers/acpi/acpica/evgpeblk.c
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,7 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
gpe_block->gpe_count = (u16)(register_count * ACPI_GPE_REGISTER_WIDTH);
gpe_block->register_count = register_count;
gpe_block->block_base_number = gpe_block_base_number;
gpe_block->initialized = FALSE;

ACPI_MEMCPY(&gpe_block->block_address, gpe_block_address,
sizeof(struct acpi_generic_address));
Expand All @@ -385,11 +386,12 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
return_ACPI_STATUS(status);
}

acpi_all_gpes_initialized = FALSE;

/* Find all GPE methods (_Lxx or_Exx) for this block */

walk_info.gpe_block = gpe_block;
walk_info.gpe_device = gpe_device;
walk_info.enable_this_gpe = FALSE;
walk_info.execute_by_owner_id = FALSE;

status = acpi_ns_walk_namespace(ACPI_TYPE_METHOD, gpe_device,
Expand Down Expand Up @@ -434,63 +436,54 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
******************************************************************************/

acpi_status
acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device,
struct acpi_gpe_block_info *gpe_block)
acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
struct acpi_gpe_block_info *gpe_block,
void *ignored)
{
acpi_status status;
struct acpi_gpe_event_info *gpe_event_info;
u32 gpe_enabled_count;
u32 gpe_index;
u32 gpe_number;
u32 i;
u32 j;

ACPI_FUNCTION_TRACE(ev_initialize_gpe_block);

/* Ignore a null GPE block (e.g., if no GPE block 1 exists) */

if (!gpe_block) {
/*
* Ignore a null GPE block (e.g., if no GPE block 1 exists) and
* GPE blocks that have been initialized already.
*/
if (!gpe_block || gpe_block->initialized) {
return_ACPI_STATUS(AE_OK);
}

/*
* Enable all GPEs that have a corresponding method. Any other GPEs
* within this block must be enabled via the acpi_enable_gpe interface.
* Enable all GPEs that have a corresponding method and have the
* ACPI_GPE_CAN_WAKE flag unset. Any other GPEs within this block must
* be enabled via the acpi_enable_gpe() interface.
*/
gpe_enabled_count = 0;

if (gpe_device == acpi_gbl_fadt_gpe_device) {
gpe_device = NULL;
}

for (i = 0; i < gpe_block->register_count; i++) {
for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {

/* Get the info block for this particular GPE */

gpe_index = (i * ACPI_GPE_REGISTER_WIDTH) + j;
gpe_event_info = &gpe_block->event_info[gpe_index];
gpe_number = gpe_index + gpe_block->block_base_number;

/* Ignore GPEs that have no corresponding _Lxx/_Exx method */

if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD)) {
if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD)
|| (gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) {
continue;
}

/*
* If the GPE has already been enabled for runtime
* signaling, make sure it remains enabled, but do not
* increment its reference counter.
*/
status = gpe_event_info->runtime_count ?
acpi_ev_enable_gpe(gpe_event_info) :
acpi_enable_gpe(gpe_device, gpe_number);

status = acpi_raw_enable_gpe(gpe_event_info);
if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status,
"Could not enable GPE 0x%02X",
gpe_number));
"Could not enable GPE 0x%02X",
gpe_index + gpe_block->block_base_number));
continue;
}

Expand All @@ -504,5 +497,7 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device,
gpe_enabled_count));
}

gpe_block->initialized = TRUE;

return_ACPI_STATUS(AE_OK);
}
31 changes: 1 addition & 30 deletions drivers/acpi/acpica/evgpeinit.c
Original file line number Diff line number Diff line change
Expand Up @@ -210,8 +210,7 @@ acpi_status acpi_ev_gpe_initialize(void)
*
* DESCRIPTION: Check for new GPE methods (_Lxx/_Exx) made available as a
* result of a Load() or load_table() operation. If new GPE
* methods have been installed, register the new methods and
* enable and runtime GPEs that are associated with them.
* methods have been installed, register the new methods.
*
******************************************************************************/

Expand Down Expand Up @@ -239,7 +238,6 @@ void acpi_ev_update_gpes(acpi_owner_id table_owner_id)
walk_info.owner_id = table_owner_id;
walk_info.execute_by_owner_id = TRUE;
walk_info.count = 0;
walk_info.enable_this_gpe = TRUE;

/* Walk the interrupt level descriptor list */

Expand Down Expand Up @@ -301,8 +299,6 @@ void acpi_ev_update_gpes(acpi_owner_id table_owner_id)
*
* If walk_info->execute_by_owner_id is TRUE, we only execute examine GPE methods
* with that owner.
* If walk_info->enable_this_gpe is TRUE, the GPE that is referred to by a GPE
* method is immediately enabled (Used for Load/load_table operators)
*
******************************************************************************/

Expand All @@ -315,8 +311,6 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle,
struct acpi_gpe_walk_info *walk_info =
ACPI_CAST_PTR(struct acpi_gpe_walk_info, context);
struct acpi_gpe_event_info *gpe_event_info;
struct acpi_namespace_node *gpe_device;
acpi_status status;
u32 gpe_number;
char name[ACPI_NAME_SIZE + 1];
u8 type;
Expand Down Expand Up @@ -421,29 +415,6 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle,
gpe_event_info->flags |= (u8)(type | ACPI_GPE_DISPATCH_METHOD);
gpe_event_info->dispatch.method_node = method_node;

/*
* Enable this GPE if requested. This only happens when during the
* execution of a Load or load_table operator. We have found a new
* GPE method and want to immediately enable the GPE if it is a
* runtime GPE.
*/
if (walk_info->enable_this_gpe) {

walk_info->count++;
gpe_device = walk_info->gpe_device;

if (gpe_device == acpi_gbl_fadt_gpe_device) {
gpe_device = NULL;
}

status = acpi_enable_gpe(gpe_device, gpe_number);
if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status,
"Could not enable GPE 0x%02X",
gpe_number));
}
}

ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
"Registered GPE method %s as GPE number 0x%.2X\n",
name, gpe_number));
Expand Down
19 changes: 10 additions & 9 deletions drivers/acpi/acpica/evxface.c
Original file line number Diff line number Diff line change
Expand Up @@ -726,15 +726,16 @@ acpi_install_gpe_handler(acpi_handle gpe_device,
(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);

/*
* If the GPE is associated with a method and it cannot wake up the
* system from sleep states, it was enabled automatically during
* initialization, so it has to be disabled now to avoid spurious
* execution of the handler.
* If the GPE is associated with a method, it might have been enabled
* automatically during initialization, in which case it has to be
* disabled now to avoid spurious execution of the handler.
*/

if ((handler->orig_flags & ACPI_GPE_DISPATCH_METHOD)
&& !(gpe_event_info->flags & ACPI_GPE_CAN_WAKE))
&& gpe_event_info->runtime_count) {
handler->orig_enabled = 1;
(void)acpi_raw_disable_gpe(gpe_event_info);
}

/* Install the handler */

Expand Down Expand Up @@ -837,13 +838,13 @@ acpi_remove_gpe_handler(acpi_handle gpe_device,
gpe_event_info->flags |= handler->orig_flags;

/*
* If the GPE was previously associated with a method and it cannot wake
* up the system from sleep states, it should be enabled at this point
* to restore the post-initialization configuration.
* If the GPE was previously associated with a method and it was
* enabled, it should be enabled at this point to restore the
* post-initialization configuration.
*/

if ((handler->orig_flags & ACPI_GPE_DISPATCH_METHOD)
&& !(gpe_event_info->flags & ACPI_GPE_CAN_WAKE))
&& handler->orig_enabled)
(void)acpi_raw_enable_gpe(gpe_event_info);

/* Now we can free the handler object */
Expand Down
61 changes: 44 additions & 17 deletions drivers/acpi/acpica/evxfevnt.c
Original file line number Diff line number Diff line change
Expand Up @@ -379,21 +379,12 @@ acpi_status acpi_gpe_can_wake(acpi_handle gpe_device, u32 gpe_number)
/* Ensure that we have a valid GPE number */

gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
if (!gpe_event_info) {
if (gpe_event_info) {
gpe_event_info->flags |= ACPI_GPE_CAN_WAKE;
} else {
status = AE_BAD_PARAMETER;
goto unlock_and_exit;
}

if (gpe_event_info->flags & ACPI_GPE_CAN_WAKE) {
goto unlock_and_exit;
}

gpe_event_info->flags |= ACPI_GPE_CAN_WAKE;
if (gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD) {
(void)acpi_raw_disable_gpe(gpe_event_info);
}

unlock_and_exit:
acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
return_ACPI_STATUS(status);
}
Expand Down Expand Up @@ -651,7 +642,7 @@ acpi_install_gpe_block(acpi_handle gpe_device,
struct acpi_generic_address *gpe_block_address,
u32 register_count, u32 interrupt_number)
{
acpi_status status;
acpi_status status = AE_OK;
union acpi_operand_object *obj_desc;
struct acpi_namespace_node *node;
struct acpi_gpe_block_info *gpe_block;
Expand Down Expand Up @@ -715,10 +706,6 @@ acpi_install_gpe_block(acpi_handle gpe_device,

obj_desc->device.gpe_block = gpe_block;

/* Enable the runtime GPEs in the new block */

status = acpi_ev_initialize_gpe_block(node, gpe_block);

unlock_and_exit:
(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
return_ACPI_STATUS(status);
Expand Down Expand Up @@ -924,3 +911,43 @@ acpi_status acpi_enable_all_runtime_gpes(void)

return_ACPI_STATUS(status);
}

/******************************************************************************
*
* FUNCTION: acpi_update_gpes
*
* PARAMETERS: None
*
* RETURN: None
*
* DESCRIPTION: Enable all GPEs that have associated _Lxx or _Exx methods and
* are not pointed to by any device _PRW methods indicating that
* these GPEs are generally intended for system or device wakeup
* (such GPEs have to be enabled directly when the devices whose
* _PRW methods point to them are set up for wakeup signaling).
*
******************************************************************************/

acpi_status acpi_update_gpes(void)
{
acpi_status status;

ACPI_FUNCTION_TRACE(acpi_update_gpes);

status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
} else if (acpi_all_gpes_initialized) {
goto unlock;
}

status = acpi_ev_walk_gpe_list(acpi_ev_initialize_gpe_block, NULL);
if (ACPI_SUCCESS(status)) {
acpi_all_gpes_initialized = TRUE;
}

unlock:
(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);

return_ACPI_STATUS(status);
}
Loading

0 comments on commit 6e04c41

Please sign in to comment.