Commit fa5b4a50 authored by Lv Zheng's avatar Lv Zheng Committed by Rafael J. Wysocki

ACPI / EC: Fix code ordering issue in ec_remove_handlers()

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: dcf15cbd
    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: dcf15cbd (ACPI / EC: Fix a boot EC regresion by restoring boot EC)
Link: https://bugzilla.kernel.org/show_bug.cgi?id=102421Reported-and-tested-by: default avatarWolfram Sang <wsa@the-dreams.de>
Reported-by: default avatarNicholas <nkudriavtsev@gmail.com>
Signed-off-by: default avatarLv Zheng <lv.zheng@intel.com>
[ rjw: Changelog ]
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent a99cde43
...@@ -1331,8 +1331,6 @@ static int ec_install_handlers(struct acpi_ec *ec) ...@@ -1331,8 +1331,6 @@ static int ec_install_handlers(struct acpi_ec *ec)
static void ec_remove_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 (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->handle,
ACPI_ADR_SPACE_EC, &acpi_ec_space_handler))) ACPI_ADR_SPACE_EC, &acpi_ec_space_handler)))
...@@ -1340,6 +1338,19 @@ static void ec_remove_handlers(struct acpi_ec *ec) ...@@ -1340,6 +1338,19 @@ static void ec_remove_handlers(struct acpi_ec *ec)
clear_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags); 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 (test_bit(EC_FLAGS_GPE_HANDLER_INSTALLED, &ec->flags)) {
if (ACPI_FAILURE(acpi_remove_gpe_handler(NULL, ec->gpe, if (ACPI_FAILURE(acpi_remove_gpe_handler(NULL, ec->gpe,
&acpi_ec_gpe_handler))) &acpi_ec_gpe_handler)))
......
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