diff options
-rw-r--r-- | drivers/acpi/events/evgpe.c | 17 | ||||
-rw-r--r-- | drivers/acpi/osl.c | 42 |
2 files changed, 21 insertions, 38 deletions
diff --git a/drivers/acpi/events/evgpe.c b/drivers/acpi/events/evgpe.c index e22f4a973c0f..b4509f93ff81 100644 --- a/drivers/acpi/events/evgpe.c +++ b/drivers/acpi/events/evgpe.c | |||
@@ -501,6 +501,7 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) | |||
501 | * an interrupt handler. | 501 | * an interrupt handler. |
502 | * | 502 | * |
503 | ******************************************************************************/ | 503 | ******************************************************************************/ |
504 | static void acpi_ev_asynch_enable_gpe(void *context); | ||
504 | 505 | ||
505 | static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) | 506 | static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) |
506 | { | 507 | { |
@@ -576,22 +577,30 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) | |||
576 | method_node))); | 577 | method_node))); |
577 | } | 578 | } |
578 | } | 579 | } |
580 | /* Defer enabling of GPE until all notify handlers are done */ | ||
581 | acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_ev_asynch_enable_gpe, | ||
582 | gpe_event_info); | ||
583 | return_VOID; | ||
584 | } | ||
579 | 585 | ||
580 | if ((local_gpe_event_info.flags & ACPI_GPE_XRUPT_TYPE_MASK) == | 586 | static void acpi_ev_asynch_enable_gpe(void *context) |
587 | { | ||
588 | struct acpi_gpe_event_info *gpe_event_info = context; | ||
589 | acpi_status status; | ||
590 | if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) == | ||
581 | ACPI_GPE_LEVEL_TRIGGERED) { | 591 | ACPI_GPE_LEVEL_TRIGGERED) { |
582 | /* | 592 | /* |
583 | * GPE is level-triggered, we clear the GPE status bit after | 593 | * GPE is level-triggered, we clear the GPE status bit after |
584 | * handling the event. | 594 | * handling the event. |
585 | */ | 595 | */ |
586 | status = acpi_hw_clear_gpe(&local_gpe_event_info); | 596 | status = acpi_hw_clear_gpe(gpe_event_info); |
587 | if (ACPI_FAILURE(status)) { | 597 | if (ACPI_FAILURE(status)) { |
588 | return_VOID; | 598 | return_VOID; |
589 | } | 599 | } |
590 | } | 600 | } |
591 | 601 | ||
592 | /* Enable this GPE */ | 602 | /* Enable this GPE */ |
593 | 603 | (void)acpi_hw_write_gpe_enable_reg(gpe_event_info); | |
594 | (void)acpi_hw_write_gpe_enable_reg(&local_gpe_event_info); | ||
595 | return_VOID; | 604 | return_VOID; |
596 | } | 605 | } |
597 | 606 | ||
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index e3a673a00845..21d34595dbae 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -618,25 +618,6 @@ static void acpi_os_execute_deferred(struct work_struct *work) | |||
618 | dpc->function(dpc->context); | 618 | dpc->function(dpc->context); |
619 | kfree(dpc); | 619 | kfree(dpc); |
620 | 620 | ||
621 | /* Yield cpu to notify thread */ | ||
622 | cond_resched(); | ||
623 | |||
624 | return; | ||
625 | } | ||
626 | |||
627 | static void acpi_os_execute_notify(struct work_struct *work) | ||
628 | { | ||
629 | struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work); | ||
630 | |||
631 | if (!dpc) { | ||
632 | printk(KERN_ERR PREFIX "Invalid (NULL) context\n"); | ||
633 | return; | ||
634 | } | ||
635 | |||
636 | dpc->function(dpc->context); | ||
637 | |||
638 | kfree(dpc); | ||
639 | |||
640 | return; | 621 | return; |
641 | } | 622 | } |
642 | 623 | ||
@@ -660,7 +641,7 @@ acpi_status acpi_os_execute(acpi_execute_type type, | |||
660 | { | 641 | { |
661 | acpi_status status = AE_OK; | 642 | acpi_status status = AE_OK; |
662 | struct acpi_os_dpc *dpc; | 643 | struct acpi_os_dpc *dpc; |
663 | 644 | struct workqueue_struct *queue; | |
664 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | 645 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
665 | "Scheduling function [%p(%p)] for deferred execution.\n", | 646 | "Scheduling function [%p(%p)] for deferred execution.\n", |
666 | function, context)); | 647 | function, context)); |
@@ -684,20 +665,13 @@ acpi_status acpi_os_execute(acpi_execute_type type, | |||
684 | dpc->function = function; | 665 | dpc->function = function; |
685 | dpc->context = context; | 666 | dpc->context = context; |
686 | 667 | ||
687 | if (type == OSL_NOTIFY_HANDLER) { | 668 | INIT_WORK(&dpc->work, acpi_os_execute_deferred); |
688 | INIT_WORK(&dpc->work, acpi_os_execute_notify); | 669 | queue = (type == OSL_NOTIFY_HANDLER) ? kacpi_notify_wq : kacpid_wq; |
689 | if (!queue_work(kacpi_notify_wq, &dpc->work)) { | 670 | if (!queue_work(queue, &dpc->work)) { |
690 | status = AE_ERROR; | 671 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, |
691 | kfree(dpc); | 672 | "Call to queue_work() failed.\n")); |
692 | } | 673 | status = AE_ERROR; |
693 | } else { | 674 | kfree(dpc); |
694 | INIT_WORK(&dpc->work, acpi_os_execute_deferred); | ||
695 | if (!queue_work(kacpid_wq, &dpc->work)) { | ||
696 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
697 | "Call to queue_work() failed.\n")); | ||
698 | status = AE_ERROR; | ||
699 | kfree(dpc); | ||
700 | } | ||
701 | } | 675 | } |
702 | return_ACPI_STATUS(status); | 676 | return_ACPI_STATUS(status); |
703 | } | 677 | } |