Skip to content

Commit

Permalink
ACPI / EC: Fix code ordering issue in ec_remove_handlers()
Browse files Browse the repository at this point in the history
There is an order issue in ec_remove_handlers() that acpi_ec_stop()
is called before removing the operation region handler. That is
incorrect, because the operation region handler removal triggers
_REG(DISCONNECT) which may result in new EC transactions to carry
out.

That existing issue has been triggered by the following commit:

    Commit: dcf15cb
    Subject: ACPI / EC: Fix a boot EC regresion by restoring boot EC

which changed the driver to call ec_remove_handlers() after invoking
_REG(CONNECT), so the issue has become visible.

Fixes: dcf15cb (ACPI / EC: Fix a boot EC regresion by restoring boot EC)
Link: https://bugzilla.kernel.org/show_bug.cgi?id=102421
Reported-and-tested-by: Wolfram Sang <[email protected]>
Reported-by: Nicholas <[email protected]>
Signed-off-by: Lv Zheng <[email protected]>
[ rjw: Changelog ]
Signed-off-by: Rafael J. Wysocki <[email protected]>
  • Loading branch information
Lv Zheng authored and rafaeljw committed Jul 8, 2016
1 parent a99cde4 commit fa5b4a5
Showing 1 changed file with 13 additions and 2 deletions.
15 changes: 13 additions & 2 deletions drivers/acpi/ec.c
Original file line number Diff line number Diff line change
Expand Up @@ -1331,15 +1331,26 @@ static int ec_install_handlers(struct acpi_ec *ec)

static void ec_remove_handlers(struct acpi_ec *ec)
{
acpi_ec_stop(ec, false);

if (test_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags)) {
if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle,
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);
}

/*
* Stops handling the EC transactions after removing the operation
* region handler. This is required because _REG(DISCONNECT)
* invoked during the removal can result in new EC transactions.
*
* Flushes the EC requests and thus disables the GPE before
* removing the GPE handler. This is required by the current ACPICA
* GPE core. ACPICA GPE core will automatically disable a GPE when
* it is indicated but there is no way to handle it. So the drivers
* must disable the GPEs prior to removing the GPE handlers.
*/
acpi_ec_stop(ec, false);

if (test_bit(EC_FLAGS_GPE_HANDLER_INSTALLED, &ec->flags)) {
if (ACPI_FAILURE(acpi_remove_gpe_handler(NULL, ec->gpe,
&acpi_ec_gpe_handler)))
Expand Down

0 comments on commit fa5b4a5

Please sign in to comment.