diff options
author | Len Brown <len.brown@intel.com> | 2009-09-19 01:56:39 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2009-09-19 01:56:39 -0400 |
commit | 3b87bb640e77023c97cf209e3dd85887a1113ad0 (patch) | |
tree | c4531d2c954bcc28706837cc67a8865677e51fbf /drivers/acpi/ec.c | |
parent | 7a92d803227a523a9a5546e4e0dce1325a4b5926 (diff) | |
parent | dcf52fb71d988ba945054308f661bddf9b2455fb (diff) |
Merge branch 'bjorn-start-stop-2.6.32' into release
Diffstat (limited to 'drivers/acpi/ec.c')
-rw-r--r-- | drivers/acpi/ec.c | 118 |
1 files changed, 44 insertions, 74 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 5180f0f1dd02..f28619d658f7 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -787,6 +787,42 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval) | |||
787 | return AE_CTRL_TERMINATE; | 787 | return AE_CTRL_TERMINATE; |
788 | } | 788 | } |
789 | 789 | ||
790 | static int ec_install_handlers(struct acpi_ec *ec) | ||
791 | { | ||
792 | acpi_status status; | ||
793 | if (test_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags)) | ||
794 | return 0; | ||
795 | status = acpi_install_gpe_handler(NULL, ec->gpe, | ||
796 | ACPI_GPE_EDGE_TRIGGERED, | ||
797 | &acpi_ec_gpe_handler, ec); | ||
798 | if (ACPI_FAILURE(status)) | ||
799 | return -ENODEV; | ||
800 | acpi_set_gpe_type(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME); | ||
801 | acpi_enable_gpe(NULL, ec->gpe); | ||
802 | status = acpi_install_address_space_handler(ec->handle, | ||
803 | ACPI_ADR_SPACE_EC, | ||
804 | &acpi_ec_space_handler, | ||
805 | NULL, ec); | ||
806 | if (ACPI_FAILURE(status)) { | ||
807 | if (status == AE_NOT_FOUND) { | ||
808 | /* | ||
809 | * Maybe OS fails in evaluating the _REG object. | ||
810 | * The AE_NOT_FOUND error will be ignored and OS | ||
811 | * continue to initialize EC. | ||
812 | */ | ||
813 | printk(KERN_ERR "Fail in evaluating the _REG object" | ||
814 | " of EC device. Broken bios is suspected.\n"); | ||
815 | } else { | ||
816 | acpi_remove_gpe_handler(NULL, ec->gpe, | ||
817 | &acpi_ec_gpe_handler); | ||
818 | return -ENODEV; | ||
819 | } | ||
820 | } | ||
821 | |||
822 | set_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags); | ||
823 | return 0; | ||
824 | } | ||
825 | |||
790 | static void ec_remove_handlers(struct acpi_ec *ec) | 826 | static void ec_remove_handlers(struct acpi_ec *ec) |
791 | { | 827 | { |
792 | if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle, | 828 | if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle, |
@@ -801,9 +837,8 @@ static void ec_remove_handlers(struct acpi_ec *ec) | |||
801 | static int acpi_ec_add(struct acpi_device *device) | 837 | static int acpi_ec_add(struct acpi_device *device) |
802 | { | 838 | { |
803 | struct acpi_ec *ec = NULL; | 839 | struct acpi_ec *ec = NULL; |
840 | int ret; | ||
804 | 841 | ||
805 | if (!device) | ||
806 | return -EINVAL; | ||
807 | strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME); | 842 | strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME); |
808 | strcpy(acpi_device_class(device), ACPI_EC_CLASS); | 843 | strcpy(acpi_device_class(device), ACPI_EC_CLASS); |
809 | 844 | ||
@@ -838,7 +873,12 @@ static int acpi_ec_add(struct acpi_device *device) | |||
838 | ec->gpe, ec->command_addr, ec->data_addr); | 873 | ec->gpe, ec->command_addr, ec->data_addr); |
839 | pr_info(PREFIX "driver started in %s mode\n", | 874 | pr_info(PREFIX "driver started in %s mode\n", |
840 | (test_bit(EC_FLAGS_GPE_MODE, &ec->flags))?"interrupt":"poll"); | 875 | (test_bit(EC_FLAGS_GPE_MODE, &ec->flags))?"interrupt":"poll"); |
841 | return 0; | 876 | |
877 | ret = ec_install_handlers(ec); | ||
878 | |||
879 | /* EC is fully operational, allow queries */ | ||
880 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); | ||
881 | return ret; | ||
842 | } | 882 | } |
843 | 883 | ||
844 | static int acpi_ec_remove(struct acpi_device *device, int type) | 884 | static int acpi_ec_remove(struct acpi_device *device, int type) |
@@ -850,6 +890,7 @@ static int acpi_ec_remove(struct acpi_device *device, int type) | |||
850 | return -EINVAL; | 890 | return -EINVAL; |
851 | 891 | ||
852 | ec = acpi_driver_data(device); | 892 | ec = acpi_driver_data(device); |
893 | ec_remove_handlers(ec); | ||
853 | mutex_lock(&ec->lock); | 894 | mutex_lock(&ec->lock); |
854 | list_for_each_entry_safe(handler, tmp, &ec->list, node) { | 895 | list_for_each_entry_safe(handler, tmp, &ec->list, node) { |
855 | list_del(&handler->node); | 896 | list_del(&handler->node); |
@@ -887,75 +928,6 @@ ec_parse_io_ports(struct acpi_resource *resource, void *context) | |||
887 | return AE_OK; | 928 | return AE_OK; |
888 | } | 929 | } |
889 | 930 | ||
890 | static int ec_install_handlers(struct acpi_ec *ec) | ||
891 | { | ||
892 | acpi_status status; | ||
893 | if (test_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags)) | ||
894 | return 0; | ||
895 | status = acpi_install_gpe_handler(NULL, ec->gpe, | ||
896 | ACPI_GPE_EDGE_TRIGGERED, | ||
897 | &acpi_ec_gpe_handler, ec); | ||
898 | if (ACPI_FAILURE(status)) | ||
899 | return -ENODEV; | ||
900 | acpi_set_gpe_type(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME); | ||
901 | acpi_enable_gpe(NULL, ec->gpe); | ||
902 | status = acpi_install_address_space_handler(ec->handle, | ||
903 | ACPI_ADR_SPACE_EC, | ||
904 | &acpi_ec_space_handler, | ||
905 | NULL, ec); | ||
906 | if (ACPI_FAILURE(status)) { | ||
907 | if (status == AE_NOT_FOUND) { | ||
908 | /* | ||
909 | * Maybe OS fails in evaluating the _REG object. | ||
910 | * The AE_NOT_FOUND error will be ignored and OS | ||
911 | * continue to initialize EC. | ||
912 | */ | ||
913 | printk(KERN_ERR "Fail in evaluating the _REG object" | ||
914 | " of EC device. Broken bios is suspected.\n"); | ||
915 | } else { | ||
916 | acpi_remove_gpe_handler(NULL, ec->gpe, | ||
917 | &acpi_ec_gpe_handler); | ||
918 | return -ENODEV; | ||
919 | } | ||
920 | } | ||
921 | |||
922 | set_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags); | ||
923 | return 0; | ||
924 | } | ||
925 | |||
926 | static int acpi_ec_start(struct acpi_device *device) | ||
927 | { | ||
928 | struct acpi_ec *ec; | ||
929 | int ret = 0; | ||
930 | |||
931 | if (!device) | ||
932 | return -EINVAL; | ||
933 | |||
934 | ec = acpi_driver_data(device); | ||
935 | |||
936 | if (!ec) | ||
937 | return -EINVAL; | ||
938 | |||
939 | ret = ec_install_handlers(ec); | ||
940 | |||
941 | /* EC is fully operational, allow queries */ | ||
942 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); | ||
943 | return ret; | ||
944 | } | ||
945 | |||
946 | static int acpi_ec_stop(struct acpi_device *device, int type) | ||
947 | { | ||
948 | struct acpi_ec *ec; | ||
949 | if (!device) | ||
950 | return -EINVAL; | ||
951 | ec = acpi_driver_data(device); | ||
952 | if (!ec) | ||
953 | return -EINVAL; | ||
954 | ec_remove_handlers(ec); | ||
955 | |||
956 | return 0; | ||
957 | } | ||
958 | |||
959 | int __init acpi_boot_ec_enable(void) | 931 | int __init acpi_boot_ec_enable(void) |
960 | { | 932 | { |
961 | if (!boot_ec || test_bit(EC_FLAGS_HANDLERS_INSTALLED, &boot_ec->flags)) | 933 | if (!boot_ec || test_bit(EC_FLAGS_HANDLERS_INSTALLED, &boot_ec->flags)) |
@@ -1076,8 +1048,6 @@ static struct acpi_driver acpi_ec_driver = { | |||
1076 | .ops = { | 1048 | .ops = { |
1077 | .add = acpi_ec_add, | 1049 | .add = acpi_ec_add, |
1078 | .remove = acpi_ec_remove, | 1050 | .remove = acpi_ec_remove, |
1079 | .start = acpi_ec_start, | ||
1080 | .stop = acpi_ec_stop, | ||
1081 | .suspend = acpi_ec_suspend, | 1051 | .suspend = acpi_ec_suspend, |
1082 | .resume = acpi_ec_resume, | 1052 | .resume = acpi_ec_resume, |
1083 | }, | 1053 | }, |