diff options
| -rw-r--r-- | drivers/acpi/acpica/acevents.h | 6 | ||||
| -rw-r--r-- | drivers/acpi/acpica/aclocal.h | 2 | ||||
| -rw-r--r-- | drivers/acpi/acpica/evgpe.c | 153 | ||||
| -rw-r--r-- | drivers/acpi/acpica/evgpeblk.c | 87 | ||||
| -rw-r--r-- | drivers/acpi/acpica/evxface.c | 14 | ||||
| -rw-r--r-- | drivers/acpi/acpica/evxfevnt.c | 90 | ||||
| -rw-r--r-- | drivers/acpi/button.c | 13 | ||||
| -rw-r--r-- | drivers/acpi/ec.c | 14 | ||||
| -rw-r--r-- | drivers/acpi/sleep.c | 15 | ||||
| -rw-r--r-- | drivers/acpi/system.c | 4 | ||||
| -rw-r--r-- | drivers/acpi/wakeup.c | 81 | ||||
| -rw-r--r-- | include/acpi/acpixf.h | 6 | ||||
| -rw-r--r-- | include/acpi/actypes.h | 28 |
13 files changed, 188 insertions, 325 deletions
diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h index 0bba148a2c61..197aa4f39640 100644 --- a/drivers/acpi/acpica/acevents.h +++ b/drivers/acpi/acpica/acevents.h | |||
| @@ -76,8 +76,7 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node *node, | |||
| 76 | * evgpe - GPE handling and dispatch | 76 | * evgpe - GPE handling and dispatch |
| 77 | */ | 77 | */ |
| 78 | acpi_status | 78 | acpi_status |
| 79 | acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info, | 79 | acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info); |
| 80 | u8 type); | ||
| 81 | 80 | ||
| 82 | acpi_status | 81 | acpi_status |
| 83 | acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info, | 82 | acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info, |
| @@ -122,9 +121,6 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, | |||
| 122 | u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info *gpe_xrupt_list); | 121 | u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info *gpe_xrupt_list); |
| 123 | 122 | ||
| 124 | acpi_status | 123 | acpi_status |
| 125 | acpi_ev_set_gpe_type(struct acpi_gpe_event_info *gpe_event_info, u8 type); | ||
| 126 | |||
| 127 | acpi_status | ||
| 128 | acpi_ev_check_for_wake_only_gpe(struct acpi_gpe_event_info *gpe_event_info); | 124 | acpi_ev_check_for_wake_only_gpe(struct acpi_gpe_event_info *gpe_event_info); |
| 129 | 125 | ||
| 130 | acpi_status acpi_ev_gpe_initialize(void); | 126 | acpi_status acpi_ev_gpe_initialize(void); |
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 81e64f478679..13cb80caacde 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h | |||
| @@ -426,6 +426,8 @@ struct acpi_gpe_event_info { | |||
| 426 | struct acpi_gpe_register_info *register_info; /* Backpointer to register info */ | 426 | struct acpi_gpe_register_info *register_info; /* Backpointer to register info */ |
| 427 | u8 flags; /* Misc info about this GPE */ | 427 | u8 flags; /* Misc info about this GPE */ |
| 428 | u8 gpe_number; /* This GPE */ | 428 | u8 gpe_number; /* This GPE */ |
| 429 | u8 runtime_count; | ||
| 430 | u8 wakeup_count; | ||
| 429 | }; | 431 | }; |
| 430 | 432 | ||
| 431 | /* Information about a GPE register pair, one per each status/enable pair in an array */ | 433 | /* Information about a GPE register pair, one per each status/enable pair in an array */ |
diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index afacf4416c73..30ca3a30ef00 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c | |||
| @@ -54,54 +54,9 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context); | |||
| 54 | 54 | ||
| 55 | /******************************************************************************* | 55 | /******************************************************************************* |
| 56 | * | 56 | * |
| 57 | * FUNCTION: acpi_ev_set_gpe_type | ||
| 58 | * | ||
| 59 | * PARAMETERS: gpe_event_info - GPE to set | ||
| 60 | * Type - New type | ||
| 61 | * | ||
| 62 | * RETURN: Status | ||
| 63 | * | ||
| 64 | * DESCRIPTION: Sets the new type for the GPE (wake, run, or wake/run) | ||
| 65 | * | ||
| 66 | ******************************************************************************/ | ||
| 67 | |||
| 68 | acpi_status | ||
| 69 | acpi_ev_set_gpe_type(struct acpi_gpe_event_info *gpe_event_info, u8 type) | ||
| 70 | { | ||
| 71 | acpi_status status; | ||
| 72 | |||
| 73 | ACPI_FUNCTION_TRACE(ev_set_gpe_type); | ||
| 74 | |||
| 75 | /* Validate type and update register enable masks */ | ||
| 76 | |||
| 77 | switch (type) { | ||
| 78 | case ACPI_GPE_TYPE_WAKE: | ||
| 79 | case ACPI_GPE_TYPE_RUNTIME: | ||
| 80 | case ACPI_GPE_TYPE_WAKE_RUN: | ||
| 81 | break; | ||
| 82 | |||
| 83 | default: | ||
| 84 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
| 85 | } | ||
| 86 | |||
| 87 | /* Disable the GPE if currently enabled */ | ||
| 88 | |||
| 89 | status = acpi_ev_disable_gpe(gpe_event_info); | ||
| 90 | |||
| 91 | /* Clear the type bits and insert the new Type */ | ||
| 92 | |||
| 93 | gpe_event_info->flags &= ~ACPI_GPE_TYPE_MASK; | ||
| 94 | gpe_event_info->flags |= type; | ||
| 95 | return_ACPI_STATUS(status); | ||
| 96 | } | ||
| 97 | |||
| 98 | /******************************************************************************* | ||
| 99 | * | ||
| 100 | * FUNCTION: acpi_ev_update_gpe_enable_masks | 57 | * FUNCTION: acpi_ev_update_gpe_enable_masks |
| 101 | * | 58 | * |
| 102 | * PARAMETERS: gpe_event_info - GPE to update | 59 | * PARAMETERS: gpe_event_info - GPE to update |
| 103 | * Type - What to do: ACPI_GPE_DISABLE or | ||
| 104 | * ACPI_GPE_ENABLE | ||
| 105 | * | 60 | * |
| 106 | * RETURN: Status | 61 | * RETURN: Status |
| 107 | * | 62 | * |
| @@ -110,8 +65,7 @@ acpi_ev_set_gpe_type(struct acpi_gpe_event_info *gpe_event_info, u8 type) | |||
| 110 | ******************************************************************************/ | 65 | ******************************************************************************/ |
| 111 | 66 | ||
| 112 | acpi_status | 67 | acpi_status |
| 113 | acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info, | 68 | acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info) |
| 114 | u8 type) | ||
| 115 | { | 69 | { |
| 116 | struct acpi_gpe_register_info *gpe_register_info; | 70 | struct acpi_gpe_register_info *gpe_register_info; |
| 117 | u8 register_bit; | 71 | u8 register_bit; |
| @@ -127,37 +81,14 @@ acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info, | |||
| 127 | (1 << | 81 | (1 << |
| 128 | (gpe_event_info->gpe_number - gpe_register_info->base_gpe_number)); | 82 | (gpe_event_info->gpe_number - gpe_register_info->base_gpe_number)); |
| 129 | 83 | ||
| 130 | /* 1) Disable case. Simply clear all enable bits */ | 84 | ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake, register_bit); |
| 131 | 85 | ACPI_CLEAR_BIT(gpe_register_info->enable_for_run, register_bit); | |
| 132 | if (type == ACPI_GPE_DISABLE) { | ||
| 133 | ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake, | ||
| 134 | register_bit); | ||
| 135 | ACPI_CLEAR_BIT(gpe_register_info->enable_for_run, register_bit); | ||
| 136 | return_ACPI_STATUS(AE_OK); | ||
| 137 | } | ||
| 138 | |||
| 139 | /* 2) Enable case. Set/Clear the appropriate enable bits */ | ||
| 140 | 86 | ||
| 141 | switch (gpe_event_info->flags & ACPI_GPE_TYPE_MASK) { | 87 | if (gpe_event_info->runtime_count) |
| 142 | case ACPI_GPE_TYPE_WAKE: | ||
| 143 | ACPI_SET_BIT(gpe_register_info->enable_for_wake, register_bit); | ||
| 144 | ACPI_CLEAR_BIT(gpe_register_info->enable_for_run, register_bit); | ||
| 145 | break; | ||
| 146 | |||
| 147 | case ACPI_GPE_TYPE_RUNTIME: | ||
| 148 | ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake, | ||
| 149 | register_bit); | ||
| 150 | ACPI_SET_BIT(gpe_register_info->enable_for_run, register_bit); | 88 | ACPI_SET_BIT(gpe_register_info->enable_for_run, register_bit); |
| 151 | break; | ||
| 152 | 89 | ||
| 153 | case ACPI_GPE_TYPE_WAKE_RUN: | 90 | if (gpe_event_info->wakeup_count) |
| 154 | ACPI_SET_BIT(gpe_register_info->enable_for_wake, register_bit); | 91 | ACPI_SET_BIT(gpe_register_info->enable_for_wake, register_bit); |
| 155 | ACPI_SET_BIT(gpe_register_info->enable_for_run, register_bit); | ||
| 156 | break; | ||
| 157 | |||
| 158 | default: | ||
| 159 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
| 160 | } | ||
| 161 | 92 | ||
| 162 | return_ACPI_STATUS(AE_OK); | 93 | return_ACPI_STATUS(AE_OK); |
| 163 | } | 94 | } |
| @@ -186,47 +117,20 @@ acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info, | |||
| 186 | 117 | ||
| 187 | /* Make sure HW enable masks are updated */ | 118 | /* Make sure HW enable masks are updated */ |
| 188 | 119 | ||
| 189 | status = | 120 | status = acpi_ev_update_gpe_enable_masks(gpe_event_info); |
| 190 | acpi_ev_update_gpe_enable_masks(gpe_event_info, ACPI_GPE_ENABLE); | 121 | if (ACPI_FAILURE(status)) |
| 191 | if (ACPI_FAILURE(status)) { | ||
| 192 | return_ACPI_STATUS(status); | 122 | return_ACPI_STATUS(status); |
| 193 | } | ||
| 194 | 123 | ||
| 195 | /* Mark wake-enabled or HW enable, or both */ | 124 | /* Mark wake-enabled or HW enable, or both */ |
| 196 | 125 | ||
| 197 | switch (gpe_event_info->flags & ACPI_GPE_TYPE_MASK) { | 126 | if (gpe_event_info->runtime_count && write_to_hardware) { |
| 198 | case ACPI_GPE_TYPE_WAKE: | 127 | /* Clear the GPE (of stale events), then enable it */ |
| 199 | 128 | status = acpi_hw_clear_gpe(gpe_event_info); | |
| 200 | ACPI_SET_BIT(gpe_event_info->flags, ACPI_GPE_WAKE_ENABLED); | 129 | if (ACPI_FAILURE(status)) |
| 201 | break; | 130 | return_ACPI_STATUS(status); |
| 202 | |||
| 203 | case ACPI_GPE_TYPE_WAKE_RUN: | ||
| 204 | |||
| 205 | ACPI_SET_BIT(gpe_event_info->flags, ACPI_GPE_WAKE_ENABLED); | ||
| 206 | |||
| 207 | /*lint -fallthrough */ | ||
| 208 | |||
| 209 | case ACPI_GPE_TYPE_RUNTIME: | ||
| 210 | |||
| 211 | ACPI_SET_BIT(gpe_event_info->flags, ACPI_GPE_RUN_ENABLED); | ||
| 212 | |||
| 213 | if (write_to_hardware) { | ||
| 214 | |||
| 215 | /* Clear the GPE (of stale events), then enable it */ | ||
| 216 | |||
| 217 | status = acpi_hw_clear_gpe(gpe_event_info); | ||
| 218 | if (ACPI_FAILURE(status)) { | ||
| 219 | return_ACPI_STATUS(status); | ||
| 220 | } | ||
| 221 | |||
| 222 | /* Enable the requested runtime GPE */ | ||
| 223 | |||
| 224 | status = acpi_hw_write_gpe_enable_reg(gpe_event_info); | ||
| 225 | } | ||
| 226 | break; | ||
| 227 | 131 | ||
| 228 | default: | 132 | /* Enable the requested runtime GPE */ |
| 229 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 133 | status = acpi_hw_write_gpe_enable_reg(gpe_event_info); |
| 230 | } | 134 | } |
| 231 | 135 | ||
| 232 | return_ACPI_STATUS(AE_OK); | 136 | return_ACPI_STATUS(AE_OK); |
| @@ -252,34 +156,9 @@ acpi_status acpi_ev_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) | |||
| 252 | 156 | ||
| 253 | /* Make sure HW enable masks are updated */ | 157 | /* Make sure HW enable masks are updated */ |
| 254 | 158 | ||
| 255 | status = | 159 | status = acpi_ev_update_gpe_enable_masks(gpe_event_info); |
| 256 | acpi_ev_update_gpe_enable_masks(gpe_event_info, ACPI_GPE_DISABLE); | 160 | if (ACPI_FAILURE(status)) |
| 257 | if (ACPI_FAILURE(status)) { | ||
| 258 | return_ACPI_STATUS(status); | 161 | return_ACPI_STATUS(status); |
| 259 | } | ||
| 260 | |||
| 261 | /* Clear the appropriate enabled flags for this GPE */ | ||
| 262 | |||
| 263 | switch (gpe_event_info->flags & ACPI_GPE_TYPE_MASK) { | ||
| 264 | case ACPI_GPE_TYPE_WAKE: | ||
| 265 | ACPI_CLEAR_BIT(gpe_event_info->flags, ACPI_GPE_WAKE_ENABLED); | ||
| 266 | break; | ||
| 267 | |||
| 268 | case ACPI_GPE_TYPE_WAKE_RUN: | ||
| 269 | ACPI_CLEAR_BIT(gpe_event_info->flags, ACPI_GPE_WAKE_ENABLED); | ||
| 270 | |||
| 271 | /* fallthrough */ | ||
| 272 | |||
| 273 | case ACPI_GPE_TYPE_RUNTIME: | ||
| 274 | |||
| 275 | /* Disable the requested runtime GPE */ | ||
| 276 | |||
| 277 | ACPI_CLEAR_BIT(gpe_event_info->flags, ACPI_GPE_RUN_ENABLED); | ||
| 278 | break; | ||
| 279 | |||
| 280 | default: | ||
| 281 | break; | ||
| 282 | } | ||
| 283 | 162 | ||
| 284 | /* | 163 | /* |
| 285 | * Even if we don't know the GPE type, make sure that we always | 164 | * Even if we don't know the GPE type, make sure that we always |
diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c index 247920900187..3d4c4aca11cd 100644 --- a/drivers/acpi/acpica/evgpeblk.c +++ b/drivers/acpi/acpica/evgpeblk.c | |||
| @@ -258,7 +258,6 @@ acpi_ev_save_method_info(acpi_handle obj_handle, | |||
| 258 | u32 gpe_number; | 258 | u32 gpe_number; |
| 259 | char name[ACPI_NAME_SIZE + 1]; | 259 | char name[ACPI_NAME_SIZE + 1]; |
| 260 | u8 type; | 260 | u8 type; |
| 261 | acpi_status status; | ||
| 262 | 261 | ||
| 263 | ACPI_FUNCTION_TRACE(ev_save_method_info); | 262 | ACPI_FUNCTION_TRACE(ev_save_method_info); |
| 264 | 263 | ||
| @@ -325,26 +324,20 @@ acpi_ev_save_method_info(acpi_handle obj_handle, | |||
| 325 | 324 | ||
| 326 | /* | 325 | /* |
| 327 | * Now we can add this information to the gpe_event_info block for use | 326 | * Now we can add this information to the gpe_event_info block for use |
| 328 | * during dispatch of this GPE. Default type is RUNTIME, although this may | 327 | * during dispatch of this GPE. |
| 329 | * change when the _PRW methods are executed later. | ||
| 330 | */ | 328 | */ |
| 331 | gpe_event_info = | 329 | gpe_event_info = |
| 332 | &gpe_block->event_info[gpe_number - gpe_block->block_base_number]; | 330 | &gpe_block->event_info[gpe_number - gpe_block->block_base_number]; |
| 333 | 331 | ||
| 334 | gpe_event_info->flags = (u8) | 332 | gpe_event_info->flags = (u8) (type | ACPI_GPE_DISPATCH_METHOD); |
| 335 | (type | ACPI_GPE_DISPATCH_METHOD | ACPI_GPE_TYPE_RUNTIME); | ||
| 336 | 333 | ||
| 337 | gpe_event_info->dispatch.method_node = | 334 | gpe_event_info->dispatch.method_node = |
| 338 | (struct acpi_namespace_node *)obj_handle; | 335 | (struct acpi_namespace_node *)obj_handle; |
| 339 | 336 | ||
| 340 | /* Update enable mask, but don't enable the HW GPE as of yet */ | ||
| 341 | |||
| 342 | status = acpi_ev_enable_gpe(gpe_event_info, FALSE); | ||
| 343 | |||
| 344 | ACPI_DEBUG_PRINT((ACPI_DB_LOAD, | 337 | ACPI_DEBUG_PRINT((ACPI_DB_LOAD, |
| 345 | "Registered GPE method %s as GPE number 0x%.2X\n", | 338 | "Registered GPE method %s as GPE number 0x%.2X\n", |
| 346 | name, gpe_number)); | 339 | name, gpe_number)); |
| 347 | return_ACPI_STATUS(status); | 340 | return_ACPI_STATUS(AE_OK); |
| 348 | } | 341 | } |
| 349 | 342 | ||
| 350 | /******************************************************************************* | 343 | /******************************************************************************* |
| @@ -454,20 +447,7 @@ acpi_ev_match_prw_and_gpe(acpi_handle obj_handle, | |||
| 454 | gpe_block-> | 447 | gpe_block-> |
| 455 | block_base_number]; | 448 | block_base_number]; |
| 456 | 449 | ||
| 457 | /* Mark GPE for WAKE-ONLY but WAKE_DISABLED */ | 450 | gpe_event_info->flags |= ACPI_GPE_CAN_WAKE; |
| 458 | |||
| 459 | gpe_event_info->flags &= | ||
| 460 | ~(ACPI_GPE_WAKE_ENABLED | ACPI_GPE_RUN_ENABLED); | ||
| 461 | |||
| 462 | status = | ||
| 463 | acpi_ev_set_gpe_type(gpe_event_info, ACPI_GPE_TYPE_WAKE); | ||
| 464 | if (ACPI_FAILURE(status)) { | ||
| 465 | goto cleanup; | ||
| 466 | } | ||
| 467 | |||
| 468 | status = | ||
| 469 | acpi_ev_update_gpe_enable_masks(gpe_event_info, | ||
| 470 | ACPI_GPE_DISABLE); | ||
| 471 | } | 451 | } |
| 472 | 452 | ||
| 473 | cleanup: | 453 | cleanup: |
| @@ -989,7 +969,6 @@ acpi_status | |||
| 989 | acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, | 969 | acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, |
| 990 | struct acpi_gpe_block_info *gpe_block) | 970 | struct acpi_gpe_block_info *gpe_block) |
| 991 | { | 971 | { |
| 992 | acpi_status status; | ||
| 993 | struct acpi_gpe_event_info *gpe_event_info; | 972 | struct acpi_gpe_event_info *gpe_event_info; |
| 994 | struct acpi_gpe_walk_info gpe_info; | 973 | struct acpi_gpe_walk_info gpe_info; |
| 995 | u32 wake_gpe_count; | 974 | u32 wake_gpe_count; |
| @@ -1019,42 +998,50 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, | |||
| 1019 | gpe_info.gpe_block = gpe_block; | 998 | gpe_info.gpe_block = gpe_block; |
| 1020 | gpe_info.gpe_device = gpe_device; | 999 | gpe_info.gpe_device = gpe_device; |
| 1021 | 1000 | ||
| 1022 | status = | 1001 | acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, |
| 1023 | acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, | ||
| 1024 | ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK, | 1002 | ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK, |
| 1025 | acpi_ev_match_prw_and_gpe, NULL, | 1003 | acpi_ev_match_prw_and_gpe, NULL, |
| 1026 | &gpe_info, NULL); | 1004 | &gpe_info, NULL); |
| 1027 | } | 1005 | } |
| 1028 | 1006 | ||
| 1029 | /* | 1007 | /* |
| 1030 | * Enable all GPEs in this block that have these attributes: | 1008 | * Enable all GPEs that have a corresponding method and aren't |
| 1031 | * 1) are "runtime" or "run/wake" GPEs, and | 1009 | * capable of generating wakeups. Any other GPEs within this block |
| 1032 | * 2) have a corresponding _Lxx or _Exx method | 1010 | * must be enabled via the acpi_enable_gpe() interface. |
| 1033 | * | ||
| 1034 | * Any other GPEs within this block must be enabled via the | ||
| 1035 | * acpi_enable_gpe() external interface. | ||
| 1036 | */ | 1011 | */ |
| 1037 | wake_gpe_count = 0; | 1012 | wake_gpe_count = 0; |
| 1038 | gpe_enabled_count = 0; | 1013 | gpe_enabled_count = 0; |
| 1014 | if (gpe_device == acpi_gbl_fadt_gpe_device) | ||
| 1015 | gpe_device = NULL; | ||
| 1039 | 1016 | ||
| 1040 | for (i = 0; i < gpe_block->register_count; i++) { | 1017 | for (i = 0; i < gpe_block->register_count; i++) { |
| 1041 | for (j = 0; j < 8; j++) { | 1018 | for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) { |
| 1019 | acpi_status status; | ||
| 1020 | acpi_size gpe_index; | ||
| 1021 | int gpe_number; | ||
| 1042 | 1022 | ||
| 1043 | /* Get the info block for this particular GPE */ | 1023 | /* Get the info block for this particular GPE */ |
| 1024 | gpe_index = (acpi_size)i * ACPI_GPE_REGISTER_WIDTH + j; | ||
| 1025 | gpe_event_info = &gpe_block->event_info[gpe_index]; | ||
| 1044 | 1026 | ||
| 1045 | gpe_event_info = &gpe_block->event_info[((acpi_size) i * | 1027 | if (gpe_event_info->flags & ACPI_GPE_CAN_WAKE) { |
| 1046 | ACPI_GPE_REGISTER_WIDTH) | ||
| 1047 | + j]; | ||
| 1048 | |||
| 1049 | if (((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == | ||
| 1050 | ACPI_GPE_DISPATCH_METHOD) && | ||
| 1051 | (gpe_event_info->flags & ACPI_GPE_TYPE_RUNTIME)) { | ||
| 1052 | gpe_enabled_count++; | ||
| 1053 | } | ||
| 1054 | |||
| 1055 | if (gpe_event_info->flags & ACPI_GPE_TYPE_WAKE) { | ||
| 1056 | wake_gpe_count++; | 1028 | wake_gpe_count++; |
| 1029 | if (acpi_gbl_leave_wake_gpes_disabled) | ||
| 1030 | continue; | ||
| 1057 | } | 1031 | } |
| 1032 | |||
| 1033 | if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD)) | ||
| 1034 | continue; | ||
| 1035 | |||
| 1036 | gpe_number = gpe_index + gpe_block->block_base_number; | ||
| 1037 | status = acpi_enable_gpe(gpe_device, gpe_number, | ||
| 1038 | ACPI_GPE_TYPE_RUNTIME); | ||
| 1039 | if (ACPI_FAILURE(status)) | ||
| 1040 | ACPI_ERROR((AE_INFO, | ||
| 1041 | "Failed to enable GPE %02X\n", | ||
| 1042 | gpe_number)); | ||
| 1043 | else | ||
| 1044 | gpe_enabled_count++; | ||
| 1058 | } | 1045 | } |
| 1059 | } | 1046 | } |
| 1060 | 1047 | ||
| @@ -1062,15 +1049,7 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, | |||
| 1062 | "Found %u Wake, Enabled %u Runtime GPEs in this block\n", | 1049 | "Found %u Wake, Enabled %u Runtime GPEs in this block\n", |
| 1063 | wake_gpe_count, gpe_enabled_count)); | 1050 | wake_gpe_count, gpe_enabled_count)); |
| 1064 | 1051 | ||
| 1065 | /* Enable all valid runtime GPEs found above */ | 1052 | return_ACPI_STATUS(AE_OK); |
| 1066 | |||
| 1067 | status = acpi_hw_enable_runtime_gpe_block(NULL, gpe_block, NULL); | ||
| 1068 | if (ACPI_FAILURE(status)) { | ||
| 1069 | ACPI_ERROR((AE_INFO, "Could not enable GPEs in GpeBlock %p", | ||
| 1070 | gpe_block)); | ||
| 1071 | } | ||
| 1072 | |||
| 1073 | return_ACPI_STATUS(status); | ||
| 1074 | } | 1053 | } |
| 1075 | 1054 | ||
| 1076 | /******************************************************************************* | 1055 | /******************************************************************************* |
diff --git a/drivers/acpi/acpica/evxface.c b/drivers/acpi/acpica/evxface.c index 2fe0809d4eb2..166cbfe1c706 100644 --- a/drivers/acpi/acpica/evxface.c +++ b/drivers/acpi/acpica/evxface.c | |||
| @@ -617,13 +617,6 @@ acpi_install_gpe_handler(acpi_handle gpe_device, | |||
| 617 | handler->context = context; | 617 | handler->context = context; |
| 618 | handler->method_node = gpe_event_info->dispatch.method_node; | 618 | handler->method_node = gpe_event_info->dispatch.method_node; |
| 619 | 619 | ||
| 620 | /* Disable the GPE before installing the handler */ | ||
| 621 | |||
| 622 | status = acpi_ev_disable_gpe(gpe_event_info); | ||
| 623 | if (ACPI_FAILURE(status)) { | ||
| 624 | goto unlock_and_exit; | ||
| 625 | } | ||
| 626 | |||
| 627 | /* Install the handler */ | 620 | /* Install the handler */ |
| 628 | 621 | ||
| 629 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | 622 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); |
| @@ -707,13 +700,6 @@ acpi_remove_gpe_handler(acpi_handle gpe_device, | |||
| 707 | goto unlock_and_exit; | 700 | goto unlock_and_exit; |
| 708 | } | 701 | } |
| 709 | 702 | ||
| 710 | /* Disable the GPE before removing the handler */ | ||
| 711 | |||
| 712 | status = acpi_ev_disable_gpe(gpe_event_info); | ||
| 713 | if (ACPI_FAILURE(status)) { | ||
| 714 | goto unlock_and_exit; | ||
| 715 | } | ||
| 716 | |||
| 717 | /* Make sure all deferred tasks are completed */ | 703 | /* Make sure all deferred tasks are completed */ |
| 718 | 704 | ||
| 719 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | 705 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); |
diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c index eed7a38d25f2..1aea1a734159 100644 --- a/drivers/acpi/acpica/evxfevnt.c +++ b/drivers/acpi/acpica/evxfevnt.c | |||
| @@ -201,23 +201,27 @@ ACPI_EXPORT_SYMBOL(acpi_enable_event) | |||
| 201 | 201 | ||
| 202 | /******************************************************************************* | 202 | /******************************************************************************* |
| 203 | * | 203 | * |
| 204 | * FUNCTION: acpi_set_gpe_type | 204 | * FUNCTION: acpi_set_gpe |
| 205 | * | 205 | * |
| 206 | * PARAMETERS: gpe_device - Parent GPE Device | 206 | * PARAMETERS: gpe_device - Parent GPE Device |
| 207 | * gpe_number - GPE level within the GPE block | 207 | * gpe_number - GPE level within the GPE block |
| 208 | * Type - New GPE type | 208 | * action - Enable or disable |
| 209 | * Called from ISR or not | ||
| 209 | * | 210 | * |
| 210 | * RETURN: Status | 211 | * RETURN: Status |
| 211 | * | 212 | * |
| 212 | * DESCRIPTION: Set the type of an individual GPE | 213 | * DESCRIPTION: Enable or disable an ACPI event (general purpose) |
| 213 | * | 214 | * |
| 214 | ******************************************************************************/ | 215 | ******************************************************************************/ |
| 215 | acpi_status acpi_set_gpe_type(acpi_handle gpe_device, u32 gpe_number, u8 type) | 216 | acpi_status acpi_set_gpe(acpi_handle gpe_device, u32 gpe_number, u8 action) |
| 216 | { | 217 | { |
| 217 | acpi_status status = AE_OK; | 218 | acpi_status status = AE_OK; |
| 219 | acpi_cpu_flags flags; | ||
| 218 | struct acpi_gpe_event_info *gpe_event_info; | 220 | struct acpi_gpe_event_info *gpe_event_info; |
| 219 | 221 | ||
| 220 | ACPI_FUNCTION_TRACE(acpi_set_gpe_type); | 222 | ACPI_FUNCTION_TRACE(acpi_set_gpe); |
| 223 | |||
| 224 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | ||
| 221 | 225 | ||
| 222 | /* Ensure that we have a valid GPE number */ | 226 | /* Ensure that we have a valid GPE number */ |
| 223 | 227 | ||
| @@ -227,19 +231,29 @@ acpi_status acpi_set_gpe_type(acpi_handle gpe_device, u32 gpe_number, u8 type) | |||
| 227 | goto unlock_and_exit; | 231 | goto unlock_and_exit; |
| 228 | } | 232 | } |
| 229 | 233 | ||
| 230 | if ((gpe_event_info->flags & ACPI_GPE_TYPE_MASK) == type) { | 234 | /* Perform the action */ |
| 231 | return_ACPI_STATUS(AE_OK); | 235 | |
| 232 | } | 236 | switch (action) { |
| 237 | case ACPI_GPE_ENABLE: | ||
| 238 | status = acpi_ev_enable_gpe(gpe_event_info, TRUE); | ||
| 239 | break; | ||
| 233 | 240 | ||
| 234 | /* Set the new type (will disable GPE if currently enabled) */ | 241 | case ACPI_GPE_DISABLE: |
| 242 | status = acpi_ev_disable_gpe(gpe_event_info); | ||
| 243 | break; | ||
| 235 | 244 | ||
| 236 | status = acpi_ev_set_gpe_type(gpe_event_info, type); | 245 | default: |
| 246 | ACPI_ERROR((AE_INFO, "Invalid action\n")); | ||
| 247 | status = AE_BAD_PARAMETER; | ||
| 248 | break; | ||
| 249 | } | ||
| 237 | 250 | ||
| 238 | unlock_and_exit: | 251 | unlock_and_exit: |
| 252 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | ||
| 239 | return_ACPI_STATUS(status); | 253 | return_ACPI_STATUS(status); |
| 240 | } | 254 | } |
| 241 | 255 | ||
| 242 | ACPI_EXPORT_SYMBOL(acpi_set_gpe_type) | 256 | ACPI_EXPORT_SYMBOL(acpi_set_gpe) |
| 243 | 257 | ||
| 244 | /******************************************************************************* | 258 | /******************************************************************************* |
| 245 | * | 259 | * |
| @@ -247,15 +261,14 @@ ACPI_EXPORT_SYMBOL(acpi_set_gpe_type) | |||
| 247 | * | 261 | * |
| 248 | * PARAMETERS: gpe_device - Parent GPE Device | 262 | * PARAMETERS: gpe_device - Parent GPE Device |
| 249 | * gpe_number - GPE level within the GPE block | 263 | * gpe_number - GPE level within the GPE block |
| 250 | * Flags - Just enable, or also wake enable? | 264 | * type - Purpose the GPE will be used for |
| 251 | * Called from ISR or not | ||
| 252 | * | 265 | * |
| 253 | * RETURN: Status | 266 | * RETURN: Status |
| 254 | * | 267 | * |
| 255 | * DESCRIPTION: Enable an ACPI event (general purpose) | 268 | * DESCRIPTION: Take a reference to a GPE and enable it if necessary |
| 256 | * | 269 | * |
| 257 | ******************************************************************************/ | 270 | ******************************************************************************/ |
| 258 | acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number) | 271 | acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 type) |
| 259 | { | 272 | { |
| 260 | acpi_status status = AE_OK; | 273 | acpi_status status = AE_OK; |
| 261 | acpi_cpu_flags flags; | 274 | acpi_cpu_flags flags; |
| @@ -273,15 +286,32 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number) | |||
| 273 | goto unlock_and_exit; | 286 | goto unlock_and_exit; |
| 274 | } | 287 | } |
| 275 | 288 | ||
| 276 | /* Perform the enable */ | 289 | if (type & ACPI_GPE_TYPE_RUNTIME) { |
| 290 | if (++gpe_event_info->runtime_count == 1) | ||
| 291 | status = acpi_ev_enable_gpe(gpe_event_info, TRUE); | ||
| 277 | 292 | ||
| 278 | status = acpi_ev_enable_gpe(gpe_event_info, TRUE); | 293 | if (ACPI_FAILURE(status)) |
| 294 | gpe_event_info->runtime_count--; | ||
| 295 | } | ||
| 279 | 296 | ||
| 280 | unlock_and_exit: | 297 | if (type & ACPI_GPE_TYPE_WAKE) { |
| 298 | if (!(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) { | ||
| 299 | status = AE_BAD_PARAMETER; | ||
| 300 | goto unlock_and_exit; | ||
| 301 | } | ||
| 302 | |||
| 303 | /* | ||
| 304 | * Wake-up GPEs are only enabled right prior to putting the | ||
| 305 | * system into a sleep state. | ||
| 306 | */ | ||
| 307 | if (++gpe_event_info->wakeup_count == 1) | ||
| 308 | acpi_ev_update_gpe_enable_masks(gpe_event_info); | ||
| 309 | } | ||
| 310 | |||
| 311 | unlock_and_exit: | ||
| 281 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | 312 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); |
| 282 | return_ACPI_STATUS(status); | 313 | return_ACPI_STATUS(status); |
| 283 | } | 314 | } |
| 284 | |||
| 285 | ACPI_EXPORT_SYMBOL(acpi_enable_gpe) | 315 | ACPI_EXPORT_SYMBOL(acpi_enable_gpe) |
| 286 | 316 | ||
| 287 | /******************************************************************************* | 317 | /******************************************************************************* |
| @@ -290,15 +320,14 @@ ACPI_EXPORT_SYMBOL(acpi_enable_gpe) | |||
| 290 | * | 320 | * |
| 291 | * PARAMETERS: gpe_device - Parent GPE Device | 321 | * PARAMETERS: gpe_device - Parent GPE Device |
| 292 | * gpe_number - GPE level within the GPE block | 322 | * gpe_number - GPE level within the GPE block |
| 293 | * Flags - Just disable, or also wake disable? | 323 | * type - Purpose the GPE won't be used for any more |
| 294 | * Called from ISR or not | ||
| 295 | * | 324 | * |
| 296 | * RETURN: Status | 325 | * RETURN: Status |
| 297 | * | 326 | * |
| 298 | * DESCRIPTION: Disable an ACPI event (general purpose) | 327 | * DESCRIPTION: Release a reference to a GPE and disable it if necessary |
| 299 | * | 328 | * |
| 300 | ******************************************************************************/ | 329 | ******************************************************************************/ |
| 301 | acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number) | 330 | acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 type) |
| 302 | { | 331 | { |
| 303 | acpi_status status = AE_OK; | 332 | acpi_status status = AE_OK; |
| 304 | acpi_cpu_flags flags; | 333 | acpi_cpu_flags flags; |
| @@ -315,13 +344,24 @@ acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number) | |||
| 315 | goto unlock_and_exit; | 344 | goto unlock_and_exit; |
| 316 | } | 345 | } |
| 317 | 346 | ||
| 318 | status = acpi_ev_disable_gpe(gpe_event_info); | 347 | if ((type & ACPI_GPE_TYPE_WAKE) && gpe_event_info->runtime_count) { |
| 348 | if (--gpe_event_info->runtime_count == 0) | ||
| 349 | acpi_ev_disable_gpe(gpe_event_info); | ||
| 350 | } | ||
| 351 | |||
| 352 | if ((type & ACPI_GPE_TYPE_RUNTIME) && gpe_event_info->wakeup_count) { | ||
| 353 | /* | ||
| 354 | * Wake-up GPEs are not enabled after leaving system sleep | ||
| 355 | * states, so we don't need to disable them here. | ||
| 356 | */ | ||
| 357 | if (--gpe_event_info->wakeup_count == 0) | ||
| 358 | acpi_ev_update_gpe_enable_masks(gpe_event_info); | ||
| 359 | } | ||
| 319 | 360 | ||
| 320 | unlock_and_exit: | 361 | unlock_and_exit: |
| 321 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | 362 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); |
| 322 | return_ACPI_STATUS(status); | 363 | return_ACPI_STATUS(status); |
| 323 | } | 364 | } |
| 324 | |||
| 325 | ACPI_EXPORT_SYMBOL(acpi_disable_gpe) | 365 | ACPI_EXPORT_SYMBOL(acpi_disable_gpe) |
| 326 | 366 | ||
| 327 | /******************************************************************************* | 367 | /******************************************************************************* |
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index 8a95e8329df7..09ca3ce7a051 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c | |||
| @@ -422,11 +422,9 @@ static int acpi_button_add(struct acpi_device *device) | |||
| 422 | 422 | ||
| 423 | if (device->wakeup.flags.valid) { | 423 | if (device->wakeup.flags.valid) { |
| 424 | /* Button's GPE is run-wake GPE */ | 424 | /* Button's GPE is run-wake GPE */ |
| 425 | acpi_set_gpe_type(device->wakeup.gpe_device, | ||
| 426 | device->wakeup.gpe_number, | ||
| 427 | ACPI_GPE_TYPE_WAKE_RUN); | ||
| 428 | acpi_enable_gpe(device->wakeup.gpe_device, | 425 | acpi_enable_gpe(device->wakeup.gpe_device, |
| 429 | device->wakeup.gpe_number); | 426 | device->wakeup.gpe_number, |
| 427 | ACPI_GPE_TYPE_WAKE_RUN); | ||
| 430 | device->wakeup.state.enabled = 1; | 428 | device->wakeup.state.enabled = 1; |
| 431 | } | 429 | } |
| 432 | 430 | ||
| @@ -446,6 +444,13 @@ static int acpi_button_remove(struct acpi_device *device, int type) | |||
| 446 | { | 444 | { |
| 447 | struct acpi_button *button = acpi_driver_data(device); | 445 | struct acpi_button *button = acpi_driver_data(device); |
| 448 | 446 | ||
| 447 | if (device->wakeup.flags.valid) { | ||
| 448 | acpi_disable_gpe(device->wakeup.gpe_device, | ||
| 449 | device->wakeup.gpe_number, | ||
| 450 | ACPI_GPE_TYPE_WAKE_RUN); | ||
| 451 | device->wakeup.state.enabled = 0; | ||
| 452 | } | ||
| 453 | |||
| 449 | acpi_button_remove_fs(device); | 454 | acpi_button_remove_fs(device); |
| 450 | input_unregister_device(button->input); | 455 | input_unregister_device(button->input); |
| 451 | kfree(button); | 456 | kfree(button); |
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index d6471bb6852f..0fa65a8210da 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
| @@ -307,7 +307,7 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) | |||
| 307 | pr_debug(PREFIX "transaction start\n"); | 307 | pr_debug(PREFIX "transaction start\n"); |
| 308 | /* disable GPE during transaction if storm is detected */ | 308 | /* disable GPE during transaction if storm is detected */ |
| 309 | if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { | 309 | if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { |
| 310 | acpi_disable_gpe(NULL, ec->gpe); | 310 | acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_DISABLE); |
| 311 | } | 311 | } |
| 312 | 312 | ||
| 313 | status = acpi_ec_transaction_unlocked(ec, t); | 313 | status = acpi_ec_transaction_unlocked(ec, t); |
| @@ -317,7 +317,7 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) | |||
| 317 | if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { | 317 | if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { |
| 318 | msleep(1); | 318 | msleep(1); |
| 319 | /* it is safe to enable GPE outside of transaction */ | 319 | /* it is safe to enable GPE outside of transaction */ |
| 320 | acpi_enable_gpe(NULL, ec->gpe); | 320 | acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_ENABLE); |
| 321 | } else if (t->irq_count > ACPI_EC_STORM_THRESHOLD) { | 321 | } else if (t->irq_count > ACPI_EC_STORM_THRESHOLD) { |
| 322 | pr_info(PREFIX "GPE storm detected, " | 322 | pr_info(PREFIX "GPE storm detected, " |
| 323 | "transactions will use polling mode\n"); | 323 | "transactions will use polling mode\n"); |
| @@ -788,8 +788,8 @@ static int ec_install_handlers(struct acpi_ec *ec) | |||
| 788 | &acpi_ec_gpe_handler, ec); | 788 | &acpi_ec_gpe_handler, ec); |
| 789 | if (ACPI_FAILURE(status)) | 789 | if (ACPI_FAILURE(status)) |
| 790 | return -ENODEV; | 790 | return -ENODEV; |
| 791 | acpi_set_gpe_type(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME); | 791 | |
| 792 | acpi_enable_gpe(NULL, ec->gpe); | 792 | acpi_enable_gpe(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME); |
| 793 | status = acpi_install_address_space_handler(ec->handle, | 793 | status = acpi_install_address_space_handler(ec->handle, |
| 794 | ACPI_ADR_SPACE_EC, | 794 | ACPI_ADR_SPACE_EC, |
| 795 | &acpi_ec_space_handler, | 795 | &acpi_ec_space_handler, |
| @@ -806,6 +806,7 @@ static int ec_install_handlers(struct acpi_ec *ec) | |||
| 806 | } else { | 806 | } else { |
| 807 | acpi_remove_gpe_handler(NULL, ec->gpe, | 807 | acpi_remove_gpe_handler(NULL, ec->gpe, |
| 808 | &acpi_ec_gpe_handler); | 808 | &acpi_ec_gpe_handler); |
| 809 | acpi_disable_gpe(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME); | ||
| 809 | return -ENODEV; | 810 | return -ENODEV; |
| 810 | } | 811 | } |
| 811 | } | 812 | } |
| @@ -816,6 +817,7 @@ static int ec_install_handlers(struct acpi_ec *ec) | |||
| 816 | 817 | ||
| 817 | static void ec_remove_handlers(struct acpi_ec *ec) | 818 | static void ec_remove_handlers(struct acpi_ec *ec) |
| 818 | { | 819 | { |
| 820 | acpi_disable_gpe(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME); | ||
| 819 | if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle, | 821 | if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle, |
| 820 | ACPI_ADR_SPACE_EC, &acpi_ec_space_handler))) | 822 | ACPI_ADR_SPACE_EC, &acpi_ec_space_handler))) |
| 821 | pr_err(PREFIX "failed to remove space handler\n"); | 823 | pr_err(PREFIX "failed to remove space handler\n"); |
| @@ -1058,7 +1060,7 @@ static int acpi_ec_suspend(struct acpi_device *device, pm_message_t state) | |||
| 1058 | { | 1060 | { |
| 1059 | struct acpi_ec *ec = acpi_driver_data(device); | 1061 | struct acpi_ec *ec = acpi_driver_data(device); |
| 1060 | /* Stop using GPE */ | 1062 | /* Stop using GPE */ |
| 1061 | acpi_disable_gpe(NULL, ec->gpe); | 1063 | acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_DISABLE); |
| 1062 | return 0; | 1064 | return 0; |
| 1063 | } | 1065 | } |
| 1064 | 1066 | ||
| @@ -1066,7 +1068,7 @@ static int acpi_ec_resume(struct acpi_device *device) | |||
| 1066 | { | 1068 | { |
| 1067 | struct acpi_ec *ec = acpi_driver_data(device); | 1069 | struct acpi_ec *ec = acpi_driver_data(device); |
| 1068 | /* Enable use of GPE back */ | 1070 | /* Enable use of GPE back */ |
| 1069 | acpi_enable_gpe(NULL, ec->gpe); | 1071 | acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_ENABLE); |
| 1070 | return 0; | 1072 | return 0; |
| 1071 | } | 1073 | } |
| 1072 | 1074 | ||
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 79d33d908b5a..3bde594a9979 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c | |||
| @@ -745,9 +745,18 @@ int acpi_pm_device_sleep_wake(struct device *dev, bool enable) | |||
| 745 | return -ENODEV; | 745 | return -ENODEV; |
| 746 | } | 746 | } |
| 747 | 747 | ||
| 748 | error = enable ? | 748 | if (enable) { |
| 749 | acpi_enable_wakeup_device_power(adev, acpi_target_sleep_state) : | 749 | error = acpi_enable_wakeup_device_power(adev, |
| 750 | acpi_disable_wakeup_device_power(adev); | 750 | acpi_target_sleep_state); |
| 751 | if (!error) | ||
| 752 | acpi_enable_gpe(adev->wakeup.gpe_device, | ||
| 753 | adev->wakeup.gpe_number, | ||
| 754 | ACPI_GPE_TYPE_WAKE); | ||
| 755 | } else { | ||
| 756 | acpi_disable_gpe(adev->wakeup.gpe_device, adev->wakeup.gpe_number, | ||
| 757 | ACPI_GPE_TYPE_WAKE); | ||
| 758 | error = acpi_disable_wakeup_device_power(adev); | ||
| 759 | } | ||
| 751 | if (!error) | 760 | if (!error) |
| 752 | dev_info(dev, "wake-up capability %s by ACPI\n", | 761 | dev_info(dev, "wake-up capability %s by ACPI\n", |
| 753 | enable ? "enabled" : "disabled"); | 762 | enable ? "enabled" : "disabled"); |
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c index d11282975f35..a206a12da78a 100644 --- a/drivers/acpi/system.c +++ b/drivers/acpi/system.c | |||
| @@ -387,10 +387,10 @@ static ssize_t counter_set(struct kobject *kobj, | |||
| 387 | if (index < num_gpes) { | 387 | if (index < num_gpes) { |
| 388 | if (!strcmp(buf, "disable\n") && | 388 | if (!strcmp(buf, "disable\n") && |
| 389 | (status & ACPI_EVENT_FLAG_ENABLED)) | 389 | (status & ACPI_EVENT_FLAG_ENABLED)) |
| 390 | result = acpi_disable_gpe(handle, index); | 390 | result = acpi_set_gpe(handle, index, ACPI_GPE_DISABLE); |
| 391 | else if (!strcmp(buf, "enable\n") && | 391 | else if (!strcmp(buf, "enable\n") && |
| 392 | !(status & ACPI_EVENT_FLAG_ENABLED)) | 392 | !(status & ACPI_EVENT_FLAG_ENABLED)) |
| 393 | result = acpi_enable_gpe(handle, index); | 393 | result = acpi_set_gpe(handle, index, ACPI_GPE_ENABLE); |
| 394 | else if (!strcmp(buf, "clear\n") && | 394 | else if (!strcmp(buf, "clear\n") && |
| 395 | (status & ACPI_EVENT_FLAG_SET)) | 395 | (status & ACPI_EVENT_FLAG_SET)) |
| 396 | result = acpi_clear_gpe(handle, index, ACPI_NOT_ISR); | 396 | result = acpi_clear_gpe(handle, index, ACPI_NOT_ISR); |
diff --git a/drivers/acpi/wakeup.c b/drivers/acpi/wakeup.c index e0ee0c036f5a..6783986c7469 100644 --- a/drivers/acpi/wakeup.c +++ b/drivers/acpi/wakeup.c | |||
| @@ -21,12 +21,12 @@ | |||
| 21 | ACPI_MODULE_NAME("wakeup_devices") | 21 | ACPI_MODULE_NAME("wakeup_devices") |
| 22 | 22 | ||
| 23 | /** | 23 | /** |
| 24 | * acpi_enable_wakeup_device_prep - prepare wakeup devices | 24 | * acpi_enable_wakeup_device_prep - Prepare wake-up devices. |
| 25 | * @sleep_state: ACPI state | 25 | * @sleep_state: ACPI system sleep state. |
| 26 | * Enable all wakup devices power if the devices' wakeup level | 26 | * |
| 27 | * is higher than requested sleep level | 27 | * Enable all wake-up devices' power, unless the requested system sleep state is |
| 28 | * too deep. | ||
| 28 | */ | 29 | */ |
| 29 | |||
| 30 | void acpi_enable_wakeup_device_prep(u8 sleep_state) | 30 | void acpi_enable_wakeup_device_prep(u8 sleep_state) |
| 31 | { | 31 | { |
| 32 | struct list_head *node, *next; | 32 | struct list_head *node, *next; |
| @@ -36,9 +36,8 @@ void acpi_enable_wakeup_device_prep(u8 sleep_state) | |||
| 36 | struct acpi_device, | 36 | struct acpi_device, |
| 37 | wakeup_list); | 37 | wakeup_list); |
| 38 | 38 | ||
| 39 | if (!dev->wakeup.flags.valid || | 39 | if (!dev->wakeup.flags.valid || !dev->wakeup.state.enabled |
| 40 | !dev->wakeup.state.enabled || | 40 | || (sleep_state > (u32) dev->wakeup.sleep_state)) |
| 41 | (sleep_state > (u32) dev->wakeup.sleep_state)) | ||
| 42 | continue; | 41 | continue; |
| 43 | 42 | ||
| 44 | acpi_enable_wakeup_device_power(dev, sleep_state); | 43 | acpi_enable_wakeup_device_power(dev, sleep_state); |
| @@ -46,9 +45,12 @@ void acpi_enable_wakeup_device_prep(u8 sleep_state) | |||
| 46 | } | 45 | } |
| 47 | 46 | ||
| 48 | /** | 47 | /** |
| 49 | * acpi_enable_wakeup_device - enable wakeup devices | 48 | * acpi_enable_wakeup_device - Enable wake-up device GPEs. |
| 50 | * @sleep_state: ACPI state | 49 | * @sleep_state: ACPI system sleep state. |
| 51 | * Enable all wakup devices's GPE | 50 | * |
| 51 | * Enable all wake-up devices' GPEs, with the assumption that | ||
| 52 | * acpi_disable_all_gpes() was executed before, so we don't need to disable any | ||
| 53 | * GPEs here. | ||
| 52 | */ | 54 | */ |
| 53 | void acpi_enable_wakeup_device(u8 sleep_state) | 55 | void acpi_enable_wakeup_device(u8 sleep_state) |
| 54 | { | 56 | { |
| @@ -65,29 +67,22 @@ void acpi_enable_wakeup_device(u8 sleep_state) | |||
| 65 | if (!dev->wakeup.flags.valid) | 67 | if (!dev->wakeup.flags.valid) |
| 66 | continue; | 68 | continue; |
| 67 | 69 | ||
| 68 | /* If users want to disable run-wake GPE, | ||
| 69 | * we only disable it for wake and leave it for runtime | ||
| 70 | */ | ||
| 71 | if ((!dev->wakeup.state.enabled && !dev->wakeup.prepare_count) | 70 | if ((!dev->wakeup.state.enabled && !dev->wakeup.prepare_count) |
| 72 | || sleep_state > (u32) dev->wakeup.sleep_state) { | 71 | || sleep_state > (u32) dev->wakeup.sleep_state) |
| 73 | if (dev->wakeup.flags.run_wake) { | ||
| 74 | /* set_gpe_type will disable GPE, leave it like that */ | ||
| 75 | acpi_set_gpe_type(dev->wakeup.gpe_device, | ||
| 76 | dev->wakeup.gpe_number, | ||
| 77 | ACPI_GPE_TYPE_RUNTIME); | ||
| 78 | } | ||
| 79 | continue; | 72 | continue; |
| 80 | } | 73 | |
| 81 | if (!dev->wakeup.flags.run_wake) | 74 | /* The wake-up power should have been enabled already. */ |
| 82 | acpi_enable_gpe(dev->wakeup.gpe_device, | 75 | acpi_set_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number, |
| 83 | dev->wakeup.gpe_number); | 76 | ACPI_GPE_ENABLE); |
| 84 | } | 77 | } |
| 85 | } | 78 | } |
| 86 | 79 | ||
| 87 | /** | 80 | /** |
| 88 | * acpi_disable_wakeup_device - disable devices' wakeup capability | 81 | * acpi_disable_wakeup_device - Disable devices' wakeup capability. |
| 89 | * @sleep_state: ACPI state | 82 | * @sleep_state: ACPI system sleep state. |
| 90 | * Disable all wakup devices's GPE and wakeup capability | 83 | * |
| 84 | * This function only affects devices with wakeup.state.enabled set, which means | ||
| 85 | * that it reverses the changes made by acpi_enable_wakeup_device_prep(). | ||
| 91 | */ | 86 | */ |
| 92 | void acpi_disable_wakeup_device(u8 sleep_state) | 87 | void acpi_disable_wakeup_device(u8 sleep_state) |
| 93 | { | 88 | { |
| @@ -97,30 +92,11 @@ void acpi_disable_wakeup_device(u8 sleep_state) | |||
| 97 | struct acpi_device *dev = | 92 | struct acpi_device *dev = |
| 98 | container_of(node, struct acpi_device, wakeup_list); | 93 | container_of(node, struct acpi_device, wakeup_list); |
| 99 | 94 | ||
| 100 | if (!dev->wakeup.flags.valid) | 95 | if (!dev->wakeup.flags.valid || !dev->wakeup.state.enabled |
| 101 | continue; | 96 | || (sleep_state > (u32) dev->wakeup.sleep_state)) |
| 102 | |||
| 103 | if ((!dev->wakeup.state.enabled && !dev->wakeup.prepare_count) | ||
| 104 | || sleep_state > (u32) dev->wakeup.sleep_state) { | ||
| 105 | if (dev->wakeup.flags.run_wake) { | ||
| 106 | acpi_set_gpe_type(dev->wakeup.gpe_device, | ||
| 107 | dev->wakeup.gpe_number, | ||
| 108 | ACPI_GPE_TYPE_WAKE_RUN); | ||
| 109 | /* Re-enable it, since set_gpe_type will disable it */ | ||
| 110 | acpi_enable_gpe(dev->wakeup.gpe_device, | ||
| 111 | dev->wakeup.gpe_number); | ||
| 112 | } | ||
| 113 | continue; | 97 | continue; |
| 114 | } | ||
| 115 | 98 | ||
| 116 | acpi_disable_wakeup_device_power(dev); | 99 | acpi_disable_wakeup_device_power(dev); |
| 117 | /* Never disable run-wake GPE */ | ||
| 118 | if (!dev->wakeup.flags.run_wake) { | ||
| 119 | acpi_disable_gpe(dev->wakeup.gpe_device, | ||
| 120 | dev->wakeup.gpe_number); | ||
| 121 | acpi_clear_gpe(dev->wakeup.gpe_device, | ||
| 122 | dev->wakeup.gpe_number, ACPI_NOT_ISR); | ||
| 123 | } | ||
| 124 | } | 100 | } |
| 125 | } | 101 | } |
| 126 | 102 | ||
| @@ -136,11 +112,8 @@ int __init acpi_wakeup_device_init(void) | |||
| 136 | /* In case user doesn't load button driver */ | 112 | /* In case user doesn't load button driver */ |
| 137 | if (!dev->wakeup.flags.run_wake || dev->wakeup.state.enabled) | 113 | if (!dev->wakeup.flags.run_wake || dev->wakeup.state.enabled) |
| 138 | continue; | 114 | continue; |
| 139 | acpi_set_gpe_type(dev->wakeup.gpe_device, | 115 | acpi_enable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number, |
| 140 | dev->wakeup.gpe_number, | 116 | ACPI_GPE_TYPE_WAKE); |
| 141 | ACPI_GPE_TYPE_WAKE_RUN); | ||
| 142 | acpi_enable_gpe(dev->wakeup.gpe_device, | ||
| 143 | dev->wakeup.gpe_number); | ||
| 144 | dev->wakeup.state.enabled = 1; | 117 | dev->wakeup.state.enabled = 1; |
| 145 | } | 118 | } |
| 146 | mutex_unlock(&acpi_device_lock); | 119 | mutex_unlock(&acpi_device_lock); |
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index 86e9735a96bd..3988f93b9c66 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h | |||
| @@ -281,11 +281,11 @@ acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status); | |||
| 281 | /* | 281 | /* |
| 282 | * GPE Interfaces | 282 | * GPE Interfaces |
| 283 | */ | 283 | */ |
| 284 | acpi_status acpi_set_gpe_type(acpi_handle gpe_device, u32 gpe_number, u8 type); | 284 | acpi_status acpi_set_gpe(acpi_handle gpe_device, u32 gpe_number, u8 action); |
| 285 | 285 | ||
| 286 | acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number); | 286 | acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 type); |
| 287 | 287 | ||
| 288 | acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number); | 288 | acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 type); |
| 289 | 289 | ||
| 290 | acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags); | 290 | acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags); |
| 291 | 291 | ||
diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index 153f12dc3373..73af40863371 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h | |||
| @@ -668,15 +668,16 @@ typedef u32 acpi_event_status; | |||
| 668 | 668 | ||
| 669 | /* | 669 | /* |
| 670 | * GPE info flags - Per GPE | 670 | * GPE info flags - Per GPE |
| 671 | * +-+-+-+---+---+-+ | 671 | * +-+-+-+---+-+-+-+ |
| 672 | * |7|6|5|4:3|2:1|0| | 672 | * |7|6|5|4:3|2|1|0| |
| 673 | * +-+-+-+---+---+-+ | 673 | * +-+-+-+---+-+-+-+ |
| 674 | * | | | | | | | 674 | * | | | | | | | |
| 675 | * | | | | | +--- Interrupt type: Edge or Level Triggered | 675 | * | | | | | | +--- Interrupt type: Edge or Level Triggered |
| 676 | * | | | | +--- Type: Wake-only, Runtime-only, or wake/runtime | 676 | * | | | | | +--- GPE can wake the system |
| 677 | * | | | | +--- Unused | ||
| 677 | * | | | +--- Type of dispatch -- to method, handler, or none | 678 | * | | | +--- Type of dispatch -- to method, handler, or none |
| 678 | * | | +--- Enabled for runtime? | 679 | * | | +--- Unused |
| 679 | * | +--- Enabled for wake? | 680 | * | +--- Unused |
| 680 | * +--- Unused | 681 | * +--- Unused |
| 681 | */ | 682 | */ |
| 682 | #define ACPI_GPE_XRUPT_TYPE_MASK (u8) 0x01 | 683 | #define ACPI_GPE_XRUPT_TYPE_MASK (u8) 0x01 |
| @@ -687,22 +688,13 @@ typedef u32 acpi_event_status; | |||
| 687 | #define ACPI_GPE_TYPE_WAKE_RUN (u8) 0x06 | 688 | #define ACPI_GPE_TYPE_WAKE_RUN (u8) 0x06 |
| 688 | #define ACPI_GPE_TYPE_WAKE (u8) 0x02 | 689 | #define ACPI_GPE_TYPE_WAKE (u8) 0x02 |
| 689 | #define ACPI_GPE_TYPE_RUNTIME (u8) 0x04 /* Default */ | 690 | #define ACPI_GPE_TYPE_RUNTIME (u8) 0x04 /* Default */ |
| 691 | #define ACPI_GPE_CAN_WAKE (u8) 0x02 | ||
| 690 | 692 | ||
| 691 | #define ACPI_GPE_DISPATCH_MASK (u8) 0x18 | 693 | #define ACPI_GPE_DISPATCH_MASK (u8) 0x18 |
| 692 | #define ACPI_GPE_DISPATCH_HANDLER (u8) 0x08 | 694 | #define ACPI_GPE_DISPATCH_HANDLER (u8) 0x08 |
| 693 | #define ACPI_GPE_DISPATCH_METHOD (u8) 0x10 | 695 | #define ACPI_GPE_DISPATCH_METHOD (u8) 0x10 |
| 694 | #define ACPI_GPE_DISPATCH_NOT_USED (u8) 0x00 /* Default */ | 696 | #define ACPI_GPE_DISPATCH_NOT_USED (u8) 0x00 /* Default */ |
| 695 | 697 | ||
| 696 | #define ACPI_GPE_RUN_ENABLE_MASK (u8) 0x20 | ||
| 697 | #define ACPI_GPE_RUN_ENABLED (u8) 0x20 | ||
| 698 | #define ACPI_GPE_RUN_DISABLED (u8) 0x00 /* Default */ | ||
| 699 | |||
| 700 | #define ACPI_GPE_WAKE_ENABLE_MASK (u8) 0x40 | ||
| 701 | #define ACPI_GPE_WAKE_ENABLED (u8) 0x40 | ||
| 702 | #define ACPI_GPE_WAKE_DISABLED (u8) 0x00 /* Default */ | ||
| 703 | |||
| 704 | #define ACPI_GPE_ENABLE_MASK (u8) 0x60 /* Both run/wake */ | ||
| 705 | |||
| 706 | /* | 698 | /* |
| 707 | * Flags for GPE and Lock interfaces | 699 | * Flags for GPE and Lock interfaces |
| 708 | */ | 700 | */ |
