diff options
| -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 | ||
