ACPICA: Global event handler
The global event handler is called whenever a general purpose or fixed ACPI event occurs. Also update Linux OSL to collect events counter with global event handler. Signed-off-by: Lin Ming <ming.m.lin@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
This commit is contained in:
@@ -146,6 +146,9 @@ u8 acpi_gbl_system_awake_and_running;
|
|||||||
|
|
||||||
extern u32 acpi_gbl_nesting_level;
|
extern u32 acpi_gbl_nesting_level;
|
||||||
|
|
||||||
|
ACPI_EXTERN u32 acpi_gpe_count;
|
||||||
|
ACPI_EXTERN u32 acpi_fixed_event_count[ACPI_NUM_FIXED_EVENTS];
|
||||||
|
|
||||||
/* Support for dynamic control method tracing mechanism */
|
/* Support for dynamic control method tracing mechanism */
|
||||||
|
|
||||||
ACPI_EXTERN u32 acpi_gbl_original_dbg_level;
|
ACPI_EXTERN u32 acpi_gbl_original_dbg_level;
|
||||||
@@ -371,6 +374,8 @@ ACPI_EXTERN struct acpi_gpe_xrupt_info *acpi_gbl_gpe_xrupt_list_head;
|
|||||||
ACPI_EXTERN struct acpi_gpe_block_info
|
ACPI_EXTERN struct acpi_gpe_block_info
|
||||||
*acpi_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS];
|
*acpi_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS];
|
||||||
ACPI_EXTERN u8 acpi_gbl_all_gpes_initialized;
|
ACPI_EXTERN u8 acpi_gbl_all_gpes_initialized;
|
||||||
|
ACPI_EXTERN ACPI_GBL_EVENT_HANDLER acpi_gbl_global_event_handler;
|
||||||
|
ACPI_EXTERN void *acpi_gbl_global_event_handler_context;
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
*
|
*
|
||||||
|
@@ -217,9 +217,17 @@ u32 acpi_ev_fixed_event_detect(void)
|
|||||||
status_bit_mask)
|
status_bit_mask)
|
||||||
&& (fixed_enable & acpi_gbl_fixed_event_info[i].
|
&& (fixed_enable & acpi_gbl_fixed_event_info[i].
|
||||||
enable_bit_mask)) {
|
enable_bit_mask)) {
|
||||||
|
/*
|
||||||
|
* Found an active (signalled) event. Invoke global event
|
||||||
|
* handler if present.
|
||||||
|
*/
|
||||||
|
acpi_fixed_event_count[i]++;
|
||||||
|
if (acpi_gbl_global_event_handler) {
|
||||||
|
acpi_gbl_global_event_handler
|
||||||
|
(ACPI_EVENT_TYPE_FIXED, NULL, i,
|
||||||
|
acpi_gbl_global_event_handler_context);
|
||||||
|
}
|
||||||
|
|
||||||
/* Found an active (signalled) event */
|
|
||||||
acpi_os_fixed_event_count(i);
|
|
||||||
int_status |= acpi_ev_fixed_event_dispatch(i);
|
int_status |= acpi_ev_fixed_event_dispatch(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -642,7 +642,14 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device,
|
|||||||
|
|
||||||
ACPI_FUNCTION_TRACE(ev_gpe_dispatch);
|
ACPI_FUNCTION_TRACE(ev_gpe_dispatch);
|
||||||
|
|
||||||
acpi_os_gpe_count(gpe_number);
|
/* Invoke global event handler if present */
|
||||||
|
|
||||||
|
acpi_gpe_count++;
|
||||||
|
if (acpi_gbl_global_event_handler) {
|
||||||
|
acpi_gbl_global_event_handler(ACPI_EVENT_TYPE_GPE, gpe_device,
|
||||||
|
gpe_number,
|
||||||
|
acpi_gbl_global_event_handler_context);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If edge-triggered, clear the GPE status bit now. Note that
|
* If edge-triggered, clear the GPE status bit now. Note that
|
||||||
|
@@ -92,6 +92,57 @@ acpi_status acpi_install_exception_handler(acpi_exception_handler handler)
|
|||||||
|
|
||||||
ACPI_EXPORT_SYMBOL(acpi_install_exception_handler)
|
ACPI_EXPORT_SYMBOL(acpi_install_exception_handler)
|
||||||
#endif /* ACPI_FUTURE_USAGE */
|
#endif /* ACPI_FUTURE_USAGE */
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* FUNCTION: acpi_install_global_event_handler
|
||||||
|
*
|
||||||
|
* PARAMETERS: Handler - Pointer to the global event handler function
|
||||||
|
* Context - Value passed to the handler on each event
|
||||||
|
*
|
||||||
|
* RETURN: Status
|
||||||
|
*
|
||||||
|
* DESCRIPTION: Saves the pointer to the handler function. The global handler
|
||||||
|
* is invoked upon each incoming GPE and Fixed Event. It is
|
||||||
|
* invoked at interrupt level at the time of the event dispatch.
|
||||||
|
* Can be used to update event counters, etc.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
acpi_status
|
||||||
|
acpi_install_global_event_handler(ACPI_GBL_EVENT_HANDLER handler, void *context)
|
||||||
|
{
|
||||||
|
acpi_status status;
|
||||||
|
|
||||||
|
ACPI_FUNCTION_TRACE(acpi_install_global_event_handler);
|
||||||
|
|
||||||
|
/* Parameter validation */
|
||||||
|
|
||||||
|
if (!handler) {
|
||||||
|
return_ACPI_STATUS(AE_BAD_PARAMETER);
|
||||||
|
}
|
||||||
|
|
||||||
|
status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
|
||||||
|
if (ACPI_FAILURE(status)) {
|
||||||
|
return_ACPI_STATUS(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Don't allow two handlers. */
|
||||||
|
|
||||||
|
if (acpi_gbl_global_event_handler) {
|
||||||
|
status = AE_ALREADY_EXISTS;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
acpi_gbl_global_event_handler = handler;
|
||||||
|
acpi_gbl_global_event_handler_context = context;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
|
||||||
|
return_ACPI_STATUS(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
ACPI_EXPORT_SYMBOL(acpi_install_global_event_handler)
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
*
|
*
|
||||||
* FUNCTION: acpi_install_fixed_event_handler
|
* FUNCTION: acpi_install_fixed_event_handler
|
||||||
|
@@ -778,6 +778,7 @@ acpi_status acpi_ut_init_globals(void)
|
|||||||
acpi_gbl_init_handler = NULL;
|
acpi_gbl_init_handler = NULL;
|
||||||
acpi_gbl_table_handler = NULL;
|
acpi_gbl_table_handler = NULL;
|
||||||
acpi_gbl_interface_handler = NULL;
|
acpi_gbl_interface_handler = NULL;
|
||||||
|
acpi_gbl_global_event_handler = NULL;
|
||||||
|
|
||||||
/* Global Lock support */
|
/* Global Lock support */
|
||||||
|
|
||||||
|
@@ -438,7 +438,7 @@ static void delete_gpe_attr_array(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void acpi_os_gpe_count(u32 gpe_number)
|
static void gpe_count(u32 gpe_number)
|
||||||
{
|
{
|
||||||
acpi_gpe_count++;
|
acpi_gpe_count++;
|
||||||
|
|
||||||
@@ -454,7 +454,7 @@ void acpi_os_gpe_count(u32 gpe_number)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void acpi_os_fixed_event_count(u32 event_number)
|
static void fixed_event_count(u32 event_number)
|
||||||
{
|
{
|
||||||
if (!all_counters)
|
if (!all_counters)
|
||||||
return;
|
return;
|
||||||
@@ -468,6 +468,16 @@ void acpi_os_fixed_event_count(u32 event_number)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void acpi_gbl_event_handler(u32 event_type, acpi_handle device,
|
||||||
|
u32 event_number, void *context)
|
||||||
|
{
|
||||||
|
if (event_type == ACPI_EVENT_TYPE_GPE)
|
||||||
|
gpe_count(event_number);
|
||||||
|
|
||||||
|
if (event_type == ACPI_EVENT_TYPE_FIXED)
|
||||||
|
fixed_event_count(event_number);
|
||||||
|
}
|
||||||
|
|
||||||
static int get_status(u32 index, acpi_event_status *status,
|
static int get_status(u32 index, acpi_event_status *status,
|
||||||
acpi_handle *handle)
|
acpi_handle *handle)
|
||||||
{
|
{
|
||||||
@@ -601,6 +611,7 @@ end:
|
|||||||
|
|
||||||
void acpi_irq_stats_init(void)
|
void acpi_irq_stats_init(void)
|
||||||
{
|
{
|
||||||
|
acpi_status status;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (all_counters)
|
if (all_counters)
|
||||||
@@ -619,6 +630,10 @@ void acpi_irq_stats_init(void)
|
|||||||
if (all_counters == NULL)
|
if (all_counters == NULL)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
status = acpi_install_global_event_handler(acpi_gbl_event_handler, NULL);
|
||||||
|
if (ACPI_FAILURE(status))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
counter_attrs = kzalloc(sizeof(struct kobj_attribute) * (num_counters),
|
counter_attrs = kzalloc(sizeof(struct kobj_attribute) * (num_counters),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (counter_attrs == NULL)
|
if (counter_attrs == NULL)
|
||||||
|
@@ -228,6 +228,10 @@ acpi_status acpi_get_parent(acpi_handle object, acpi_handle * out_handle);
|
|||||||
acpi_status
|
acpi_status
|
||||||
acpi_install_initialization_handler(acpi_init_handler handler, u32 function);
|
acpi_install_initialization_handler(acpi_init_handler handler, u32 function);
|
||||||
|
|
||||||
|
acpi_status
|
||||||
|
acpi_install_global_event_handler(ACPI_GBL_EVENT_HANDLER handler,
|
||||||
|
void *context);
|
||||||
|
|
||||||
acpi_status
|
acpi_status
|
||||||
acpi_install_fixed_event_handler(u32 acpi_event,
|
acpi_install_fixed_event_handler(u32 acpi_event,
|
||||||
acpi_event_handler handler, void *context);
|
acpi_event_handler handler, void *context);
|
||||||
|
@@ -895,6 +895,14 @@ typedef void
|
|||||||
/*
|
/*
|
||||||
* Various handlers and callback procedures
|
* Various handlers and callback procedures
|
||||||
*/
|
*/
|
||||||
|
typedef
|
||||||
|
void (*ACPI_GBL_EVENT_HANDLER) (u32 event_type,
|
||||||
|
acpi_handle device,
|
||||||
|
u32 event_number, void *context);
|
||||||
|
|
||||||
|
#define ACPI_EVENT_TYPE_GPE 0
|
||||||
|
#define ACPI_EVENT_TYPE_FIXED 1
|
||||||
|
|
||||||
typedef u32(*acpi_event_handler) (void *context);
|
typedef u32(*acpi_event_handler) (void *context);
|
||||||
|
|
||||||
typedef
|
typedef
|
||||||
|
Reference in New Issue
Block a user