diff options
Diffstat (limited to 'drivers/acpi/ec.c')
-rw-r--r-- | drivers/acpi/ec.c | 47 |
1 files changed, 31 insertions, 16 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 56bee9e065cf..43749c86861f 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -696,14 +696,6 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval) | |||
696 | return AE_CTRL_TERMINATE; | 696 | return AE_CTRL_TERMINATE; |
697 | } | 697 | } |
698 | 698 | ||
699 | static void ec_remove_handlers(struct acpi_ec *ec) | ||
700 | { | ||
701 | acpi_remove_address_space_handler(ec->handle, | ||
702 | ACPI_ADR_SPACE_EC, | ||
703 | &acpi_ec_space_handler); | ||
704 | acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler); | ||
705 | } | ||
706 | |||
707 | static int acpi_ec_add(struct acpi_device *device) | 699 | static int acpi_ec_add(struct acpi_device *device) |
708 | { | 700 | { |
709 | struct acpi_ec *ec = NULL; | 701 | struct acpi_ec *ec = NULL; |
@@ -727,13 +719,16 @@ static int acpi_ec_add(struct acpi_device *device) | |||
727 | /* Check if we found the boot EC */ | 719 | /* Check if we found the boot EC */ |
728 | if (boot_ec) { | 720 | if (boot_ec) { |
729 | if (boot_ec->gpe == ec->gpe) { | 721 | if (boot_ec->gpe == ec->gpe) { |
730 | ec_remove_handlers(boot_ec); | 722 | /* We might have incorrect info for GL at boot time */ |
731 | mutex_destroy(&boot_ec->lock); | 723 | mutex_lock(&boot_ec->lock); |
732 | kfree(boot_ec); | 724 | boot_ec->global_lock = ec->global_lock; |
733 | first_ec = boot_ec = NULL; | 725 | /* Copy handlers from new ec into boot ec */ |
726 | list_splice(&ec->list, &boot_ec->list); | ||
727 | mutex_unlock(&boot_ec->lock); | ||
728 | kfree(ec); | ||
729 | ec = boot_ec; | ||
734 | } | 730 | } |
735 | } | 731 | } else |
736 | if (!first_ec) | ||
737 | first_ec = ec; | 732 | first_ec = ec; |
738 | ec->handle = device->handle; | 733 | ec->handle = device->handle; |
739 | acpi_driver_data(device) = ec; | 734 | acpi_driver_data(device) = ec; |
@@ -762,6 +757,9 @@ static int acpi_ec_remove(struct acpi_device *device, int type) | |||
762 | if (ec == first_ec) | 757 | if (ec == first_ec) |
763 | first_ec = NULL; | 758 | first_ec = NULL; |
764 | 759 | ||
760 | /* Don't touch boot EC */ | ||
761 | if (boot_ec != ec) | ||
762 | kfree(ec); | ||
765 | return 0; | 763 | return 0; |
766 | } | 764 | } |
767 | 765 | ||
@@ -825,7 +823,9 @@ static int acpi_ec_start(struct acpi_device *device) | |||
825 | if (!ec) | 823 | if (!ec) |
826 | return -EINVAL; | 824 | return -EINVAL; |
827 | 825 | ||
828 | ret = ec_install_handlers(ec); | 826 | /* Boot EC is already working */ |
827 | if (ec != boot_ec) | ||
828 | ret = ec_install_handlers(ec); | ||
829 | 829 | ||
830 | /* EC is fully operational, allow queries */ | 830 | /* EC is fully operational, allow queries */ |
831 | atomic_set(&ec->query_pending, 0); | 831 | atomic_set(&ec->query_pending, 0); |
@@ -835,6 +835,7 @@ static int acpi_ec_start(struct acpi_device *device) | |||
835 | 835 | ||
836 | static int acpi_ec_stop(struct acpi_device *device, int type) | 836 | static int acpi_ec_stop(struct acpi_device *device, int type) |
837 | { | 837 | { |
838 | acpi_status status; | ||
838 | struct acpi_ec *ec; | 839 | struct acpi_ec *ec; |
839 | 840 | ||
840 | if (!device) | 841 | if (!device) |
@@ -843,7 +844,21 @@ static int acpi_ec_stop(struct acpi_device *device, int type) | |||
843 | ec = acpi_driver_data(device); | 844 | ec = acpi_driver_data(device); |
844 | if (!ec) | 845 | if (!ec) |
845 | return -EINVAL; | 846 | return -EINVAL; |
846 | ec_remove_handlers(ec); | 847 | |
848 | /* Don't touch boot EC */ | ||
849 | if (ec == boot_ec) | ||
850 | return 0; | ||
851 | |||
852 | status = acpi_remove_address_space_handler(ec->handle, | ||
853 | ACPI_ADR_SPACE_EC, | ||
854 | &acpi_ec_space_handler); | ||
855 | if (ACPI_FAILURE(status)) | ||
856 | return -ENODEV; | ||
857 | |||
858 | status = acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler); | ||
859 | if (ACPI_FAILURE(status)) | ||
860 | return -ENODEV; | ||
861 | |||
847 | return 0; | 862 | return 0; |
848 | } | 863 | } |
849 | 864 | ||