Commit 35d48993 authored by Andy Grover's avatar Andy Grover

Merge groveronline.com:/root/bk/linux-2.5

into groveronline.com:/root/bk/linux-acpi
parents 63ac2a63 6ad53b6d
...@@ -516,6 +516,14 @@ running once the system is up. ...@@ -516,6 +516,14 @@ running once the system is up.
[KNL,BOOT] Force usage of a specific region of memory [KNL,BOOT] Force usage of a specific region of memory
Region of memory to be used, from ss to ss+nn. Region of memory to be used, from ss to ss+nn.
mem=nn[KMG]#ss[KMG]
[KNL,BOOT,ACPI] Mark specific memory as ACPI data.
Region of memory to be used, from ss to ss+nn.
mem=nn[KMG]$ss[KMG]
[KNL,BOOT,ACPI] Mark specific memory as reserved.
Region of memory to be used, from ss to ss+nn.
mem=nopentium [BUGS=IA-32] Disable usage of 4MB pages for kernel mem=nopentium [BUGS=IA-32] Disable usage of 4MB pages for kernel
memory. memory.
......
...@@ -319,6 +319,31 @@ ret_point: ...@@ -319,6 +319,31 @@ ret_point:
pushl saved_context_eflags ; popfl pushl saved_context_eflags ; popfl
ret ret
ENTRY(do_suspend_lowlevel_s4bios)
cmpl $0,4(%esp)
jne ret_point
call save_processor_state
movl %esp, saved_context_esp
movl %eax, saved_context_eax
movl %ebx, saved_context_ebx
movl %ecx, saved_context_ecx
movl %edx, saved_context_edx
movl %ebp, saved_context_ebp
movl %esi, saved_context_esi
movl %edi, saved_context_edi
pushfl ; popl saved_context_eflags
movl $ret_point,saved_eip
movl %esp,saved_esp
movl %ebp,saved_ebp
movl %ebx,saved_ebx
movl %edi,saved_edi
movl %esi,saved_esi
call acpi_enter_sleep_state_s4bios
ret
ALIGN ALIGN
# saved registers # saved registers
saved_gdt: .long 0,0 saved_gdt: .long 0,0
......
...@@ -552,6 +552,12 @@ static void __init parse_cmdline_early (char ** cmdline_p) ...@@ -552,6 +552,12 @@ static void __init parse_cmdline_early (char ** cmdline_p)
if (*from == '@') { if (*from == '@') {
start_at = memparse(from+1, &from); start_at = memparse(from+1, &from);
add_memory_region(start_at, mem_size, E820_RAM); add_memory_region(start_at, mem_size, E820_RAM);
} else if (*from == '#') {
start_at = memparse(from+1, &from);
add_memory_region(start_at, mem_size, E820_ACPI);
} else if (*from == '$') {
start_at = memparse(from+1, &from);
add_memory_region(start_at, mem_size, E820_RESERVED);
} else { } else {
limit_regions(mem_size); limit_regions(mem_size);
userdef=1; userdef=1;
......
...@@ -6,6 +6,7 @@ menu "ACPI Support" ...@@ -6,6 +6,7 @@ menu "ACPI Support"
config ACPI config ACPI
bool "ACPI Support" if X86 bool "ACPI Support" if X86
depends on !X86_VISWS
default y if IA64 && (!IA64_HP_SIM || IA64_SGI_SN) default y if IA64 && (!IA64_HP_SIM || IA64_SGI_SN)
---help--- ---help---
Advanced Configuration and Power Interface (ACPI) support for Advanced Configuration and Power Interface (ACPI) support for
......
...@@ -76,6 +76,7 @@ EXPORT_SYMBOL(acpi_acquire_global_lock); ...@@ -76,6 +76,7 @@ EXPORT_SYMBOL(acpi_acquire_global_lock);
EXPORT_SYMBOL(acpi_release_global_lock); EXPORT_SYMBOL(acpi_release_global_lock);
EXPORT_SYMBOL(acpi_get_current_resources); EXPORT_SYMBOL(acpi_get_current_resources);
EXPORT_SYMBOL(acpi_get_possible_resources); EXPORT_SYMBOL(acpi_get_possible_resources);
EXPORT_SYMBOL(acpi_walk_resources);
EXPORT_SYMBOL(acpi_set_current_resources); EXPORT_SYMBOL(acpi_set_current_resources);
EXPORT_SYMBOL(acpi_enable_event); EXPORT_SYMBOL(acpi_enable_event);
EXPORT_SYMBOL(acpi_disable_event); EXPORT_SYMBOL(acpi_disable_event);
...@@ -86,6 +87,7 @@ EXPORT_SYMBOL(acpi_get_sleep_type_data); ...@@ -86,6 +87,7 @@ EXPORT_SYMBOL(acpi_get_sleep_type_data);
EXPORT_SYMBOL(acpi_get_register); EXPORT_SYMBOL(acpi_get_register);
EXPORT_SYMBOL(acpi_set_register); EXPORT_SYMBOL(acpi_set_register);
EXPORT_SYMBOL(acpi_enter_sleep_state); EXPORT_SYMBOL(acpi_enter_sleep_state);
EXPORT_SYMBOL(acpi_enter_sleep_state_s4bios);
EXPORT_SYMBOL(acpi_get_system_info); EXPORT_SYMBOL(acpi_get_system_info);
EXPORT_SYMBOL(acpi_get_devices); EXPORT_SYMBOL(acpi_get_devices);
......
...@@ -644,15 +644,46 @@ acpi_ec_remove ( ...@@ -644,15 +644,46 @@ acpi_ec_remove (
} }
static acpi_status
acpi_ec_io_ports (
struct acpi_resource *resource,
void *context)
{
struct acpi_ec *ec = (struct acpi_ec *) context;
struct acpi_generic_address *addr;
if (resource->id != ACPI_RSTYPE_IO) {
return AE_OK;
}
/*
* The first address region returned is the data port, and
* the second address region returned is the status/command
* port.
*/
if (ec->data_addr.register_bit_width == 0) {
addr = &ec->data_addr;
} else if (ec->command_addr.register_bit_width == 0) {
addr = &ec->command_addr;
} else {
return AE_CTRL_TERMINATE;
}
addr->address_space_id = ACPI_ADR_SPACE_SYSTEM_IO;
addr->register_bit_width = 8;
addr->register_bit_offset = 0;
addr->address = resource->data.io.min_base_address;
return AE_OK;
}
static int static int
acpi_ec_start ( acpi_ec_start (
struct acpi_device *device) struct acpi_device *device)
{ {
int result = 0;
acpi_status status = AE_OK; acpi_status status = AE_OK;
struct acpi_ec *ec = NULL; struct acpi_ec *ec = NULL;
struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
struct acpi_resource *resource = NULL;
ACPI_FUNCTION_TRACE("acpi_ec_start"); ACPI_FUNCTION_TRACE("acpi_ec_start");
...@@ -667,33 +698,13 @@ acpi_ec_start ( ...@@ -667,33 +698,13 @@ acpi_ec_start (
/* /*
* Get I/O port addresses. Convert to GAS format. * Get I/O port addresses. Convert to GAS format.
*/ */
status = acpi_get_current_resources(ec->handle, &buffer); status = acpi_walk_resources(ec->handle, METHOD_NAME__CRS,
if (ACPI_FAILURE(status)) { acpi_ec_io_ports, ec);
if (ACPI_FAILURE(status) || ec->command_addr.register_bit_width == 0) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error getting I/O port addresses")); ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error getting I/O port addresses"));
return_VALUE(-ENODEV); return_VALUE(-ENODEV);
} }
resource = (struct acpi_resource *) buffer.pointer;
if (!resource || (resource->id != ACPI_RSTYPE_IO)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid or missing resource\n"));
result = -ENODEV;
goto end;
}
ec->data_addr.address_space_id = ACPI_ADR_SPACE_SYSTEM_IO;
ec->data_addr.register_bit_width = 8;
ec->data_addr.register_bit_offset = 0;
ec->data_addr.address = resource->data.io.min_base_address;
resource = ACPI_NEXT_RESOURCE(resource);
if (!resource || (resource->id != ACPI_RSTYPE_IO)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid or missing resource\n"));
result = -ENODEV;
goto end;
}
ec->command_addr.address_space_id = ACPI_ADR_SPACE_SYSTEM_IO;
ec->command_addr.register_bit_width = 8;
ec->command_addr.register_bit_offset = 0;
ec->command_addr.address = resource->data.io.min_base_address;
ec->status_addr = ec->command_addr; ec->status_addr = ec->command_addr;
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02x, ports=0x%2x,0x%2x\n", ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02x, ports=0x%2x,0x%2x\n",
...@@ -706,8 +717,7 @@ acpi_ec_start ( ...@@ -706,8 +717,7 @@ acpi_ec_start (
status = acpi_install_gpe_handler(ec->gpe_bit, status = acpi_install_gpe_handler(ec->gpe_bit,
ACPI_EVENT_EDGE_TRIGGERED, &acpi_ec_gpe_handler, ec); ACPI_EVENT_EDGE_TRIGGERED, &acpi_ec_gpe_handler, ec);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
result = -ENODEV; return_VALUE(-ENODEV);
goto end;
} }
status = acpi_install_address_space_handler (ec->handle, status = acpi_install_address_space_handler (ec->handle,
...@@ -715,13 +725,10 @@ acpi_ec_start ( ...@@ -715,13 +725,10 @@ acpi_ec_start (
&acpi_ec_space_setup, ec); &acpi_ec_space_setup, ec);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
acpi_remove_gpe_handler(ec->gpe_bit, &acpi_ec_gpe_handler); acpi_remove_gpe_handler(ec->gpe_bit, &acpi_ec_gpe_handler);
result = -ENODEV; return_VALUE(-ENODEV);
goto end;
} }
end:
acpi_os_free(buffer.pointer);
return_VALUE(result); return_VALUE(AE_OK);
} }
......
...@@ -4,6 +4,6 @@ ...@@ -4,6 +4,6 @@
obj-y := evevent.o evregion.o evsci.o evxfevnt.o \ obj-y := evevent.o evregion.o evsci.o evxfevnt.o \
evmisc.o evrgnini.o evxface.o evxfregn.o \ evmisc.o evrgnini.o evxface.o evxfregn.o \
evgpe.o evgpe.o evgpeblk.o
EXTRA_CFLAGS += $(ACPI_CFLAGS) EXTRA_CFLAGS += $(ACPI_CFLAGS)
...@@ -110,7 +110,7 @@ acpi_ev_initialize ( ...@@ -110,7 +110,7 @@ acpi_ev_initialize (
* *
* RETURN: Status * RETURN: Status
* *
* DESCRIPTION: Install handlers for the SCI, Global Lock, and GPEs. * DESCRIPTION: Install interrupt handlers for the SCI and Global Lock
* *
******************************************************************************/ ******************************************************************************/
...@@ -134,16 +134,6 @@ acpi_ev_handler_initialize ( ...@@ -134,16 +134,6 @@ acpi_ev_handler_initialize (
return_ACPI_STATUS (status); return_ACPI_STATUS (status);
} }
/* Install handlers for control method GPE handlers (_Lxx, _Exx) */
status = acpi_ev_init_gpe_control_methods ();
if (ACPI_FAILURE (status)) {
ACPI_REPORT_ERROR ((
"Unable to initialize GPE control methods, %s\n",
acpi_format_exception (status)));
return_ACPI_STATUS (status);
}
/* Install the handler for the Global Lock */ /* Install the handler for the Global Lock */
status = acpi_ev_init_global_lock_handler (); status = acpi_ev_init_global_lock_handler ();
......
This diff is collapsed.
This diff is collapsed.
...@@ -84,84 +84,6 @@ acpi_ev_is_notify_object ( ...@@ -84,84 +84,6 @@ acpi_ev_is_notify_object (
} }
/*******************************************************************************
*
* FUNCTION: acpi_ev_get_gpe_register_info
*
* PARAMETERS: gpe_number - Raw GPE number
*
* RETURN: Pointer to the info struct for this GPE register.
*
* DESCRIPTION: Returns the register index (index into the GPE register info
* table) associated with this GPE.
*
******************************************************************************/
struct acpi_gpe_register_info *
acpi_ev_get_gpe_register_info (
u32 gpe_number)
{
if (gpe_number > acpi_gbl_gpe_number_max) {
return (NULL);
}
return (&acpi_gbl_gpe_register_info [ACPI_DIV_8 (acpi_gbl_gpe_number_to_index[gpe_number].number_index)]);
}
/*******************************************************************************
*
* FUNCTION: acpi_ev_get_gpe_number_info
*
* PARAMETERS: gpe_number - Raw GPE number
*
* RETURN: None.
*
* DESCRIPTION: Returns the number index (index into the GPE number info table)
* associated with this GPE.
*
******************************************************************************/
struct acpi_gpe_number_info *
acpi_ev_get_gpe_number_info (
u32 gpe_number)
{
if (gpe_number > acpi_gbl_gpe_number_max) {
return (NULL);
}
return (&acpi_gbl_gpe_number_info [acpi_gbl_gpe_number_to_index[gpe_number].number_index]);
}
/*******************************************************************************
*
* FUNCTION: acpi_ev_get_gpe_number_index
*
* PARAMETERS: gpe_number - Raw GPE number
*
* RETURN: None.
*
* DESCRIPTION: Returns the number index (index into the GPE number info table)
* associated with this GPE.
*
******************************************************************************/
u32
acpi_ev_get_gpe_number_index (
u32 gpe_number)
{
if (gpe_number > acpi_gbl_gpe_number_max) {
return (ACPI_GPE_INVALID);
}
return (acpi_gbl_gpe_number_to_index[gpe_number].number_index);
}
/******************************************************************************* /*******************************************************************************
* *
* FUNCTION: acpi_ev_queue_notify_request * FUNCTION: acpi_ev_queue_notify_request
...@@ -601,6 +523,9 @@ acpi_ev_terminate (void) ...@@ -601,6 +523,9 @@ acpi_ev_terminate (void)
{ {
acpi_native_uint i; acpi_native_uint i;
acpi_status status; acpi_status status;
struct acpi_gpe_block_info *gpe_block;
struct acpi_gpe_block_info *next_gpe_block;
struct acpi_gpe_event_info *gpe_event_info;
ACPI_FUNCTION_TRACE ("ev_terminate"); ACPI_FUNCTION_TRACE ("ev_terminate");
...@@ -625,13 +550,19 @@ acpi_ev_terminate (void) ...@@ -625,13 +550,19 @@ acpi_ev_terminate (void)
/* /*
* Disable all GPEs * Disable all GPEs
*/ */
for (i = 0; i < acpi_gbl_gpe_number_max; i++) { gpe_block = acpi_gbl_gpe_block_list_head;
if (acpi_ev_get_gpe_number_index ((u32)i) != ACPI_GPE_INVALID) { while (gpe_block) {
status = acpi_hw_disable_gpe((u32) i); gpe_event_info = gpe_block->event_info;
for (i = 0; i < (gpe_block->register_count * 8); i++) {
status = acpi_hw_disable_gpe (gpe_event_info);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not disable GPE %d\n", (u32) i)); ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not disable GPE %d\n", (u32) i));
} }
gpe_event_info++;
} }
gpe_block = gpe_block->next;
} }
/* /*
...@@ -654,21 +585,16 @@ acpi_ev_terminate (void) ...@@ -654,21 +585,16 @@ acpi_ev_terminate (void)
} }
/* /*
* Free global tables, etc. * Free global GPE blocks and related info structures
*/ */
if (acpi_gbl_gpe_register_info) { gpe_block = acpi_gbl_gpe_block_list_head;
ACPI_MEM_FREE (acpi_gbl_gpe_register_info); while (gpe_block) {
acpi_gbl_gpe_register_info = NULL; next_gpe_block = gpe_block->next;
} ACPI_MEM_FREE (gpe_block->event_info);
ACPI_MEM_FREE (gpe_block->register_info);
if (acpi_gbl_gpe_number_info) { ACPI_MEM_FREE (gpe_block);
ACPI_MEM_FREE (acpi_gbl_gpe_number_info);
acpi_gbl_gpe_number_info = NULL; gpe_block = next_gpe_block;
}
if (acpi_gbl_gpe_number_to_index) {
ACPI_MEM_FREE (acpi_gbl_gpe_number_to_index);
acpi_gbl_gpe_number_to_index = NULL;
} }
return_VOID; return_VOID;
......
...@@ -69,38 +69,24 @@ acpi_ev_sci_handler ( ...@@ -69,38 +69,24 @@ acpi_ev_sci_handler (
void *context) void *context)
{ {
u32 interrupt_handled = ACPI_INTERRUPT_NOT_HANDLED; u32 interrupt_handled = ACPI_INTERRUPT_NOT_HANDLED;
u32 value;
acpi_status status;
ACPI_FUNCTION_TRACE("ev_sci_handler"); ACPI_FUNCTION_TRACE("ev_sci_handler");
/* /*
* Make sure that ACPI is enabled by checking SCI_EN. Note that we are * We are guaranteed by the ACPI CA initialization/shutdown code that
* required to treat the SCI interrupt as sharable, level, active low. * if this interrupt handler is installed, ACPI is enabled.
*/ */
status = acpi_get_register (ACPI_BITREG_SCI_ENABLE, &value, ACPI_MTX_DO_NOT_LOCK);
if (ACPI_FAILURE (status)) {
return (ACPI_INTERRUPT_NOT_HANDLED);
}
if (!value) {
/* ACPI is not enabled; this interrupt cannot be for us */
return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
}
/* /*
* Fixed acpi_events: * Fixed acpi_events:
* -------------
* Check for and dispatch any Fixed acpi_events that have occurred * Check for and dispatch any Fixed acpi_events that have occurred
*/ */
interrupt_handled |= acpi_ev_fixed_event_detect (); interrupt_handled |= acpi_ev_fixed_event_detect ();
/* /*
* GPEs: * GPEs:
* -----
* Check for and dispatch any GPEs that have occurred * Check for and dispatch any GPEs that have occurred
*/ */
interrupt_handled |= acpi_ev_gpe_detect (); interrupt_handled |= acpi_ev_gpe_detect ();
......
...@@ -492,7 +492,7 @@ acpi_install_gpe_handler ( ...@@ -492,7 +492,7 @@ acpi_install_gpe_handler (
void *context) void *context)
{ {
acpi_status status; acpi_status status;
struct acpi_gpe_number_info *gpe_number_info; struct acpi_gpe_event_info *gpe_event_info;
ACPI_FUNCTION_TRACE ("acpi_install_gpe_handler"); ACPI_FUNCTION_TRACE ("acpi_install_gpe_handler");
...@@ -506,8 +506,8 @@ acpi_install_gpe_handler ( ...@@ -506,8 +506,8 @@ acpi_install_gpe_handler (
/* Ensure that we have a valid GPE number */ /* Ensure that we have a valid GPE number */
gpe_number_info = acpi_ev_get_gpe_number_info (gpe_number); gpe_event_info = acpi_ev_get_gpe_event_info (gpe_number);
if (!gpe_number_info) { if (!gpe_event_info) {
return_ACPI_STATUS (AE_BAD_PARAMETER); return_ACPI_STATUS (AE_BAD_PARAMETER);
} }
...@@ -518,25 +518,25 @@ acpi_install_gpe_handler ( ...@@ -518,25 +518,25 @@ acpi_install_gpe_handler (
/* Make sure that there isn't a handler there already */ /* Make sure that there isn't a handler there already */
if (gpe_number_info->handler) { if (gpe_event_info->handler) {
status = AE_ALREADY_EXISTS; status = AE_ALREADY_EXISTS;
goto cleanup; goto cleanup;
} }
/* Install the handler */ /* Install the handler */
gpe_number_info->handler = handler; gpe_event_info->handler = handler;
gpe_number_info->context = context; gpe_event_info->context = context;
gpe_number_info->type = (u8) type; gpe_event_info->type = (u8) type;
/* Clear the GPE (of stale events), the enable it */ /* Clear the GPE (of stale events), the enable it */
status = acpi_hw_clear_gpe (gpe_number); status = acpi_hw_clear_gpe (gpe_event_info);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
goto cleanup; goto cleanup;
} }
status = acpi_hw_enable_gpe (gpe_number); status = acpi_hw_enable_gpe (gpe_event_info);
cleanup: cleanup:
...@@ -564,7 +564,7 @@ acpi_remove_gpe_handler ( ...@@ -564,7 +564,7 @@ acpi_remove_gpe_handler (
acpi_gpe_handler handler) acpi_gpe_handler handler)
{ {
acpi_status status; acpi_status status;
struct acpi_gpe_number_info *gpe_number_info; struct acpi_gpe_event_info *gpe_event_info;
ACPI_FUNCTION_TRACE ("acpi_remove_gpe_handler"); ACPI_FUNCTION_TRACE ("acpi_remove_gpe_handler");
...@@ -578,14 +578,14 @@ acpi_remove_gpe_handler ( ...@@ -578,14 +578,14 @@ acpi_remove_gpe_handler (
/* Ensure that we have a valid GPE number */ /* Ensure that we have a valid GPE number */
gpe_number_info = acpi_ev_get_gpe_number_info (gpe_number); gpe_event_info = acpi_ev_get_gpe_event_info (gpe_number);
if (!gpe_number_info) { if (!gpe_event_info) {
return_ACPI_STATUS (AE_BAD_PARAMETER); return_ACPI_STATUS (AE_BAD_PARAMETER);
} }
/* Disable the GPE before removing the handler */ /* Disable the GPE before removing the handler */
status = acpi_hw_disable_gpe (gpe_number); status = acpi_hw_disable_gpe (gpe_event_info);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status); return_ACPI_STATUS (status);
} }
...@@ -597,16 +597,16 @@ acpi_remove_gpe_handler ( ...@@ -597,16 +597,16 @@ acpi_remove_gpe_handler (
/* Make sure that the installed handler is the same */ /* Make sure that the installed handler is the same */
if (gpe_number_info->handler != handler) { if (gpe_event_info->handler != handler) {
(void) acpi_hw_enable_gpe (gpe_number); (void) acpi_hw_enable_gpe (gpe_event_info);
status = AE_BAD_PARAMETER; status = AE_BAD_PARAMETER;
goto cleanup; goto cleanup;
} }
/* Remove the handler */ /* Remove the handler */
gpe_number_info->handler = NULL; gpe_event_info->handler = NULL;
gpe_number_info->context = NULL; gpe_event_info->context = NULL;
cleanup: cleanup:
......
...@@ -163,6 +163,7 @@ acpi_enable_event ( ...@@ -163,6 +163,7 @@ acpi_enable_event (
{ {
acpi_status status = AE_OK; acpi_status status = AE_OK;
u32 value; u32 value;
struct acpi_gpe_event_info *gpe_event_info;
ACPI_FUNCTION_TRACE ("acpi_enable_event"); ACPI_FUNCTION_TRACE ("acpi_enable_event");
...@@ -209,19 +210,20 @@ acpi_enable_event ( ...@@ -209,19 +210,20 @@ acpi_enable_event (
/* Ensure that we have a valid GPE number */ /* Ensure that we have a valid GPE number */
if (acpi_ev_get_gpe_number_index (event) == ACPI_GPE_INVALID) { gpe_event_info = acpi_ev_get_gpe_event_info (event);
if (!gpe_event_info) {
return_ACPI_STATUS (AE_BAD_PARAMETER); return_ACPI_STATUS (AE_BAD_PARAMETER);
} }
/* Enable the requested GPE number */ /* Enable the requested GPE number */
status = acpi_hw_enable_gpe (event); status = acpi_hw_enable_gpe (gpe_event_info);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status); return_ACPI_STATUS (status);
} }
if (flags & ACPI_EVENT_WAKE_ENABLE) { if (flags & ACPI_EVENT_WAKE_ENABLE) {
acpi_hw_enable_gpe_for_wakeup (event); acpi_hw_enable_gpe_for_wakeup (gpe_event_info);
} }
break; break;
...@@ -257,6 +259,7 @@ acpi_disable_event ( ...@@ -257,6 +259,7 @@ acpi_disable_event (
{ {
acpi_status status = AE_OK; acpi_status status = AE_OK;
u32 value; u32 value;
struct acpi_gpe_event_info *gpe_event_info;
ACPI_FUNCTION_TRACE ("acpi_disable_event"); ACPI_FUNCTION_TRACE ("acpi_disable_event");
...@@ -301,7 +304,8 @@ acpi_disable_event ( ...@@ -301,7 +304,8 @@ acpi_disable_event (
/* Ensure that we have a valid GPE number */ /* Ensure that we have a valid GPE number */
if (acpi_ev_get_gpe_number_index (event) == ACPI_GPE_INVALID) { gpe_event_info = acpi_ev_get_gpe_event_info (event);
if (!gpe_event_info) {
return_ACPI_STATUS (AE_BAD_PARAMETER); return_ACPI_STATUS (AE_BAD_PARAMETER);
} }
...@@ -311,10 +315,10 @@ acpi_disable_event ( ...@@ -311,10 +315,10 @@ acpi_disable_event (
*/ */
if (flags & ACPI_EVENT_WAKE_DISABLE) { if (flags & ACPI_EVENT_WAKE_DISABLE) {
acpi_hw_disable_gpe_for_wakeup (event); acpi_hw_disable_gpe_for_wakeup (gpe_event_info);
} }
else { else {
status = acpi_hw_disable_gpe (event); status = acpi_hw_disable_gpe (gpe_event_info);
} }
break; break;
...@@ -346,6 +350,7 @@ acpi_clear_event ( ...@@ -346,6 +350,7 @@ acpi_clear_event (
u32 type) u32 type)
{ {
acpi_status status = AE_OK; acpi_status status = AE_OK;
struct acpi_gpe_event_info *gpe_event_info;
ACPI_FUNCTION_TRACE ("acpi_clear_event"); ACPI_FUNCTION_TRACE ("acpi_clear_event");
...@@ -375,11 +380,12 @@ acpi_clear_event ( ...@@ -375,11 +380,12 @@ acpi_clear_event (
/* Ensure that we have a valid GPE number */ /* Ensure that we have a valid GPE number */
if (acpi_ev_get_gpe_number_index (event) == ACPI_GPE_INVALID) { gpe_event_info = acpi_ev_get_gpe_event_info (event);
if (!gpe_event_info) {
return_ACPI_STATUS (AE_BAD_PARAMETER); return_ACPI_STATUS (AE_BAD_PARAMETER);
} }
status = acpi_hw_clear_gpe (event); status = acpi_hw_clear_gpe (gpe_event_info);
break; break;
...@@ -415,6 +421,7 @@ acpi_get_event_status ( ...@@ -415,6 +421,7 @@ acpi_get_event_status (
acpi_event_status *event_status) acpi_event_status *event_status)
{ {
acpi_status status = AE_OK; acpi_status status = AE_OK;
struct acpi_gpe_event_info *gpe_event_info;
ACPI_FUNCTION_TRACE ("acpi_get_event_status"); ACPI_FUNCTION_TRACE ("acpi_get_event_status");
...@@ -447,7 +454,8 @@ acpi_get_event_status ( ...@@ -447,7 +454,8 @@ acpi_get_event_status (
/* Ensure that we have a valid GPE number */ /* Ensure that we have a valid GPE number */
if (acpi_ev_get_gpe_number_index (event) == ACPI_GPE_INVALID) { gpe_event_info = acpi_ev_get_gpe_event_info (event);
if (!gpe_event_info) {
return_ACPI_STATUS (AE_BAD_PARAMETER); return_ACPI_STATUS (AE_BAD_PARAMETER);
} }
...@@ -464,3 +472,4 @@ acpi_get_event_status ( ...@@ -464,3 +472,4 @@ acpi_get_event_status (
return_ACPI_STATUS (status); return_ACPI_STATUS (status);
} }
...@@ -49,26 +49,6 @@ ...@@ -49,26 +49,6 @@
ACPI_MODULE_NAME ("hwgpe") ACPI_MODULE_NAME ("hwgpe")
/******************************************************************************
*
* FUNCTION: acpi_hw_get_gpe_bit_mask
*
* PARAMETERS: gpe_number - The GPE
*
* RETURN: Gpe register bitmask for this gpe level
*
* DESCRIPTION: Get the bitmask for this GPE
*
******************************************************************************/
u8
acpi_hw_get_gpe_bit_mask (
u32 gpe_number)
{
return (acpi_gbl_gpe_number_info [acpi_ev_get_gpe_number_index (gpe_number)].bit_mask);
}
/****************************************************************************** /******************************************************************************
* *
* FUNCTION: acpi_hw_enable_gpe * FUNCTION: acpi_hw_enable_gpe
...@@ -83,37 +63,29 @@ acpi_hw_get_gpe_bit_mask ( ...@@ -83,37 +63,29 @@ acpi_hw_get_gpe_bit_mask (
acpi_status acpi_status
acpi_hw_enable_gpe ( acpi_hw_enable_gpe (
u32 gpe_number) struct acpi_gpe_event_info *gpe_event_info)
{ {
u32 in_byte; u32 in_byte;
acpi_status status; acpi_status status;
struct acpi_gpe_register_info *gpe_register_info;
ACPI_FUNCTION_ENTRY (); ACPI_FUNCTION_ENTRY ();
/* Get the info block for the entire GPE register */
gpe_register_info = acpi_ev_get_gpe_register_info (gpe_number);
if (!gpe_register_info) {
return (AE_BAD_PARAMETER);
}
/* /*
* Read the current value of the register, set the appropriate bit * Read the current value of the register, set the appropriate bit
* to enable the GPE, and write out the new register. * to enable the GPE, and write out the new register.
*/ */
status = acpi_hw_low_level_read (8, &in_byte, status = acpi_hw_low_level_read (8, &in_byte,
&gpe_register_info->enable_address, 0); &gpe_event_info->register_info->enable_address, 0);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
return (status); return (status);
} }
/* Write with the new GPE bit enabled */ /* Write with the new GPE bit enabled */
status = acpi_hw_low_level_write (8, (in_byte | acpi_hw_get_gpe_bit_mask (gpe_number)), status = acpi_hw_low_level_write (8, (in_byte | gpe_event_info->bit_mask),
&gpe_register_info->enable_address, 0); &gpe_event_info->register_info->enable_address, 0);
return (status); return (status);
} }
...@@ -134,7 +106,7 @@ acpi_hw_enable_gpe ( ...@@ -134,7 +106,7 @@ acpi_hw_enable_gpe (
void void
acpi_hw_enable_gpe_for_wakeup ( acpi_hw_enable_gpe_for_wakeup (
u32 gpe_number) struct acpi_gpe_event_info *gpe_event_info)
{ {
struct acpi_gpe_register_info *gpe_register_info; struct acpi_gpe_register_info *gpe_register_info;
...@@ -144,7 +116,7 @@ acpi_hw_enable_gpe_for_wakeup ( ...@@ -144,7 +116,7 @@ acpi_hw_enable_gpe_for_wakeup (
/* Get the info block for the entire GPE register */ /* Get the info block for the entire GPE register */
gpe_register_info = acpi_ev_get_gpe_register_info (gpe_number); gpe_register_info = gpe_event_info->register_info;
if (!gpe_register_info) { if (!gpe_register_info) {
return; return;
} }
...@@ -152,7 +124,7 @@ acpi_hw_enable_gpe_for_wakeup ( ...@@ -152,7 +124,7 @@ acpi_hw_enable_gpe_for_wakeup (
/* /*
* Set the bit so we will not disable this when sleeping * Set the bit so we will not disable this when sleeping
*/ */
gpe_register_info->wake_enable |= acpi_hw_get_gpe_bit_mask (gpe_number); gpe_register_info->wake_enable |= gpe_event_info->bit_mask;
} }
...@@ -170,7 +142,7 @@ acpi_hw_enable_gpe_for_wakeup ( ...@@ -170,7 +142,7 @@ acpi_hw_enable_gpe_for_wakeup (
acpi_status acpi_status
acpi_hw_disable_gpe ( acpi_hw_disable_gpe (
u32 gpe_number) struct acpi_gpe_event_info *gpe_event_info)
{ {
u32 in_byte; u32 in_byte;
acpi_status status; acpi_status status;
...@@ -182,7 +154,7 @@ acpi_hw_disable_gpe ( ...@@ -182,7 +154,7 @@ acpi_hw_disable_gpe (
/* Get the info block for the entire GPE register */ /* Get the info block for the entire GPE register */
gpe_register_info = acpi_ev_get_gpe_register_info (gpe_number); gpe_register_info = gpe_event_info->register_info;
if (!gpe_register_info) { if (!gpe_register_info) {
return (AE_BAD_PARAMETER); return (AE_BAD_PARAMETER);
} }
...@@ -199,13 +171,13 @@ acpi_hw_disable_gpe ( ...@@ -199,13 +171,13 @@ acpi_hw_disable_gpe (
/* Write the byte with this GPE bit cleared */ /* Write the byte with this GPE bit cleared */
status = acpi_hw_low_level_write (8, (in_byte & ~(acpi_hw_get_gpe_bit_mask (gpe_number))), status = acpi_hw_low_level_write (8, (in_byte & ~(gpe_event_info->bit_mask)),
&gpe_register_info->enable_address, 0); &gpe_register_info->enable_address, 0);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
return (status); return (status);
} }
acpi_hw_disable_gpe_for_wakeup(gpe_number); acpi_hw_disable_gpe_for_wakeup (gpe_event_info);
return (AE_OK); return (AE_OK);
} }
...@@ -225,7 +197,7 @@ acpi_hw_disable_gpe ( ...@@ -225,7 +197,7 @@ acpi_hw_disable_gpe (
void void
acpi_hw_disable_gpe_for_wakeup ( acpi_hw_disable_gpe_for_wakeup (
u32 gpe_number) struct acpi_gpe_event_info *gpe_event_info)
{ {
struct acpi_gpe_register_info *gpe_register_info; struct acpi_gpe_register_info *gpe_register_info;
...@@ -235,7 +207,7 @@ acpi_hw_disable_gpe_for_wakeup ( ...@@ -235,7 +207,7 @@ acpi_hw_disable_gpe_for_wakeup (
/* Get the info block for the entire GPE register */ /* Get the info block for the entire GPE register */
gpe_register_info = acpi_ev_get_gpe_register_info (gpe_number); gpe_register_info = gpe_event_info->register_info;
if (!gpe_register_info) { if (!gpe_register_info) {
return; return;
} }
...@@ -243,7 +215,7 @@ acpi_hw_disable_gpe_for_wakeup ( ...@@ -243,7 +215,7 @@ acpi_hw_disable_gpe_for_wakeup (
/* /*
* Clear the bit so we will disable this when sleeping * Clear the bit so we will disable this when sleeping
*/ */
gpe_register_info->wake_enable &= ~(acpi_hw_get_gpe_bit_mask (gpe_number)); gpe_register_info->wake_enable &= ~(gpe_event_info->bit_mask);
} }
...@@ -261,28 +233,20 @@ acpi_hw_disable_gpe_for_wakeup ( ...@@ -261,28 +233,20 @@ acpi_hw_disable_gpe_for_wakeup (
acpi_status acpi_status
acpi_hw_clear_gpe ( acpi_hw_clear_gpe (
u32 gpe_number) struct acpi_gpe_event_info *gpe_event_info)
{ {
acpi_status status; acpi_status status;
struct acpi_gpe_register_info *gpe_register_info;
ACPI_FUNCTION_ENTRY (); ACPI_FUNCTION_ENTRY ();
/* Get the info block for the entire GPE register */
gpe_register_info = acpi_ev_get_gpe_register_info (gpe_number);
if (!gpe_register_info) {
return (AE_BAD_PARAMETER);
}
/* /*
* Write a one to the appropriate bit in the status register to * Write a one to the appropriate bit in the status register to
* clear this GPE. * clear this GPE.
*/ */
status = acpi_hw_low_level_write (8, acpi_hw_get_gpe_bit_mask (gpe_number), status = acpi_hw_low_level_write (8, gpe_event_info->bit_mask,
&gpe_register_info->status_address, 0); &gpe_event_info->register_info->status_address, 0);
return (status); return (status);
} }
...@@ -308,6 +272,7 @@ acpi_hw_get_gpe_status ( ...@@ -308,6 +272,7 @@ acpi_hw_get_gpe_status (
u32 in_byte; u32 in_byte;
u8 bit_mask; u8 bit_mask;
struct acpi_gpe_register_info *gpe_register_info; struct acpi_gpe_register_info *gpe_register_info;
struct acpi_gpe_event_info *gpe_event_info;
acpi_status status; acpi_status status;
acpi_event_status local_event_status = 0; acpi_event_status local_event_status = 0;
...@@ -319,16 +284,18 @@ acpi_hw_get_gpe_status ( ...@@ -319,16 +284,18 @@ acpi_hw_get_gpe_status (
return (AE_BAD_PARAMETER); return (AE_BAD_PARAMETER);
} }
/* Get the info block for the entire GPE register */ gpe_event_info = acpi_ev_get_gpe_event_info (gpe_number);
if (!gpe_event_info) {
gpe_register_info = acpi_ev_get_gpe_register_info (gpe_number);
if (!gpe_register_info) {
return (AE_BAD_PARAMETER); return (AE_BAD_PARAMETER);
} }
/* Get the info block for the entire GPE register */
gpe_register_info = gpe_event_info->register_info;
/* Get the register bitmask for this GPE */ /* Get the register bitmask for this GPE */
bit_mask = acpi_hw_get_gpe_bit_mask (gpe_number); bit_mask = gpe_event_info->bit_mask;
/* GPE Enabled? */ /* GPE Enabled? */
...@@ -375,7 +342,7 @@ acpi_hw_get_gpe_status ( ...@@ -375,7 +342,7 @@ acpi_hw_get_gpe_status (
* *
* DESCRIPTION: Disable all non-wakeup GPEs * DESCRIPTION: Disable all non-wakeup GPEs
* Call with interrupts disabled. The interrupt handler also * Call with interrupts disabled. The interrupt handler also
* modifies acpi_gbl_gpe_register_info[i].Enable, so it should not be * modifies gpe_register_info->Enable, so it should not be
* given the chance to run until after non-wake GPEs are * given the chance to run until after non-wake GPEs are
* re-enabled. * re-enabled.
* *
...@@ -389,40 +356,49 @@ acpi_hw_disable_non_wakeup_gpes ( ...@@ -389,40 +356,49 @@ acpi_hw_disable_non_wakeup_gpes (
struct acpi_gpe_register_info *gpe_register_info; struct acpi_gpe_register_info *gpe_register_info;
u32 in_value; u32 in_value;
acpi_status status; acpi_status status;
struct acpi_gpe_block_info *gpe_block;
ACPI_FUNCTION_ENTRY (); ACPI_FUNCTION_ENTRY ();
for (i = 0; i < acpi_gbl_gpe_register_count; i++) { gpe_block = acpi_gbl_gpe_block_list_head;
/* Get the info block for the entire GPE register */ while (gpe_block) {
/* Get the register info for the entire GPE block */
gpe_register_info = &acpi_gbl_gpe_register_info[i]; gpe_register_info = gpe_block->register_info;
if (!gpe_register_info) { if (!gpe_register_info) {
return (AE_BAD_PARAMETER); return (AE_BAD_PARAMETER);
} }
/* for (i = 0; i < gpe_block->register_count; i++) {
* Read the enabled status of all GPEs. We /*
* will be using it to restore all the GPEs later. * Read the enabled status of all GPEs. We
*/ * will be using it to restore all the GPEs later.
status = acpi_hw_low_level_read (8, &in_value, */
&gpe_register_info->enable_address, 0); status = acpi_hw_low_level_read (8, &in_value,
if (ACPI_FAILURE (status)) { &gpe_register_info->enable_address, 0);
return (status); if (ACPI_FAILURE (status)) {
return (status);
}
gpe_register_info->enable = (u8) in_value;
/*
* Disable all GPEs except wakeup GPEs.
*/
status = acpi_hw_low_level_write (8, gpe_register_info->wake_enable,
&gpe_register_info->enable_address, 0);
if (ACPI_FAILURE (status)) {
return (status);
}
gpe_register_info++;
} }
gpe_register_info->enable = (u8) in_value; gpe_block = gpe_block->next;
/*
* Disable all GPEs except wakeup GPEs.
*/
status = acpi_hw_low_level_write (8, gpe_register_info->wake_enable,
&gpe_register_info->enable_address, 0);
if (ACPI_FAILURE (status)) {
return (status);
}
} }
return (AE_OK); return (AE_OK);
} }
...@@ -446,28 +422,37 @@ acpi_hw_enable_non_wakeup_gpes ( ...@@ -446,28 +422,37 @@ acpi_hw_enable_non_wakeup_gpes (
u32 i; u32 i;
struct acpi_gpe_register_info *gpe_register_info; struct acpi_gpe_register_info *gpe_register_info;
acpi_status status; acpi_status status;
struct acpi_gpe_block_info *gpe_block;
ACPI_FUNCTION_ENTRY (); ACPI_FUNCTION_ENTRY ();
for (i = 0; i < acpi_gbl_gpe_register_count; i++) { gpe_block = acpi_gbl_gpe_block_list_head;
/* Get the info block for the entire GPE register */ while (gpe_block) {
/* Get the register info for the entire GPE block */
gpe_register_info = &acpi_gbl_gpe_register_info[i]; gpe_register_info = gpe_block->register_info;
if (!gpe_register_info) { if (!gpe_register_info) {
return (AE_BAD_PARAMETER); return (AE_BAD_PARAMETER);
} }
/* for (i = 0; i < gpe_block->register_count; i++) {
* We previously stored the enabled status of all GPEs. /*
* Blast them back in. * We previously stored the enabled status of all GPEs.
*/ * Blast them back in.
status = acpi_hw_low_level_write (8, gpe_register_info->enable, */
&gpe_register_info->enable_address, 0); status = acpi_hw_low_level_write (8, gpe_register_info->enable,
if (ACPI_FAILURE (status)) { &gpe_register_info->enable_address, 0);
return (status); if (ACPI_FAILURE (status)) {
return (status);
}
gpe_register_info++;
} }
gpe_block = gpe_block->next;
} }
return (AE_OK); return (AE_OK);
} }
...@@ -67,8 +67,8 @@ acpi_status ...@@ -67,8 +67,8 @@ acpi_status
acpi_hw_clear_acpi_status (void) acpi_hw_clear_acpi_status (void)
{ {
acpi_native_uint i; acpi_native_uint i;
acpi_native_uint gpe_block;
acpi_status status; acpi_status status;
struct acpi_gpe_block_info *gpe_block;
ACPI_FUNCTION_TRACE ("hw_clear_acpi_status"); ACPI_FUNCTION_TRACE ("hw_clear_acpi_status");
...@@ -100,16 +100,19 @@ acpi_hw_clear_acpi_status (void) ...@@ -100,16 +100,19 @@ acpi_hw_clear_acpi_status (void)
} }
} }
/* Clear the GPE Bits */ /* Clear the GPE Bits in all GPE registers in all GPE blocks */
for (gpe_block = 0; gpe_block < ACPI_MAX_GPE_BLOCKS; gpe_block++) { gpe_block = acpi_gbl_gpe_block_list_head;
for (i = 0; i < acpi_gbl_gpe_block_info[gpe_block].register_count; i++) { while (gpe_block) {
for (i = 0; i < gpe_block->register_count; i++) {
status = acpi_hw_low_level_write (8, 0xFF, status = acpi_hw_low_level_write (8, 0xFF,
acpi_gbl_gpe_block_info[gpe_block].block_address, (u32) i); &gpe_block->register_info[i].status_address, (u32) i);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
goto unlock_and_exit; goto unlock_and_exit;
} }
} }
gpe_block = gpe_block->next;
} }
unlock_and_exit: unlock_and_exit:
......
...@@ -250,7 +250,7 @@ acpi_enter_sleep_state ( ...@@ -250,7 +250,7 @@ acpi_enter_sleep_state (
/* Get current value of PM1A control */ /* Get current value of PM1A control */
status = acpi_hw_register_read (ACPI_MTX_LOCK, ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol); status = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status); return_ACPI_STATUS (status);
} }
...@@ -268,12 +268,12 @@ acpi_enter_sleep_state ( ...@@ -268,12 +268,12 @@ acpi_enter_sleep_state (
/* Write #1: fill in SLP_TYP data */ /* Write #1: fill in SLP_TYP data */
status = acpi_hw_register_write (ACPI_MTX_LOCK, ACPI_REGISTER_PM1A_CONTROL, PM1Acontrol); status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1A_CONTROL, PM1Acontrol);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status); return_ACPI_STATUS (status);
} }
status = acpi_hw_register_write (ACPI_MTX_LOCK, ACPI_REGISTER_PM1B_CONTROL, PM1Bcontrol); status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1B_CONTROL, PM1Bcontrol);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status); return_ACPI_STATUS (status);
} }
...@@ -287,12 +287,12 @@ acpi_enter_sleep_state ( ...@@ -287,12 +287,12 @@ acpi_enter_sleep_state (
ACPI_FLUSH_CPU_CACHE (); ACPI_FLUSH_CPU_CACHE ();
status = acpi_hw_register_write (ACPI_MTX_LOCK, ACPI_REGISTER_PM1A_CONTROL, PM1Acontrol); status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1A_CONTROL, PM1Acontrol);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status); return_ACPI_STATUS (status);
} }
status = acpi_hw_register_write (ACPI_MTX_LOCK, ACPI_REGISTER_PM1B_CONTROL, PM1Bcontrol); status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1B_CONTROL, PM1Bcontrol);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status); return_ACPI_STATUS (status);
} }
...@@ -308,7 +308,7 @@ acpi_enter_sleep_state ( ...@@ -308,7 +308,7 @@ acpi_enter_sleep_state (
*/ */
acpi_os_stall (10000000); acpi_os_stall (10000000);
status = acpi_hw_register_write (ACPI_MTX_LOCK, ACPI_REGISTER_PM1_CONTROL, status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_CONTROL,
sleep_enable_reg_info->access_bit_mask); sleep_enable_reg_info->access_bit_mask);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status); return_ACPI_STATUS (status);
...@@ -318,7 +318,7 @@ acpi_enter_sleep_state ( ...@@ -318,7 +318,7 @@ acpi_enter_sleep_state (
/* Wait until we enter sleep state */ /* Wait until we enter sleep state */
do { do {
status = acpi_get_register (ACPI_BITREG_WAKE_STATUS, &in_value, ACPI_MTX_LOCK); status = acpi_get_register (ACPI_BITREG_WAKE_STATUS, &in_value, ACPI_MTX_DO_NOT_LOCK);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status); return_ACPI_STATUS (status);
} }
...@@ -327,7 +327,7 @@ acpi_enter_sleep_state ( ...@@ -327,7 +327,7 @@ acpi_enter_sleep_state (
} while (!in_value); } while (!in_value);
status = acpi_set_register (ACPI_BITREG_ARB_DISABLE, 0, ACPI_MTX_LOCK); status = acpi_set_register (ACPI_BITREG_ARB_DISABLE, 0, ACPI_MTX_DO_NOT_LOCK);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status); return_ACPI_STATUS (status);
} }
...@@ -335,6 +335,51 @@ acpi_enter_sleep_state ( ...@@ -335,6 +335,51 @@ acpi_enter_sleep_state (
return_ACPI_STATUS (AE_OK); return_ACPI_STATUS (AE_OK);
} }
/******************************************************************************
*
* FUNCTION: acpi_enter_sleep_state_s4bios
*
* PARAMETERS: None
*
* RETURN: Status
*
* DESCRIPTION: Perform a S4 bios request.
* THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
*
******************************************************************************/
acpi_status
acpi_enter_sleep_state_s4bios (
void)
{
u32 in_value;
acpi_status status;
ACPI_FUNCTION_TRACE ("acpi_enter_sleep_state_s4bios");
acpi_set_register (ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_DO_NOT_LOCK);
acpi_hw_clear_acpi_status();
acpi_hw_disable_non_wakeup_gpes();
ACPI_FLUSH_CPU_CACHE();
status = acpi_os_write_port (acpi_gbl_FADT->smi_cmd, (acpi_integer) acpi_gbl_FADT->S4bios_req, 8);
do {
acpi_os_stall(1000);
status = acpi_get_register (ACPI_BITREG_WAKE_STATUS, &in_value, ACPI_MTX_DO_NOT_LOCK);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
} while (!in_value);
return_ACPI_STATUS (AE_OK);
}
/****************************************************************************** /******************************************************************************
* *
* FUNCTION: acpi_leave_sleep_state * FUNCTION: acpi_leave_sleep_state
......
...@@ -514,10 +514,12 @@ acpi_os_write_pci_configuration ( ...@@ -514,10 +514,12 @@ acpi_os_write_pci_configuration (
/* TODO: Change code to take advantage of driver model more */ /* TODO: Change code to take advantage of driver model more */
void void
acpi_os_derive_pci_id ( acpi_os_derive_pci_id_2 (
acpi_handle rhandle, /* upper bound */ acpi_handle rhandle, /* upper bound */
acpi_handle chandle, /* current node */ acpi_handle chandle, /* current node */
struct acpi_pci_id **id) struct acpi_pci_id **id,
int *is_bridge,
u8 *bus_number)
{ {
acpi_handle handle; acpi_handle handle;
struct acpi_pci_id *pci_id = *id; struct acpi_pci_id *pci_id = *id;
...@@ -528,7 +530,7 @@ acpi_os_derive_pci_id ( ...@@ -528,7 +530,7 @@ acpi_os_derive_pci_id (
acpi_get_parent(chandle, &handle); acpi_get_parent(chandle, &handle);
if (handle != rhandle) { if (handle != rhandle) {
acpi_os_derive_pci_id(rhandle, handle, &pci_id); acpi_os_derive_pci_id_2(rhandle, handle, &pci_id, is_bridge, bus_number);
status = acpi_get_type(handle, &type); status = acpi_get_type(handle, &type);
if ( (ACPI_FAILURE(status)) || (type != ACPI_TYPE_DEVICE) ) if ( (ACPI_FAILURE(status)) || (type != ACPI_TYPE_DEVICE) )
...@@ -539,17 +541,42 @@ acpi_os_derive_pci_id ( ...@@ -539,17 +541,42 @@ acpi_os_derive_pci_id (
pci_id->device = ACPI_HIWORD (ACPI_LODWORD (temp)); pci_id->device = ACPI_HIWORD (ACPI_LODWORD (temp));
pci_id->function = ACPI_LOWORD (ACPI_LODWORD (temp)); pci_id->function = ACPI_LOWORD (ACPI_LODWORD (temp));
if (*is_bridge)
pci_id->bus = *bus_number;
/* any nicer way to get bus number of bridge ? */ /* any nicer way to get bus number of bridge ? */
status = acpi_os_read_pci_configuration(pci_id, 0x0e, &tu8, 8); status = acpi_os_read_pci_configuration(pci_id, 0x0e, &tu8, 8);
if (ACPI_SUCCESS(status) && (tu8 & 0x7f) == 1) { if (ACPI_SUCCESS(status) &&
((tu8 & 0x7f) == 1 || (tu8 & 0x7f) == 2)) {
status = acpi_os_read_pci_configuration(pci_id, 0x18, &tu8, 8);
if (!ACPI_SUCCESS(status)) {
/* Certainly broken... FIX ME */
return;
}
*is_bridge = 1;
pci_id->bus = tu8;
status = acpi_os_read_pci_configuration(pci_id, 0x19, &tu8, 8); status = acpi_os_read_pci_configuration(pci_id, 0x19, &tu8, 8);
if (ACPI_SUCCESS(status)) if (ACPI_SUCCESS(status)) {
pci_id->bus = tu8; *bus_number = tu8;
} }
} else
*is_bridge = 0;
} }
} }
} }
void
acpi_os_derive_pci_id (
acpi_handle rhandle, /* upper bound */
acpi_handle chandle, /* current node */
struct acpi_pci_id **id)
{
int is_bridge = 1;
u8 bus_number = (*id)->bus;
acpi_os_derive_pci_id_2(rhandle, chandle, id, &is_bridge, &bus_number);
}
#else /*!CONFIG_ACPI_PCI*/ #else /*!CONFIG_ACPI_PCI*/
acpi_status acpi_status
......
...@@ -90,42 +90,25 @@ static struct { ...@@ -90,42 +90,25 @@ static struct {
PCI Link Device Management PCI Link Device Management
-------------------------------------------------------------------------- */ -------------------------------------------------------------------------- */
static int static acpi_status
acpi_pci_link_get_possible ( acpi_pci_link_check_possible (
struct acpi_pci_link *link) struct acpi_resource *resource,
void *context)
{ {
int result = 0; struct acpi_pci_link *link = (struct acpi_pci_link *) context;
acpi_status status = AE_OK;
struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
struct acpi_resource *resource = NULL;
int i = 0; int i = 0;
ACPI_FUNCTION_TRACE("acpi_pci_link_get_possible"); ACPI_FUNCTION_TRACE("acpi_pci_link_check_possible");
if (!link)
return_VALUE(-EINVAL);
status = acpi_get_possible_resources(link->handle, &buffer);
if (ACPI_FAILURE(status) || !buffer.pointer) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PRS\n"));
result = -ENODEV;
goto end;
}
resource = (struct acpi_resource *) buffer.pointer;
/* skip past dependent function resource (if present) */
if (resource->id == ACPI_RSTYPE_START_DPF)
resource = ACPI_NEXT_RESOURCE(resource);
switch (resource->id) { switch (resource->id) {
case ACPI_RSTYPE_START_DPF:
return AE_OK;
case ACPI_RSTYPE_IRQ: case ACPI_RSTYPE_IRQ:
{ {
struct acpi_resource_irq *p = &resource->data.irq; struct acpi_resource_irq *p = &resource->data.irq;
if (!p || !p->number_of_interrupts) { if (!p || !p->number_of_interrupts) {
ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Blank IRQ resource\n")); ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Blank IRQ resource\n"));
result = -ENODEV; return AE_OK;
goto end;
} }
for (i = 0; (i<p->number_of_interrupts && i<ACPI_PCI_LINK_MAX_POSSIBLE); i++) { for (i = 0; (i<p->number_of_interrupts && i<ACPI_PCI_LINK_MAX_POSSIBLE); i++) {
if (!p->interrupts[i]) { if (!p->interrupts[i]) {
...@@ -143,8 +126,7 @@ acpi_pci_link_get_possible ( ...@@ -143,8 +126,7 @@ acpi_pci_link_get_possible (
if (!p || !p->number_of_interrupts) { if (!p || !p->number_of_interrupts) {
ACPI_DEBUG_PRINT((ACPI_DB_WARN, ACPI_DEBUG_PRINT((ACPI_DB_WARN,
"Blank IRQ resource\n")); "Blank IRQ resource\n"));
result = -ENODEV; return AE_OK;
goto end;
} }
for (i = 0; (i<p->number_of_interrupts && i<ACPI_PCI_LINK_MAX_POSSIBLE); i++) { for (i = 0; (i<p->number_of_interrupts && i<ACPI_PCI_LINK_MAX_POSSIBLE); i++) {
if (!p->interrupts[i]) { if (!p->interrupts[i]) {
...@@ -159,18 +141,76 @@ acpi_pci_link_get_possible ( ...@@ -159,18 +141,76 @@ acpi_pci_link_get_possible (
default: default:
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
"Resource is not an IRQ entry\n")); "Resource is not an IRQ entry\n"));
result = -ENODEV; return AE_OK;
goto end;
break;
} }
return AE_CTRL_TERMINATE;
}
static int
acpi_pci_link_get_possible (
struct acpi_pci_link *link)
{
acpi_status status;
ACPI_FUNCTION_TRACE("acpi_pci_link_get_possible");
if (!link)
return_VALUE(-EINVAL);
status = acpi_walk_resources(link->handle, METHOD_NAME__PRS,
acpi_pci_link_check_possible, link);
if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PRS\n"));
return_VALUE(-ENODEV);
}
ACPI_DEBUG_PRINT((ACPI_DB_INFO, ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Found %d possible IRQs\n", link->irq.possible_count)); "Found %d possible IRQs\n", link->irq.possible_count));
end: return_VALUE(0);
acpi_os_free(buffer.pointer); }
return_VALUE(result);
static acpi_status
acpi_pci_link_check_current (
struct acpi_resource *resource,
void *context)
{
int *irq = (int *) context;
ACPI_FUNCTION_TRACE("acpi_pci_link_check_current");
switch (resource->id) {
case ACPI_RSTYPE_IRQ:
{
struct acpi_resource_irq *p = &resource->data.irq;
if (!p || !p->number_of_interrupts) {
ACPI_DEBUG_PRINT((ACPI_DB_WARN,
"Blank IRQ resource\n"));
return AE_OK;
}
*irq = p->interrupts[0];
break;
}
case ACPI_RSTYPE_EXT_IRQ:
{
struct acpi_resource_ext_irq *p = &resource->data.extended_irq;
if (!p || !p->number_of_interrupts) {
ACPI_DEBUG_PRINT((ACPI_DB_WARN,
"Blank IRQ resource\n"));
return AE_OK;
}
*irq = p->interrupts[0];
break;
}
default:
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
"Resource isn't an IRQ\n"));
return AE_OK;
}
return AE_CTRL_TERMINATE;
} }
...@@ -180,8 +220,6 @@ acpi_pci_link_get_current ( ...@@ -180,8 +220,6 @@ acpi_pci_link_get_current (
{ {
int result = 0; int result = 0;
acpi_status status = AE_OK; acpi_status status = AE_OK;
struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
struct acpi_resource *resource = NULL;
int irq = 0; int irq = 0;
ACPI_FUNCTION_TRACE("acpi_pci_link_get_current"); ACPI_FUNCTION_TRACE("acpi_pci_link_get_current");
...@@ -206,47 +244,16 @@ acpi_pci_link_get_current ( ...@@ -206,47 +244,16 @@ acpi_pci_link_get_current (
* Query and parse _CRS to get the current IRQ assignment. * Query and parse _CRS to get the current IRQ assignment.
*/ */
status = acpi_get_current_resources(link->handle, &buffer); status = acpi_walk_resources(link->handle, METHOD_NAME__CRS,
acpi_pci_link_check_current, &irq);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _CRS\n")); ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _CRS\n"));
result = -ENODEV; result = -ENODEV;
goto end; goto end;
} }
resource = (struct acpi_resource *) buffer.pointer;
switch (resource->id) {
case ACPI_RSTYPE_IRQ:
{
struct acpi_resource_irq *p = &resource->data.irq;
if (!p || !p->number_of_interrupts) {
ACPI_DEBUG_PRINT((ACPI_DB_WARN,
"Blank IRQ resource\n"));
result = -ENODEV;
goto end;
}
irq = p->interrupts[0];
break;
}
case ACPI_RSTYPE_EXT_IRQ:
{
struct acpi_resource_ext_irq *p = &resource->data.extended_irq;
if (!p || !p->number_of_interrupts) {
ACPI_DEBUG_PRINT((ACPI_DB_WARN,
"Blank IRQ resource\n"));
result = -ENODEV;
goto end;
}
irq = p->interrupts[0];
break;
}
default:
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Resource isn't an IRQ\n"));
result = -ENODEV;
goto end;
}
if (!irq) { if (!irq) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid use of IRQ 0\n")); ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "No IRQ resource found\n"));
result = -ENODEV; result = -ENODEV;
goto end; goto end;
} }
...@@ -263,8 +270,6 @@ acpi_pci_link_get_current ( ...@@ -263,8 +270,6 @@ acpi_pci_link_get_current (
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Link at IRQ %d \n", link->irq.active)); ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Link at IRQ %d \n", link->irq.active));
end: end:
acpi_os_free(buffer.pointer);
return_VALUE(result); return_VALUE(result);
} }
......
...@@ -1560,7 +1560,7 @@ acpi_processor_get_info ( ...@@ -1560,7 +1560,7 @@ acpi_processor_get_info (
acpi_status status = 0; acpi_status status = 0;
union acpi_object object = {0}; union acpi_object object = {0};
struct acpi_buffer buffer = {sizeof(union acpi_object), &object}; struct acpi_buffer buffer = {sizeof(union acpi_object), &object};
static int cpu_count = 0; static int cpu_index = 0;
ACPI_FUNCTION_TRACE("acpi_processor_get_info"); ACPI_FUNCTION_TRACE("acpi_processor_get_info");
...@@ -1570,6 +1570,13 @@ acpi_processor_get_info ( ...@@ -1570,6 +1570,13 @@ acpi_processor_get_info (
if (num_online_cpus() > 1) if (num_online_cpus() > 1)
errata.smp = TRUE; errata.smp = TRUE;
/*
* Extra Processor objects may be enumerated on MP systems with
* less than the max # of CPUs. They should be ignored.
*/
if ((cpu_index + 1) > num_online_cpus())
return_VALUE(-ENODEV);
acpi_processor_errata(pr); acpi_processor_errata(pr);
/* /*
...@@ -1601,7 +1608,7 @@ acpi_processor_get_info ( ...@@ -1601,7 +1608,7 @@ acpi_processor_get_info (
* TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP. * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP.
* >>> 'acpi_get_processor_id(acpi_id, &id)' in arch/xxx/acpi.c * >>> 'acpi_get_processor_id(acpi_id, &id)' in arch/xxx/acpi.c
*/ */
pr->id = cpu_count++; pr->id = cpu_index++;
pr->acpi_id = object.processor.proc_id; pr->acpi_id = object.processor.proc_id;
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Processor [%d:%d]\n", pr->id, ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Processor [%d:%d]\n", pr->id,
...@@ -1609,21 +1616,17 @@ acpi_processor_get_info ( ...@@ -1609,21 +1616,17 @@ acpi_processor_get_info (
if (!object.processor.pblk_address) if (!object.processor.pblk_address)
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No PBLK (NULL address)\n")); ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No PBLK (NULL address)\n"));
else if (object.processor.pblk_length < 4) else if (object.processor.pblk_length != 6)
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid PBLK length [%d]\n", ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid PBLK length [%d]\n",
object.processor.pblk_length)); object.processor.pblk_length));
else { else {
pr->throttling.address = object.processor.pblk_address; pr->throttling.address = object.processor.pblk_address;
pr->throttling.duty_offset = acpi_fadt.duty_offset; pr->throttling.duty_offset = acpi_fadt.duty_offset;
pr->throttling.duty_width = acpi_fadt.duty_width; pr->throttling.duty_width = acpi_fadt.duty_width;
pr->power.states[ACPI_STATE_C2].address =
if (object.processor.pblk_length >= 5) object.processor.pblk_address + 4;
pr->power.states[ACPI_STATE_C2].address = pr->power.states[ACPI_STATE_C3].address =
object.processor.pblk_address + 4; object.processor.pblk_address + 5;
if (object.processor.pblk_length >= 6)
pr->power.states[ACPI_STATE_C3].address =
object.processor.pblk_address + 5;
} }
acpi_processor_get_power_info(pr); acpi_processor_get_power_info(pr);
......
...@@ -212,6 +212,60 @@ acpi_rs_get_prs_method_data ( ...@@ -212,6 +212,60 @@ acpi_rs_get_prs_method_data (
} }
/*******************************************************************************
*
* FUNCTION: acpi_rs_get_method_data
*
* PARAMETERS: Handle - a handle to the containing object
* ret_buffer - a pointer to a buffer structure for the
* results
*
* RETURN: Status
*
* DESCRIPTION: This function is called to get the _CRS or _PRS value of an
* object contained in an object specified by the handle passed in
*
* If the function fails an appropriate status will be returned
* and the contents of the callers buffer is undefined.
*
******************************************************************************/
acpi_status
acpi_rs_get_method_data (
acpi_handle handle,
char *path,
struct acpi_buffer *ret_buffer)
{
union acpi_operand_object *obj_desc;
acpi_status status;
ACPI_FUNCTION_TRACE ("rs_get_method_data");
/* Parameters guaranteed valid by caller */
/*
* Execute the method, no parameters
*/
status = acpi_ut_evaluate_object (handle, path, ACPI_BTYPE_BUFFER, &obj_desc);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
/*
* Make the call to create a resource linked list from the
* byte stream buffer that comes back from the method
* execution.
*/
status = acpi_rs_create_resource_list (obj_desc, ret_buffer);
/* On exit, we must delete the object returned by evaluate_object */
acpi_ut_remove_reference (obj_desc);
return_ACPI_STATUS (status);
}
/******************************************************************************* /*******************************************************************************
* *
* FUNCTION: acpi_rs_set_srs_method_data * FUNCTION: acpi_rs_set_srs_method_data
......
...@@ -210,6 +210,90 @@ acpi_get_possible_resources ( ...@@ -210,6 +210,90 @@ acpi_get_possible_resources (
} }
/*******************************************************************************
*
* FUNCTION: acpi_walk_resources
*
* PARAMETERS: device_handle - a handle to the device object for the
* device we are querying
* Path - method name of the resources we want
* (METHOD_NAME__CRS or METHOD_NAME__PRS)
* user_function - called for each resource
* Context - passed to user_function
*
* RETURN: Status
*
* DESCRIPTION: Retrieves the current or possible resource list for the
* specified device. The user_function is called once for
* each resource in the list.
*
******************************************************************************/
acpi_status
acpi_walk_resources (
acpi_handle device_handle,
char *path,
ACPI_WALK_RESOURCE_CALLBACK user_function,
void *context)
{
acpi_status status;
struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
struct acpi_resource *resource;
ACPI_FUNCTION_TRACE ("acpi_walk_resources");
if (!device_handle ||
(ACPI_STRNCMP (path, METHOD_NAME__CRS, sizeof (METHOD_NAME__CRS)) &&
ACPI_STRNCMP (path, METHOD_NAME__PRS, sizeof (METHOD_NAME__PRS)))) {
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
status = acpi_rs_get_method_data (device_handle, path, &buffer);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
resource = (struct acpi_resource *) buffer.pointer;
for (;;) {
if (!resource || resource->id == ACPI_RSTYPE_END_TAG) {
break;
}
status = user_function (resource, context);
switch (status) {
case AE_OK:
case AE_CTRL_DEPTH:
/* Just keep going */
status = AE_OK;
break;
case AE_CTRL_TERMINATE:
/* Exit now, with OK stats */
status = AE_OK;
goto cleanup;
default:
/* All others are valid exceptions */
goto cleanup;
}
resource = ACPI_NEXT_RESOURCE (resource);
}
cleanup:
acpi_os_free (buffer.pointer);
return_ACPI_STATUS (status);
}
/******************************************************************************* /*******************************************************************************
* *
* FUNCTION: acpi_set_current_resources * FUNCTION: acpi_set_current_resources
...@@ -252,3 +336,64 @@ acpi_set_current_resources ( ...@@ -252,3 +336,64 @@ acpi_set_current_resources (
status = acpi_rs_set_srs_method_data (device_handle, in_buffer); status = acpi_rs_set_srs_method_data (device_handle, in_buffer);
return_ACPI_STATUS (status); return_ACPI_STATUS (status);
} }
#define COPY_FIELD(out, in, field) out->field = in->field
#define COPY_ADDRESS(out, in) \
COPY_FIELD(out, in, resource_type); \
COPY_FIELD(out, in, producer_consumer); \
COPY_FIELD(out, in, decode); \
COPY_FIELD(out, in, min_address_fixed); \
COPY_FIELD(out, in, max_address_fixed); \
COPY_FIELD(out, in, attribute); \
COPY_FIELD(out, in, granularity); \
COPY_FIELD(out, in, min_address_range); \
COPY_FIELD(out, in, max_address_range); \
COPY_FIELD(out, in, address_translation_offset); \
COPY_FIELD(out, in, address_length); \
COPY_FIELD(out, in, resource_source);
/*******************************************************************************
*
* FUNCTION: acpi_resource_to_address64
*
* PARAMETERS: resource - Pointer to a resource
* out - Pointer to the users's return
* buffer (a struct
* struct acpi_resource_address64)
*
* RETURN: Status
*
* DESCRIPTION: If the resource is an address16, address32, or address64,
* copy it to the address64 return buffer. This saves the
* caller from having to duplicate code for different-sized
* addresses.
*
******************************************************************************/
acpi_status
acpi_resource_to_address64 (
struct acpi_resource *resource,
struct acpi_resource_address64 *out)
{
struct acpi_resource_address16 *address16;
struct acpi_resource_address32 *address32;
struct acpi_resource_address64 *address64;
switch (resource->id) {
case ACPI_RSTYPE_ADDRESS16:
address16 = (struct acpi_resource_address16 *) &resource->data;
COPY_ADDRESS(out, address16);
break;
case ACPI_RSTYPE_ADDRESS32:
address32 = (struct acpi_resource_address32 *) &resource->data;
COPY_ADDRESS(out, address32);
break;
case ACPI_RSTYPE_ADDRESS64:
address64 = (struct acpi_resource_address64 *) &resource->data;
COPY_ADDRESS(out, address64);
break;
default:
return (AE_BAD_PARAMETER);
}
return (AE_OK);
}
...@@ -183,14 +183,21 @@ acpi_system_suspend( ...@@ -183,14 +183,21 @@ acpi_system_suspend(
status = acpi_enter_sleep_state(state); status = acpi_enter_sleep_state(state);
break; break;
case ACPI_STATE_S2:
#ifdef CONFIG_SOFTWARE_SUSPEND #ifdef CONFIG_SOFTWARE_SUSPEND
case ACPI_STATE_S2:
case ACPI_STATE_S3: case ACPI_STATE_S3:
do_suspend_lowlevel(0); do_suspend_lowlevel(0);
break;
#endif #endif
case ACPI_STATE_S4:
do_suspend_lowlevel_s4bios(0);
break;
default:
printk(KERN_WARNING PREFIX "don't know how to handle %d state.\n", state);
break; break;
} }
local_irq_restore(flags); local_irq_restore(flags);
printk(KERN_CRIT "Back to C!\n");
return status; return status;
} }
...@@ -211,21 +218,31 @@ acpi_suspend ( ...@@ -211,21 +218,31 @@ acpi_suspend (
if (state < ACPI_STATE_S1 || state > ACPI_STATE_S5) if (state < ACPI_STATE_S1 || state > ACPI_STATE_S5)
return AE_ERROR; return AE_ERROR;
/* Since we handle S4OS via a different path (swsusp), give up if no s4bios. */
if (state == ACPI_STATE_S4 && !acpi_gbl_FACS->S4bios_f)
return AE_ERROR;
/*
* TBD: S1 can be done without device_suspend. Make a CONFIG_XX
* to handle however when S1 failed without device_suspend.
*/
freeze_processes(); /* device_suspend needs processes to be stopped */ freeze_processes(); /* device_suspend needs processes to be stopped */
/* do we have a wakeup address for S2 and S3? */ /* do we have a wakeup address for S2 and S3? */
if (state == ACPI_STATE_S2 || state == ACPI_STATE_S3) { /* Here, we support only S4BIOS, those we set the wakeup address */
/* S4OS is only supported for now via swsusp.. */
if (state == ACPI_STATE_S2 || state == ACPI_STATE_S3 || ACPI_STATE_S4) {
if (!acpi_wakeup_address) if (!acpi_wakeup_address)
return AE_ERROR; return AE_ERROR;
acpi_set_firmware_waking_vector((acpi_physical_address) acpi_wakeup_address); acpi_set_firmware_waking_vector((acpi_physical_address) acpi_wakeup_address);
} }
acpi_enter_sleep_state_prep(state);
status = acpi_system_save_state(state); status = acpi_system_save_state(state);
if (!ACPI_SUCCESS(status)) if (!ACPI_SUCCESS(status))
return status; return status;
acpi_enter_sleep_state_prep(state);
/* disable interrupts and flush caches */ /* disable interrupts and flush caches */
ACPI_DISABLE_IRQS(); ACPI_DISABLE_IRQS();
ACPI_FLUSH_CPU_CACHE(); ACPI_FLUSH_CPU_CACHE();
...@@ -237,8 +254,8 @@ acpi_suspend ( ...@@ -237,8 +254,8 @@ acpi_suspend (
* mode. So, we run these unconditionaly to make sure we have a usable system * mode. So, we run these unconditionaly to make sure we have a usable system
* no matter what. * no matter what.
*/ */
acpi_system_restore_state(state);
acpi_leave_sleep_state(state); acpi_leave_sleep_state(state);
acpi_system_restore_state(state);
/* make sure interrupts are enabled */ /* make sure interrupts are enabled */
ACPI_ENABLE_IRQS(); ACPI_ENABLE_IRQS();
...@@ -268,6 +285,10 @@ static int __init acpi_sleep_init(void) ...@@ -268,6 +285,10 @@ static int __init acpi_sleep_init(void)
sleep_states[i] = 1; sleep_states[i] = 1;
printk(" S%d", i); printk(" S%d", i);
} }
if (i == ACPI_STATE_S4 && acpi_gbl_FACS->S4bios_f) {
sleep_states[i] = 1;
printk(" S4bios");
}
} }
printk(")\n"); printk(")\n");
......
...@@ -27,8 +27,11 @@ static int acpi_system_sleep_seq_show(struct seq_file *seq, void *offset) ...@@ -27,8 +27,11 @@ static int acpi_system_sleep_seq_show(struct seq_file *seq, void *offset)
ACPI_FUNCTION_TRACE("acpi_system_sleep_seq_show"); ACPI_FUNCTION_TRACE("acpi_system_sleep_seq_show");
for (i = 0; i <= ACPI_STATE_S5; i++) { for (i = 0; i <= ACPI_STATE_S5; i++) {
if (sleep_states[i]) if (sleep_states[i]) {
seq_printf(seq,"S%d ", i); seq_printf(seq,"S%d ", i);
if (i == ACPI_STATE_S4 && acpi_gbl_FACS->S4bios_f)
seq_printf(seq, "S4bios ");
}
} }
seq_puts(seq, "\n"); seq_puts(seq, "\n");
......
...@@ -379,6 +379,7 @@ acpi_table_get_sdt ( ...@@ -379,6 +379,7 @@ acpi_table_get_sdt (
sdt.pa = ((struct acpi20_table_rsdp*)rsdp)->xsdt_address; sdt.pa = ((struct acpi20_table_rsdp*)rsdp)->xsdt_address;
/* map in just the header */
header = (struct acpi_table_header *) header = (struct acpi_table_header *)
__acpi_map_table(sdt.pa, sizeof(struct acpi_table_header)); __acpi_map_table(sdt.pa, sizeof(struct acpi_table_header));
...@@ -387,6 +388,15 @@ acpi_table_get_sdt ( ...@@ -387,6 +388,15 @@ acpi_table_get_sdt (
return -ENODEV; return -ENODEV;
} }
/* remap in the entire table before processing */
mapped_xsdt = (struct acpi_table_xsdt *)
__acpi_map_table(sdt.pa, header->length);
if (!mapped_xsdt) {
printk(KERN_WARNING PREFIX "Unable to map XSDT\n");
return -ENODEV;
}
header = &mapped_xsdt->header;
if (strncmp(header->signature, "XSDT", 4)) { if (strncmp(header->signature, "XSDT", 4)) {
printk(KERN_WARNING PREFIX "XSDT signature incorrect\n"); printk(KERN_WARNING PREFIX "XSDT signature incorrect\n");
return -ENODEV; return -ENODEV;
...@@ -404,15 +414,6 @@ acpi_table_get_sdt ( ...@@ -404,15 +414,6 @@ acpi_table_get_sdt (
sdt.count = ACPI_MAX_TABLES; sdt.count = ACPI_MAX_TABLES;
} }
mapped_xsdt = (struct acpi_table_xsdt *)
__acpi_map_table(sdt.pa, header->length);
if (!mapped_xsdt) {
printk(KERN_WARNING PREFIX "Unable to map XSDT\n");
return -ENODEV;
}
header = &mapped_xsdt->header;
for (i = 0; i < sdt.count; i++) for (i = 0; i < sdt.count; i++)
sdt.entry[i].pa = (unsigned long) mapped_xsdt->entry[i]; sdt.entry[i].pa = (unsigned long) mapped_xsdt->entry[i];
} }
...@@ -425,6 +426,7 @@ acpi_table_get_sdt ( ...@@ -425,6 +426,7 @@ acpi_table_get_sdt (
sdt.pa = rsdp->rsdt_address; sdt.pa = rsdp->rsdt_address;
/* map in just the header */
header = (struct acpi_table_header *) header = (struct acpi_table_header *)
__acpi_map_table(sdt.pa, sizeof(struct acpi_table_header)); __acpi_map_table(sdt.pa, sizeof(struct acpi_table_header));
if (!header) { if (!header) {
...@@ -432,6 +434,15 @@ acpi_table_get_sdt ( ...@@ -432,6 +434,15 @@ acpi_table_get_sdt (
return -ENODEV; return -ENODEV;
} }
/* remap in the entire table before processing */
mapped_rsdt = (struct acpi_table_rsdt *)
__acpi_map_table(sdt.pa, header->length);
if (!mapped_rsdt) {
printk(KERN_WARNING PREFIX "Unable to map RSDT\n");
return -ENODEV;
}
header = &mapped_rsdt->header;
if (strncmp(header->signature, "RSDT", 4)) { if (strncmp(header->signature, "RSDT", 4)) {
printk(KERN_WARNING PREFIX "RSDT signature incorrect\n"); printk(KERN_WARNING PREFIX "RSDT signature incorrect\n");
return -ENODEV; return -ENODEV;
...@@ -449,15 +460,6 @@ acpi_table_get_sdt ( ...@@ -449,15 +460,6 @@ acpi_table_get_sdt (
sdt.count = ACPI_MAX_TABLES; sdt.count = ACPI_MAX_TABLES;
} }
mapped_rsdt = (struct acpi_table_rsdt *)
__acpi_map_table(sdt.pa, header->length);
if (!mapped_rsdt) {
printk(KERN_WARNING PREFIX "Unable to map RSDT\n");
return -ENODEV;
}
header = &mapped_rsdt->header;
for (i = 0; i < sdt.count; i++) for (i = 0; i < sdt.count; i++)
sdt.entry[i].pa = (unsigned long) mapped_rsdt->entry[i]; sdt.entry[i].pa = (unsigned long) mapped_rsdt->entry[i];
} }
...@@ -471,12 +473,20 @@ acpi_table_get_sdt ( ...@@ -471,12 +473,20 @@ acpi_table_get_sdt (
for (i = 0; i < sdt.count; i++) { for (i = 0; i < sdt.count; i++) {
/* map in just the header */
header = (struct acpi_table_header *) header = (struct acpi_table_header *)
__acpi_map_table(sdt.entry[i].pa, __acpi_map_table(sdt.entry[i].pa,
sizeof(struct acpi_table_header)); sizeof(struct acpi_table_header));
if (!header) if (!header)
continue; continue;
/* remap in the entire table before processing */
header = (struct acpi_table_header *)
__acpi_map_table(sdt.entry[i].pa,
header->length);
if (!header)
continue;
acpi_table_print(header, sdt.entry[i].pa); acpi_table_print(header, sdt.entry[i].pa);
if (acpi_table_compute_checksum(header, header->length)) { if (acpi_table_compute_checksum(header, header->length)) {
......
...@@ -239,9 +239,8 @@ acpi_tb_convert_fadt1 ( ...@@ -239,9 +239,8 @@ acpi_tb_convert_fadt1 (
ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xpm1b_cnt_blk, local_fadt->pm1_cnt_len, local_fadt->V1_pm1b_cnt_blk); ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xpm1b_cnt_blk, local_fadt->pm1_cnt_len, local_fadt->V1_pm1b_cnt_blk);
ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xpm2_cnt_blk, local_fadt->pm2_cnt_len, local_fadt->V1_pm2_cnt_blk); ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xpm2_cnt_blk, local_fadt->pm2_cnt_len, local_fadt->V1_pm2_cnt_blk);
ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xpm_tmr_blk, local_fadt->pm_tm_len, local_fadt->V1_pm_tmr_blk); ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xpm_tmr_blk, local_fadt->pm_tm_len, local_fadt->V1_pm_tmr_blk);
ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xgpe0_blk, local_fadt->gpe0_blk_len, local_fadt->V1_gpe0_blk); ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xgpe0_blk, 0, local_fadt->V1_gpe0_blk);
ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xgpe1_blk, local_fadt->gpe1_blk_len, local_fadt->V1_gpe1_blk); ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xgpe1_blk, 0, local_fadt->V1_gpe1_blk);
} }
...@@ -314,15 +313,16 @@ acpi_tb_convert_fadt2 ( ...@@ -314,15 +313,16 @@ acpi_tb_convert_fadt2 (
if (!(local_fadt->xgpe0_blk.address)) { if (!(local_fadt->xgpe0_blk.address)) {
ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xgpe0_blk, ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xgpe0_blk,
local_fadt->gpe0_blk_len, local_fadt->V1_gpe0_blk); 0, local_fadt->V1_gpe0_blk);
} }
if (!(local_fadt->xgpe1_blk.address)) { if (!(local_fadt->xgpe1_blk.address)) {
ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xgpe1_blk, ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xgpe1_blk,
local_fadt->gpe1_blk_len, local_fadt->V1_gpe1_blk); 0, local_fadt->V1_gpe1_blk);
} }
} }
/******************************************************************************* /*******************************************************************************
* *
* FUNCTION: acpi_tb_convert_table_fadt * FUNCTION: acpi_tb_convert_table_fadt
......
...@@ -645,11 +645,11 @@ acpi_ut_copy_simple_object ( ...@@ -645,11 +645,11 @@ acpi_ut_copy_simple_object (
/* /*
* Allocate and copy the actual buffer if and only if: * Allocate and copy the actual buffer if and only if:
* 1) There is a valid buffer (length > 0) * 1) There is a valid buffer pointer
* 2) The buffer is not static (not in an ACPI table) (in this case, * 2) The buffer is not static (not in an ACPI table) (in this case,
* the actual pointer was already copied above) * the actual pointer was already copied above)
*/ */
if ((source_desc->buffer.length) && if ((source_desc->buffer.pointer) &&
(!(source_desc->common.flags & AOPOBJ_STATIC_POINTER))) { (!(source_desc->common.flags & AOPOBJ_STATIC_POINTER))) {
dest_desc->buffer.pointer = ACPI_MEM_ALLOCATE (source_desc->buffer.length); dest_desc->buffer.pointer = ACPI_MEM_ALLOCATE (source_desc->buffer.length);
if (!dest_desc->buffer.pointer) { if (!dest_desc->buffer.pointer) {
...@@ -665,11 +665,11 @@ acpi_ut_copy_simple_object ( ...@@ -665,11 +665,11 @@ acpi_ut_copy_simple_object (
/* /*
* Allocate and copy the actual string if and only if: * Allocate and copy the actual string if and only if:
* 1) There is a valid string (length > 0) * 1) There is a valid string pointer
* 2) The string is not static (not in an ACPI table) (in this case, * 2) The string is not static (not in an ACPI table) (in this case,
* the actual pointer was already copied above) * the actual pointer was already copied above)
*/ */
if ((source_desc->string.length) && if ((source_desc->string.pointer) &&
(!(source_desc->common.flags & AOPOBJ_STATIC_POINTER))) { (!(source_desc->common.flags & AOPOBJ_STATIC_POINTER))) {
dest_desc->string.pointer = ACPI_MEM_ALLOCATE ((acpi_size) source_desc->string.length + 1); dest_desc->string.pointer = ACPI_MEM_ALLOCATE ((acpi_size) source_desc->string.length + 1);
if (!dest_desc->string.pointer) { if (!dest_desc->string.pointer) {
......
...@@ -729,6 +729,10 @@ acpi_ut_init_globals ( ...@@ -729,6 +729,10 @@ acpi_ut_init_globals (
acpi_gbl_acpi_mutex_info[i].use_count = 0; acpi_gbl_acpi_mutex_info[i].use_count = 0;
} }
/* GPE support */
acpi_gbl_gpe_block_list_head = NULL;
/* Global notify handlers */ /* Global notify handlers */
acpi_gbl_sys_notify.handler = NULL; acpi_gbl_sys_notify.handler = NULL;
...@@ -766,8 +770,6 @@ acpi_ut_init_globals ( ...@@ -766,8 +770,6 @@ acpi_ut_init_globals (
/* Hardware oriented */ /* Hardware oriented */
acpi_gbl_gpe_register_info = NULL;
acpi_gbl_gpe_number_info = NULL;
acpi_gbl_events_initialized = FALSE; acpi_gbl_events_initialized = FALSE;
/* Namespace */ /* Namespace */
......
...@@ -229,136 +229,55 @@ static int detect_ejectable_slots (acpi_handle *bridge_handle) ...@@ -229,136 +229,55 @@ static int detect_ejectable_slots (acpi_handle *bridge_handle)
/* decode ACPI _CRS data and convert into our internal resource list /* decode ACPI _CRS data and convert into our internal resource list
* TBD: _TRA, etc. * TBD: _TRA, etc.
*/ */
static void static acpi_status
decode_acpi_resource (struct acpi_resource *resource, struct acpiphp_bridge *bridge) decode_acpi_resource (struct acpi_resource *resource, void *context)
{ {
struct acpi_resource_address16 *address16_data; struct acpiphp_bridge *bridge = (struct acpiphp_bridge *) context;
struct acpi_resource_address32 *address32_data; struct acpi_resource_address64 address;
struct acpi_resource_address64 *address64_data;
struct pci_resource *res; struct pci_resource *res;
u32 resource_type, producer_consumer, address_length; if (resource->id != ACPI_RSTYPE_ADDRESS16 &&
u64 min_address_range, max_address_range; resource->id != ACPI_RSTYPE_ADDRESS32 &&
u16 cache_attribute = 0; resource->id != ACPI_RSTYPE_ADDRESS64)
return AE_OK;
int done = 0, found;
/* shut up gcc */
resource_type = producer_consumer = address_length = 0;
min_address_range = max_address_range = 0;
while (!done) {
found = 0;
switch (resource->id) {
case ACPI_RSTYPE_ADDRESS16:
address16_data = (struct acpi_resource_address16 *)&resource->data;
resource_type = address16_data->resource_type;
producer_consumer = address16_data->producer_consumer;
min_address_range = address16_data->min_address_range;
max_address_range = address16_data->max_address_range;
address_length = address16_data->address_length;
if (resource_type == ACPI_MEMORY_RANGE)
cache_attribute = address16_data->attribute.memory.cache_attribute;
found = 1;
break;
case ACPI_RSTYPE_ADDRESS32: acpi_resource_to_address64(resource, &address);
address32_data = (struct acpi_resource_address32 *)&resource->data;
resource_type = address32_data->resource_type;
producer_consumer = address32_data->producer_consumer;
min_address_range = address32_data->min_address_range;
max_address_range = address32_data->max_address_range;
address_length = address32_data->address_length;
if (resource_type == ACPI_MEMORY_RANGE)
cache_attribute = address32_data->attribute.memory.cache_attribute;
found = 1;
break;
case ACPI_RSTYPE_ADDRESS64: if (address.producer_consumer == ACPI_PRODUCER && address.address_length > 0) {
address64_data = (struct acpi_resource_address64 *)&resource->data; dbg("resource type: %d: 0x%llx - 0x%llx\n", address.resource_type, address.min_address_range, address.max_address_range);
resource_type = address64_data->resource_type; res = acpiphp_make_resource(address.min_address_range,
producer_consumer = address64_data->producer_consumer; address.address_length);
min_address_range = address64_data->min_address_range; if (!res) {
max_address_range = address64_data->max_address_range; err("out of memory\n");
address_length = address64_data->address_length; return AE_OK;
if (resource_type == ACPI_MEMORY_RANGE) }
cache_attribute = address64_data->attribute.memory.cache_attribute;
found = 1;
break;
case ACPI_RSTYPE_END_TAG: switch (address.resource_type) {
done = 1; case ACPI_MEMORY_RANGE:
if (address.attribute.memory.cache_attribute == ACPI_PREFETCHABLE_MEMORY) {
res->next = bridge->p_mem_head;
bridge->p_mem_head = res;
} else {
res->next = bridge->mem_head;
bridge->mem_head = res;
}
break;
case ACPI_IO_RANGE:
res->next = bridge->io_head;
bridge->io_head = res;
break;
case ACPI_BUS_NUMBER_RANGE:
res->next = bridge->bus_head;
bridge->bus_head = res;
break; break;
default: default:
/* ignore */ /* invalid type */
kfree(res);
break; break;
} }
resource = (struct acpi_resource *)((char*)resource + resource->length);
if (found && producer_consumer == ACPI_PRODUCER && address_length > 0) {
switch (resource_type) {
case ACPI_MEMORY_RANGE:
if (cache_attribute == ACPI_PREFETCHABLE_MEMORY) {
dbg("resource type: prefetchable memory 0x%x - 0x%x\n", (u32)min_address_range, (u32)max_address_range);
res = acpiphp_make_resource(min_address_range,
address_length);
if (!res) {
err("out of memory\n");
return;
}
res->next = bridge->p_mem_head;
bridge->p_mem_head = res;
} else {
dbg("resource type: memory 0x%x - 0x%x\n", (u32)min_address_range, (u32)max_address_range);
res = acpiphp_make_resource(min_address_range,
address_length);
if (!res) {
err("out of memory\n");
return;
}
res->next = bridge->mem_head;
bridge->mem_head = res;
}
break;
case ACPI_IO_RANGE:
dbg("resource type: io 0x%x - 0x%x\n", (u32)min_address_range, (u32)max_address_range);
res = acpiphp_make_resource(min_address_range,
address_length);
if (!res) {
err("out of memory\n");
return;
}
res->next = bridge->io_head;
bridge->io_head = res;
break;
case ACPI_BUS_NUMBER_RANGE:
dbg("resource type: bus number %d - %d\n", (u32)min_address_range, (u32)max_address_range);
res = acpiphp_make_resource(min_address_range,
address_length);
if (!res) {
err("out of memory\n");
return;
}
res->next = bridge->bus_head;
bridge->bus_head = res;
break;
default:
/* invalid type */
break;
}
}
} }
acpiphp_resource_sort_and_combine(&bridge->io_head); return AE_OK;
acpiphp_resource_sort_and_combine(&bridge->mem_head);
acpiphp_resource_sort_and_combine(&bridge->p_mem_head);
acpiphp_resource_sort_and_combine(&bridge->bus_head);
dbg("ACPI _CRS resource:\n");
acpiphp_dump_resource(bridge);
} }
...@@ -476,9 +395,6 @@ static void init_bridge_misc (struct acpiphp_bridge *bridge) ...@@ -476,9 +395,6 @@ static void init_bridge_misc (struct acpiphp_bridge *bridge)
static void add_host_bridge (acpi_handle *handle, int seg, int bus) static void add_host_bridge (acpi_handle *handle, int seg, int bus)
{ {
acpi_status status; acpi_status status;
struct acpi_buffer buffer = { .length = ACPI_ALLOCATE_BUFFER,
.pointer = NULL};
struct acpiphp_bridge *bridge; struct acpiphp_bridge *bridge;
bridge = kmalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL); bridge = kmalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL);
...@@ -501,7 +417,8 @@ static void add_host_bridge (acpi_handle *handle, int seg, int bus) ...@@ -501,7 +417,8 @@ static void add_host_bridge (acpi_handle *handle, int seg, int bus)
/* decode resources */ /* decode resources */
status = acpi_get_current_resources(handle, &buffer); status = acpi_walk_resources(handle, METHOD_NAME__CRS,
decode_acpi_resource, bridge);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
err("failed to decode bridge resources\n"); err("failed to decode bridge resources\n");
...@@ -509,8 +426,13 @@ static void add_host_bridge (acpi_handle *handle, int seg, int bus) ...@@ -509,8 +426,13 @@ static void add_host_bridge (acpi_handle *handle, int seg, int bus)
return; return;
} }
decode_acpi_resource(buffer.pointer, bridge); acpiphp_resource_sort_and_combine(&bridge->io_head);
kfree(buffer.pointer); acpiphp_resource_sort_and_combine(&bridge->mem_head);
acpiphp_resource_sort_and_combine(&bridge->p_mem_head);
acpiphp_resource_sort_and_combine(&bridge->bus_head);
dbg("ACPI _CRS resource:\n");
acpiphp_dump_resource(bridge);
if (bridge->bus_head) { if (bridge->bus_head) {
bridge->bus = bridge->bus_head->base; bridge->bus = bridge->bus_head->base;
......
...@@ -72,7 +72,7 @@ ...@@ -72,7 +72,7 @@
/* Version string */ /* Version string */
#define ACPI_CA_VERSION 0x20030122 #define ACPI_CA_VERSION 0x20030228
/* Version of ACPI supported */ /* Version of ACPI supported */
......
...@@ -176,6 +176,9 @@ void ...@@ -176,6 +176,9 @@ void
acpi_db_display_resources ( acpi_db_display_resources (
char *object_arg); char *object_arg);
void
acpi_db_display_gpes (void);
void void
acpi_db_check_integrity ( acpi_db_check_integrity (
void); void);
...@@ -208,6 +211,10 @@ acpi_db_walk_for_specific_objects ( ...@@ -208,6 +211,10 @@ acpi_db_walk_for_specific_objects (
void *context, void *context,
void **return_value); void **return_value);
void
acpi_db_generate_gpe (
char *gpe_arg,
char *block_arg);
/* /*
* dbdisply - debug display commands * dbdisply - debug display commands
......
...@@ -91,14 +91,6 @@ acpi_status ...@@ -91,14 +91,6 @@ acpi_status
acpi_ev_init_global_lock_handler ( acpi_ev_init_global_lock_handler (
void); void);
struct acpi_gpe_register_info *
acpi_ev_get_gpe_register_info (
u32 gpe_number);
struct acpi_gpe_number_info *
acpi_ev_get_gpe_number_info (
u32 gpe_number);
u32 u32
acpi_ev_get_gpe_number_index ( acpi_ev_get_gpe_number_index (
u32 gpe_number); u32 gpe_number);
...@@ -117,17 +109,17 @@ acpi_ev_notify_dispatch ( ...@@ -117,17 +109,17 @@ acpi_ev_notify_dispatch (
* Evgpe - GPE handling and dispatch * Evgpe - GPE handling and dispatch
*/ */
acpi_status struct acpi_gpe_event_info *
acpi_ev_gpe_initialize ( acpi_ev_get_gpe_event_info (
void); u32 gpe_number);
acpi_status acpi_status
acpi_ev_init_gpe_control_methods ( acpi_ev_gpe_initialize (
void); void);
u32 u32
acpi_ev_gpe_dispatch ( acpi_ev_gpe_dispatch (
u32 gpe_number); struct acpi_gpe_event_info *gpe_event_info);
u32 u32
acpi_ev_gpe_detect ( acpi_ev_gpe_detect (
......
...@@ -234,22 +234,7 @@ ACPI_EXTERN u8 acpi_gbl_sleep_type_b; ...@@ -234,22 +234,7 @@ ACPI_EXTERN u8 acpi_gbl_sleep_type_b;
extern struct acpi_fixed_event_info acpi_gbl_fixed_event_info[ACPI_NUM_FIXED_EVENTS]; extern struct acpi_fixed_event_info acpi_gbl_fixed_event_info[ACPI_NUM_FIXED_EVENTS];
ACPI_EXTERN struct acpi_fixed_event_handler acpi_gbl_fixed_event_handlers[ACPI_NUM_FIXED_EVENTS]; ACPI_EXTERN struct acpi_fixed_event_handler acpi_gbl_fixed_event_handlers[ACPI_NUM_FIXED_EVENTS];
ACPI_EXTERN struct acpi_gpe_block_info *acpi_gbl_gpe_block_list_head;
ACPI_EXTERN acpi_handle acpi_gbl_gpe_obj_handle;
ACPI_EXTERN u32 acpi_gbl_gpe_register_count;
ACPI_EXTERN u32 acpi_gbl_gpe_number_max;
ACPI_EXTERN struct acpi_gpe_register_info *acpi_gbl_gpe_register_info;
ACPI_EXTERN struct acpi_gpe_number_info *acpi_gbl_gpe_number_info;
ACPI_EXTERN struct acpi_gpe_block_info acpi_gbl_gpe_block_info[ACPI_MAX_GPE_BLOCKS];
/*
* GPE translation table
* Indexed by the GPE number, returns a valid index into the global GPE tables.
*
* This table is needed because the GPE numbers supported by block 1 do not
* have to be contiguous with the GPE numbers supported by block 0.
*/
ACPI_EXTERN struct acpi_gpe_index_info *acpi_gbl_gpe_number_to_index;
/***************************************************************************** /*****************************************************************************
......
...@@ -115,29 +115,25 @@ acpi_hw_clear_acpi_status ( ...@@ -115,29 +115,25 @@ acpi_hw_clear_acpi_status (
/* GPE support */ /* GPE support */
u8
acpi_hw_get_gpe_bit_mask (
u32 gpe_number);
acpi_status acpi_status
acpi_hw_enable_gpe ( acpi_hw_enable_gpe (
u32 gpe_number); struct acpi_gpe_event_info *gpe_event_info);
void void
acpi_hw_enable_gpe_for_wakeup ( acpi_hw_enable_gpe_for_wakeup (
u32 gpe_number); struct acpi_gpe_event_info *gpe_event_info);
acpi_status acpi_status
acpi_hw_disable_gpe ( acpi_hw_disable_gpe (
u32 gpe_number); struct acpi_gpe_event_info *gpe_event_info);
void void
acpi_hw_disable_gpe_for_wakeup ( acpi_hw_disable_gpe_for_wakeup (
u32 gpe_number); struct acpi_gpe_event_info *gpe_event_info);
acpi_status acpi_status
acpi_hw_clear_gpe ( acpi_hw_clear_gpe (
u32 gpe_number); struct acpi_gpe_event_info *gpe_event_info);
acpi_status acpi_status
acpi_hw_get_gpe_status ( acpi_hw_get_gpe_status (
......
...@@ -308,25 +308,28 @@ struct acpi_create_field_info ...@@ -308,25 +308,28 @@ struct acpi_create_field_info
* *
****************************************************************************/ ****************************************************************************/
/* Information about each GPE register block */ /* Information about each particular GPE level */
struct acpi_gpe_block_info struct acpi_gpe_event_info
{ {
struct acpi_generic_address *block_address; struct acpi_namespace_node *method_node; /* Method node for this GPE level */
u16 register_count; acpi_gpe_handler handler; /* Address of handler, if any */
u8 block_base_number; void *context; /* Context to be passed to handler */
struct acpi_gpe_register_info *register_info;
u8 type; /* Level or Edge */
u8 bit_mask;
}; };
/* Information about a particular GPE register pair */ /* Information about a particular GPE register pair */
struct acpi_gpe_register_info struct acpi_gpe_register_info
{ {
struct acpi_generic_address status_address; /* Address of status reg */ struct acpi_generic_address status_address; /* Address of status reg */
struct acpi_generic_address enable_address; /* Address of enable reg */ struct acpi_generic_address enable_address; /* Address of enable reg */
u8 status; /* Current value of status reg */ u8 status; /* Current value of status reg */
u8 enable; /* Current value of enable reg */ u8 enable; /* Current value of enable reg */
u8 wake_enable; /* Mask of bits to keep enabled when sleeping */ u8 wake_enable; /* Mask of bits to keep enabled when sleeping */
u8 base_gpe_number; /* Base GPE number for this register */ u8 base_gpe_number; /* Base GPE number for this register */
}; };
...@@ -334,23 +337,21 @@ struct acpi_gpe_register_info ...@@ -334,23 +337,21 @@ struct acpi_gpe_register_info
#define ACPI_GPE_EDGE_TRIGGERED 2 #define ACPI_GPE_EDGE_TRIGGERED 2
/* Information about each particular GPE level */ /* Information about each GPE register block */
struct acpi_gpe_number_info struct acpi_gpe_block_info
{ {
struct acpi_namespace_node *method_node; /* Method node for this GPE level */ struct acpi_gpe_block_info *previous;
acpi_gpe_handler handler; /* Address of handler, if any */ struct acpi_gpe_block_info *next;
void *context; /* Context to be passed to handler */ struct acpi_gpe_block_info *next_on_interrupt;
u8 type; /* Level or Edge */ struct acpi_gpe_register_info *register_info;
u8 bit_mask; struct acpi_gpe_event_info *event_info;
struct acpi_generic_address block_address;
u32 register_count;
u8 block_base_number;
}; };
struct acpi_gpe_index_info
{
u8 number_index;
};
/* Information about each particular fixed event */ /* Information about each particular fixed event */
struct acpi_fixed_event_handler struct acpi_fixed_event_handler
......
...@@ -339,6 +339,12 @@ acpi_get_event_status ( ...@@ -339,6 +339,12 @@ acpi_get_event_status (
* Resource interfaces * Resource interfaces
*/ */
typedef
acpi_status (*ACPI_WALK_RESOURCE_CALLBACK) (
struct acpi_resource *resource,
void *context);
acpi_status acpi_status
acpi_get_current_resources( acpi_get_current_resources(
acpi_handle device_handle, acpi_handle device_handle,
...@@ -349,6 +355,13 @@ acpi_get_possible_resources( ...@@ -349,6 +355,13 @@ acpi_get_possible_resources(
acpi_handle device_handle, acpi_handle device_handle,
struct acpi_buffer *ret_buffer); struct acpi_buffer *ret_buffer);
acpi_status
acpi_walk_resources (
acpi_handle device_handle,
char *path,
ACPI_WALK_RESOURCE_CALLBACK user_function,
void *context);
acpi_status acpi_status
acpi_set_current_resources ( acpi_set_current_resources (
acpi_handle device_handle, acpi_handle device_handle,
...@@ -359,6 +372,10 @@ acpi_get_irq_routing_table ( ...@@ -359,6 +372,10 @@ acpi_get_irq_routing_table (
acpi_handle bus_device_handle, acpi_handle bus_device_handle,
struct acpi_buffer *ret_buffer); struct acpi_buffer *ret_buffer);
acpi_status
acpi_resource_to_address64 (
struct acpi_resource *resource,
struct acpi_resource_address64 *out);
/* /*
* Hardware (ACPI device) interfaces * Hardware (ACPI device) interfaces
...@@ -398,6 +415,10 @@ acpi_status ...@@ -398,6 +415,10 @@ acpi_status
acpi_enter_sleep_state ( acpi_enter_sleep_state (
u8 sleep_state); u8 sleep_state);
acpi_status
acpi_enter_sleep_state_s4bios (
void);
acpi_status acpi_status
acpi_leave_sleep_state ( acpi_leave_sleep_state (
u8 sleep_state); u8 sleep_state);
......
...@@ -65,6 +65,12 @@ acpi_rs_get_prs_method_data ( ...@@ -65,6 +65,12 @@ acpi_rs_get_prs_method_data (
acpi_handle handle, acpi_handle handle,
struct acpi_buffer *ret_buffer); struct acpi_buffer *ret_buffer);
acpi_status
acpi_rs_get_method_data (
acpi_handle handle,
char *path,
struct acpi_buffer *ret_buffer);
acpi_status acpi_status
acpi_rs_set_srs_method_data ( acpi_rs_set_srs_method_data (
acpi_handle handle, acpi_handle handle,
......
...@@ -463,6 +463,8 @@ acpi_ut_delete_internal_object_list ( ...@@ -463,6 +463,8 @@ acpi_ut_delete_internal_object_list (
#define METHOD_NAME__SEG "_SEG" #define METHOD_NAME__SEG "_SEG"
#define METHOD_NAME__BBN "_BBN" #define METHOD_NAME__BBN "_BBN"
#define METHOD_NAME__PRT "_PRT" #define METHOD_NAME__PRT "_PRT"
#define METHOD_NAME__CRS "_CRS"
#define METHOD_NAME__PRS "_PRS"
acpi_status acpi_status
......
...@@ -73,6 +73,7 @@ extern void do_magic_suspend_2(void); ...@@ -73,6 +73,7 @@ extern void do_magic_suspend_2(void);
/* Communication between acpi and arch/i386/suspend.c */ /* Communication between acpi and arch/i386/suspend.c */
extern void do_suspend_lowlevel(int resume); extern void do_suspend_lowlevel(int resume);
extern void do_suspend_lowlevel_s4bios(int resume);
#else #else
static inline void software_suspend(void) static inline void software_suspend(void)
......
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