mirror of https://gitee.com/openkylin/linux.git
Merge branches 'bugzilla-11884' and 'bugzilla-8544' into release
This commit is contained in:
commit
f1f055f103
|
@ -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[] = {
|
||||||
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)
|
||||||
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)
|
||||||
/* 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)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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)
|
||||||
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)
|
||||||
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)
|
||||||
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;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue