diff options
author | Alexey Starikovskiy <astarikovskiy@suse.de> | 2008-11-26 17:11:53 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2008-11-26 17:11:53 -0500 |
commit | c5279dee26c0e8d7c4200993bfc4b540d2469598 (patch) | |
tree | 7fa8c42a9693f5a017b5e3bf9ae7a52d9cbb057b /drivers/acpi/ec.c | |
parent | ed313489badef16d700f5a3be50e8fd8f8294bc8 (diff) |
ACPI: EC: Add some basic check for ECDT data
One more ASUS comes with empty ECDT, add a guard for it...
http://bugzilla.kernel.org/show_bug.cgi?id=11880
Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/ec.c')
-rw-r--r-- | drivers/acpi/ec.c | 43 |
1 files changed, 22 insertions, 21 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index cf41f9fc24a7..3ba034fffda5 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -977,7 +977,6 @@ static const struct acpi_device_id ec_device_ids[] = { | |||
977 | 977 | ||
978 | int __init acpi_ec_ecdt_probe(void) | 978 | int __init acpi_ec_ecdt_probe(void) |
979 | { | 979 | { |
980 | int ret; | ||
981 | acpi_status status; | 980 | acpi_status status; |
982 | struct acpi_table_ecdt *ecdt_ptr; | 981 | struct acpi_table_ecdt *ecdt_ptr; |
983 | 982 | ||
@@ -1005,30 +1004,32 @@ int __init acpi_ec_ecdt_probe(void) | |||
1005 | boot_ec->gpe = ecdt_ptr->gpe; | 1004 | boot_ec->gpe = ecdt_ptr->gpe; |
1006 | boot_ec->handle = ACPI_ROOT_OBJECT; | 1005 | boot_ec->handle = ACPI_ROOT_OBJECT; |
1007 | acpi_get_handle(ACPI_ROOT_OBJECT, ecdt_ptr->id, &boot_ec->handle); | 1006 | acpi_get_handle(ACPI_ROOT_OBJECT, ecdt_ptr->id, &boot_ec->handle); |
1008 | } else { | 1007 | /* Add some basic check against completely broken table */ |
1009 | /* This workaround is needed only on some broken machines, | 1008 | if (boot_ec->data_addr != boot_ec->command_addr) |
1010 | * which require early EC, but fail to provide ECDT */ | 1009 | goto install; |
1011 | acpi_handle x; | 1010 | /* fall through */ |
1012 | printk(KERN_DEBUG PREFIX "Look up EC in DSDT\n"); | ||
1013 | status = acpi_get_devices(ec_device_ids[0].id, ec_parse_device, | ||
1014 | boot_ec, NULL); | ||
1015 | /* Check that acpi_get_devices actually find something */ | ||
1016 | if (ACPI_FAILURE(status) || !boot_ec->handle) | ||
1017 | goto error; | ||
1018 | /* We really need to limit this workaround, the only ASUS, | ||
1019 | * which needs it, has fake EC._INI method, so use it as flag. | ||
1020 | * Keep boot_ec struct as it will be needed soon. | ||
1021 | */ | ||
1022 | if (ACPI_FAILURE(acpi_get_handle(boot_ec->handle, "_INI", &x))) | ||
1023 | return -ENODEV; | ||
1024 | } | 1011 | } |
1025 | 1012 | /* This workaround is needed only on some broken machines, | |
1026 | ret = ec_install_handlers(boot_ec); | 1013 | * which require early EC, but fail to provide ECDT */ |
1027 | if (!ret) { | 1014 | acpi_handle x; |
1015 | printk(KERN_DEBUG PREFIX "Look up EC in DSDT\n"); | ||
1016 | status = acpi_get_devices(ec_device_ids[0].id, ec_parse_device, | ||
1017 | boot_ec, NULL); | ||
1018 | /* Check that acpi_get_devices actually find something */ | ||
1019 | if (ACPI_FAILURE(status) || !boot_ec->handle) | ||
1020 | goto error; | ||
1021 | /* We really need to limit this workaround, the only ASUS, | ||
1022 | * which needs it, has fake EC._INI method, so use it as flag. | ||
1023 | * Keep boot_ec struct as it will be needed soon. | ||
1024 | */ | ||
1025 | if (ACPI_FAILURE(acpi_get_handle(boot_ec->handle, "_INI", &x))) | ||
1026 | return -ENODEV; | ||
1027 | install: | ||
1028 | if (!ec_install_handlers(boot_ec)) { | ||
1028 | first_ec = boot_ec; | 1029 | first_ec = boot_ec; |
1029 | return 0; | 1030 | return 0; |
1030 | } | 1031 | } |
1031 | error: | 1032 | error: |
1032 | kfree(boot_ec); | 1033 | kfree(boot_ec); |
1033 | boot_ec = NULL; | 1034 | boot_ec = NULL; |
1034 | return -ENODEV; | 1035 | return -ENODEV; |