diff options
| author | Lin Ming <ming.m.lin@intel.com> | 2010-12-13 00:39:26 -0500 |
|---|---|---|
| committer | Len Brown <len.brown@intel.com> | 2011-01-12 04:27:00 -0500 |
| commit | a0fcdb237fcd4eaa7e5009b28ef5be07415f287d (patch) | |
| tree | d07a4950648ad9a7eaab8fd28b37685926bb23a9 | |
| parent | bba63a296ffab20e08d9e8252d2f0d99050ac859 (diff) | |
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 fc694647699f..9bb69c59bb12 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h | |||
| @@ -146,6 +146,9 @@ u8 acpi_gbl_system_awake_and_running; | |||
| 146 | 146 | ||
| 147 | extern u32 acpi_gbl_nesting_level; | 147 | extern u32 acpi_gbl_nesting_level; |
| 148 | 148 | ||
| 149 | ACPI_EXTERN u32 acpi_gpe_count; | ||
| 150 | ACPI_EXTERN u32 acpi_fixed_event_count[ACPI_NUM_FIXED_EVENTS]; | ||
| 151 | |||
| 149 | /* Support for dynamic control method tracing mechanism */ | 152 | /* Support for dynamic control method tracing mechanism */ |
| 150 | 153 | ||
| 151 | ACPI_EXTERN u32 acpi_gbl_original_dbg_level; | 154 | 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; | |||
| 371 | ACPI_EXTERN struct acpi_gpe_block_info | 374 | ACPI_EXTERN struct acpi_gpe_block_info |
| 372 | *acpi_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS]; | 375 | *acpi_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS]; |
| 373 | ACPI_EXTERN u8 acpi_gbl_all_gpes_initialized; | 376 | ACPI_EXTERN u8 acpi_gbl_all_gpes_initialized; |
| 377 | ACPI_EXTERN ACPI_GBL_EVENT_HANDLER acpi_gbl_global_event_handler; | ||
| 378 | ACPI_EXTERN void *acpi_gbl_global_event_handler_context; | ||
| 374 | 379 | ||
| 375 | /***************************************************************************** | 380 | /***************************************************************************** |
| 376 | * | 381 | * |
diff --git a/drivers/acpi/acpica/evevent.c b/drivers/acpi/acpica/evevent.c index c61c3039c31a..e5e313c663a5 100644 --- a/drivers/acpi/acpica/evevent.c +++ b/drivers/acpi/acpica/evevent.c | |||
| @@ -217,9 +217,17 @@ u32 acpi_ev_fixed_event_detect(void) | |||
| 217 | status_bit_mask) | 217 | status_bit_mask) |
| 218 | && (fixed_enable & acpi_gbl_fixed_event_info[i]. | 218 | && (fixed_enable & acpi_gbl_fixed_event_info[i]. |
| 219 | enable_bit_mask)) { | 219 | enable_bit_mask)) { |
| 220 | /* | ||
| 221 | * Found an active (signalled) event. Invoke global event | ||
| 222 | * handler if present. | ||
| 223 | */ | ||
| 224 | acpi_fixed_event_count[i]++; | ||
| 225 | if (acpi_gbl_global_event_handler) { | ||
| 226 | acpi_gbl_global_event_handler | ||
| 227 | (ACPI_EVENT_TYPE_FIXED, NULL, i, | ||
| 228 | acpi_gbl_global_event_handler_context); | ||
| 229 | } | ||
| 220 | 230 | ||
| 221 | /* Found an active (signalled) event */ | ||
| 222 | acpi_os_fixed_event_count(i); | ||
| 223 | int_status |= acpi_ev_fixed_event_dispatch(i); | 231 | int_status |= acpi_ev_fixed_event_dispatch(i); |
| 224 | } | 232 | } |
| 225 | } | 233 | } |
diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index 2dbca95979ce..3bcf5ef74c62 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, | |||
| 642 | 642 | ||
| 643 | ACPI_FUNCTION_TRACE(ev_gpe_dispatch); | 643 | ACPI_FUNCTION_TRACE(ev_gpe_dispatch); |
| 644 | 644 | ||
| 645 | acpi_os_gpe_count(gpe_number); | 645 | /* Invoke global event handler if present */ |
| 646 | |||
| 647 | acpi_gpe_count++; | ||
| 648 | if (acpi_gbl_global_event_handler) { | ||
| 649 | acpi_gbl_global_event_handler(ACPI_EVENT_TYPE_GPE, gpe_device, | ||
| 650 | gpe_number, | ||
| 651 | acpi_gbl_global_event_handler_context); | ||
| 652 | } | ||
| 646 | 653 | ||
| 647 | /* | 654 | /* |
| 648 | * If edge-triggered, clear the GPE status bit now. Note that | 655 | * 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 d193b905dfa2..1226689bdb1b 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) | |||
| 92 | 92 | ||
| 93 | ACPI_EXPORT_SYMBOL(acpi_install_exception_handler) | 93 | ACPI_EXPORT_SYMBOL(acpi_install_exception_handler) |
| 94 | #endif /* ACPI_FUTURE_USAGE */ | 94 | #endif /* ACPI_FUTURE_USAGE */ |
| 95 | |||
| 96 | /******************************************************************************* | ||
| 97 | * | ||
| 98 | * FUNCTION: acpi_install_global_event_handler | ||
| 99 | * | ||
| 100 | * PARAMETERS: Handler - Pointer to the global event handler function | ||
| 101 | * Context - Value passed to the handler on each event | ||
| 102 | * | ||
| 103 | * RETURN: Status | ||
| 104 | * | ||
| 105 | * DESCRIPTION: Saves the pointer to the handler function. The global handler | ||
| 106 | * is invoked upon each incoming GPE and Fixed Event. It is | ||
| 107 | * invoked at interrupt level at the time of the event dispatch. | ||
| 108 | * Can be used to update event counters, etc. | ||
| 109 | * | ||
| 110 | ******************************************************************************/ | ||
| 111 | acpi_status | ||
| 112 | acpi_install_global_event_handler(ACPI_GBL_EVENT_HANDLER handler, void *context) | ||
| 113 | { | ||
| 114 | acpi_status status; | ||
| 115 | |||
| 116 | ACPI_FUNCTION_TRACE(acpi_install_global_event_handler); | ||
| 117 | |||
| 118 | /* Parameter validation */ | ||
| 119 | |||
| 120 | if (!handler) { | ||
| 121 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
| 122 | } | ||
| 123 | |||
| 124 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); | ||
| 125 | if (ACPI_FAILURE(status)) { | ||
| 126 | return_ACPI_STATUS(status); | ||
| 127 | } | ||
| 128 | |||
| 129 | /* Don't allow two handlers. */ | ||
| 130 | |||
| 131 | if (acpi_gbl_global_event_handler) { | ||
| 132 | status = AE_ALREADY_EXISTS; | ||
| 133 | goto cleanup; | ||
| 134 | } | ||
| 135 | |||
| 136 | acpi_gbl_global_event_handler = handler; | ||
| 137 | acpi_gbl_global_event_handler_context = context; | ||
| 138 | |||
| 139 | cleanup: | ||
| 140 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | ||
| 141 | return_ACPI_STATUS(status); | ||
| 142 | } | ||
| 143 | |||
| 144 | ACPI_EXPORT_SYMBOL(acpi_install_global_event_handler) | ||
| 145 | |||
| 95 | /******************************************************************************* | 146 | /******************************************************************************* |
| 96 | * | 147 | * |
| 97 | * FUNCTION: acpi_install_fixed_event_handler | 148 | * FUNCTION: acpi_install_fixed_event_handler |
diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c index a99c32aa48a4..508537f884ac 100644 --- a/drivers/acpi/acpica/utglobal.c +++ b/drivers/acpi/acpica/utglobal.c | |||
| @@ -778,6 +778,7 @@ acpi_status acpi_ut_init_globals(void) | |||
| 778 | acpi_gbl_init_handler = NULL; | 778 | acpi_gbl_init_handler = NULL; |
| 779 | acpi_gbl_table_handler = NULL; | 779 | acpi_gbl_table_handler = NULL; |
| 780 | acpi_gbl_interface_handler = NULL; | 780 | acpi_gbl_interface_handler = NULL; |
| 781 | acpi_gbl_global_event_handler = NULL; | ||
| 781 | 782 | ||
| 782 | /* Global Lock support */ | 783 | /* Global Lock support */ |
| 783 | 784 | ||
diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index f8588f81048a..61891e75583d 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c | |||
| @@ -438,7 +438,7 @@ static void delete_gpe_attr_array(void) | |||
| 438 | return; | 438 | return; |
| 439 | } | 439 | } |
| 440 | 440 | ||
| 441 | void acpi_os_gpe_count(u32 gpe_number) | 441 | static void gpe_count(u32 gpe_number) |
| 442 | { | 442 | { |
| 443 | acpi_gpe_count++; | 443 | acpi_gpe_count++; |
| 444 | 444 | ||
| @@ -454,7 +454,7 @@ void acpi_os_gpe_count(u32 gpe_number) | |||
| 454 | return; | 454 | return; |
| 455 | } | 455 | } |
| 456 | 456 | ||
| 457 | void acpi_os_fixed_event_count(u32 event_number) | 457 | static void fixed_event_count(u32 event_number) |
| 458 | { | 458 | { |
| 459 | if (!all_counters) | 459 | if (!all_counters) |
| 460 | return; | 460 | return; |
| @@ -468,6 +468,16 @@ void acpi_os_fixed_event_count(u32 event_number) | |||
| 468 | return; | 468 | return; |
| 469 | } | 469 | } |
| 470 | 470 | ||
| 471 | static void acpi_gbl_event_handler(u32 event_type, acpi_handle device, | ||
| 472 | u32 event_number, void *context) | ||
| 473 | { | ||
| 474 | if (event_type == ACPI_EVENT_TYPE_GPE) | ||
| 475 | gpe_count(event_number); | ||
| 476 | |||
| 477 | if (event_type == ACPI_EVENT_TYPE_FIXED) | ||
| 478 | fixed_event_count(event_number); | ||
| 479 | } | ||
| 480 | |||
| 471 | static int get_status(u32 index, acpi_event_status *status, | 481 | static int get_status(u32 index, acpi_event_status *status, |
| 472 | acpi_handle *handle) | 482 | acpi_handle *handle) |
| 473 | { | 483 | { |
| @@ -601,6 +611,7 @@ end: | |||
| 601 | 611 | ||
| 602 | void acpi_irq_stats_init(void) | 612 | void acpi_irq_stats_init(void) |
| 603 | { | 613 | { |
| 614 | acpi_status status; | ||
| 604 | int i; | 615 | int i; |
| 605 | 616 | ||
| 606 | if (all_counters) | 617 | if (all_counters) |
| @@ -619,6 +630,10 @@ void acpi_irq_stats_init(void) | |||
| 619 | if (all_counters == NULL) | 630 | if (all_counters == NULL) |
| 620 | goto fail; | 631 | goto fail; |
| 621 | 632 | ||
| 633 | status = acpi_install_global_event_handler(acpi_gbl_event_handler, NULL); | ||
| 634 | if (ACPI_FAILURE(status)) | ||
| 635 | goto fail; | ||
| 636 | |||
| 622 | counter_attrs = kzalloc(sizeof(struct kobj_attribute) * (num_counters), | 637 | counter_attrs = kzalloc(sizeof(struct kobj_attribute) * (num_counters), |
| 623 | GFP_KERNEL); | 638 | GFP_KERNEL); |
| 624 | if (counter_attrs == NULL) | 639 | if (counter_attrs == NULL) |
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index 9de6a17cbd4c..e8142d5ebab9 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h | |||
| @@ -229,6 +229,10 @@ acpi_status | |||
| 229 | acpi_install_initialization_handler(acpi_init_handler handler, u32 function); | 229 | acpi_install_initialization_handler(acpi_init_handler handler, u32 function); |
| 230 | 230 | ||
| 231 | acpi_status | 231 | acpi_status |
| 232 | acpi_install_global_event_handler(ACPI_GBL_EVENT_HANDLER handler, | ||
| 233 | void *context); | ||
| 234 | |||
| 235 | acpi_status | ||
| 232 | acpi_install_fixed_event_handler(u32 acpi_event, | 236 | acpi_install_fixed_event_handler(u32 acpi_event, |
| 233 | acpi_event_handler handler, void *context); | 237 | acpi_event_handler handler, void *context); |
| 234 | 238 | ||
diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index d7274ee4474f..939a431a6ab6 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h | |||
| @@ -895,6 +895,14 @@ typedef void | |||
| 895 | /* | 895 | /* |
| 896 | * Various handlers and callback procedures | 896 | * Various handlers and callback procedures |
| 897 | */ | 897 | */ |
| 898 | typedef | ||
| 899 | void (*ACPI_GBL_EVENT_HANDLER) (u32 event_type, | ||
| 900 | acpi_handle device, | ||
| 901 | u32 event_number, void *context); | ||
| 902 | |||
| 903 | #define ACPI_EVENT_TYPE_GPE 0 | ||
| 904 | #define ACPI_EVENT_TYPE_FIXED 1 | ||
| 905 | |||
| 898 | typedef u32(*acpi_event_handler) (void *context); | 906 | typedef u32(*acpi_event_handler) (void *context); |
| 899 | 907 | ||
| 900 | typedef | 908 | typedef |
