aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica/evxfevnt.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/acpica/evxfevnt.c')
-rw-r--r--drivers/acpi/acpica/evxfevnt.c59
1 files changed, 53 insertions, 6 deletions
diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c
index d5a5efc043bf..d97b8dce1668 100644
--- a/drivers/acpi/acpica/evxfevnt.c
+++ b/drivers/acpi/acpica/evxfevnt.c
@@ -210,6 +210,44 @@ ACPI_EXPORT_SYMBOL(acpi_enable_event)
210 210
211/******************************************************************************* 211/*******************************************************************************
212 * 212 *
213 * FUNCTION: acpi_clear_and_enable_gpe
214 *
215 * PARAMETERS: gpe_event_info - GPE to enable
216 *
217 * RETURN: Status
218 *
219 * DESCRIPTION: Clear the given GPE from stale events and enable it.
220 *
221 ******************************************************************************/
222static acpi_status
223acpi_clear_and_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
224{
225 acpi_status status;
226
227 /*
228 * We will only allow a GPE to be enabled if it has either an
229 * associated method (_Lxx/_Exx) or a handler. Otherwise, the
230 * GPE will be immediately disabled by acpi_ev_gpe_dispatch the
231 * first time it fires.
232 */
233 if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)) {
234 return_ACPI_STATUS(AE_NO_HANDLER);
235 }
236
237 /* Clear the GPE (of stale events) */
238 status = acpi_hw_clear_gpe(gpe_event_info);
239 if (ACPI_FAILURE(status)) {
240 return_ACPI_STATUS(status);
241 }
242
243 /* Enable the requested GPE */
244 status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_ENABLE);
245
246 return_ACPI_STATUS(status);
247}
248
249/*******************************************************************************
250 *
213 * FUNCTION: acpi_set_gpe 251 * FUNCTION: acpi_set_gpe
214 * 252 *
215 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 253 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
@@ -249,11 +287,11 @@ acpi_status acpi_set_gpe(acpi_handle gpe_device, u32 gpe_number, u8 action)
249 287
250 switch (action) { 288 switch (action) {
251 case ACPI_GPE_ENABLE: 289 case ACPI_GPE_ENABLE:
252 status = acpi_ev_enable_gpe(gpe_event_info); 290 status = acpi_clear_and_enable_gpe(gpe_event_info);
253 break; 291 break;
254 292
255 case ACPI_GPE_DISABLE: 293 case ACPI_GPE_DISABLE:
256 status = acpi_ev_disable_gpe(gpe_event_info); 294 status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE);
257 break; 295 break;
258 296
259 default: 297 default:
@@ -316,7 +354,11 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 gpe_type)
316 354
317 gpe_event_info->runtime_count++; 355 gpe_event_info->runtime_count++;
318 if (gpe_event_info->runtime_count == 1) { 356 if (gpe_event_info->runtime_count == 1) {
319 status = acpi_ev_enable_gpe(gpe_event_info); 357 status = acpi_ev_update_gpe_enable_masks(gpe_event_info);
358 if (ACPI_SUCCESS(status)) {
359 status = acpi_clear_and_enable_gpe(gpe_event_info);
360 }
361
320 if (ACPI_FAILURE(status)) { 362 if (ACPI_FAILURE(status)) {
321 gpe_event_info->runtime_count--; 363 gpe_event_info->runtime_count--;
322 goto unlock_and_exit; 364 goto unlock_and_exit;
@@ -343,7 +385,7 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 gpe_type)
343 */ 385 */
344 gpe_event_info->wakeup_count++; 386 gpe_event_info->wakeup_count++;
345 if (gpe_event_info->wakeup_count == 1) { 387 if (gpe_event_info->wakeup_count == 1) {
346 (void)acpi_ev_update_gpe_enable_masks(gpe_event_info); 388 status = acpi_ev_update_gpe_enable_masks(gpe_event_info);
347 } 389 }
348 } 390 }
349 391
@@ -403,7 +445,12 @@ acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 gpe_type
403 445
404 gpe_event_info->runtime_count--; 446 gpe_event_info->runtime_count--;
405 if (!gpe_event_info->runtime_count) { 447 if (!gpe_event_info->runtime_count) {
406 status = acpi_ev_disable_gpe(gpe_event_info); 448 status = acpi_ev_update_gpe_enable_masks(gpe_event_info);
449 if (ACPI_SUCCESS(status)) {
450 status = acpi_hw_low_set_gpe(gpe_event_info,
451 ACPI_GPE_DISABLE);
452 }
453
407 if (ACPI_FAILURE(status)) { 454 if (ACPI_FAILURE(status)) {
408 gpe_event_info->runtime_count++; 455 gpe_event_info->runtime_count++;
409 goto unlock_and_exit; 456 goto unlock_and_exit;
@@ -424,7 +471,7 @@ acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 gpe_type
424 471
425 gpe_event_info->wakeup_count--; 472 gpe_event_info->wakeup_count--;
426 if (!gpe_event_info->wakeup_count) { 473 if (!gpe_event_info->wakeup_count) {
427 (void)acpi_ev_update_gpe_enable_masks(gpe_event_info); 474 status = acpi_ev_update_gpe_enable_masks(gpe_event_info);
428 } 475 }
429 } 476 }
430 477