Commit f1f055f1 authored by Len Brown's avatar Len Brown

Merge branches 'bugzilla-11884' and 'bugzilla-8544' into release

...@@ -120,31 +120,6 @@ static struct acpi_ec { ...@@ -120,31 +120,6 @@ static struct acpi_ec {
spinlock_t curr_lock; spinlock_t curr_lock;
} *boot_ec, *first_ec; } *boot_ec, *first_ec;
/*
* Some Asus system have exchanged ECDT data/command IO addresses.
*/
static int print_ecdt_error(const struct dmi_system_id *id)
{
printk(KERN_NOTICE PREFIX "%s detected - "
"ECDT has exchanged control/data I/O address\n",
id->ident);
return 0;
}
static struct dmi_system_id __cpuinitdata ec_dmi_table[] = {
{
print_ecdt_error, "Asus L4R", {
DMI_MATCH(DMI_BIOS_VERSION, "1008.006"),
DMI_MATCH(DMI_PRODUCT_NAME, "L4R"),
DMI_MATCH(DMI_BOARD_NAME, "L4R") }, NULL},
{
print_ecdt_error, "Asus M6R", {
DMI_MATCH(DMI_BIOS_VERSION, "0207"),
DMI_MATCH(DMI_PRODUCT_NAME, "M6R"),
DMI_MATCH(DMI_BOARD_NAME, "M6R") }, NULL},
{},
};
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
Transaction Management Transaction Management
-------------------------------------------------------------------------- */ -------------------------------------------------------------------------- */
...@@ -983,8 +958,8 @@ static const struct acpi_device_id ec_device_ids[] = { ...@@ -983,8 +958,8 @@ static const struct acpi_device_id ec_device_ids[] = {
int __init acpi_ec_ecdt_probe(void) int __init acpi_ec_ecdt_probe(void)
{ {
acpi_status status; acpi_status status;
struct acpi_ec *saved_ec = NULL;
struct acpi_table_ecdt *ecdt_ptr; struct acpi_table_ecdt *ecdt_ptr;
acpi_handle dummy;
boot_ec = make_acpi_ec(); boot_ec = make_acpi_ec();
if (!boot_ec) if (!boot_ec)
...@@ -998,21 +973,16 @@ int __init acpi_ec_ecdt_probe(void) ...@@ -998,21 +973,16 @@ int __init acpi_ec_ecdt_probe(void)
pr_info(PREFIX "EC description table is found, configuring boot EC\n"); pr_info(PREFIX "EC description table is found, configuring boot EC\n");
boot_ec->command_addr = ecdt_ptr->control.address; boot_ec->command_addr = ecdt_ptr->control.address;
boot_ec->data_addr = ecdt_ptr->data.address; boot_ec->data_addr = ecdt_ptr->data.address;
if (dmi_check_system(ec_dmi_table)) {
/*
* If the board falls into ec_dmi_table, it means
* that ECDT table gives the incorrect command/status
* & data I/O address. Just fix it.
*/
boot_ec->data_addr = ecdt_ptr->control.address;
boot_ec->command_addr = ecdt_ptr->data.address;
}
boot_ec->gpe = ecdt_ptr->gpe; boot_ec->gpe = ecdt_ptr->gpe;
boot_ec->handle = ACPI_ROOT_OBJECT; boot_ec->handle = ACPI_ROOT_OBJECT;
acpi_get_handle(ACPI_ROOT_OBJECT, ecdt_ptr->id, &boot_ec->handle); acpi_get_handle(ACPI_ROOT_OBJECT, ecdt_ptr->id, &boot_ec->handle);
/* Add some basic check against completely broken table */ /* Don't trust ECDT, which comes from ASUSTek */
if (boot_ec->data_addr != boot_ec->command_addr) if (!dmi_name_in_vendors("ASUS"))
goto install; goto install;
saved_ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL);
if (!saved_ec)
return -ENOMEM;
memcpy(&saved_ec, boot_ec, sizeof(saved_ec));
/* fall through */ /* fall through */
} }
/* This workaround is needed only on some broken machines, /* This workaround is needed only on some broken machines,
...@@ -1023,12 +993,29 @@ int __init acpi_ec_ecdt_probe(void) ...@@ -1023,12 +993,29 @@ int __init acpi_ec_ecdt_probe(void)
/* Check that acpi_get_devices actually find something */ /* Check that acpi_get_devices actually find something */
if (ACPI_FAILURE(status) || !boot_ec->handle) if (ACPI_FAILURE(status) || !boot_ec->handle)
goto error; goto error;
/* We really need to limit this workaround, the only ASUS, if (saved_ec) {
* which needs it, has fake EC._INI method, so use it as flag. /* try to find good ECDT from ASUSTek */
* Keep boot_ec struct as it will be needed soon. if (saved_ec->command_addr != boot_ec->command_addr ||
*/ saved_ec->data_addr != boot_ec->data_addr ||
if (ACPI_FAILURE(acpi_get_handle(boot_ec->handle, "_INI", &dummy))) saved_ec->gpe != boot_ec->gpe ||
return -ENODEV; saved_ec->handle != boot_ec->handle)
pr_info(PREFIX "ASUSTek keeps feeding us with broken "
"ECDT tables, which are very hard to workaround. "
"Trying to use DSDT EC info instead. Please send "
"output of acpidump to linux-acpi@vger.kernel.org\n");
kfree(saved_ec);
saved_ec = NULL;
} else {
/* We really need to limit this workaround, the only ASUS,
* which needs it, has fake EC._INI method, so use it as flag.
* Keep boot_ec struct as it will be needed soon.
*/
acpi_handle dummy;
if (!dmi_name_in_vendors("ASUS") ||
ACPI_FAILURE(acpi_get_handle(boot_ec->handle, "_INI",
&dummy)))
return -ENODEV;
}
install: install:
if (!ec_install_handlers(boot_ec)) { if (!ec_install_handlers(boot_ec)) {
first_ec = boot_ec; first_ec = boot_ec;
......
...@@ -416,7 +416,8 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) ...@@ -416,7 +416,8 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
} }
/* Passive (optional) */ /* Passive (optional) */
if (flag & ACPI_TRIPS_PASSIVE) { if (((flag & ACPI_TRIPS_PASSIVE) && tz->trips.passive.flags.valid) ||
(flag == ACPI_TRIPS_INIT)) {
valid = tz->trips.passive.flags.valid; valid = tz->trips.passive.flags.valid;
if (psv == -1) { if (psv == -1) {
status = AE_SUPPORT; status = AE_SUPPORT;
...@@ -462,8 +463,11 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) ...@@ -462,8 +463,11 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
memset(&devices, 0, sizeof(struct acpi_handle_list)); memset(&devices, 0, sizeof(struct acpi_handle_list));
status = acpi_evaluate_reference(tz->device->handle, "_PSL", status = acpi_evaluate_reference(tz->device->handle, "_PSL",
NULL, &devices); NULL, &devices);
if (ACPI_FAILURE(status)) if (ACPI_FAILURE(status)) {
printk(KERN_WARNING PREFIX
"Invalid passive threshold\n");
tz->trips.passive.flags.valid = 0; tz->trips.passive.flags.valid = 0;
}
else else
tz->trips.passive.flags.valid = 1; tz->trips.passive.flags.valid = 1;
...@@ -487,7 +491,8 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) ...@@ -487,7 +491,8 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
if (act == -1) if (act == -1)
break; /* disable all active trip points */ break; /* disable all active trip points */
if (flag & ACPI_TRIPS_ACTIVE) { if ((flag == ACPI_TRIPS_INIT) || ((flag & ACPI_TRIPS_ACTIVE) &&
tz->trips.active[i].flags.valid)) {
status = acpi_evaluate_integer(tz->device->handle, status = acpi_evaluate_integer(tz->device->handle,
name, NULL, &tmp); name, NULL, &tmp);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
...@@ -521,8 +526,11 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) ...@@ -521,8 +526,11 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
memset(&devices, 0, sizeof(struct acpi_handle_list)); memset(&devices, 0, sizeof(struct acpi_handle_list));
status = acpi_evaluate_reference(tz->device->handle, status = acpi_evaluate_reference(tz->device->handle,
name, NULL, &devices); name, NULL, &devices);
if (ACPI_FAILURE(status)) if (ACPI_FAILURE(status)) {
printk(KERN_WARNING PREFIX
"Invalid active%d threshold\n", i);
tz->trips.active[i].flags.valid = 0; tz->trips.active[i].flags.valid = 0;
}
else else
tz->trips.active[i].flags.valid = 1; tz->trips.active[i].flags.valid = 1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment