aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/ec.c
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2009-09-19 01:56:39 -0400
committerLen Brown <len.brown@intel.com>2009-09-19 01:56:39 -0400
commit3b87bb640e77023c97cf209e3dd85887a1113ad0 (patch)
treec4531d2c954bcc28706837cc67a8865677e51fbf /drivers/acpi/ec.c
parent7a92d803227a523a9a5546e4e0dce1325a4b5926 (diff)
parentdcf52fb71d988ba945054308f661bddf9b2455fb (diff)
Merge branch 'bjorn-start-stop-2.6.32' into release
Diffstat (limited to 'drivers/acpi/ec.c')
-rw-r--r--drivers/acpi/ec.c118
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
790static 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
790static void ec_remove_handlers(struct acpi_ec *ec) 826static 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)
801static int acpi_ec_add(struct acpi_device *device) 837static 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
844static int acpi_ec_remove(struct acpi_device *device, int type) 884static 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
890static 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
926static 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
946static 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
959int __init acpi_boot_ec_enable(void) 931int __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 },