Merge branch 'acpi-ec' into acpi
* acpi-ec: ACPI / EC: Fix regression related to PM ops support in ECDT device
This commit is contained in:
Коммит
b6c7026872
|
@ -1597,32 +1597,41 @@ static int acpi_ec_add(struct acpi_device *device)
|
||||||
{
|
{
|
||||||
struct acpi_ec *ec = NULL;
|
struct acpi_ec *ec = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
|
bool is_ecdt = false;
|
||||||
|
acpi_status status;
|
||||||
|
|
||||||
strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME);
|
strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME);
|
||||||
strcpy(acpi_device_class(device), ACPI_EC_CLASS);
|
strcpy(acpi_device_class(device), ACPI_EC_CLASS);
|
||||||
|
|
||||||
ec = acpi_ec_alloc();
|
if (!strcmp(acpi_device_hid(device), ACPI_ECDT_HID)) {
|
||||||
if (!ec)
|
is_ecdt = true;
|
||||||
return -ENOMEM;
|
ec = boot_ec;
|
||||||
if (ec_parse_device(device->handle, 0, ec, NULL) !=
|
} else {
|
||||||
AE_CTRL_TERMINATE) {
|
ec = acpi_ec_alloc();
|
||||||
|
if (!ec)
|
||||||
|
return -ENOMEM;
|
||||||
|
status = ec_parse_device(device->handle, 0, ec, NULL);
|
||||||
|
if (status != AE_CTRL_TERMINATE) {
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto err_alloc;
|
goto err_alloc;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (acpi_is_boot_ec(ec)) {
|
if (acpi_is_boot_ec(ec)) {
|
||||||
boot_ec_is_ecdt = false;
|
boot_ec_is_ecdt = is_ecdt;
|
||||||
/*
|
if (!is_ecdt) {
|
||||||
* Trust PNP0C09 namespace location rather than ECDT ID.
|
/*
|
||||||
*
|
* Trust PNP0C09 namespace location rather than
|
||||||
* But trust ECDT GPE rather than _GPE because of ASUS quirks,
|
* ECDT ID. But trust ECDT GPE rather than _GPE
|
||||||
* so do not change boot_ec->gpe to ec->gpe.
|
* because of ASUS quirks, so do not change
|
||||||
*/
|
* boot_ec->gpe to ec->gpe.
|
||||||
boot_ec->handle = ec->handle;
|
*/
|
||||||
acpi_handle_debug(ec->handle, "duplicated.\n");
|
boot_ec->handle = ec->handle;
|
||||||
acpi_ec_free(ec);
|
acpi_handle_debug(ec->handle, "duplicated.\n");
|
||||||
ec = boot_ec;
|
acpi_ec_free(ec);
|
||||||
ret = acpi_config_boot_ec(ec, ec->handle, true, false);
|
ec = boot_ec;
|
||||||
|
}
|
||||||
|
ret = acpi_config_boot_ec(ec, ec->handle, true, is_ecdt);
|
||||||
} else
|
} else
|
||||||
ret = acpi_ec_setup(ec, true);
|
ret = acpi_ec_setup(ec, true);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@ -1635,8 +1644,10 @@ static int acpi_ec_add(struct acpi_device *device)
|
||||||
ret = !!request_region(ec->command_addr, 1, "EC cmd");
|
ret = !!request_region(ec->command_addr, 1, "EC cmd");
|
||||||
WARN(!ret, "Could not request EC cmd io port 0x%lx", ec->command_addr);
|
WARN(!ret, "Could not request EC cmd io port 0x%lx", ec->command_addr);
|
||||||
|
|
||||||
/* Reprobe devices depending on the EC */
|
if (!is_ecdt) {
|
||||||
acpi_walk_dep_device_list(ec->handle);
|
/* Reprobe devices depending on the EC */
|
||||||
|
acpi_walk_dep_device_list(ec->handle);
|
||||||
|
}
|
||||||
acpi_handle_debug(ec->handle, "enumerated.\n");
|
acpi_handle_debug(ec->handle, "enumerated.\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -1692,6 +1703,7 @@ ec_parse_io_ports(struct acpi_resource *resource, void *context)
|
||||||
|
|
||||||
static const struct acpi_device_id ec_device_ids[] = {
|
static const struct acpi_device_id ec_device_ids[] = {
|
||||||
{"PNP0C09", 0},
|
{"PNP0C09", 0},
|
||||||
|
{ACPI_ECDT_HID, 0},
|
||||||
{"", 0},
|
{"", 0},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1764,11 +1776,14 @@ static int __init acpi_ec_ecdt_start(void)
|
||||||
* Note: ec->handle can be valid if this function is called after
|
* Note: ec->handle can be valid if this function is called after
|
||||||
* acpi_ec_add(), hence the fast path.
|
* acpi_ec_add(), hence the fast path.
|
||||||
*/
|
*/
|
||||||
if (boot_ec->handle != ACPI_ROOT_OBJECT)
|
if (boot_ec->handle == ACPI_ROOT_OBJECT) {
|
||||||
handle = boot_ec->handle;
|
if (!acpi_ec_ecdt_get_handle(&handle))
|
||||||
else if (!acpi_ec_ecdt_get_handle(&handle))
|
return -ENODEV;
|
||||||
return -ENODEV;
|
boot_ec->handle = handle;
|
||||||
return acpi_config_boot_ec(boot_ec, handle, true, true);
|
}
|
||||||
|
|
||||||
|
/* Register to ACPI bus with PM ops attached */
|
||||||
|
return acpi_bus_register_early_device(ACPI_BUS_TYPE_ECDT_EC);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -2022,6 +2037,12 @@ int __init acpi_ec_init(void)
|
||||||
|
|
||||||
/* Drivers must be started after acpi_ec_query_init() */
|
/* Drivers must be started after acpi_ec_query_init() */
|
||||||
dsdt_fail = acpi_bus_register_driver(&acpi_ec_driver);
|
dsdt_fail = acpi_bus_register_driver(&acpi_ec_driver);
|
||||||
|
/*
|
||||||
|
* Register ECDT to ACPI bus only when PNP0C09 probe fails. This is
|
||||||
|
* useful for platforms (confirmed on ASUS X550ZE) with valid ECDT
|
||||||
|
* settings but invalid DSDT settings.
|
||||||
|
* https://bugzilla.kernel.org/show_bug.cgi?id=196847
|
||||||
|
*/
|
||||||
ecdt_fail = acpi_ec_ecdt_start();
|
ecdt_fail = acpi_ec_ecdt_start();
|
||||||
return ecdt_fail && dsdt_fail ? -ENODEV : 0;
|
return ecdt_fail && dsdt_fail ? -ENODEV : 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,6 +115,7 @@ bool acpi_device_is_present(const struct acpi_device *adev);
|
||||||
bool acpi_device_is_battery(struct acpi_device *adev);
|
bool acpi_device_is_battery(struct acpi_device *adev);
|
||||||
bool acpi_device_is_first_physical_node(struct acpi_device *adev,
|
bool acpi_device_is_first_physical_node(struct acpi_device *adev,
|
||||||
const struct device *dev);
|
const struct device *dev);
|
||||||
|
int acpi_bus_register_early_device(int type);
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------
|
||||||
Device Matching and Notification
|
Device Matching and Notification
|
||||||
|
|
|
@ -1024,6 +1024,9 @@ static void acpi_device_get_busid(struct acpi_device *device)
|
||||||
case ACPI_BUS_TYPE_SLEEP_BUTTON:
|
case ACPI_BUS_TYPE_SLEEP_BUTTON:
|
||||||
strcpy(device->pnp.bus_id, "SLPF");
|
strcpy(device->pnp.bus_id, "SLPF");
|
||||||
break;
|
break;
|
||||||
|
case ACPI_BUS_TYPE_ECDT_EC:
|
||||||
|
strcpy(device->pnp.bus_id, "ECDT");
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
acpi_get_name(device->handle, ACPI_SINGLE_NAME, &buffer);
|
acpi_get_name(device->handle, ACPI_SINGLE_NAME, &buffer);
|
||||||
/* Clean up trailing underscores (if any) */
|
/* Clean up trailing underscores (if any) */
|
||||||
|
@ -1304,6 +1307,9 @@ static void acpi_set_pnp_ids(acpi_handle handle, struct acpi_device_pnp *pnp,
|
||||||
case ACPI_BUS_TYPE_SLEEP_BUTTON:
|
case ACPI_BUS_TYPE_SLEEP_BUTTON:
|
||||||
acpi_add_id(pnp, ACPI_BUTTON_HID_SLEEPF);
|
acpi_add_id(pnp, ACPI_BUTTON_HID_SLEEPF);
|
||||||
break;
|
break;
|
||||||
|
case ACPI_BUS_TYPE_ECDT_EC:
|
||||||
|
acpi_add_id(pnp, ACPI_ECDT_HID);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2046,6 +2052,21 @@ void acpi_bus_trim(struct acpi_device *adev)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(acpi_bus_trim);
|
EXPORT_SYMBOL_GPL(acpi_bus_trim);
|
||||||
|
|
||||||
|
int acpi_bus_register_early_device(int type)
|
||||||
|
{
|
||||||
|
struct acpi_device *device = NULL;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
result = acpi_add_single_object(&device, NULL,
|
||||||
|
type, ACPI_STA_DEFAULT);
|
||||||
|
if (result)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
device->flags.match_driver = true;
|
||||||
|
return device_attach(&device->dev);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(acpi_bus_register_early_device);
|
||||||
|
|
||||||
static int acpi_bus_scan_fixed(void)
|
static int acpi_bus_scan_fixed(void)
|
||||||
{
|
{
|
||||||
int result = 0;
|
int result = 0;
|
||||||
|
|
|
@ -105,6 +105,7 @@ enum acpi_bus_device_type {
|
||||||
ACPI_BUS_TYPE_THERMAL,
|
ACPI_BUS_TYPE_THERMAL,
|
||||||
ACPI_BUS_TYPE_POWER_BUTTON,
|
ACPI_BUS_TYPE_POWER_BUTTON,
|
||||||
ACPI_BUS_TYPE_SLEEP_BUTTON,
|
ACPI_BUS_TYPE_SLEEP_BUTTON,
|
||||||
|
ACPI_BUS_TYPE_ECDT_EC,
|
||||||
ACPI_BUS_DEVICE_TYPE_COUNT
|
ACPI_BUS_DEVICE_TYPE_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,7 @@
|
||||||
#define ACPI_VIDEO_HID "LNXVIDEO"
|
#define ACPI_VIDEO_HID "LNXVIDEO"
|
||||||
#define ACPI_BAY_HID "LNXIOBAY"
|
#define ACPI_BAY_HID "LNXIOBAY"
|
||||||
#define ACPI_DOCK_HID "LNXDOCK"
|
#define ACPI_DOCK_HID "LNXDOCK"
|
||||||
|
#define ACPI_ECDT_HID "LNXEC"
|
||||||
/* Quirk for broken IBM BIOSes */
|
/* Quirk for broken IBM BIOSes */
|
||||||
#define ACPI_SMBUS_IBM_HID "SMBUSIBM"
|
#define ACPI_SMBUS_IBM_HID "SMBUSIBM"
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче