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:
parent
bba63a296f
commit
a0fcdb237f
8 changed files with 104 additions and 5 deletions
|
@ -146,6 +146,9 @@ u8 acpi_gbl_system_awake_and_running;
|
|||
|
||||
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 */
|
||||
|
||||
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_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS];
|
||||
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)
|
||||
&& (fixed_enable & acpi_gbl_fixed_event_info[i].
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -642,7 +642,14 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device,
|
|||
|
||||
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
|
||||
|
|
|
@ -92,6 +92,57 @@ acpi_status acpi_install_exception_handler(acpi_exception_handler handler)
|
|||
|
||||
ACPI_EXPORT_SYMBOL(acpi_install_exception_handler)
|
||||
#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
|
||||
|
|
|
@ -778,6 +778,7 @@ acpi_status acpi_ut_init_globals(void)
|
|||
acpi_gbl_init_handler = NULL;
|
||||
acpi_gbl_table_handler = NULL;
|
||||
acpi_gbl_interface_handler = NULL;
|
||||
acpi_gbl_global_event_handler = NULL;
|
||||
|
||||
/* Global Lock support */
|
||||
|
||||
|
|
|
@ -438,7 +438,7 @@ static void delete_gpe_attr_array(void)
|
|||
return;
|
||||
}
|
||||
|
||||
void acpi_os_gpe_count(u32 gpe_number)
|
||||
static void gpe_count(u32 gpe_number)
|
||||
{
|
||||
acpi_gpe_count++;
|
||||
|
||||
|
@ -454,7 +454,7 @@ void acpi_os_gpe_count(u32 gpe_number)
|
|||
return;
|
||||
}
|
||||
|
||||
void acpi_os_fixed_event_count(u32 event_number)
|
||||
static void fixed_event_count(u32 event_number)
|
||||
{
|
||||
if (!all_counters)
|
||||
return;
|
||||
|
@ -468,6 +468,16 @@ void acpi_os_fixed_event_count(u32 event_number)
|
|||
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,
|
||||
acpi_handle *handle)
|
||||
{
|
||||
|
@ -601,6 +611,7 @@ static ssize_t counter_set(struct kobject *kobj,
|
|||
|
||||
void acpi_irq_stats_init(void)
|
||||
{
|
||||
acpi_status status;
|
||||
int i;
|
||||
|
||||
if (all_counters)
|
||||
|
@ -619,6 +630,10 @@ void acpi_irq_stats_init(void)
|
|||
if (all_counters == NULL)
|
||||
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),
|
||||
GFP_KERNEL);
|
||||
if (counter_attrs == NULL)
|
||||
|
|
|
@ -228,6 +228,10 @@ acpi_status acpi_get_parent(acpi_handle object, acpi_handle * out_handle);
|
|||
acpi_status
|
||||
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_install_fixed_event_handler(u32 acpi_event,
|
||||
acpi_event_handler handler, void *context);
|
||||
|
|
|
@ -895,6 +895,14 @@ typedef void
|
|||
/*
|
||||
* 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
|
||||
|
|
Loading…
Reference in a new issue