diff options
Diffstat (limited to 'drivers/acpi/osl.c')
-rw-r--r-- | drivers/acpi/osl.c | 55 |
1 files changed, 45 insertions, 10 deletions
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 235a1386888a..4be252145cb4 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -608,7 +608,7 @@ static void acpi_os_derive_pci_id_2(acpi_handle rhandle, /* upper bound */ | |||
608 | acpi_handle handle; | 608 | acpi_handle handle; |
609 | struct acpi_pci_id *pci_id = *id; | 609 | struct acpi_pci_id *pci_id = *id; |
610 | acpi_status status; | 610 | acpi_status status; |
611 | unsigned long temp; | 611 | unsigned long long temp; |
612 | acpi_object_type type; | 612 | acpi_object_type type; |
613 | 613 | ||
614 | acpi_get_parent(chandle, &handle); | 614 | acpi_get_parent(chandle, &handle); |
@@ -620,8 +620,7 @@ static void acpi_os_derive_pci_id_2(acpi_handle rhandle, /* upper bound */ | |||
620 | if ((ACPI_FAILURE(status)) || (type != ACPI_TYPE_DEVICE)) | 620 | if ((ACPI_FAILURE(status)) || (type != ACPI_TYPE_DEVICE)) |
621 | return; | 621 | return; |
622 | 622 | ||
623 | status = | 623 | status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, |
624 | acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, | ||
625 | &temp); | 624 | &temp); |
626 | if (ACPI_SUCCESS(status)) { | 625 | if (ACPI_SUCCESS(status)) { |
627 | u32 val; | 626 | u32 val; |
@@ -682,6 +681,22 @@ static void acpi_os_execute_deferred(struct work_struct *work) | |||
682 | return; | 681 | return; |
683 | } | 682 | } |
684 | 683 | ||
684 | static void acpi_os_execute_hp_deferred(struct work_struct *work) | ||
685 | { | ||
686 | struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work); | ||
687 | if (!dpc) { | ||
688 | printk(KERN_ERR PREFIX "Invalid (NULL) context\n"); | ||
689 | return; | ||
690 | } | ||
691 | |||
692 | acpi_os_wait_events_complete(NULL); | ||
693 | |||
694 | dpc->function(dpc->context); | ||
695 | kfree(dpc); | ||
696 | |||
697 | return; | ||
698 | } | ||
699 | |||
685 | /******************************************************************************* | 700 | /******************************************************************************* |
686 | * | 701 | * |
687 | * FUNCTION: acpi_os_execute | 702 | * FUNCTION: acpi_os_execute |
@@ -697,12 +712,13 @@ static void acpi_os_execute_deferred(struct work_struct *work) | |||
697 | * | 712 | * |
698 | ******************************************************************************/ | 713 | ******************************************************************************/ |
699 | 714 | ||
700 | acpi_status acpi_os_execute(acpi_execute_type type, | 715 | static acpi_status __acpi_os_execute(acpi_execute_type type, |
701 | acpi_osd_exec_callback function, void *context) | 716 | acpi_osd_exec_callback function, void *context, int hp) |
702 | { | 717 | { |
703 | acpi_status status = AE_OK; | 718 | acpi_status status = AE_OK; |
704 | struct acpi_os_dpc *dpc; | 719 | struct acpi_os_dpc *dpc; |
705 | struct workqueue_struct *queue; | 720 | struct workqueue_struct *queue; |
721 | int ret; | ||
706 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | 722 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
707 | "Scheduling function [%p(%p)] for deferred execution.\n", | 723 | "Scheduling function [%p(%p)] for deferred execution.\n", |
708 | function, context)); | 724 | function, context)); |
@@ -726,19 +742,38 @@ acpi_status acpi_os_execute(acpi_execute_type type, | |||
726 | dpc->function = function; | 742 | dpc->function = function; |
727 | dpc->context = context; | 743 | dpc->context = context; |
728 | 744 | ||
729 | INIT_WORK(&dpc->work, acpi_os_execute_deferred); | 745 | if (!hp) { |
730 | queue = (type == OSL_NOTIFY_HANDLER) ? kacpi_notify_wq : kacpid_wq; | 746 | INIT_WORK(&dpc->work, acpi_os_execute_deferred); |
731 | if (!queue_work(queue, &dpc->work)) { | 747 | queue = (type == OSL_NOTIFY_HANDLER) ? |
732 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | 748 | kacpi_notify_wq : kacpid_wq; |
733 | "Call to queue_work() failed.\n")); | 749 | ret = queue_work(queue, &dpc->work); |
750 | } else { | ||
751 | INIT_WORK(&dpc->work, acpi_os_execute_hp_deferred); | ||
752 | ret = schedule_work(&dpc->work); | ||
753 | } | ||
754 | |||
755 | if (!ret) { | ||
756 | printk(KERN_ERR PREFIX | ||
757 | "Call to queue_work() failed.\n"); | ||
734 | status = AE_ERROR; | 758 | status = AE_ERROR; |
735 | kfree(dpc); | 759 | kfree(dpc); |
736 | } | 760 | } |
737 | return_ACPI_STATUS(status); | 761 | return_ACPI_STATUS(status); |
738 | } | 762 | } |
739 | 763 | ||
764 | acpi_status acpi_os_execute(acpi_execute_type type, | ||
765 | acpi_osd_exec_callback function, void *context) | ||
766 | { | ||
767 | return __acpi_os_execute(type, function, context, 0); | ||
768 | } | ||
740 | EXPORT_SYMBOL(acpi_os_execute); | 769 | EXPORT_SYMBOL(acpi_os_execute); |
741 | 770 | ||
771 | acpi_status acpi_os_hotplug_execute(acpi_osd_exec_callback function, | ||
772 | void *context) | ||
773 | { | ||
774 | return __acpi_os_execute(0, function, context, 1); | ||
775 | } | ||
776 | |||
742 | void acpi_os_wait_events_complete(void *context) | 777 | void acpi_os_wait_events_complete(void *context) |
743 | { | 778 | { |
744 | flush_workqueue(kacpid_wq); | 779 | flush_workqueue(kacpid_wq); |