diff options
Diffstat (limited to 'drivers/acpi/ec.c')
-rw-r--r-- | drivers/acpi/ec.c | 57 |
1 files changed, 31 insertions, 26 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 30f3ef236ecb..8dfcbb8aff73 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -42,7 +42,6 @@ | |||
42 | #include <asm/io.h> | 42 | #include <asm/io.h> |
43 | #include <acpi/acpi_bus.h> | 43 | #include <acpi/acpi_bus.h> |
44 | #include <acpi/acpi_drivers.h> | 44 | #include <acpi/acpi_drivers.h> |
45 | #include <acpi/actypes.h> | ||
46 | 45 | ||
47 | #define ACPI_EC_CLASS "embedded_controller" | 46 | #define ACPI_EC_CLASS "embedded_controller" |
48 | #define ACPI_EC_DEVICE_NAME "Embedded Controller" | 47 | #define ACPI_EC_DEVICE_NAME "Embedded Controller" |
@@ -370,7 +369,7 @@ unlock: | |||
370 | * Note: samsung nv5000 doesn't work with ec burst mode. | 369 | * Note: samsung nv5000 doesn't work with ec burst mode. |
371 | * http://bugzilla.kernel.org/show_bug.cgi?id=4980 | 370 | * http://bugzilla.kernel.org/show_bug.cgi?id=4980 |
372 | */ | 371 | */ |
373 | int acpi_ec_burst_enable(struct acpi_ec *ec) | 372 | static int acpi_ec_burst_enable(struct acpi_ec *ec) |
374 | { | 373 | { |
375 | u8 d; | 374 | u8 d; |
376 | struct transaction t = {.command = ACPI_EC_BURST_ENABLE, | 375 | struct transaction t = {.command = ACPI_EC_BURST_ENABLE, |
@@ -380,7 +379,7 @@ int acpi_ec_burst_enable(struct acpi_ec *ec) | |||
380 | return acpi_ec_transaction(ec, &t, 0); | 379 | return acpi_ec_transaction(ec, &t, 0); |
381 | } | 380 | } |
382 | 381 | ||
383 | int acpi_ec_burst_disable(struct acpi_ec *ec) | 382 | static int acpi_ec_burst_disable(struct acpi_ec *ec) |
384 | { | 383 | { |
385 | struct transaction t = {.command = ACPI_EC_BURST_DISABLE, | 384 | struct transaction t = {.command = ACPI_EC_BURST_DISABLE, |
386 | .wdata = NULL, .rdata = NULL, | 385 | .wdata = NULL, .rdata = NULL, |
@@ -756,10 +755,15 @@ static acpi_status | |||
756 | acpi_ec_register_query_methods(acpi_handle handle, u32 level, | 755 | acpi_ec_register_query_methods(acpi_handle handle, u32 level, |
757 | void *context, void **return_value) | 756 | void *context, void **return_value) |
758 | { | 757 | { |
759 | struct acpi_namespace_node *node = handle; | 758 | char node_name[5]; |
759 | struct acpi_buffer buffer = { sizeof(node_name), node_name }; | ||
760 | struct acpi_ec *ec = context; | 760 | struct acpi_ec *ec = context; |
761 | int value = 0; | 761 | int value = 0; |
762 | if (sscanf(node->name.ascii, "_Q%x", &value) == 1) { | 762 | acpi_status status; |
763 | |||
764 | status = acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer); | ||
765 | |||
766 | if (ACPI_SUCCESS(status) && sscanf(node_name, "_Q%x", &value) == 1) { | ||
763 | acpi_ec_add_query_handler(ec, value, handle, NULL, NULL); | 767 | acpi_ec_add_query_handler(ec, value, handle, NULL, NULL); |
764 | } | 768 | } |
765 | return AE_OK; | 769 | return AE_OK; |
@@ -978,9 +982,9 @@ static const struct acpi_device_id ec_device_ids[] = { | |||
978 | 982 | ||
979 | int __init acpi_ec_ecdt_probe(void) | 983 | int __init acpi_ec_ecdt_probe(void) |
980 | { | 984 | { |
981 | int ret; | ||
982 | acpi_status status; | 985 | acpi_status status; |
983 | struct acpi_table_ecdt *ecdt_ptr; | 986 | struct acpi_table_ecdt *ecdt_ptr; |
987 | acpi_handle dummy; | ||
984 | 988 | ||
985 | boot_ec = make_acpi_ec(); | 989 | boot_ec = make_acpi_ec(); |
986 | if (!boot_ec) | 990 | if (!boot_ec) |
@@ -1006,30 +1010,31 @@ int __init acpi_ec_ecdt_probe(void) | |||
1006 | boot_ec->gpe = ecdt_ptr->gpe; | 1010 | boot_ec->gpe = ecdt_ptr->gpe; |
1007 | boot_ec->handle = ACPI_ROOT_OBJECT; | 1011 | boot_ec->handle = ACPI_ROOT_OBJECT; |
1008 | acpi_get_handle(ACPI_ROOT_OBJECT, ecdt_ptr->id, &boot_ec->handle); | 1012 | acpi_get_handle(ACPI_ROOT_OBJECT, ecdt_ptr->id, &boot_ec->handle); |
1009 | } else { | 1013 | /* Add some basic check against completely broken table */ |
1010 | /* This workaround is needed only on some broken machines, | 1014 | if (boot_ec->data_addr != boot_ec->command_addr) |
1011 | * which require early EC, but fail to provide ECDT */ | 1015 | goto install; |
1012 | acpi_handle x; | 1016 | /* fall through */ |
1013 | printk(KERN_DEBUG PREFIX "Look up EC in DSDT\n"); | ||
1014 | status = acpi_get_devices(ec_device_ids[0].id, ec_parse_device, | ||
1015 | boot_ec, NULL); | ||
1016 | /* Check that acpi_get_devices actually find something */ | ||
1017 | if (ACPI_FAILURE(status) || !boot_ec->handle) | ||
1018 | goto error; | ||
1019 | /* We really need to limit this workaround, the only ASUS, | ||
1020 | * which needs it, has fake EC._INI method, so use it as flag. | ||
1021 | * Keep boot_ec struct as it will be needed soon. | ||
1022 | */ | ||
1023 | if (ACPI_FAILURE(acpi_get_handle(boot_ec->handle, "_INI", &x))) | ||
1024 | return -ENODEV; | ||
1025 | } | 1017 | } |
1026 | 1018 | /* This workaround is needed only on some broken machines, | |
1027 | ret = ec_install_handlers(boot_ec); | 1019 | * which require early EC, but fail to provide ECDT */ |
1028 | if (!ret) { | 1020 | printk(KERN_DEBUG PREFIX "Look up EC in DSDT\n"); |
1021 | status = acpi_get_devices(ec_device_ids[0].id, ec_parse_device, | ||
1022 | boot_ec, NULL); | ||
1023 | /* Check that acpi_get_devices actually find something */ | ||
1024 | if (ACPI_FAILURE(status) || !boot_ec->handle) | ||
1025 | goto error; | ||
1026 | /* We really need to limit this workaround, the only ASUS, | ||
1027 | * which needs it, has fake EC._INI method, so use it as flag. | ||
1028 | * Keep boot_ec struct as it will be needed soon. | ||
1029 | */ | ||
1030 | if (ACPI_FAILURE(acpi_get_handle(boot_ec->handle, "_INI", &dummy))) | ||
1031 | return -ENODEV; | ||
1032 | install: | ||
1033 | if (!ec_install_handlers(boot_ec)) { | ||
1029 | first_ec = boot_ec; | 1034 | first_ec = boot_ec; |
1030 | return 0; | 1035 | return 0; |
1031 | } | 1036 | } |
1032 | error: | 1037 | error: |
1033 | kfree(boot_ec); | 1038 | kfree(boot_ec); |
1034 | boot_ec = NULL; | 1039 | boot_ec = NULL; |
1035 | return -ENODEV; | 1040 | return -ENODEV; |