aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/ec.c45
1 files changed, 16 insertions, 29 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 629289034b61..71caa7d983a3 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -679,6 +679,14 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval)
679 return AE_CTRL_TERMINATE; 679 return AE_CTRL_TERMINATE;
680} 680}
681 681
682static void ec_remove_handlers(struct acpi_ec *ec)
683{
684 acpi_remove_address_space_handler(ec->handle,
685 ACPI_ADR_SPACE_EC,
686 &acpi_ec_space_handler);
687 acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler);
688}
689
682static int acpi_ec_add(struct acpi_device *device) 690static int acpi_ec_add(struct acpi_device *device)
683{ 691{
684 struct acpi_ec *ec = NULL; 692 struct acpi_ec *ec = NULL;
@@ -702,16 +710,15 @@ static int acpi_ec_add(struct acpi_device *device)
702 /* Check if we found the boot EC */ 710 /* Check if we found the boot EC */
703 if (boot_ec) { 711 if (boot_ec) {
704 if (boot_ec->gpe == ec->gpe) { 712 if (boot_ec->gpe == ec->gpe) {
705 /* We might have incorrect info for GL at boot time */
706 mutex_lock(&boot_ec->lock); 713 mutex_lock(&boot_ec->lock);
707 boot_ec->global_lock = ec->global_lock; 714 ec_remove_handlers(boot_ec);
708 /* Copy handlers from new ec into boot ec */
709 list_splice(&ec->list, &boot_ec->list);
710 mutex_unlock(&boot_ec->lock); 715 mutex_unlock(&boot_ec->lock);
711 kfree(ec); 716 mutex_destroy(&boot_ec->lock);
712 ec = boot_ec; 717 kfree(boot_ec);
718 first_ec = boot_ec = NULL;
713 } 719 }
714 } else 720 }
721 if (!first_ec)
715 first_ec = ec; 722 first_ec = ec;
716 ec->handle = device->handle; 723 ec->handle = device->handle;
717 acpi_driver_data(device) = ec; 724 acpi_driver_data(device) = ec;
@@ -740,9 +747,6 @@ static int acpi_ec_remove(struct acpi_device *device, int type)
740 if (ec == first_ec) 747 if (ec == first_ec)
741 first_ec = NULL; 748 first_ec = NULL;
742 749
743 /* Don't touch boot EC */
744 if (boot_ec != ec)
745 kfree(ec);
746 return 0; 750 return 0;
747} 751}
748 752
@@ -806,9 +810,7 @@ static int acpi_ec_start(struct acpi_device *device)
806 if (!ec) 810 if (!ec)
807 return -EINVAL; 811 return -EINVAL;
808 812
809 /* Boot EC is already working */ 813 ret = ec_install_handlers(ec);
810 if (ec != boot_ec)
811 ret = ec_install_handlers(ec);
812 814
813 /* EC is fully operational, allow queries */ 815 /* EC is fully operational, allow queries */
814 atomic_set(&ec->query_pending, 0); 816 atomic_set(&ec->query_pending, 0);
@@ -818,7 +820,6 @@ static int acpi_ec_start(struct acpi_device *device)
818 820
819static int acpi_ec_stop(struct acpi_device *device, int type) 821static int acpi_ec_stop(struct acpi_device *device, int type)
820{ 822{
821 acpi_status status;
822 struct acpi_ec *ec; 823 struct acpi_ec *ec;
823 824
824 if (!device) 825 if (!device)
@@ -827,21 +828,7 @@ static int acpi_ec_stop(struct acpi_device *device, int type)
827 ec = acpi_driver_data(device); 828 ec = acpi_driver_data(device);
828 if (!ec) 829 if (!ec)
829 return -EINVAL; 830 return -EINVAL;
830 831 ec_remove_handlers(ec);
831 /* Don't touch boot EC */
832 if (ec == boot_ec)
833 return 0;
834
835 status = acpi_remove_address_space_handler(ec->handle,
836 ACPI_ADR_SPACE_EC,
837 &acpi_ec_space_handler);
838 if (ACPI_FAILURE(status))
839 return -ENODEV;
840
841 status = acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler);
842 if (ACPI_FAILURE(status))
843 return -ENODEV;
844
845 return 0; 832 return 0;
846} 833}
847 834