Pull ec into release branch

Len Brown d88da66f 6712a4fb

+45 -68
+45 -68
drivers/acpi/ec.c
··· 471 } 472 } 473 mutex_unlock(&ec->lock); 474 - printk(KERN_ERR PREFIX "Handler for query 0x%x is not found!\n", value); 475 } 476 477 static u32 acpi_ec_gpe_handler(void *data) ··· 652 } 653 654 static acpi_status 655 - acpi_ec_register_query_methods(acpi_handle handle, u32 level, 656 - void *context, void **return_value) 657 { 658 - struct acpi_namespace_node *node = handle; 659 - struct acpi_ec *ec = context; 660 - int value = 0; 661 - if (sscanf(node->name.ascii, "_Q%x", &value) == 1) { 662 - acpi_ec_add_query_handler(ec, value, handle, NULL, NULL); 663 - } 664 - return AE_OK; 665 - } 666 667 - static int ec_parse_device(struct acpi_ec *ec, acpi_handle handle) 668 - { 669 - if (ACPI_FAILURE(acpi_walk_resources(handle, METHOD_NAME__CRS, 670 - ec_parse_io_ports, ec))) 671 - return -EINVAL; 672 673 /* Get GPE bit assignment (EC events). */ 674 /* TODO: Add support for _GPE returning a package */ 675 - if (ACPI_FAILURE(acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe))) 676 - return -EINVAL; 677 678 /* Use the global lock for all EC transactions? */ 679 acpi_evaluate_integer(handle, "_GLK", NULL, &ec->global_lock); 680 681 - /* Find and register all query methods */ 682 - acpi_walk_namespace(ACPI_TYPE_METHOD, handle, 1, 683 - acpi_ec_register_query_methods, ec, NULL); 684 - 685 ec->handle = handle; 686 687 - printk(KERN_INFO PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx", 688 ec->gpe, ec->command_addr, ec->data_addr); 689 690 - return 0; 691 } 692 693 static int acpi_ec_add(struct acpi_device *device) ··· 701 if (!ec) 702 return -ENOMEM; 703 704 - if (ec_parse_device(ec, device->handle)) { 705 kfree(ec); 706 return -EINVAL; 707 } ··· 710 /* Check if we found the boot EC */ 711 if (boot_ec) { 712 if (boot_ec->gpe == ec->gpe) { 713 - /* We might have incorrect info for GL at boot time */ 714 - mutex_lock(&boot_ec->lock); 715 - boot_ec->global_lock = ec->global_lock; 716 - /* Copy handlers from new ec into boot ec */ 717 - list_splice(&ec->list, &boot_ec->list); 718 - mutex_unlock(&boot_ec->lock); 719 - kfree(ec); 720 - ec = boot_ec; 721 } 722 - } else 723 first_ec = ec; 724 ec->handle = device->handle; 725 acpi_driver_data(device) = ec; ··· 728 static int acpi_ec_remove(struct acpi_device *device, int type) 729 { 730 struct acpi_ec *ec; 731 - struct acpi_ec_query_handler *handler; 732 733 if (!device) 734 return -EINVAL; 735 736 ec = acpi_driver_data(device); 737 mutex_lock(&ec->lock); 738 - list_for_each_entry(handler, &ec->list, node) { 739 list_del(&handler->node); 740 kfree(handler); 741 } ··· 745 if (ec == first_ec) 746 first_ec = NULL; 747 748 - /* Don't touch boot EC */ 749 - if (boot_ec != ec) 750 - kfree(ec); 751 return 0; 752 } 753 ··· 808 if (!ec) 809 return -EINVAL; 810 811 - /* Boot EC is already working */ 812 - if (ec != boot_ec) 813 - ret = ec_install_handlers(ec); 814 815 /* EC is fully operational, allow queries */ 816 atomic_set(&ec->query_pending, 0); ··· 818 819 static int acpi_ec_stop(struct acpi_device *device, int type) 820 { 821 - acpi_status status; 822 struct acpi_ec *ec; 823 824 if (!device) ··· 826 ec = acpi_driver_data(device); 827 if (!ec) 828 return -EINVAL; 829 - 830 - /* Don't touch boot EC */ 831 - if (ec == boot_ec) 832 - return 0; 833 - 834 - status = acpi_remove_address_space_handler(ec->handle, 835 - ACPI_ADR_SPACE_EC, 836 - &acpi_ec_space_handler); 837 - if (ACPI_FAILURE(status)) 838 - return -ENODEV; 839 - 840 - status = acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler); 841 - if (ACPI_FAILURE(status)) 842 - return -ENODEV; 843 - 844 return 0; 845 } 846 ··· 842 /* 843 * Generate a boot ec context 844 */ 845 - 846 status = acpi_get_table(ACPI_SIG_ECDT, 1, 847 (struct acpi_table_header **)&ecdt_ptr); 848 - if (ACPI_FAILURE(status)) 849 - goto error; 850 - 851 - printk(KERN_INFO PREFIX "EC description table is found, configuring boot EC\n"); 852 - 853 - boot_ec->command_addr = ecdt_ptr->control.address; 854 - boot_ec->data_addr = ecdt_ptr->data.address; 855 - boot_ec->gpe = ecdt_ptr->gpe; 856 - boot_ec->handle = ACPI_ROOT_OBJECT; 857 858 ret = ec_install_handlers(boot_ec); 859 if (!ret) {
··· 471 } 472 } 473 mutex_unlock(&ec->lock); 474 } 475 476 static u32 acpi_ec_gpe_handler(void *data) ··· 653 } 654 655 static acpi_status 656 + ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval) 657 { 658 + acpi_status status; 659 660 + struct acpi_ec *ec = context; 661 + status = acpi_walk_resources(handle, METHOD_NAME__CRS, 662 + ec_parse_io_ports, ec); 663 + if (ACPI_FAILURE(status)) 664 + return status; 665 666 /* Get GPE bit assignment (EC events). */ 667 /* TODO: Add support for _GPE returning a package */ 668 + status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe); 669 + if (ACPI_FAILURE(status)) 670 + return status; 671 672 /* Use the global lock for all EC transactions? */ 673 acpi_evaluate_integer(handle, "_GLK", NULL, &ec->global_lock); 674 675 ec->handle = handle; 676 677 + printk(KERN_INFO PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n", 678 ec->gpe, ec->command_addr, ec->data_addr); 679 680 + return AE_CTRL_TERMINATE; 681 + } 682 + 683 + static void ec_remove_handlers(struct acpi_ec *ec) 684 + { 685 + acpi_remove_address_space_handler(ec->handle, 686 + ACPI_ADR_SPACE_EC, 687 + &acpi_ec_space_handler); 688 + acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler); 689 } 690 691 static int acpi_ec_add(struct acpi_device *device) ··· 705 if (!ec) 706 return -ENOMEM; 707 708 + if (ec_parse_device(device->handle, 0, ec, NULL) != 709 + AE_CTRL_TERMINATE) { 710 kfree(ec); 711 return -EINVAL; 712 } ··· 713 /* Check if we found the boot EC */ 714 if (boot_ec) { 715 if (boot_ec->gpe == ec->gpe) { 716 + ec_remove_handlers(boot_ec); 717 + mutex_destroy(&boot_ec->lock); 718 + kfree(boot_ec); 719 + first_ec = boot_ec = NULL; 720 } 721 + } 722 + if (!first_ec) 723 first_ec = ec; 724 ec->handle = device->handle; 725 acpi_driver_data(device) = ec; ··· 734 static int acpi_ec_remove(struct acpi_device *device, int type) 735 { 736 struct acpi_ec *ec; 737 + struct acpi_ec_query_handler *handler, *tmp; 738 739 if (!device) 740 return -EINVAL; 741 742 ec = acpi_driver_data(device); 743 mutex_lock(&ec->lock); 744 + list_for_each_entry_safe(handler, tmp, &ec->list, node) { 745 list_del(&handler->node); 746 kfree(handler); 747 } ··· 751 if (ec == first_ec) 752 first_ec = NULL; 753 754 return 0; 755 } 756 ··· 817 if (!ec) 818 return -EINVAL; 819 820 + ret = ec_install_handlers(ec); 821 822 /* EC is fully operational, allow queries */ 823 atomic_set(&ec->query_pending, 0); ··· 829 830 static int acpi_ec_stop(struct acpi_device *device, int type) 831 { 832 struct acpi_ec *ec; 833 834 if (!device) ··· 838 ec = acpi_driver_data(device); 839 if (!ec) 840 return -EINVAL; 841 + ec_remove_handlers(ec); 842 return 0; 843 } 844 ··· 868 /* 869 * Generate a boot ec context 870 */ 871 status = acpi_get_table(ACPI_SIG_ECDT, 1, 872 (struct acpi_table_header **)&ecdt_ptr); 873 + if (ACPI_SUCCESS(status)) { 874 + printk(KERN_INFO PREFIX "EC description table is found, configuring boot EC\n\n"); 875 + boot_ec->command_addr = ecdt_ptr->control.address; 876 + boot_ec->data_addr = ecdt_ptr->data.address; 877 + boot_ec->gpe = ecdt_ptr->gpe; 878 + boot_ec->handle = ACPI_ROOT_OBJECT; 879 + } else { 880 + printk(KERN_DEBUG PREFIX "Look up EC in DSDT\n"); 881 + status = acpi_get_devices(ec_device_ids[0].id, ec_parse_device, 882 + boot_ec, NULL); 883 + if (ACPI_FAILURE(status)) 884 + goto error; 885 + } 886 887 ret = ec_install_handlers(boot_ec); 888 if (!ret) {