Commit 09199f7e authored by Andy Grover's avatar Andy Grover

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

into groveronline.com:/root/bk/linux-acpi
parents cc4b0bcd 72de792b
......@@ -28,6 +28,7 @@
#include <linux/acpi.h>
#include <asm/pgalloc.h>
#include <asm/apic.h>
#include <asm/io.h>
#include <asm/mpspec.h>
#if defined (CONFIG_X86_LOCAL_APIC)
......
......@@ -132,7 +132,7 @@ config ACPI_THERMAL
may be damaged without it.
config ACPI_NUMA
bool "NUMA support" if NUMA && (IA64 && !IA64_HP_SIM || X86 && ACPI && !ACPI_HT_ONLY)
bool "NUMA support" if NUMA && (IA64 && !IA64_HP_SIM || X86 && ACPI && !ACPI_HT_ONLY && !X86_64)
default y if IA64 && IA64_SGI_SN
config ACPI_TOSHIBA
......
......@@ -378,7 +378,7 @@ acpi_ec_gpe_query (
acpi_evaluate_object(ec->handle, object_name, NULL, NULL);
end:
acpi_enable_event(ec->gpe_bit, ACPI_EVENT_GPE, 0);
acpi_enable_gpe(NULL, ec->gpe_bit, 0);
}
static void
......@@ -391,7 +391,7 @@ acpi_ec_gpe_handler (
if (!ec)
return;
acpi_disable_event(ec->gpe_bit, ACPI_EVENT_GPE, 0);
acpi_disable_gpe(NULL, ec->gpe_bit, 0);
status = acpi_os_queue_for_execution(OSD_PRIORITY_GPE,
acpi_ec_gpe_query, ec);
......@@ -589,12 +589,13 @@ acpi_ec_add (
acpi_remove_address_space_handler(ACPI_ROOT_OBJECT,
ACPI_ADR_SPACE_EC, &acpi_ec_space_handler);
acpi_remove_gpe_handler(ec_ecdt->gpe_bit, &acpi_ec_gpe_handler);
acpi_remove_gpe_handler(NULL, ec_ecdt->gpe_bit, &acpi_ec_gpe_handler);
kfree(ec_ecdt);
}
/* Get GPE bit assignment (EC events). */
/* TODO: Add support for _GPE returning a package */
status = acpi_evaluate_integer(ec->handle, "_GPE", NULL, &ec->gpe_bit);
if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
......@@ -714,7 +715,7 @@ acpi_ec_start (
/*
* Install GPE handler
*/
status = acpi_install_gpe_handler(ec->gpe_bit,
status = acpi_install_gpe_handler(NULL, ec->gpe_bit,
ACPI_EVENT_EDGE_TRIGGERED, &acpi_ec_gpe_handler, ec);
if (ACPI_FAILURE(status)) {
return_VALUE(-ENODEV);
......@@ -724,7 +725,7 @@ acpi_ec_start (
ACPI_ADR_SPACE_EC, &acpi_ec_space_handler,
&acpi_ec_space_setup, ec);
if (ACPI_FAILURE(status)) {
acpi_remove_gpe_handler(ec->gpe_bit, &acpi_ec_gpe_handler);
acpi_remove_gpe_handler(NULL, ec->gpe_bit, &acpi_ec_gpe_handler);
return_VALUE(-ENODEV);
}
......@@ -752,7 +753,7 @@ acpi_ec_stop (
if (ACPI_FAILURE(status))
return_VALUE(-ENODEV);
status = acpi_remove_gpe_handler(ec->gpe_bit, &acpi_ec_gpe_handler);
status = acpi_remove_gpe_handler(NULL, ec->gpe_bit, &acpi_ec_gpe_handler);
if (ACPI_FAILURE(status))
return_VALUE(-ENODEV);
......@@ -798,7 +799,7 @@ acpi_ec_ecdt_probe (void)
/*
* Install GPE handler
*/
status = acpi_install_gpe_handler(ec_ecdt->gpe_bit,
status = acpi_install_gpe_handler(NULL, ec_ecdt->gpe_bit,
ACPI_EVENT_EDGE_TRIGGERED, &acpi_ec_gpe_handler,
ec_ecdt);
if (ACPI_FAILURE(status)) {
......@@ -809,7 +810,7 @@ acpi_ec_ecdt_probe (void)
ACPI_ADR_SPACE_EC, &acpi_ec_space_handler,
&acpi_ec_space_setup, ec_ecdt);
if (ACPI_FAILURE(status)) {
acpi_remove_gpe_handler(ec_ecdt->gpe_bit,
acpi_remove_gpe_handler(NULL, ec_ecdt->gpe_bit,
&acpi_ec_gpe_handler);
goto error;
}
......
......@@ -78,9 +78,9 @@ acpi_ev_initialize (
}
/*
* Initialize the Fixed and General Purpose acpi_events prior. This is
* done prior to enabling SCIs to prevent interrupts from occurring
* before handers are installed.
* Initialize the Fixed and General Purpose Events. This is
* done prior to enabling SCIs to prevent interrupts from
* occurring before handers are installed.
*/
status = acpi_ev_fixed_event_initialize ();
if (ACPI_FAILURE (status)) {
......@@ -225,7 +225,7 @@ acpi_ev_fixed_event_detect (
(void) acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_ENABLE, &fixed_enable);
ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS,
"Fixed acpi_event Block: Enable %08X Status %08X\n",
"Fixed Event Block: Enable %08X Status %08X\n",
fixed_enable, fixed_status));
/*
......@@ -282,7 +282,7 @@ acpi_ev_fixed_event_dispatch (
0, ACPI_MTX_DO_NOT_LOCK);
ACPI_REPORT_ERROR (
("ev_gpe_dispatch: No installed handler for fixed event [%08X]\n",
("No installed handler for fixed event [%08X]\n",
event));
return (ACPI_INTERRUPT_NOT_HANDLED);
......
This diff is collapsed.
This diff is collapsed.
......@@ -525,7 +525,8 @@ acpi_ev_terminate (void)
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;
struct acpi_gpe_xrupt_info *gpe_xrupt_info;
struct acpi_gpe_xrupt_info *next_gpe_xrupt_info;
ACPI_FUNCTION_TRACE ("ev_terminate");
......@@ -537,46 +538,29 @@ acpi_ev_terminate (void)
* In all cases, on error, print a message but obviously we don't abort.
*/
/*
* Disable all fixed events
*/
/* Disable all fixed events */
for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) {
status = acpi_disable_event ((u32) i, ACPI_EVENT_FIXED, 0);
status = acpi_disable_event ((u32) i, 0);
if (ACPI_FAILURE (status)) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not disable fixed event %d\n", (u32) i));
}
}
/*
* Disable all GPEs
*/
gpe_block = acpi_gbl_gpe_block_list_head;
while (gpe_block) {
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)) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not disable GPE %d\n", (u32) i));
}
gpe_event_info++;
}
/* Disable all GPEs in all GPE blocks */
gpe_block = gpe_block->next;
}
status = acpi_ev_walk_gpe_list (acpi_hw_disable_gpe_block);
/* Remove SCI handler */
/*
* Remove SCI handler
*/
status = acpi_ev_remove_sci_handler ();
if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not remove SCI handler\n"));
}
}
/*
* Return to original mode if necessary
*/
/* Return to original mode if necessary */
if (acpi_gbl_original_mode == ACPI_SYS_MODE_LEGACY) {
status = acpi_disable ();
if (ACPI_FAILURE (status)) {
......@@ -584,19 +568,23 @@ acpi_ev_terminate (void)
}
}
/*
* Free global GPE blocks and related info structures
*/
gpe_block = acpi_gbl_gpe_block_list_head;
while (gpe_block) {
next_gpe_block = gpe_block->next;
ACPI_MEM_FREE (gpe_block->event_info);
ACPI_MEM_FREE (gpe_block->register_info);
ACPI_MEM_FREE (gpe_block);
gpe_block = next_gpe_block;
}
/* Free global GPE blocks and related info structures */
gpe_xrupt_info = acpi_gbl_gpe_xrupt_list_head;
while (gpe_xrupt_info) {
gpe_block = gpe_xrupt_info->gpe_block_list_head;
while (gpe_block) {
next_gpe_block = gpe_block->next;
ACPI_MEM_FREE (gpe_block->event_info);
ACPI_MEM_FREE (gpe_block->register_info);
ACPI_MEM_FREE (gpe_block);
gpe_block = next_gpe_block;
}
next_gpe_xrupt_info = gpe_xrupt_info->next;
ACPI_MEM_FREE (gpe_xrupt_info);
gpe_xrupt_info = next_gpe_xrupt_info;
}
return_VOID;
}
......@@ -52,26 +52,26 @@
/*******************************************************************************
*
* FUNCTION: acpi_ev_sci_handler
* FUNCTION: acpi_ev_sci_xrupt_handler
*
* PARAMETERS: Context - Calling Context
*
* RETURN: Status code indicates whether interrupt was handled.
*
* DESCRIPTION: Interrupt handler that will figure out what function or
* control method to call to deal with a SCI. Installed
* using BU interrupt support.
* control method to call to deal with a SCI.
*
******************************************************************************/
static u32 ACPI_SYSTEM_XFACE
acpi_ev_sci_handler (
acpi_ev_sci_xrupt_handler (
void *context)
{
struct acpi_gpe_xrupt_info *gpe_xrupt_list = context;
u32 interrupt_handled = ACPI_INTERRUPT_NOT_HANDLED;
ACPI_FUNCTION_TRACE("ev_sci_handler");
ACPI_FUNCTION_TRACE("ev_sci_xrupt_handler");
/*
......@@ -85,11 +85,51 @@ acpi_ev_sci_handler (
*/
interrupt_handled |= acpi_ev_fixed_event_detect ();
/* TBD: What if there are no GPEs defined? */
/*
* GPEs:
* Check for and dispatch any GPEs that have occurred
*/
interrupt_handled |= acpi_ev_gpe_detect (gpe_xrupt_list);
return_VALUE (interrupt_handled);
}
/*******************************************************************************
*
* FUNCTION: acpi_ev_gpe_xrupt_handler
*
* PARAMETERS: Context - Calling Context
*
* RETURN: Status code indicates whether interrupt was handled.
*
* DESCRIPTION: Handler for GPE Block Device interrupts
*
******************************************************************************/
u32 ACPI_SYSTEM_XFACE
acpi_ev_gpe_xrupt_handler (
void *context)
{
struct acpi_gpe_xrupt_info *gpe_xrupt_list = context;
u32 interrupt_handled = ACPI_INTERRUPT_NOT_HANDLED;
ACPI_FUNCTION_TRACE("ev_gpe_xrupt_handler");
/*
* We are guaranteed by the ACPI CA initialization/shutdown code that
* if this interrupt handler is installed, ACPI is enabled.
*/
/*
* GPEs:
* Check for and dispatch any GPEs that have occurred
*/
interrupt_handled |= acpi_ev_gpe_detect ();
interrupt_handled |= acpi_ev_gpe_detect (gpe_xrupt_list);
return_VALUE (interrupt_handled);
}
......@@ -117,7 +157,7 @@ acpi_ev_install_sci_handler (void)
status = acpi_os_install_interrupt_handler ((u32) acpi_gbl_FADT->sci_int,
acpi_ev_sci_handler, NULL);
acpi_ev_sci_xrupt_handler, acpi_gbl_gpe_xrupt_list_head);
return_ACPI_STATUS (status);
}
......@@ -153,7 +193,7 @@ acpi_ev_remove_sci_handler (void)
/* Just let the OS remove the handler and disable the level */
status = acpi_os_remove_interrupt_handler ((u32) acpi_gbl_FADT->sci_int,
acpi_ev_sci_handler);
acpi_ev_sci_xrupt_handler);
return_ACPI_STATUS (status);
}
......
......@@ -102,7 +102,7 @@ acpi_install_fixed_event_handler (
acpi_gbl_fixed_event_handlers[event].handler = handler;
acpi_gbl_fixed_event_handlers[event].context = context;
status = acpi_enable_event (event, ACPI_EVENT_FIXED, 0);
status = acpi_enable_event (event, 0);
if (ACPI_FAILURE (status)) {
ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Could not enable fixed event.\n"));
......@@ -160,7 +160,7 @@ acpi_remove_fixed_event_handler (
/* Disable the event before removing the handler */
status = acpi_disable_event(event, ACPI_EVENT_FIXED, 0);
status = acpi_disable_event (event, 0);
/* Always Remove the handler */
......@@ -471,8 +471,8 @@ acpi_remove_notify_handler (
*
* FUNCTION: acpi_install_gpe_handler
*
* PARAMETERS: gpe_number - The GPE number. The numbering scheme is
* bank 0 first, then bank 1.
* PARAMETERS: gpe_number - The GPE number within the GPE block
* gpe_block - GPE block (NULL == FADT GPEs)
* Type - Whether this GPE should be treated as an
* edge- or level-triggered interrupt.
* Handler - Address of the handler
......@@ -486,6 +486,7 @@ acpi_remove_notify_handler (
acpi_status
acpi_install_gpe_handler (
acpi_handle gpe_device,
u32 gpe_number,
u32 type,
acpi_gpe_handler handler,
......@@ -504,42 +505,45 @@ acpi_install_gpe_handler (
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
/* Ensure that we have a valid GPE number */
gpe_event_info = acpi_ev_get_gpe_event_info (gpe_number);
if (!gpe_event_info) {
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
/* Ensure that we have a valid GPE number */
gpe_event_info = acpi_ev_get_gpe_event_info (gpe_device, gpe_number);
if (!gpe_event_info) {
status = AE_BAD_PARAMETER;
goto unlock_and_exit;
}
/* Make sure that there isn't a handler there already */
if (gpe_event_info->handler) {
status = AE_ALREADY_EXISTS;
goto cleanup;
goto unlock_and_exit;
}
/* Install the handler */
acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
gpe_event_info->handler = handler;
gpe_event_info->context = context;
gpe_event_info->type = (u8) type;
gpe_event_info->flags = (u8) type;
acpi_os_release_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
/* Clear the GPE (of stale events), the enable it */
status = acpi_hw_clear_gpe (gpe_event_info);
if (ACPI_FAILURE (status)) {
goto cleanup;
goto unlock_and_exit;
}
status = acpi_hw_enable_gpe (gpe_event_info);
cleanup:
unlock_and_exit:
(void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
return_ACPI_STATUS (status);
}
......@@ -550,6 +554,7 @@ acpi_install_gpe_handler (
* FUNCTION: acpi_remove_gpe_handler
*
* PARAMETERS: gpe_number - The event to remove a handler
* gpe_block - GPE block (NULL == FADT GPEs)
* Handler - Address of the handler
*
* RETURN: Status
......@@ -560,6 +565,7 @@ acpi_install_gpe_handler (
acpi_status
acpi_remove_gpe_handler (
acpi_handle gpe_device,
u32 gpe_number,
acpi_gpe_handler handler)
{
......@@ -576,23 +582,24 @@ acpi_remove_gpe_handler (
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
/* Ensure that we have a valid GPE number */
gpe_event_info = acpi_ev_get_gpe_event_info (gpe_number);
gpe_event_info = acpi_ev_get_gpe_event_info (gpe_device, gpe_number);
if (!gpe_event_info) {
return_ACPI_STATUS (AE_BAD_PARAMETER);
status = AE_BAD_PARAMETER;
goto unlock_and_exit;
}
/* Disable the GPE before removing the handler */
status = acpi_hw_disable_gpe (gpe_event_info);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
goto unlock_and_exit;
}
/* Make sure that the installed handler is the same */
......@@ -600,16 +607,18 @@ acpi_remove_gpe_handler (
if (gpe_event_info->handler != handler) {
(void) acpi_hw_enable_gpe (gpe_event_info);
status = AE_BAD_PARAMETER;
goto cleanup;
goto unlock_and_exit;
}
/* Remove the handler */
acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
gpe_event_info->handler = NULL;
gpe_event_info->context = NULL;
acpi_os_release_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
cleanup:
unlock_and_exit:
(void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
return_ACPI_STATUS (status);
}
......
This diff is collapsed.
......@@ -266,13 +266,12 @@ acpi_hw_clear_gpe (
acpi_status
acpi_hw_get_gpe_status (
u32 gpe_number,
struct acpi_gpe_event_info *gpe_event_info,
acpi_event_status *event_status)
{
u32 in_byte;
u8 bit_mask;
struct acpi_gpe_register_info *gpe_register_info;
struct acpi_gpe_event_info *gpe_event_info;
acpi_status status;
acpi_event_status local_event_status = 0;
......@@ -284,11 +283,6 @@ acpi_hw_get_gpe_status (
return (AE_BAD_PARAMETER);
}
gpe_event_info = acpi_ev_get_gpe_event_info (gpe_number);
if (!gpe_event_info) {
return (AE_BAD_PARAMETER);
}
/* Get the info block for the entire GPE register */
gpe_register_info = gpe_event_info->register_info;
......@@ -301,7 +295,7 @@ acpi_hw_get_gpe_status (
status = acpi_hw_low_level_read (8, &in_byte, &gpe_register_info->enable_address, 0);
if (ACPI_FAILURE (status)) {
return (status);
goto unlock_and_exit;
}
if (bit_mask & in_byte) {
......@@ -318,7 +312,7 @@ acpi_hw_get_gpe_status (
status = acpi_hw_low_level_read (8, &in_byte, &gpe_register_info->status_address, 0);
if (ACPI_FAILURE (status)) {
return (status);
goto unlock_and_exit;
}
if (bit_mask & in_byte) {
......@@ -328,6 +322,150 @@ acpi_hw_get_gpe_status (
/* Set return value */
(*event_status) = local_event_status;
unlock_and_exit:
return (status);
}
/******************************************************************************
*
* FUNCTION: acpi_hw_disable_gpe_block
*
* PARAMETERS: gpe_xrupt_info - GPE Interrupt info
* gpe_block - Gpe Block info
*
* RETURN: Status
*
* DESCRIPTION: Disable all GPEs within a GPE block
*
******************************************************************************/
acpi_status
acpi_hw_disable_gpe_block (
struct acpi_gpe_xrupt_info *gpe_xrupt_info,
struct acpi_gpe_block_info *gpe_block)
{
u32 i;
struct acpi_gpe_register_info *gpe_register_info;
acpi_status status;
/* Get the register info for the entire GPE block */
gpe_register_info = gpe_block->register_info;
/* Examine each GPE Register within the block */
for (i = 0; i < gpe_block->register_count; i++) {
status = acpi_hw_low_level_write (8, 0x00,
&gpe_block->register_info[i].enable_address, (u32) i);
if (ACPI_FAILURE (status)) {
return (status);
}
}
return (AE_OK);
}
/******************************************************************************
*
* FUNCTION: acpi_hw_clear_gpe_block
*
* PARAMETERS: gpe_xrupt_info - GPE Interrupt info
* gpe_block - Gpe Block info
*
* RETURN: Status
*
* DESCRIPTION: Clear all GPEs within a GPE block
*
******************************************************************************/
acpi_status
acpi_hw_clear_gpe_block (
struct acpi_gpe_xrupt_info *gpe_xrupt_info,
struct acpi_gpe_block_info *gpe_block)
{
u32 i;
struct acpi_gpe_register_info *gpe_register_info;
acpi_status status;
/* Get the register info for the entire GPE block */
gpe_register_info = gpe_block->register_info;
/* Examine each GPE Register within the block */
for (i = 0; i < gpe_block->register_count; i++) {
status = acpi_hw_low_level_write (8, 0xFF,
&gpe_block->register_info[i].status_address, (u32) i);
if (ACPI_FAILURE (status)) {
return (status);
}
}
return (AE_OK);
}
/******************************************************************************
*
* FUNCTION: acpi_hw_disable_non_wakeup_gpe_block
*
* PARAMETERS: gpe_xrupt_info - GPE Interrupt info
* gpe_block - Gpe Block info
*
* RETURN: Status
*
* DESCRIPTION: Disable all GPEs except wakeup GPEs in a GPE block
*
******************************************************************************/
acpi_status
acpi_hw_disable_non_wakeup_gpe_block (
struct acpi_gpe_xrupt_info *gpe_xrupt_info,
struct acpi_gpe_block_info *gpe_block)
{
u32 i;
struct acpi_gpe_register_info *gpe_register_info;
u32 in_value;
acpi_status status;
/* Get the register info for the entire GPE block */
gpe_register_info = gpe_block->register_info;
/* Examine each GPE Register within the block */
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.
*/
status = acpi_hw_low_level_read (8, &in_value,
&gpe_register_info->enable_address, 0);
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++;
}
return (AE_OK);
}
......@@ -341,7 +479,7 @@ acpi_hw_get_gpe_status (
* RETURN: None
*
* DESCRIPTION: Disable all non-wakeup GPEs
* Call with interrupts disabled. The interrupt handler also
* Called with interrupts disabled. The interrupt handler also
* modifies gpe_register_info->Enable, so it should not be
* given the chance to run until after non-wake GPEs are
* re-enabled.
......@@ -351,54 +489,65 @@ acpi_hw_get_gpe_status (
acpi_status
acpi_hw_disable_non_wakeup_gpes (
void)
{
acpi_status status;
ACPI_FUNCTION_ENTRY ();
status = acpi_ev_walk_gpe_list (acpi_hw_disable_non_wakeup_gpe_block);
return (status);
}
/******************************************************************************
*
* FUNCTION: acpi_hw_enable_non_wakeup_gpe_block
*
* PARAMETERS: gpe_xrupt_info - GPE Interrupt info
* gpe_block - Gpe Block info
*
* RETURN: Status
*
* DESCRIPTION: Enable a single GPE.
*
******************************************************************************/
acpi_status
acpi_hw_enable_non_wakeup_gpe_block (
struct acpi_gpe_xrupt_info *gpe_xrupt_info,
struct acpi_gpe_block_info *gpe_block)
{
u32 i;
struct acpi_gpe_register_info *gpe_register_info;
u32 in_value;
acpi_status status;
struct acpi_gpe_block_info *gpe_block;
ACPI_FUNCTION_ENTRY ();
/* This callback processes one entire GPE block */
/* Get the register info for the entire GPE block */
gpe_block = acpi_gbl_gpe_block_list_head;
while (gpe_block) {
/* Get the register info for the entire GPE block */
gpe_register_info = gpe_block->register_info;
gpe_register_info = gpe_block->register_info;
if (!gpe_register_info) {
return (AE_BAD_PARAMETER);
}
/* Examine each GPE register within the block */
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.
*/
status = acpi_hw_low_level_read (8, &in_value,
&gpe_register_info->enable_address, 0);
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++;
for (i = 0; i < gpe_block->register_count; i++) {
/*
* 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);
if (ACPI_FAILURE (status)) {
return (status);
}
gpe_block = gpe_block->next;
gpe_register_info++;
}
return (AE_OK);
}
......@@ -419,40 +568,13 @@ acpi_status
acpi_hw_enable_non_wakeup_gpes (
void)
{
u32 i;
struct acpi_gpe_register_info *gpe_register_info;
acpi_status status;
struct acpi_gpe_block_info *gpe_block;
ACPI_FUNCTION_ENTRY ();
gpe_block = acpi_gbl_gpe_block_list_head;
while (gpe_block) {
/* Get the register info for the entire GPE block */
status = acpi_ev_walk_gpe_list (acpi_hw_enable_non_wakeup_gpe_block);
gpe_register_info = gpe_block->register_info;
if (!gpe_register_info) {
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.
*/
status = acpi_hw_low_level_write (8, gpe_register_info->enable,
&gpe_register_info->enable_address, 0);
if (ACPI_FAILURE (status)) {
return (status);
}
gpe_register_info++;
}
gpe_block = gpe_block->next;
}
return (AE_OK);
return (status);
}
......@@ -46,6 +46,7 @@
#include <acpi/acpi.h>
#include <acpi/acnamesp.h>
#include <acpi/acevents.h>
#define _COMPONENT ACPI_HARDWARE
ACPI_MODULE_NAME ("hwregs")
......@@ -66,9 +67,7 @@
acpi_status
acpi_hw_clear_acpi_status (void)
{
acpi_native_uint i;
acpi_status status;
struct acpi_gpe_block_info *gpe_block;
ACPI_FUNCTION_TRACE ("hw_clear_acpi_status");
......@@ -102,18 +101,7 @@ acpi_hw_clear_acpi_status (void)
/* Clear the GPE Bits in all GPE registers in all GPE blocks */
gpe_block = acpi_gbl_gpe_block_list_head;
while (gpe_block) {
for (i = 0; i < gpe_block->register_count; i++) {
status = acpi_hw_low_level_write (8, 0xFF,
&gpe_block->register_info[i].status_address, (u32) i);
if (ACPI_FAILURE (status)) {
goto unlock_and_exit;
}
}
gpe_block = gpe_block->next;
}
status = acpi_ev_walk_gpe_list (acpi_hw_clear_gpe_block);
unlock_and_exit:
(void) acpi_ut_release_mutex (ACPI_MTX_HARDWARE);
......
......@@ -73,6 +73,7 @@ acpi_ns_root_initialize (void)
const struct acpi_predefined_names *init_val = NULL;
struct acpi_namespace_node *new_node;
union acpi_operand_object *obj_desc;
acpi_string val = NULL;
ACPI_FUNCTION_TRACE ("ns_root_initialize");
......@@ -119,9 +120,7 @@ acpi_ns_root_initialize (void)
* initial value, create the initial value.
*/
if (init_val->val) {
acpi_string val;
status = acpi_os_predefined_override(init_val, &val);
status = acpi_os_predefined_override (init_val, &val);
if (ACPI_FAILURE (status)) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not override predefined %s\n",
init_val->name));
......
......@@ -164,6 +164,7 @@ acpi_ns_walk_namespace (
void **return_value)
{
acpi_status status;
acpi_status mutex_status;
struct acpi_namespace_node *child_node;
struct acpi_namespace_node *parent_node;
acpi_object_type child_type;
......@@ -211,9 +212,9 @@ acpi_ns_walk_namespace (
* callback function
*/
if (unlock_before_callback) {
status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
mutex_status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
if (ACPI_FAILURE (mutex_status)) {
return_ACPI_STATUS (mutex_status);
}
}
......@@ -221,9 +222,9 @@ acpi_ns_walk_namespace (
context, return_value);
if (unlock_before_callback) {
status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
mutex_status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
if (ACPI_FAILURE (mutex_status)) {
return_ACPI_STATUS (mutex_status);
}
}
......
......@@ -581,24 +581,32 @@ acpi_os_derive_pci_id (
acpi_status
acpi_os_write_pci_configuration (
acpi_pci_id *pci_id,
u32 reg,
acpi_integer value,
u32 width)
struct acpi_pci_id *pci_id,
u32 reg,
acpi_integer value,
u32 width)
{
return (AE_SUPPORT);
}
acpi_status
acpi_os_read_pci_configuration (
acpi_pci_id *pci_id,
u32 reg,
void *value,
u32 width)
struct acpi_pci_id *pci_id,
u32 reg,
void *value,
u32 width)
{
return (AE_SUPPORT);
}
void
acpi_os_derive_pci_id (
acpi_handle rhandle, /* upper bound */
acpi_handle chandle, /* current node */
struct acpi_pci_id **id)
{
}
#endif /*CONFIG_ACPI_PCI*/
static void
......@@ -669,6 +677,92 @@ acpi_os_queue_for_execution(
return_ACPI_STATUS (status);
}
/*
* Allocate the memory for a spinlock and initialize it.
*/
acpi_status
acpi_os_create_lock (
acpi_handle *out_handle)
{
spinlock_t *lock_ptr;
ACPI_FUNCTION_TRACE ("os_create_lock");
lock_ptr = acpi_os_allocate(sizeof(spinlock_t));
spin_lock_init(lock_ptr);
ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Creating spinlock[%p].\n", lock_ptr));
*out_handle = lock_ptr;
return_ACPI_STATUS (AE_OK);
}
/*
* Deallocate the memory for a spinlock.
*/
void
acpi_os_delete_lock (
acpi_handle handle)
{
ACPI_FUNCTION_TRACE ("os_create_lock");
ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Deleting spinlock[%p].\n", handle));
acpi_os_free(handle);
return_VOID;
}
/*
* Acquire a spinlock.
*
* handle is a pointer to the spinlock_t.
* flags is *not* the result of save_flags - it is an ACPI-specific flag variable
* that indicates whether we are at interrupt level.
*/
void
acpi_os_acquire_lock (
acpi_handle handle,
u32 flags)
{
ACPI_FUNCTION_TRACE ("os_acquire_lock");
ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Acquiring spinlock[%p] from %s level\n", handle,
((flags & ACPI_NOT_ISR) ? "non-interrupt" : "interrupt")));
if (flags & ACPI_NOT_ISR)
ACPI_DISABLE_IRQS();
spin_lock(handle);
return_VOID;
}
/*
* Release a spinlock. See above.
*/
void
acpi_os_release_lock (
acpi_handle handle,
u32 flags)
{
ACPI_FUNCTION_TRACE ("os_release_lock");
ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Releasing spinlock[%p] from %s level\n", handle,
((flags & ACPI_NOT_ISR) ? "non-interrupt" : "interrupt")));
spin_unlock(handle);
if (flags & ACPI_NOT_ISR)
ACPI_ENABLE_IRQS();
return_VOID;
}
acpi_status
acpi_os_create_semaphore(
......
......@@ -639,7 +639,7 @@ acpi_processor_get_power_info (
/*
* C2 latency must be less than or equal to 100 microseconds.
*/
if (acpi_fadt.plvl2_lat >= ACPI_PROCESSOR_MAX_C2_LATENCY)
if (acpi_fadt.plvl2_lat > ACPI_PROCESSOR_MAX_C2_LATENCY)
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"C2 latency too large [%d]\n",
acpi_fadt.plvl2_lat));
......@@ -673,7 +673,7 @@ acpi_processor_get_power_info (
/*
* C3 latency must be less than or equal to 1000 microseconds.
*/
if (acpi_fadt.plvl3_lat >= ACPI_PROCESSOR_MAX_C3_LATENCY)
if (acpi_fadt.plvl3_lat > ACPI_PROCESSOR_MAX_C3_LATENCY)
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"C3 latency too large [%d]\n",
acpi_fadt.plvl3_lat));
......
......@@ -240,12 +240,13 @@ acpi_walk_resources (
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)))) {
ACPI_STRNCMP (path, METHOD_NAME__PRS, sizeof (METHOD_NAME__PRS)))) {
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
......@@ -290,10 +291,10 @@ acpi_walk_resources (
cleanup:
acpi_os_free (buffer.pointer);
return_ACPI_STATUS (status);
}
/*******************************************************************************
*
* FUNCTION: acpi_set_current_resources
......@@ -337,6 +338,7 @@ acpi_set_current_resources (
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); \
......@@ -352,48 +354,53 @@ acpi_set_current_resources (
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.
*
******************************************************************************/
/******************************************************************************
*
* 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 *resource,
struct acpi_resource_address64 *out)
{
struct acpi_resource_address16 *address16;
struct acpi_resource_address32 *address32;
struct acpi_resource_address64 *address64;
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);
}
......@@ -228,7 +228,7 @@ acpi_tb_get_required_tables (
* any SSDTs.
*/
for (i = 0; i < acpi_gbl_rsdt_table_count; i++) {
/* Get the table addresss from the common internal XSDT */
/* Get the table address from the common internal XSDT */
address.pointer.value = acpi_gbl_XSDT->table_offset_entry[i];
......
......@@ -731,7 +731,9 @@ acpi_ut_init_globals (
/* GPE support */
acpi_gbl_gpe_block_list_head = NULL;
acpi_gbl_gpe_xrupt_list_head = NULL;
acpi_gbl_gpe_fadt_blocks[0] = NULL;
acpi_gbl_gpe_fadt_blocks[1] = NULL;
/* Global notify handlers */
......
......@@ -556,6 +556,9 @@ acpi_ut_mutex_initialize (
}
}
status = acpi_os_create_lock (&acpi_gbl_gpe_lock);
return_ACPI_STATUS (AE_OK);
}
......@@ -589,6 +592,7 @@ acpi_ut_mutex_terminate (
(void) acpi_ut_delete_mutex (i);
}
(void) acpi_os_delete_lock (acpi_gbl_gpe_lock);
return_VOID;
}
......
......@@ -72,7 +72,7 @@
/* Version string */
#define ACPI_CA_VERSION 0x20030228
#define ACPI_CA_VERSION 0x20030321
/* Version of ACPI supported */
......
......@@ -109,8 +109,17 @@ acpi_ev_notify_dispatch (
* Evgpe - GPE handling and dispatch
*/
acpi_status
acpi_ev_walk_gpe_list (
ACPI_GPE_CALLBACK gpe_walk_callback);
u8
acpi_ev_valid_gpe_event (
struct acpi_gpe_event_info *gpe_event_info);
struct acpi_gpe_event_info *
acpi_ev_get_gpe_event_info (
acpi_handle gpe_device,
u32 gpe_number);
acpi_status
......@@ -119,11 +128,12 @@ acpi_ev_gpe_initialize (
u32
acpi_ev_gpe_dispatch (
struct acpi_gpe_event_info *gpe_event_info);
struct acpi_gpe_event_info *gpe_event_info,
u32 gpe_number);
u32
acpi_ev_gpe_detect (
void);
struct acpi_gpe_xrupt_info *gpe_xrupt_list);
/*
* Evregion - Address Space handling
......@@ -216,6 +226,10 @@ acpi_ev_initialize_region (
* Evsci - SCI (System Control Interrupt) handling/dispatch
*/
u32 ACPI_SYSTEM_XFACE
acpi_ev_gpe_xrupt_handler (
void *context);
u32
acpi_ev_install_sci_handler (
void);
......
......@@ -234,7 +234,9 @@ ACPI_EXTERN u8 acpi_gbl_sleep_type_b;
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_gpe_block_info *acpi_gbl_gpe_block_list_head;
ACPI_EXTERN struct acpi_gpe_xrupt_info *acpi_gbl_gpe_xrupt_list_head;
ACPI_EXTERN struct acpi_gpe_block_info *acpi_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS];
ACPI_EXTERN acpi_handle acpi_gbl_gpe_lock;
/*****************************************************************************
......
......@@ -127,6 +127,11 @@ acpi_status
acpi_hw_disable_gpe (
struct acpi_gpe_event_info *gpe_event_info);
acpi_status
acpi_hw_disable_gpe_block (
struct acpi_gpe_xrupt_info *gpe_xrupt_info,
struct acpi_gpe_block_info *gpe_block);
void
acpi_hw_disable_gpe_for_wakeup (
struct acpi_gpe_event_info *gpe_event_info);
......@@ -135,9 +140,14 @@ acpi_status
acpi_hw_clear_gpe (
struct acpi_gpe_event_info *gpe_event_info);
acpi_status
acpi_hw_clear_gpe_block (
struct acpi_gpe_xrupt_info *gpe_xrupt_info,
struct acpi_gpe_block_info *gpe_block);
acpi_status
acpi_hw_get_gpe_status (
u32 gpe_number,
struct acpi_gpe_event_info *gpe_event_info,
acpi_event_status *event_status);
acpi_status
......
......@@ -308,19 +308,19 @@ struct acpi_create_field_info
*
****************************************************************************/
/* Information about each particular GPE level */
/* Information about a GPE, one per each GPE in an array */
struct acpi_gpe_event_info
{
struct acpi_namespace_node *method_node; /* Method node for this GPE level */
acpi_gpe_handler handler; /* Address of handler, if any */
void *context; /* Context to be passed to handler */
struct acpi_gpe_register_info *register_info;
u8 type; /* Level or Edge */
u8 bit_mask;
struct acpi_gpe_register_info *register_info; /* Backpointer to register info */
u8 flags; /* Level or Edge */
u8 bit_mask; /* This GPE within the register */
};
/* Information about a particular GPE register pair */
/* Information about a GPE register pair, one per each status/enable pair in an array */
struct acpi_gpe_register_info
{
......@@ -332,25 +332,36 @@ struct acpi_gpe_register_info
u8 base_gpe_number; /* Base GPE number for this register */
};
#define ACPI_GPE_LEVEL_TRIGGERED 1
#define ACPI_GPE_EDGE_TRIGGERED 2
/* Information about each GPE register block */
/*
* Information about a GPE register block, one per each installed block --
* GPE0, GPE1, and one per each installed GPE Block Device.
*/
struct acpi_gpe_block_info
{
struct acpi_gpe_block_info *previous;
struct acpi_gpe_block_info *next;
struct acpi_gpe_block_info *next_on_interrupt;
struct acpi_gpe_register_info *register_info;
struct acpi_gpe_event_info *event_info;
struct acpi_generic_address block_address;
u32 register_count;
u8 block_base_number;
struct acpi_gpe_register_info *register_info; /* One per GPE register pair */
struct acpi_gpe_event_info *event_info; /* One for each GPE */
struct acpi_generic_address block_address; /* Base address of the block */
u32 register_count; /* Number of register pairs in block */
u8 block_base_number;/* Base GPE number for this block */
};
/* Information about GPE interrupt handlers, one per each interrupt level used for GPEs */
struct acpi_gpe_xrupt_info
{
struct acpi_gpe_xrupt_info *previous;
struct acpi_gpe_xrupt_info *next;
struct acpi_gpe_block_info *gpe_block_list_head; /* List of GPE blocks for this xrupt */
u32 interrupt_level; /* System interrupt level */
};
typedef acpi_status (*ACPI_GPE_CALLBACK) (
struct acpi_gpe_xrupt_info *gpe_xrupt_info,
struct acpi_gpe_block_info *gpe_block);
/* Information about each particular fixed event */
......@@ -360,7 +371,6 @@ struct acpi_fixed_event_handler
void *context; /* Context to be passed to handler */
};
struct acpi_fixed_event_info
{
u8 status_register_id;
......
......@@ -239,6 +239,7 @@ struct acpi_object_device
{
ACPI_OBJECT_COMMON_HEADER
ACPI_COMMON_NOTIFY_INFO
struct acpi_gpe_block_info *gpe_block;
};
......
......@@ -147,6 +147,27 @@ acpi_os_signal_semaphore (
acpi_handle handle,
u32 units);
acpi_status
acpi_os_create_lock (
acpi_handle *out_handle);
void
acpi_os_delete_lock (
acpi_handle handle);
void
acpi_os_acquire_lock (
acpi_handle handle,
u32 flags);
void
acpi_os_release_lock (
acpi_handle handle,
u32 flags);
#define ACPI_NOT_ISR 1
#define ACPI_ISR 0
/*
* Memory allocation and mapping
......
......@@ -293,6 +293,7 @@ acpi_remove_address_space_handler (
acpi_status
acpi_install_gpe_handler (
acpi_handle gpe_device,
u32 gpe_number,
u32 type,
acpi_gpe_handler handler,
......@@ -309,30 +310,50 @@ acpi_release_global_lock (
acpi_status
acpi_remove_gpe_handler (
acpi_handle gpe_device,
u32 gpe_number,
acpi_gpe_handler handler);
acpi_status
acpi_enable_event (
u32 acpi_event,
u32 type,
u32 event,
u32 flags);
acpi_status
acpi_disable_event (
u32 acpi_event,
u32 type,
u32 event,
u32 flags);
acpi_status
acpi_clear_event (
u32 acpi_event,
u32 type);
u32 event);
acpi_status
acpi_get_event_status (
u32 acpi_event,
u32 type,
u32 event,
acpi_event_status *event_status);
acpi_status
acpi_enable_gpe (
acpi_handle gpe_device,
u32 gpe_number,
u32 flags);
acpi_status
acpi_disable_gpe (
acpi_handle gpe_device,
u32 gpe_number,
u32 flags);
acpi_status
acpi_clear_gpe (
acpi_handle gpe_device,
u32 gpe_number);
acpi_status
acpi_get_gpe_status (
acpi_handle gpe_device,
u32 gpe_number,
acpi_event_status *event_status);
/*
......
......@@ -520,9 +520,6 @@ typedef u32 acpi_object_type;
*/
typedef u32 acpi_event_type;
#define ACPI_EVENT_FIXED 0
#define ACPI_EVENT_GPE 1
/*
* Fixed events
*/
......
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