diff options
Diffstat (limited to 'drivers/acpi')
-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 |
11 files changed, 175 insertions, 304 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); |