Merge branch 'acpi-ec'
Merge additional ACPI EC driver fixes for 6.2-rc1: - Fix EC address space handler unregistration (Hans de Goede). - Defer the evaluation of _REG for ECDT described ECs till the matching EC device in the DSDT gets parsed and acpi_ec_add() gets called for it (Hans de Goede). * acpi-ec: ACPI: EC: Fix ECDT probe ordering issues ACPI: EC: Fix EC address space handler unregistration
This commit is contained in:
Коммит
3d03140c48
|
@ -94,6 +94,7 @@ enum {
|
|||
EC_FLAGS_QUERY_ENABLED, /* Query is enabled */
|
||||
EC_FLAGS_EVENT_HANDLER_INSTALLED, /* Event handler installed */
|
||||
EC_FLAGS_EC_HANDLER_INSTALLED, /* OpReg handler installed */
|
||||
EC_FLAGS_EC_REG_CALLED, /* OpReg ACPI _REG method called */
|
||||
EC_FLAGS_QUERY_METHODS_INSTALLED, /* _Qxx handlers installed */
|
||||
EC_FLAGS_STARTED, /* Driver is started */
|
||||
EC_FLAGS_STOPPED, /* Driver is stopped */
|
||||
|
@ -1446,6 +1447,7 @@ static bool install_gpio_irq_event_handler(struct acpi_ec *ec)
|
|||
* ec_install_handlers - Install service callbacks and register query methods.
|
||||
* @ec: Target EC.
|
||||
* @device: ACPI device object corresponding to @ec.
|
||||
* @call_reg: If _REG should be called to notify OpRegion availability
|
||||
*
|
||||
* Install a handler for the EC address space type unless it has been installed
|
||||
* already. If @device is not NULL, also look for EC query methods in the
|
||||
|
@ -1458,7 +1460,8 @@ static bool install_gpio_irq_event_handler(struct acpi_ec *ec)
|
|||
* -EPROBE_DEFER if GPIO IRQ acquisition needs to be deferred,
|
||||
* or 0 (success) otherwise.
|
||||
*/
|
||||
static int ec_install_handlers(struct acpi_ec *ec, struct acpi_device *device)
|
||||
static int ec_install_handlers(struct acpi_ec *ec, struct acpi_device *device,
|
||||
bool call_reg)
|
||||
{
|
||||
acpi_status status;
|
||||
|
||||
|
@ -1466,15 +1469,21 @@ static int ec_install_handlers(struct acpi_ec *ec, struct acpi_device *device)
|
|||
|
||||
if (!test_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags)) {
|
||||
acpi_ec_enter_noirq(ec);
|
||||
status = acpi_install_address_space_handler(ec->handle,
|
||||
ACPI_ADR_SPACE_EC,
|
||||
&acpi_ec_space_handler,
|
||||
NULL, ec);
|
||||
status = acpi_install_address_space_handler_no_reg(ec->handle,
|
||||
ACPI_ADR_SPACE_EC,
|
||||
&acpi_ec_space_handler,
|
||||
NULL, ec);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
acpi_ec_stop(ec, false);
|
||||
return -ENODEV;
|
||||
}
|
||||
set_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags);
|
||||
ec->address_space_handler_holder = ec->handle;
|
||||
}
|
||||
|
||||
if (call_reg && !test_bit(EC_FLAGS_EC_REG_CALLED, &ec->flags)) {
|
||||
acpi_execute_reg_methods(ec->handle, ACPI_ADR_SPACE_EC);
|
||||
set_bit(EC_FLAGS_EC_REG_CALLED, &ec->flags);
|
||||
}
|
||||
|
||||
if (!device)
|
||||
|
@ -1526,7 +1535,8 @@ static int ec_install_handlers(struct acpi_ec *ec, struct acpi_device *device)
|
|||
static void ec_remove_handlers(struct acpi_ec *ec)
|
||||
{
|
||||
if (test_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags)) {
|
||||
if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle,
|
||||
if (ACPI_FAILURE(acpi_remove_address_space_handler(
|
||||
ec->address_space_handler_holder,
|
||||
ACPI_ADR_SPACE_EC, &acpi_ec_space_handler)))
|
||||
pr_err("failed to remove space handler\n");
|
||||
clear_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags);
|
||||
|
@ -1562,11 +1572,11 @@ static void ec_remove_handlers(struct acpi_ec *ec)
|
|||
}
|
||||
}
|
||||
|
||||
static int acpi_ec_setup(struct acpi_ec *ec, struct acpi_device *device)
|
||||
static int acpi_ec_setup(struct acpi_ec *ec, struct acpi_device *device, bool call_reg)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = ec_install_handlers(ec, device);
|
||||
ret = ec_install_handlers(ec, device, call_reg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -1631,7 +1641,7 @@ static int acpi_ec_add(struct acpi_device *device)
|
|||
}
|
||||
}
|
||||
|
||||
ret = acpi_ec_setup(ec, device);
|
||||
ret = acpi_ec_setup(ec, device, true);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
|
@ -1750,7 +1760,7 @@ void __init acpi_ec_dsdt_probe(void)
|
|||
* At this point, the GPE is not fully initialized, so do not to
|
||||
* handle the events.
|
||||
*/
|
||||
ret = acpi_ec_setup(ec, NULL);
|
||||
ret = acpi_ec_setup(ec, NULL, true);
|
||||
if (ret) {
|
||||
acpi_ec_free(ec);
|
||||
return;
|
||||
|
@ -1944,7 +1954,7 @@ void __init acpi_ec_ecdt_probe(void)
|
|||
* At this point, the namespace is not initialized, so do not find
|
||||
* the namespace objects, or handle the events.
|
||||
*/
|
||||
ret = acpi_ec_setup(ec, NULL);
|
||||
ret = acpi_ec_setup(ec, NULL, false);
|
||||
if (ret) {
|
||||
acpi_ec_free(ec);
|
||||
goto out;
|
||||
|
|
|
@ -173,6 +173,7 @@ enum acpi_ec_event_state {
|
|||
|
||||
struct acpi_ec {
|
||||
acpi_handle handle;
|
||||
acpi_handle address_space_handler_holder;
|
||||
int gpe;
|
||||
int irq;
|
||||
unsigned long command_addr;
|
||||
|
|
Загрузка…
Ссылка в новой задаче