diff options
| -rw-r--r-- | drivers/acpi/ec.c | 73 | ||||
| -rw-r--r-- | drivers/acpi/thermal.c | 16 |
2 files changed, 42 insertions, 47 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 8dfcbb8aff73..a2b82c90a683 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
| @@ -120,31 +120,6 @@ static struct acpi_ec { | |||
| 120 | spinlock_t curr_lock; | 120 | spinlock_t curr_lock; |
| 121 | } *boot_ec, *first_ec; | 121 | } *boot_ec, *first_ec; |
| 122 | 122 | ||
| 123 | /* | ||
| 124 | * Some Asus system have exchanged ECDT data/command IO addresses. | ||
| 125 | */ | ||
| 126 | static int print_ecdt_error(const struct dmi_system_id *id) | ||
| 127 | { | ||
| 128 | printk(KERN_NOTICE PREFIX "%s detected - " | ||
| 129 | "ECDT has exchanged control/data I/O address\n", | ||
| 130 | id->ident); | ||
| 131 | return 0; | ||
| 132 | } | ||
| 133 | |||
| 134 | static struct dmi_system_id __cpuinitdata ec_dmi_table[] = { | ||
| 135 | { | ||
| 136 | print_ecdt_error, "Asus L4R", { | ||
| 137 | DMI_MATCH(DMI_BIOS_VERSION, "1008.006"), | ||
| 138 | DMI_MATCH(DMI_PRODUCT_NAME, "L4R"), | ||
| 139 | DMI_MATCH(DMI_BOARD_NAME, "L4R") }, NULL}, | ||
| 140 | { | ||
| 141 | print_ecdt_error, "Asus M6R", { | ||
| 142 | DMI_MATCH(DMI_BIOS_VERSION, "0207"), | ||
| 143 | DMI_MATCH(DMI_PRODUCT_NAME, "M6R"), | ||
| 144 | DMI_MATCH(DMI_BOARD_NAME, "M6R") }, NULL}, | ||
| 145 | {}, | ||
| 146 | }; | ||
| 147 | |||
| 148 | /* -------------------------------------------------------------------------- | 123 | /* -------------------------------------------------------------------------- |
| 149 | Transaction Management | 124 | Transaction Management |
| 150 | -------------------------------------------------------------------------- */ | 125 | -------------------------------------------------------------------------- */ |
| @@ -983,8 +958,8 @@ static const struct acpi_device_id ec_device_ids[] = { | |||
| 983 | int __init acpi_ec_ecdt_probe(void) | 958 | int __init acpi_ec_ecdt_probe(void) |
| 984 | { | 959 | { |
| 985 | acpi_status status; | 960 | acpi_status status; |
| 961 | struct acpi_ec *saved_ec = NULL; | ||
| 986 | struct acpi_table_ecdt *ecdt_ptr; | 962 | struct acpi_table_ecdt *ecdt_ptr; |
| 987 | acpi_handle dummy; | ||
| 988 | 963 | ||
| 989 | boot_ec = make_acpi_ec(); | 964 | boot_ec = make_acpi_ec(); |
| 990 | if (!boot_ec) | 965 | if (!boot_ec) |
| @@ -998,21 +973,16 @@ int __init acpi_ec_ecdt_probe(void) | |||
| 998 | pr_info(PREFIX "EC description table is found, configuring boot EC\n"); | 973 | pr_info(PREFIX "EC description table is found, configuring boot EC\n"); |
| 999 | boot_ec->command_addr = ecdt_ptr->control.address; | 974 | boot_ec->command_addr = ecdt_ptr->control.address; |
| 1000 | boot_ec->data_addr = ecdt_ptr->data.address; | 975 | boot_ec->data_addr = ecdt_ptr->data.address; |
| 1001 | if (dmi_check_system(ec_dmi_table)) { | ||
| 1002 | /* | ||
| 1003 | * If the board falls into ec_dmi_table, it means | ||
| 1004 | * that ECDT table gives the incorrect command/status | ||
| 1005 | * & data I/O address. Just fix it. | ||
| 1006 | */ | ||
| 1007 | boot_ec->data_addr = ecdt_ptr->control.address; | ||
| 1008 | boot_ec->command_addr = ecdt_ptr->data.address; | ||
| 1009 | } | ||
| 1010 | boot_ec->gpe = ecdt_ptr->gpe; | 976 | boot_ec->gpe = ecdt_ptr->gpe; |
| 1011 | boot_ec->handle = ACPI_ROOT_OBJECT; | 977 | boot_ec->handle = ACPI_ROOT_OBJECT; |
| 1012 | acpi_get_handle(ACPI_ROOT_OBJECT, ecdt_ptr->id, &boot_ec->handle); | 978 | acpi_get_handle(ACPI_ROOT_OBJECT, ecdt_ptr->id, &boot_ec->handle); |
| 1013 | /* Add some basic check against completely broken table */ | 979 | /* Don't trust ECDT, which comes from ASUSTek */ |
| 1014 | if (boot_ec->data_addr != boot_ec->command_addr) | 980 | if (!dmi_name_in_vendors("ASUS")) |
| 1015 | goto install; | 981 | goto install; |
| 982 | saved_ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL); | ||
| 983 | if (!saved_ec) | ||
| 984 | return -ENOMEM; | ||
| 985 | memcpy(&saved_ec, boot_ec, sizeof(saved_ec)); | ||
| 1016 | /* fall through */ | 986 | /* fall through */ |
| 1017 | } | 987 | } |
| 1018 | /* This workaround is needed only on some broken machines, | 988 | /* This workaround is needed only on some broken machines, |
| @@ -1023,12 +993,29 @@ int __init acpi_ec_ecdt_probe(void) | |||
| 1023 | /* Check that acpi_get_devices actually find something */ | 993 | /* Check that acpi_get_devices actually find something */ |
| 1024 | if (ACPI_FAILURE(status) || !boot_ec->handle) | 994 | if (ACPI_FAILURE(status) || !boot_ec->handle) |
| 1025 | goto error; | 995 | goto error; |
| 1026 | /* We really need to limit this workaround, the only ASUS, | 996 | if (saved_ec) { |
| 1027 | * which needs it, has fake EC._INI method, so use it as flag. | 997 | /* try to find good ECDT from ASUSTek */ |
| 1028 | * Keep boot_ec struct as it will be needed soon. | 998 | if (saved_ec->command_addr != boot_ec->command_addr || |
| 1029 | */ | 999 | saved_ec->data_addr != boot_ec->data_addr || |
| 1030 | if (ACPI_FAILURE(acpi_get_handle(boot_ec->handle, "_INI", &dummy))) | 1000 | saved_ec->gpe != boot_ec->gpe || |
| 1031 | return -ENODEV; | 1001 | saved_ec->handle != boot_ec->handle) |
| 1002 | pr_info(PREFIX "ASUSTek keeps feeding us with broken " | ||
| 1003 | "ECDT tables, which are very hard to workaround. " | ||
| 1004 | "Trying to use DSDT EC info instead. Please send " | ||
| 1005 | "output of acpidump to linux-acpi@vger.kernel.org\n"); | ||
| 1006 | kfree(saved_ec); | ||
| 1007 | saved_ec = NULL; | ||
| 1008 | } else { | ||
| 1009 | /* We really need to limit this workaround, the only ASUS, | ||
| 1010 | * which needs it, has fake EC._INI method, so use it as flag. | ||
| 1011 | * Keep boot_ec struct as it will be needed soon. | ||
| 1012 | */ | ||
| 1013 | acpi_handle dummy; | ||
| 1014 | if (!dmi_name_in_vendors("ASUS") || | ||
| 1015 | ACPI_FAILURE(acpi_get_handle(boot_ec->handle, "_INI", | ||
| 1016 | &dummy))) | ||
| 1017 | return -ENODEV; | ||
| 1018 | } | ||
| 1032 | install: | 1019 | install: |
| 1033 | if (!ec_install_handlers(boot_ec)) { | 1020 | if (!ec_install_handlers(boot_ec)) { |
| 1034 | first_ec = boot_ec; | 1021 | first_ec = boot_ec; |
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 073ff09218a9..99e6f1f8ea45 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c | |||
| @@ -416,7 +416,8 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) | |||
| 416 | } | 416 | } |
| 417 | 417 | ||
| 418 | /* Passive (optional) */ | 418 | /* Passive (optional) */ |
| 419 | if (flag & ACPI_TRIPS_PASSIVE) { | 419 | if (((flag & ACPI_TRIPS_PASSIVE) && tz->trips.passive.flags.valid) || |
| 420 | (flag == ACPI_TRIPS_INIT)) { | ||
| 420 | valid = tz->trips.passive.flags.valid; | 421 | valid = tz->trips.passive.flags.valid; |
| 421 | if (psv == -1) { | 422 | if (psv == -1) { |
| 422 | status = AE_SUPPORT; | 423 | status = AE_SUPPORT; |
| @@ -462,8 +463,11 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) | |||
| 462 | memset(&devices, 0, sizeof(struct acpi_handle_list)); | 463 | memset(&devices, 0, sizeof(struct acpi_handle_list)); |
| 463 | status = acpi_evaluate_reference(tz->device->handle, "_PSL", | 464 | status = acpi_evaluate_reference(tz->device->handle, "_PSL", |
| 464 | NULL, &devices); | 465 | NULL, &devices); |
| 465 | if (ACPI_FAILURE(status)) | 466 | if (ACPI_FAILURE(status)) { |
| 467 | printk(KERN_WARNING PREFIX | ||
| 468 | "Invalid passive threshold\n"); | ||
| 466 | tz->trips.passive.flags.valid = 0; | 469 | tz->trips.passive.flags.valid = 0; |
| 470 | } | ||
| 467 | else | 471 | else |
| 468 | tz->trips.passive.flags.valid = 1; | 472 | tz->trips.passive.flags.valid = 1; |
| 469 | 473 | ||
| @@ -487,7 +491,8 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) | |||
| 487 | if (act == -1) | 491 | if (act == -1) |
| 488 | break; /* disable all active trip points */ | 492 | break; /* disable all active trip points */ |
| 489 | 493 | ||
| 490 | if (flag & ACPI_TRIPS_ACTIVE) { | 494 | if ((flag == ACPI_TRIPS_INIT) || ((flag & ACPI_TRIPS_ACTIVE) && |
| 495 | tz->trips.active[i].flags.valid)) { | ||
| 491 | status = acpi_evaluate_integer(tz->device->handle, | 496 | status = acpi_evaluate_integer(tz->device->handle, |
| 492 | name, NULL, &tmp); | 497 | name, NULL, &tmp); |
| 493 | if (ACPI_FAILURE(status)) { | 498 | if (ACPI_FAILURE(status)) { |
| @@ -521,8 +526,11 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) | |||
| 521 | memset(&devices, 0, sizeof(struct acpi_handle_list)); | 526 | memset(&devices, 0, sizeof(struct acpi_handle_list)); |
| 522 | status = acpi_evaluate_reference(tz->device->handle, | 527 | status = acpi_evaluate_reference(tz->device->handle, |
| 523 | name, NULL, &devices); | 528 | name, NULL, &devices); |
| 524 | if (ACPI_FAILURE(status)) | 529 | if (ACPI_FAILURE(status)) { |
| 530 | printk(KERN_WARNING PREFIX | ||
| 531 | "Invalid active%d threshold\n", i); | ||
| 525 | tz->trips.active[i].flags.valid = 0; | 532 | tz->trips.active[i].flags.valid = 0; |
| 533 | } | ||
| 526 | else | 534 | else |
| 527 | tz->trips.active[i].flags.valid = 1; | 535 | tz->trips.active[i].flags.valid = 1; |
| 528 | 536 | ||
