diff options
| author | Lin Ming <ming.m.lin@intel.com> | 2010-12-13 13:39:26 +0800 | 
|---|---|---|
| committer | Len Brown <len.brown@intel.com> | 2011-01-12 04:27:00 -0500 | 
| commit | a0fcdb237fcd4eaa7e5009b28ef5be07415f287d (patch) | |
| tree | d07a4950648ad9a7eaab8fd28b37685926bb23a9 | |
| parent | bba63a296ffab20e08d9e8252d2f0d99050ac859 (diff) | |
| download | olio-linux-3.10-a0fcdb237fcd4eaa7e5009b28ef5be07415f287d.tar.xz olio-linux-3.10-a0fcdb237fcd4eaa7e5009b28ef5be07415f287d.zip  | |
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>
| -rw-r--r-- | drivers/acpi/acpica/acglobal.h | 5 | ||||
| -rw-r--r-- | drivers/acpi/acpica/evevent.c | 12 | ||||
| -rw-r--r-- | drivers/acpi/acpica/evgpe.c | 9 | ||||
| -rw-r--r-- | drivers/acpi/acpica/evxface.c | 51 | ||||
| -rw-r--r-- | drivers/acpi/acpica/utglobal.c | 1 | ||||
| -rw-r--r-- | drivers/acpi/sysfs.c | 19 | ||||
| -rw-r--r-- | include/acpi/acpixf.h | 4 | ||||
| -rw-r--r-- | include/acpi/actypes.h | 8 | 
8 files changed, 104 insertions, 5 deletions
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index fc694647699..9bb69c59bb1 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h @@ -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;  /*****************************************************************************   * diff --git a/drivers/acpi/acpica/evevent.c b/drivers/acpi/acpica/evevent.c index c61c3039c31..e5e313c663a 100644 --- a/drivers/acpi/acpica/evevent.c +++ b/drivers/acpi/acpica/evevent.c @@ -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);  		}  	} diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index 2dbca95979c..3bcf5ef74c6 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c @@ -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 diff --git a/drivers/acpi/acpica/evxface.c b/drivers/acpi/acpica/evxface.c index d193b905dfa..1226689bdb1 100644 --- a/drivers/acpi/acpica/evxface.c +++ b/drivers/acpi/acpica/evxface.c @@ -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 diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c index a99c32aa48a..508537f884a 100644 --- a/drivers/acpi/acpica/utglobal.c +++ b/drivers/acpi/acpica/utglobal.c @@ -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 */ diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index f8588f81048..61891e75583 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c @@ -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 @@ end:  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) diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index 9de6a17cbd4..e8142d5ebab 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -229,6 +229,10 @@ 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); diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index d7274ee4474..939a431a6ab 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h @@ -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  |