diff options
Diffstat (limited to 'drivers/acpi/acpica')
-rw-r--r-- | drivers/acpi/acpica/acevents.h | 10 | ||||
-rw-r--r-- | drivers/acpi/acpica/aclocal.h | 2 | ||||
-rw-r--r-- | drivers/acpi/acpica/acobject.h | 2 | ||||
-rw-r--r-- | drivers/acpi/acpica/evgpe.c | 161 | ||||
-rw-r--r-- | drivers/acpi/acpica/evgpeblk.c | 87 | ||||
-rw-r--r-- | drivers/acpi/acpica/evmisc.c | 12 | ||||
-rw-r--r-- | drivers/acpi/acpica/evxface.c | 189 | ||||
-rw-r--r-- | drivers/acpi/acpica/evxfevnt.c | 96 |
8 files changed, 276 insertions, 283 deletions
diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h index 0bba148a2c61..4ced54f7a5d9 100644 --- a/drivers/acpi/acpica/acevents.h +++ b/drivers/acpi/acpica/acevents.h | |||
@@ -76,12 +76,9 @@ 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 acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info); |
83 | acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info, | ||
84 | u8 write_to_hardware); | ||
85 | 82 | ||
86 | acpi_status acpi_ev_disable_gpe(struct acpi_gpe_event_info *gpe_event_info); | 83 | acpi_status acpi_ev_disable_gpe(struct acpi_gpe_event_info *gpe_event_info); |
87 | 84 | ||
@@ -122,9 +119,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); | 119 | u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info *gpe_xrupt_list); |
123 | 120 | ||
124 | acpi_status | 121 | 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); | 122 | acpi_ev_check_for_wake_only_gpe(struct acpi_gpe_event_info *gpe_event_info); |
129 | 123 | ||
130 | acpi_status acpi_ev_gpe_initialize(void); | 124 | 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/acobject.h b/drivers/acpi/acpica/acobject.h index 64062b1be3ee..07f6e2ea2ee5 100644 --- a/drivers/acpi/acpica/acobject.h +++ b/drivers/acpi/acpica/acobject.h | |||
@@ -287,8 +287,10 @@ struct acpi_object_buffer_field { | |||
287 | 287 | ||
288 | struct acpi_object_notify_handler { | 288 | struct acpi_object_notify_handler { |
289 | ACPI_OBJECT_COMMON_HEADER struct acpi_namespace_node *node; /* Parent device */ | 289 | ACPI_OBJECT_COMMON_HEADER struct acpi_namespace_node *node; /* Parent device */ |
290 | u32 handler_type; | ||
290 | acpi_notify_handler handler; | 291 | acpi_notify_handler handler; |
291 | void *context; | 292 | void *context; |
293 | struct acpi_object_notify_handler *next; | ||
292 | }; | 294 | }; |
293 | 295 | ||
294 | struct acpi_object_addr_handler { | 296 | struct acpi_object_addr_handler { |
diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index afacf4416c73..0b453467a5a0 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 | } |
@@ -167,8 +98,6 @@ acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info, | |||
167 | * FUNCTION: acpi_ev_enable_gpe | 98 | * FUNCTION: acpi_ev_enable_gpe |
168 | * | 99 | * |
169 | * PARAMETERS: gpe_event_info - GPE to enable | 100 | * PARAMETERS: gpe_event_info - GPE to enable |
170 | * write_to_hardware - Enable now, or just mark data structs | ||
171 | * (WAKE GPEs should be deferred) | ||
172 | * | 101 | * |
173 | * RETURN: Status | 102 | * RETURN: Status |
174 | * | 103 | * |
@@ -176,9 +105,7 @@ acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info, | |||
176 | * | 105 | * |
177 | ******************************************************************************/ | 106 | ******************************************************************************/ |
178 | 107 | ||
179 | acpi_status | 108 | acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info) |
180 | acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info, | ||
181 | u8 write_to_hardware) | ||
182 | { | 109 | { |
183 | acpi_status status; | 110 | acpi_status status; |
184 | 111 | ||
@@ -186,47 +113,20 @@ acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info, | |||
186 | 113 | ||
187 | /* Make sure HW enable masks are updated */ | 114 | /* Make sure HW enable masks are updated */ |
188 | 115 | ||
189 | status = | 116 | status = acpi_ev_update_gpe_enable_masks(gpe_event_info); |
190 | acpi_ev_update_gpe_enable_masks(gpe_event_info, ACPI_GPE_ENABLE); | 117 | if (ACPI_FAILURE(status)) |
191 | if (ACPI_FAILURE(status)) { | ||
192 | return_ACPI_STATUS(status); | 118 | return_ACPI_STATUS(status); |
193 | } | ||
194 | 119 | ||
195 | /* Mark wake-enabled or HW enable, or both */ | 120 | /* Mark wake-enabled or HW enable, or both */ |
196 | 121 | ||
197 | switch (gpe_event_info->flags & ACPI_GPE_TYPE_MASK) { | 122 | if (gpe_event_info->runtime_count) { |
198 | case ACPI_GPE_TYPE_WAKE: | 123 | /* Clear the GPE (of stale events), then enable it */ |
199 | 124 | status = acpi_hw_clear_gpe(gpe_event_info); | |
200 | ACPI_SET_BIT(gpe_event_info->flags, ACPI_GPE_WAKE_ENABLED); | 125 | if (ACPI_FAILURE(status)) |
201 | break; | 126 | 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 | 127 | ||
228 | default: | 128 | /* Enable the requested runtime GPE */ |
229 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 129 | status = acpi_hw_write_gpe_enable_reg(gpe_event_info); |
230 | } | 130 | } |
231 | 131 | ||
232 | return_ACPI_STATUS(AE_OK); | 132 | return_ACPI_STATUS(AE_OK); |
@@ -252,34 +152,9 @@ acpi_status acpi_ev_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) | |||
252 | 152 | ||
253 | /* Make sure HW enable masks are updated */ | 153 | /* Make sure HW enable masks are updated */ |
254 | 154 | ||
255 | status = | 155 | status = acpi_ev_update_gpe_enable_masks(gpe_event_info); |
256 | acpi_ev_update_gpe_enable_masks(gpe_event_info, ACPI_GPE_DISABLE); | 156 | if (ACPI_FAILURE(status)) |
257 | if (ACPI_FAILURE(status)) { | ||
258 | return_ACPI_STATUS(status); | 157 | 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 | 158 | ||
284 | /* | 159 | /* |
285 | * Even if we don't know the GPE type, make sure that we always | 160 | * Even if we don't know the GPE type, make sure that we always |
@@ -521,7 +396,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) | |||
521 | 396 | ||
522 | /* Set the GPE flags for return to enabled state */ | 397 | /* Set the GPE flags for return to enabled state */ |
523 | 398 | ||
524 | (void)acpi_ev_enable_gpe(gpe_event_info, FALSE); | 399 | (void)acpi_ev_update_gpe_enable_masks(gpe_event_info); |
525 | 400 | ||
526 | /* | 401 | /* |
527 | * Take a snapshot of the GPE info for this level - we copy the info to | 402 | * Take a snapshot of the GPE info for this level - we copy the info to |
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/evmisc.c b/drivers/acpi/acpica/evmisc.c index ce224e1eaa89..8f0fac6c4366 100644 --- a/drivers/acpi/acpica/evmisc.c +++ b/drivers/acpi/acpica/evmisc.c | |||
@@ -259,9 +259,15 @@ static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context) | |||
259 | 259 | ||
260 | handler_obj = notify_info->notify.handler_obj; | 260 | handler_obj = notify_info->notify.handler_obj; |
261 | if (handler_obj) { | 261 | if (handler_obj) { |
262 | handler_obj->notify.handler(notify_info->notify.node, | 262 | struct acpi_object_notify_handler *notifier; |
263 | notify_info->notify.value, | 263 | |
264 | handler_obj->notify.context); | 264 | notifier = &handler_obj->notify; |
265 | while (notifier) { | ||
266 | notifier->handler(notify_info->notify.node, | ||
267 | notify_info->notify.value, | ||
268 | notifier->context); | ||
269 | notifier = notifier->next; | ||
270 | } | ||
265 | } | 271 | } |
266 | 272 | ||
267 | /* All done with the info object */ | 273 | /* All done with the info object */ |
diff --git a/drivers/acpi/acpica/evxface.c b/drivers/acpi/acpica/evxface.c index 2fe0809d4eb2..474e2cab603d 100644 --- a/drivers/acpi/acpica/evxface.c +++ b/drivers/acpi/acpica/evxface.c | |||
@@ -218,6 +218,72 @@ ACPI_EXPORT_SYMBOL(acpi_remove_fixed_event_handler) | |||
218 | 218 | ||
219 | /******************************************************************************* | 219 | /******************************************************************************* |
220 | * | 220 | * |
221 | * FUNCTION: acpi_populate_handler_object | ||
222 | * | ||
223 | * PARAMETERS: handler_obj - Handler object to populate | ||
224 | * handler_type - The type of handler: | ||
225 | * ACPI_SYSTEM_NOTIFY: system_handler (00-7f) | ||
226 | * ACPI_DEVICE_NOTIFY: driver_handler (80-ff) | ||
227 | * ACPI_ALL_NOTIFY: both system and device | ||
228 | * handler - Address of the handler | ||
229 | * context - Value passed to the handler on each GPE | ||
230 | * next - Address of a handler object to link to | ||
231 | * | ||
232 | * RETURN: None | ||
233 | * | ||
234 | * DESCRIPTION: Populate a handler object. | ||
235 | * | ||
236 | ******************************************************************************/ | ||
237 | static void | ||
238 | acpi_populate_handler_object(struct acpi_object_notify_handler *handler_obj, | ||
239 | u32 handler_type, | ||
240 | acpi_notify_handler handler, void *context, | ||
241 | struct acpi_object_notify_handler *next) | ||
242 | { | ||
243 | handler_obj->handler_type = handler_type; | ||
244 | handler_obj->handler = handler; | ||
245 | handler_obj->context = context; | ||
246 | handler_obj->next = next; | ||
247 | } | ||
248 | |||
249 | /******************************************************************************* | ||
250 | * | ||
251 | * FUNCTION: acpi_add_handler_object | ||
252 | * | ||
253 | * PARAMETERS: parent_obj - Parent of the new object | ||
254 | * handler - Address of the handler | ||
255 | * context - Value passed to the handler on each GPE | ||
256 | * | ||
257 | * RETURN: Status | ||
258 | * | ||
259 | * DESCRIPTION: Create a new handler object and populate it. | ||
260 | * | ||
261 | ******************************************************************************/ | ||
262 | static acpi_status | ||
263 | acpi_add_handler_object(struct acpi_object_notify_handler *parent_obj, | ||
264 | acpi_notify_handler handler, void *context) | ||
265 | { | ||
266 | struct acpi_object_notify_handler *handler_obj; | ||
267 | |||
268 | /* The parent must not be a defice notify handler object. */ | ||
269 | if (parent_obj->handler_type & ACPI_DEVICE_NOTIFY) | ||
270 | return AE_BAD_PARAMETER; | ||
271 | |||
272 | handler_obj = ACPI_ALLOCATE_ZEROED(sizeof(*handler_obj)); | ||
273 | if (!handler_obj) | ||
274 | return AE_NO_MEMORY; | ||
275 | |||
276 | acpi_populate_handler_object(handler_obj, | ||
277 | ACPI_SYSTEM_NOTIFY, | ||
278 | handler, context, | ||
279 | parent_obj->next); | ||
280 | parent_obj->next = handler_obj; | ||
281 | |||
282 | return AE_OK; | ||
283 | } | ||
284 | |||
285 | /******************************************************************************* | ||
286 | * | ||
221 | * FUNCTION: acpi_install_notify_handler | 287 | * FUNCTION: acpi_install_notify_handler |
222 | * | 288 | * |
223 | * PARAMETERS: Device - The device for which notifies will be handled | 289 | * PARAMETERS: Device - The device for which notifies will be handled |
@@ -316,15 +382,32 @@ acpi_install_notify_handler(acpi_handle device, | |||
316 | obj_desc = acpi_ns_get_attached_object(node); | 382 | obj_desc = acpi_ns_get_attached_object(node); |
317 | if (obj_desc) { | 383 | if (obj_desc) { |
318 | 384 | ||
319 | /* Object exists - make sure there's no handler */ | 385 | /* Object exists. */ |
320 | 386 | ||
321 | if (((handler_type & ACPI_SYSTEM_NOTIFY) && | 387 | /* For a device notify, make sure there's no handler. */ |
322 | obj_desc->common_notify.system_notify) || | 388 | if ((handler_type & ACPI_DEVICE_NOTIFY) && |
323 | ((handler_type & ACPI_DEVICE_NOTIFY) && | 389 | obj_desc->common_notify.device_notify) { |
324 | obj_desc->common_notify.device_notify)) { | ||
325 | status = AE_ALREADY_EXISTS; | 390 | status = AE_ALREADY_EXISTS; |
326 | goto unlock_and_exit; | 391 | goto unlock_and_exit; |
327 | } | 392 | } |
393 | |||
394 | /* System notifies may have more handlers installed. */ | ||
395 | notify_obj = obj_desc->common_notify.system_notify; | ||
396 | |||
397 | if ((handler_type & ACPI_SYSTEM_NOTIFY) && notify_obj) { | ||
398 | struct acpi_object_notify_handler *parent_obj; | ||
399 | |||
400 | if (handler_type & ACPI_DEVICE_NOTIFY) { | ||
401 | status = AE_ALREADY_EXISTS; | ||
402 | goto unlock_and_exit; | ||
403 | } | ||
404 | |||
405 | parent_obj = ¬ify_obj->notify; | ||
406 | status = acpi_add_handler_object(parent_obj, | ||
407 | handler, | ||
408 | context); | ||
409 | goto unlock_and_exit; | ||
410 | } | ||
328 | } else { | 411 | } else { |
329 | /* Create a new object */ | 412 | /* Create a new object */ |
330 | 413 | ||
@@ -356,9 +439,10 @@ acpi_install_notify_handler(acpi_handle device, | |||
356 | goto unlock_and_exit; | 439 | goto unlock_and_exit; |
357 | } | 440 | } |
358 | 441 | ||
359 | notify_obj->notify.node = node; | 442 | acpi_populate_handler_object(¬ify_obj->notify, |
360 | notify_obj->notify.handler = handler; | 443 | handler_type, |
361 | notify_obj->notify.context = context; | 444 | handler, context, |
445 | NULL); | ||
362 | 446 | ||
363 | if (handler_type & ACPI_SYSTEM_NOTIFY) { | 447 | if (handler_type & ACPI_SYSTEM_NOTIFY) { |
364 | obj_desc->common_notify.system_notify = notify_obj; | 448 | obj_desc->common_notify.system_notify = notify_obj; |
@@ -418,6 +502,10 @@ acpi_remove_notify_handler(acpi_handle device, | |||
418 | goto exit; | 502 | goto exit; |
419 | } | 503 | } |
420 | 504 | ||
505 | |||
506 | /* Make sure all deferred tasks are completed */ | ||
507 | acpi_os_wait_events_complete(NULL); | ||
508 | |||
421 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | 509 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); |
422 | if (ACPI_FAILURE(status)) { | 510 | if (ACPI_FAILURE(status)) { |
423 | goto exit; | 511 | goto exit; |
@@ -445,15 +533,6 @@ acpi_remove_notify_handler(acpi_handle device, | |||
445 | goto unlock_and_exit; | 533 | goto unlock_and_exit; |
446 | } | 534 | } |
447 | 535 | ||
448 | /* Make sure all deferred tasks are completed */ | ||
449 | |||
450 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
451 | acpi_os_wait_events_complete(NULL); | ||
452 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
453 | if (ACPI_FAILURE(status)) { | ||
454 | goto exit; | ||
455 | } | ||
456 | |||
457 | if (handler_type & ACPI_SYSTEM_NOTIFY) { | 536 | if (handler_type & ACPI_SYSTEM_NOTIFY) { |
458 | acpi_gbl_system_notify.node = NULL; | 537 | acpi_gbl_system_notify.node = NULL; |
459 | acpi_gbl_system_notify.handler = NULL; | 538 | acpi_gbl_system_notify.handler = NULL; |
@@ -488,28 +567,60 @@ acpi_remove_notify_handler(acpi_handle device, | |||
488 | /* Object exists - make sure there's an existing handler */ | 567 | /* Object exists - make sure there's an existing handler */ |
489 | 568 | ||
490 | if (handler_type & ACPI_SYSTEM_NOTIFY) { | 569 | if (handler_type & ACPI_SYSTEM_NOTIFY) { |
570 | struct acpi_object_notify_handler *handler_obj; | ||
571 | struct acpi_object_notify_handler *parent_obj; | ||
572 | |||
491 | notify_obj = obj_desc->common_notify.system_notify; | 573 | notify_obj = obj_desc->common_notify.system_notify; |
492 | if (!notify_obj) { | 574 | if (!notify_obj) { |
493 | status = AE_NOT_EXIST; | 575 | status = AE_NOT_EXIST; |
494 | goto unlock_and_exit; | 576 | goto unlock_and_exit; |
495 | } | 577 | } |
496 | 578 | ||
497 | if (notify_obj->notify.handler != handler) { | 579 | handler_obj = ¬ify_obj->notify; |
580 | parent_obj = NULL; | ||
581 | while (handler_obj->handler != handler) { | ||
582 | if (handler_obj->next) { | ||
583 | parent_obj = handler_obj; | ||
584 | handler_obj = handler_obj->next; | ||
585 | } else { | ||
586 | break; | ||
587 | } | ||
588 | } | ||
589 | |||
590 | if (handler_obj->handler != handler) { | ||
498 | status = AE_BAD_PARAMETER; | 591 | status = AE_BAD_PARAMETER; |
499 | goto unlock_and_exit; | 592 | goto unlock_and_exit; |
500 | } | 593 | } |
501 | /* Make sure all deferred tasks are completed */ | ||
502 | 594 | ||
503 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 595 | /* |
504 | acpi_os_wait_events_complete(NULL); | 596 | * Remove the handler. There are three possible cases. |
505 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | 597 | * First, we may need to remove a non-embedded object. |
506 | if (ACPI_FAILURE(status)) { | 598 | * Second, we may need to remove the embedded object's |
507 | goto exit; | 599 | * handler data, while non-embedded objects exist. |
600 | * Finally, we may need to remove the embedded object | ||
601 | * entirely along with its container. | ||
602 | */ | ||
603 | if (parent_obj) { | ||
604 | /* Non-embedded object is being removed. */ | ||
605 | parent_obj->next = handler_obj->next; | ||
606 | ACPI_FREE(handler_obj); | ||
607 | } else if (notify_obj->notify.next) { | ||
608 | /* | ||
609 | * The handler matches the embedded object, but | ||
610 | * there are more handler objects in the list. | ||
611 | * Replace the embedded object's data with the | ||
612 | * first next object's data and remove that | ||
613 | * object. | ||
614 | */ | ||
615 | parent_obj = ¬ify_obj->notify; | ||
616 | handler_obj = notify_obj->notify.next; | ||
617 | *parent_obj = *handler_obj; | ||
618 | ACPI_FREE(handler_obj); | ||
619 | } else { | ||
620 | /* No more handler objects in the list. */ | ||
621 | obj_desc->common_notify.system_notify = NULL; | ||
622 | acpi_ut_remove_reference(notify_obj); | ||
508 | } | 623 | } |
509 | |||
510 | /* Remove the handler */ | ||
511 | obj_desc->common_notify.system_notify = NULL; | ||
512 | acpi_ut_remove_reference(notify_obj); | ||
513 | } | 624 | } |
514 | 625 | ||
515 | if (handler_type & ACPI_DEVICE_NOTIFY) { | 626 | if (handler_type & ACPI_DEVICE_NOTIFY) { |
@@ -523,14 +634,6 @@ acpi_remove_notify_handler(acpi_handle device, | |||
523 | status = AE_BAD_PARAMETER; | 634 | status = AE_BAD_PARAMETER; |
524 | goto unlock_and_exit; | 635 | goto unlock_and_exit; |
525 | } | 636 | } |
526 | /* Make sure all deferred tasks are completed */ | ||
527 | |||
528 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
529 | acpi_os_wait_events_complete(NULL); | ||
530 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
531 | if (ACPI_FAILURE(status)) { | ||
532 | goto exit; | ||
533 | } | ||
534 | 637 | ||
535 | /* Remove the handler */ | 638 | /* Remove the handler */ |
536 | obj_desc->common_notify.device_notify = NULL; | 639 | obj_desc->common_notify.device_notify = NULL; |
@@ -617,13 +720,6 @@ acpi_install_gpe_handler(acpi_handle gpe_device, | |||
617 | handler->context = context; | 720 | handler->context = context; |
618 | handler->method_node = gpe_event_info->dispatch.method_node; | 721 | handler->method_node = gpe_event_info->dispatch.method_node; |
619 | 722 | ||
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 */ | 723 | /* Install the handler */ |
628 | 724 | ||
629 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | 725 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); |
@@ -707,13 +803,6 @@ acpi_remove_gpe_handler(acpi_handle gpe_device, | |||
707 | goto unlock_and_exit; | 803 | goto unlock_and_exit; |
708 | } | 804 | } |
709 | 805 | ||
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 */ | 806 | /* Make sure all deferred tasks are completed */ |
718 | 807 | ||
719 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | 808 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); |
diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c index eed7a38d25f2..124c157215bf 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); | ||
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; |
@@ -263,6 +276,9 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number) | |||
263 | 276 | ||
264 | ACPI_FUNCTION_TRACE(acpi_enable_gpe); | 277 | ACPI_FUNCTION_TRACE(acpi_enable_gpe); |
265 | 278 | ||
279 | if (type & ~ACPI_GPE_TYPE_WAKE_RUN) | ||
280 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
281 | |||
266 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | 282 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); |
267 | 283 | ||
268 | /* Ensure that we have a valid GPE number */ | 284 | /* Ensure that we have a valid GPE number */ |
@@ -273,15 +289,32 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number) | |||
273 | goto unlock_and_exit; | 289 | goto unlock_and_exit; |
274 | } | 290 | } |
275 | 291 | ||
276 | /* Perform the enable */ | 292 | if (type & ACPI_GPE_TYPE_RUNTIME) { |
293 | if (++gpe_event_info->runtime_count == 1) { | ||
294 | status = acpi_ev_enable_gpe(gpe_event_info); | ||
295 | if (ACPI_FAILURE(status)) | ||
296 | gpe_event_info->runtime_count--; | ||
297 | } | ||
298 | } | ||
299 | |||
300 | if (type & ACPI_GPE_TYPE_WAKE) { | ||
301 | if (!(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) { | ||
302 | status = AE_BAD_PARAMETER; | ||
303 | goto unlock_and_exit; | ||
304 | } | ||
277 | 305 | ||
278 | status = acpi_ev_enable_gpe(gpe_event_info, TRUE); | 306 | /* |
307 | * Wake-up GPEs are only enabled right prior to putting the | ||
308 | * system into a sleep state. | ||
309 | */ | ||
310 | if (++gpe_event_info->wakeup_count == 1) | ||
311 | acpi_ev_update_gpe_enable_masks(gpe_event_info); | ||
312 | } | ||
279 | 313 | ||
280 | unlock_and_exit: | 314 | unlock_and_exit: |
281 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | 315 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); |
282 | return_ACPI_STATUS(status); | 316 | return_ACPI_STATUS(status); |
283 | } | 317 | } |
284 | |||
285 | ACPI_EXPORT_SYMBOL(acpi_enable_gpe) | 318 | ACPI_EXPORT_SYMBOL(acpi_enable_gpe) |
286 | 319 | ||
287 | /******************************************************************************* | 320 | /******************************************************************************* |
@@ -290,15 +323,14 @@ ACPI_EXPORT_SYMBOL(acpi_enable_gpe) | |||
290 | * | 323 | * |
291 | * PARAMETERS: gpe_device - Parent GPE Device | 324 | * PARAMETERS: gpe_device - Parent GPE Device |
292 | * gpe_number - GPE level within the GPE block | 325 | * gpe_number - GPE level within the GPE block |
293 | * Flags - Just disable, or also wake disable? | 326 | * type - Purpose the GPE won't be used for any more |
294 | * Called from ISR or not | ||
295 | * | 327 | * |
296 | * RETURN: Status | 328 | * RETURN: Status |
297 | * | 329 | * |
298 | * DESCRIPTION: Disable an ACPI event (general purpose) | 330 | * DESCRIPTION: Release a reference to a GPE and disable it if necessary |
299 | * | 331 | * |
300 | ******************************************************************************/ | 332 | ******************************************************************************/ |
301 | acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number) | 333 | acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 type) |
302 | { | 334 | { |
303 | acpi_status status = AE_OK; | 335 | acpi_status status = AE_OK; |
304 | acpi_cpu_flags flags; | 336 | acpi_cpu_flags flags; |
@@ -306,6 +338,9 @@ acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number) | |||
306 | 338 | ||
307 | ACPI_FUNCTION_TRACE(acpi_disable_gpe); | 339 | ACPI_FUNCTION_TRACE(acpi_disable_gpe); |
308 | 340 | ||
341 | if (type & ~ACPI_GPE_TYPE_WAKE_RUN) | ||
342 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
343 | |||
309 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | 344 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); |
310 | /* Ensure that we have a valid GPE number */ | 345 | /* Ensure that we have a valid GPE number */ |
311 | 346 | ||
@@ -315,13 +350,24 @@ acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number) | |||
315 | goto unlock_and_exit; | 350 | goto unlock_and_exit; |
316 | } | 351 | } |
317 | 352 | ||
318 | status = acpi_ev_disable_gpe(gpe_event_info); | 353 | if ((type & ACPI_GPE_TYPE_RUNTIME) && gpe_event_info->runtime_count) { |
354 | if (--gpe_event_info->runtime_count == 0) | ||
355 | status = acpi_ev_disable_gpe(gpe_event_info); | ||
356 | } | ||
357 | |||
358 | if ((type & ACPI_GPE_TYPE_WAKE) && gpe_event_info->wakeup_count) { | ||
359 | /* | ||
360 | * Wake-up GPEs are not enabled after leaving system sleep | ||
361 | * states, so we don't need to disable them here. | ||
362 | */ | ||
363 | if (--gpe_event_info->wakeup_count == 0) | ||
364 | acpi_ev_update_gpe_enable_masks(gpe_event_info); | ||
365 | } | ||
319 | 366 | ||
320 | unlock_and_exit: | 367 | unlock_and_exit: |
321 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | 368 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); |
322 | return_ACPI_STATUS(status); | 369 | return_ACPI_STATUS(status); |
323 | } | 370 | } |
324 | |||
325 | ACPI_EXPORT_SYMBOL(acpi_disable_gpe) | 371 | ACPI_EXPORT_SYMBOL(acpi_disable_gpe) |
326 | 372 | ||
327 | /******************************************************************************* | 373 | /******************************************************************************* |