diff options
Diffstat (limited to 'drivers/acpi')
-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 | ||