Skip to content

Commit

Permalink
ACPI / EC: Fix regression due to conflicting firmware behavior betwee…
Browse files Browse the repository at this point in the history
…n Samsung and Acer.

It is reported that Samsung laptops that need to poll events are broken by
the following commit:
 Commit 3afcf2e
 Subject: ACPI / EC: Add support to disallow QR_EC to be issued when SCI_EVT isn't set

The behaviors of the 2 vendor firmwares are conflict:
 1. Acer: OSPM shouldn't issue QR_EC unless SCI_EVT is set, firmware
         automatically sets SCI_EVT as long as there is event queued up.
 2. Samsung: OSPM should issue QR_EC whatever SCI_EVT is set, firmware
            returns 0 when there is no event queued up.

This patch is a quick fix to distinguish the behaviors to make Acer
behavior only effective for Acer EC firmware so that the breakages on
Samsung EC firmware can be avoided.

Fixes: 3afcf2e (ACPI / EC: Add support to disallow QR_EC to be issued ...)
Link: https://bugzilla.kernel.org/show_bug.cgi?id=44161
Reported-and-tested-by: Ortwin Glück <odi@odi.ch>
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
Cc: 3.17+ <stable@vger.kernel.org> # 3.17+
[ rjw : Subject ]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
  • Loading branch information
Lv Zheng authored and Rafael J. Wysocki committed Oct 29, 2014
1 parent df9ff91 commit 7914900
Showing 1 changed file with 18 additions and 7 deletions.
25 changes: 18 additions & 7 deletions drivers/acpi/ec.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ static int EC_FLAGS_MSI; /* Out-of-spec MSI controller */
static int EC_FLAGS_VALIDATE_ECDT; /* ASUStec ECDTs need to be validated */
static int EC_FLAGS_SKIP_DSDT_SCAN; /* Not all BIOS survive early DSDT scan */
static int EC_FLAGS_CLEAR_ON_RESUME; /* Needs acpi_ec_clear() on boot/resume */
static int EC_FLAGS_QUERY_HANDSHAKE; /* Needs QR_EC issued when SCI_EVT set */

/* --------------------------------------------------------------------------
* Transaction Management
Expand Down Expand Up @@ -236,13 +237,8 @@ static bool advance_transaction(struct acpi_ec *ec)
}
return wakeup;
} else {
/*
* There is firmware refusing to respond QR_EC when SCI_EVT
* is not set, for which case, we complete the QR_EC
* without issuing it to the firmware.
* https://bugzilla.kernel.org/show_bug.cgi?id=86211
*/
if (!(status & ACPI_EC_FLAG_SCI) &&
if (EC_FLAGS_QUERY_HANDSHAKE &&
!(status & ACPI_EC_FLAG_SCI) &&
(t->command == ACPI_EC_COMMAND_QUERY)) {
t->flags |= ACPI_EC_COMMAND_POLL;
t->rdata[t->ri++] = 0x00;
Expand Down Expand Up @@ -1011,6 +1007,18 @@ static int ec_enlarge_storm_threshold(const struct dmi_system_id *id)
return 0;
}

/*
* Acer EC firmware refuses to respond QR_EC when SCI_EVT is not set, for
* which case, we complete the QR_EC without issuing it to the firmware.
* https://bugzilla.kernel.org/show_bug.cgi?id=86211
*/
static int ec_flag_query_handshake(const struct dmi_system_id *id)
{
pr_debug("Detected the EC firmware requiring QR_EC issued when SCI_EVT set\n");
EC_FLAGS_QUERY_HANDSHAKE = 1;
return 0;
}

/*
* On some hardware it is necessary to clear events accumulated by the EC during
* sleep. These ECs stop reporting GPEs until they are manually polled, if too
Expand Down Expand Up @@ -1085,6 +1093,9 @@ static struct dmi_system_id ec_dmi_table[] __initdata = {
{
ec_clear_on_resume, "Samsung hardware", {
DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD.")}, NULL},
{
ec_flag_query_handshake, "Acer hardware", {
DMI_MATCH(DMI_SYS_VENDOR, "Acer"), }, NULL},
{},
};

Expand Down

0 comments on commit 7914900

Please sign in to comment.