Commit 7b3b0219 authored by Len Brown's avatar Len Brown Committed by Len Brown

[ACPI] ACPICA 20040220 from Bob Moore

Implemented execution of _SxD methods for Device objects in the
GetObjectInfo interface.

Fixed calls to _SST method to pass the correct arguments.

Added a call to _SST on wake to restore to "working" state.

Check for End-Of-Buffer failure case in the WalkResources interface.

Integrated fix for 64-bit alignment issue in acglobal.h by moving two
structures to the beginning of the file.

After wake, clear GPE status register(s) before enabling GPEs.

After wake, clear/enable power button.
(Perhaps we should clear/enable all fixed events upon wake.)

Fixed a couple of possible memory leaks in the Namespace manager.
parent daa74787
......@@ -528,6 +528,14 @@ acpi_hw_enable_non_wakeup_gpe_block (
/* Examine each GPE register within the block */
for (i = 0; i < gpe_block->register_count; i++) {
/* Clear the entire status register */
status = acpi_hw_low_level_write (8, 0xFF,
&gpe_block->register_info[i].status_address);
if (ACPI_FAILURE (status)) {
return (status);
}
/*
* We previously stored the enabled status of all GPEs.
* Blast them back in.
......
......@@ -152,11 +152,11 @@ acpi_get_sleep_type_data (
/*
* Evaluate the namespace object containing the values for this state
*/
status = acpi_ns_evaluate_by_name ((char *) acpi_gbl_db_sleep_states[sleep_state],
status = acpi_ns_evaluate_by_name ((char *) acpi_gbl_sleep_state_names[sleep_state],
NULL, &obj_desc);
if (ACPI_FAILURE (status)) {
ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s while evaluating sleep_state [%s]\n",
acpi_format_exception (status), acpi_gbl_db_sleep_states[sleep_state]));
acpi_format_exception (status), acpi_gbl_sleep_state_names[sleep_state]));
return_ACPI_STATUS (status);
}
......@@ -201,7 +201,7 @@ acpi_get_sleep_type_data (
if (ACPI_FAILURE (status)) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "While evaluating sleep_state [%s], bad Sleep object %p type %s\n",
acpi_gbl_db_sleep_states[sleep_state], obj_desc, acpi_ut_get_object_type_name (obj_desc)));
acpi_gbl_sleep_state_names[sleep_state], obj_desc, acpi_ut_get_object_type_name (obj_desc)));
}
acpi_ut_remove_reference (obj_desc);
......
......@@ -48,6 +48,19 @@
ACPI_MODULE_NAME ("hwsleep")
#define METHOD_NAME__BFS "\\_BFS"
#define METHOD_NAME__GTS "\\_GTS"
#define METHOD_NAME__PTS "\\_PTS"
#define METHOD_NAME__SST "\\_SI._SST"
#define METHOD_NAME__WAK "\\_WAK"
#define ACPI_SST_INDICATOR_OFF 0
#define ACPI_SST_WORKING 1
#define ACPI_SST_WAKING 2
#define ACPI_SST_SLEEPING 3
#define ACPI_SST_SLEEP_CONTEXT 4
/******************************************************************************
*
* FUNCTION: acpi_set_firmware_waking_vector
......@@ -171,19 +184,41 @@ acpi_enter_sleep_state_prep (
/* Run the _PTS and _GTS methods */
status = acpi_evaluate_object (NULL, "\\_PTS", &arg_list, NULL);
status = acpi_evaluate_object (NULL, METHOD_NAME__PTS, &arg_list, NULL);
if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
return_ACPI_STATUS (status);
}
status = acpi_evaluate_object (NULL, "\\_GTS", &arg_list, NULL);
status = acpi_evaluate_object (NULL, METHOD_NAME__GTS, &arg_list, NULL);
if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
return_ACPI_STATUS (status);
}
/* Setup the argument to _SST */
switch (sleep_state) {
case ACPI_STATE_S0:
arg.integer.value = ACPI_SST_WORKING;
break;
case ACPI_STATE_S1:
case ACPI_STATE_S2:
case ACPI_STATE_S3:
arg.integer.value = ACPI_SST_SLEEPING;
break;
case ACPI_STATE_S4:
arg.integer.value = ACPI_SST_SLEEP_CONTEXT;
break;
default:
arg.integer.value = ACPI_SST_INDICATOR_OFF; /* Default is indicator off */
break;
}
/* Set the system indicators to show the desired sleep state. */
status = acpi_evaluate_object (NULL, "\\_SI._SST", &arg_list, NULL);
status = acpi_evaluate_object (NULL, METHOD_NAME__SST, &arg_list, NULL);
if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
ACPI_REPORT_ERROR (("Method _SST failed, %s\n", acpi_format_exception (status)));
}
......@@ -477,19 +512,19 @@ acpi_leave_sleep_state (
/* Ignore any errors from these methods */
arg.integer.value = 0;
status = acpi_evaluate_object (NULL, "\\_SI._SST", &arg_list, NULL);
arg.integer.value = ACPI_SST_WAKING;
status = acpi_evaluate_object (NULL, METHOD_NAME__SST, &arg_list, NULL);
if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
ACPI_REPORT_ERROR (("Method _SST failed, %s\n", acpi_format_exception (status)));
}
arg.integer.value = sleep_state;
status = acpi_evaluate_object (NULL, "\\_BFS", &arg_list, NULL);
status = acpi_evaluate_object (NULL, METHOD_NAME__BFS, &arg_list, NULL);
if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
ACPI_REPORT_ERROR (("Method _BFS failed, %s\n", acpi_format_exception (status)));
}
status = acpi_evaluate_object (NULL, "\\_WAK", &arg_list, NULL);
status = acpi_evaluate_object (NULL, METHOD_NAME__WAK, &arg_list, NULL);
if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
ACPI_REPORT_ERROR (("Method _WAK failed, %s\n", acpi_format_exception (status)));
}
......@@ -501,8 +536,25 @@ acpi_leave_sleep_state (
return_ACPI_STATUS (status);
}
/* Enable power button */
acpi_set_register(acpi_gbl_fixed_event_info[ACPI_EVENT_POWER_BUTTON].enable_register_id,
1, ACPI_MTX_DO_NOT_LOCK);
acpi_set_register(acpi_gbl_fixed_event_info[ACPI_EVENT_POWER_BUTTON].status_register_id,
1, ACPI_MTX_DO_NOT_LOCK);
/* Enable BM arbitration */
status = acpi_set_register (ACPI_BITREG_ARB_DISABLE, 0, ACPI_MTX_LOCK);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
arg.integer.value = ACPI_SST_WORKING;
status = acpi_evaluate_object (NULL, METHOD_NAME__SST, &arg_list, NULL);
if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
ACPI_REPORT_ERROR (("Method _SST failed, %s\n", acpi_format_exception (status)));
}
return_ACPI_STATUS (status);
}
......@@ -110,7 +110,7 @@ acpi_ns_evaluate_relative (
status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
goto cleanup;
}
prefix_node = acpi_ns_map_handle_to_node (handle);
......@@ -197,7 +197,7 @@ acpi_ns_evaluate_by_name (
status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
goto cleanup;
}
/* Lookup the name in the namespace */
......
......@@ -918,7 +918,7 @@ acpi_ns_get_node_by_path (
status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
goto cleanup;
}
/* Setup lookup scope (search starting point) */
......@@ -936,10 +936,10 @@ acpi_ns_get_node_by_path (
internal_path, acpi_format_exception (status)));
}
/* Cleanup */
(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
cleanup:
/* Cleanup */
if (internal_path) {
ACPI_MEM_FREE (internal_path);
}
......
......@@ -326,6 +326,13 @@ acpi_get_object_info (
info.valid |= ACPI_VALID_ADR;
}
/* Execute the Device._sx_d methods */
status = acpi_ut_execute_sxds (node, info.highest_dstates);
if (ACPI_SUCCESS (status)) {
info.valid |= ACPI_VALID_STA;
}
status = AE_OK;
}
......
......@@ -239,6 +239,7 @@ acpi_walk_resources (
acpi_status status;
struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
struct acpi_resource *resource;
struct acpi_resource *buffer_end;
ACPI_FUNCTION_TRACE ("acpi_walk_resources");
......@@ -255,7 +256,13 @@ acpi_walk_resources (
return_ACPI_STATUS (status);
}
resource = (struct acpi_resource *) buffer.pointer;
/* Setup pointers */
resource = (struct acpi_resource *) buffer.pointer;
buffer_end = (struct acpi_resource *) ((u8 *) buffer.pointer + buffer.length);
/* Walk the resource list */
for (;;) {
if (!resource || resource->id == ACPI_RSTYPE_END_TAG) {
break;
......@@ -268,6 +275,7 @@ acpi_walk_resources (
case AE_CTRL_DEPTH:
/* Just keep going */
status = AE_OK;
break;
......@@ -285,7 +293,15 @@ acpi_walk_resources (
goto cleanup;
}
/* Get the next resource descriptor */
resource = ACPI_NEXT_RESOURCE (resource);
/* Check for end-of-buffer */
if (resource >= buffer_end) {
goto cleanup;
}
}
cleanup:
......
......@@ -562,3 +562,63 @@ acpi_ut_execute_STA (
acpi_ut_remove_reference (obj_desc);
return_ACPI_STATUS (status);
}
/*******************************************************************************
*
* FUNCTION: acpi_ut_execute_Sxds
*
* PARAMETERS: device_node - Node for the device
* *Flags - Where the status flags are returned
*
* RETURN: Status
*
* DESCRIPTION: Executes _STA for selected device and stores results in
* *Flags.
*
* NOTE: Internal function, no parameter validation
*
******************************************************************************/
acpi_status
acpi_ut_execute_sxds (
struct acpi_namespace_node *device_node,
u8 *highest)
{
union acpi_operand_object *obj_desc;
acpi_status status;
u32 i;
ACPI_FUNCTION_TRACE ("ut_execute_Sxds");
for (i = 0; i < 4; i++) {
highest[i] = 0xFF;
status = acpi_ut_evaluate_object (device_node,
(char *) acpi_gbl_highest_dstate_names[i],
ACPI_BTYPE_INTEGER, &obj_desc);
if (ACPI_FAILURE (status)) {
if (status != AE_NOT_FOUND) {
ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
"%s on Device %4.4s, %s\n",
(char *) acpi_gbl_highest_dstate_names[i],
acpi_ut_get_node_name (device_node),
acpi_format_exception (status)));
return_ACPI_STATUS (status);
}
}
else {
/* Extract the Dstate value */
highest[i] = (u8) obj_desc->integer.value;
/* Delete the return object */
acpi_ut_remove_reference (obj_desc);
}
}
return_ACPI_STATUS (AE_OK);
}
......@@ -171,7 +171,7 @@ u8 acpi_gbl_shutdown = TRUE;
const u8 acpi_gbl_decode_to8bit [8] = {1,2,4,8,16,32,64,128};
const char *acpi_gbl_db_sleep_states[ACPI_S_STATE_COUNT] = {
const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT] = {
"\\_S0_",
"\\_S1_",
"\\_S2_",
......@@ -179,6 +179,11 @@ const char *acpi_gbl_db_sleep_states[ACPI_S_STATE_COUNT
"\\_S4_",
"\\_S5_"};
const char *acpi_gbl_highest_dstate_names[4] = {
"_S1D",
"_S2D",
"_S3D",
"_S4D"};
/******************************************************************************
*
......
......@@ -64,7 +64,7 @@
/* Version string */
#define ACPI_CA_VERSION 0x20040211
#define ACPI_CA_VERSION 0x20040220
/* Maximum objects in the various object caches */
......
......@@ -57,6 +57,12 @@
#define ACPI_EXTERN extern
#endif
/*
* Keep local copies of these FADT-based registers. NOTE: These globals
* are first in this file for alignment reasons on 64-bit systems.
*/
ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1a_enable;
ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1b_enable;
/*****************************************************************************
*
......@@ -97,6 +103,11 @@ ACPI_EXTERN FADT_DESCRIPTOR *acpi_gbl_FADT;
ACPI_EXTERN struct acpi_table_header *acpi_gbl_DSDT;
ACPI_EXTERN FACS_DESCRIPTOR *acpi_gbl_FACS;
ACPI_EXTERN struct acpi_common_facs acpi_gbl_common_fACS;
/*
* Since there may be multiple SSDTs and PSDTS, a single pointer is not
* sufficient; Therefore, there isn't one!
*/
/*
* Handle both ACPI 1.0 and ACPI 2.0 Integer widths
......@@ -107,17 +118,6 @@ ACPI_EXTERN u8 acpi_gbl_integer_bit_width;
ACPI_EXTERN u8 acpi_gbl_integer_byte_width;
ACPI_EXTERN u8 acpi_gbl_integer_nybble_width;
/* Keep local copies of these FADT-based registers */
ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1a_enable;
ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1b_enable;
/*
* Since there may be multiple SSDTs and PSDTS, a single pointer is not
* sufficient; Therefore, there isn't one!
*/
/*
* ACPI Table info arrays
*/
......@@ -165,7 +165,8 @@ ACPI_EXTERN u8 acpi_gbl_events_initialized;
extern u8 acpi_gbl_shutdown;
extern u32 acpi_gbl_startup_flags;
extern const u8 acpi_gbl_decode_to8bit[8];
extern const char *acpi_gbl_db_sleep_states[ACPI_S_STATE_COUNT];
extern const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT];
extern const char *acpi_gbl_highest_dstate_names[4];
extern const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES];
extern const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS];
......
......@@ -880,7 +880,8 @@ struct acpi_device_info
{
ACPI_COMMON_OBJ_INFO;
u32 valid; /* Indicates which fields are valid */
u8 highest_dstates[4]; /* _sx_d values 0xFF indicates not valid */
u32 valid; /* Indicates which fields below are valid */
u32 current_status; /* _STA value */
acpi_integer address; /* _ADR value if any */
struct acpi_device_id hardware_id; /* _HID value if any */
......
......@@ -508,6 +508,10 @@ acpi_ut_execute_UID (
struct acpi_namespace_node *device_node,
struct acpi_device_id *uid);
acpi_status
acpi_ut_execute_sxds (
struct acpi_namespace_node *device_node,
u8 *highest);
/*
* ut_mutex - mutual exclusion interfaces
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment