Commit 692749e8 authored by Lv Zheng's avatar Lv Zheng Committed by Greg Kroah-Hartman

ACPI / EC: Add support to disallow QR_EC to be issued when SCI_EVT isn't set

commit 3afcf2ec upstream.

There is a platform refusing to respond QR_EC when SCI_EVT isn't set
(Acer Aspire V5-573G).

Currently, we rely on the behaviour that the EC firmware can respond
something (for example, 0x00 to indicate "no outstanding events") to
QR_EC even when SCI_EVT is not set, but the reporter has complained
about AC/battery pluging/unpluging and video brightness change delay
on that platform.

This is because the work item that has issued QR_EC has to wait until
timeout in this case, and the _Qxx method evaluation work item queued
after QR_EC one is delayed.

It sounds reasonable to fix this issue by:
 1. Implementing SCI_EVT sanity check before issuing QR_EC in the EC
    driver's main state machine.
 2. Moving QR_EC issuing out of the work queue used by _Qxx evaluation
    to a seperate IRQ handling thread.

This patch fixes this issue using solution 1.

By disallowing QR_EC to be issued when SCI_EVT isn't set, we are able to
handle such platform in the EC driver's main state machine. This patch
enhances the state machine in this way to survive with such malfunctioning
EC firmware.

Note that this patch can also fix CLEAR_ON_RESUME quirk which also relies
on the assumption that the platforms are able to respond even when SCI_EVT
isn't set.

Fixes: c0d65341 ACPI / EC: Fix race condition in ec_transaction_completed()
Link: https://bugzilla.kernel.org/show_bug.cgi?id=82611Reported-and-tested-by: default avatarAlexander Mezin <mezin.alexander@gmail.com>
Signed-off-by: default avatarLv Zheng <lv.zheng@intel.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent afdd3bcc
...@@ -197,6 +197,8 @@ static bool advance_transaction(struct acpi_ec *ec) ...@@ -197,6 +197,8 @@ static bool advance_transaction(struct acpi_ec *ec)
t->rdata[t->ri++] = acpi_ec_read_data(ec); t->rdata[t->ri++] = acpi_ec_read_data(ec);
if (t->rlen == t->ri) { if (t->rlen == t->ri) {
t->flags |= ACPI_EC_COMMAND_COMPLETE; t->flags |= ACPI_EC_COMMAND_COMPLETE;
if (t->command == ACPI_EC_COMMAND_QUERY)
pr_debug("hardware QR_EC completion\n");
wakeup = true; wakeup = true;
} }
} else } else
...@@ -208,7 +210,20 @@ static bool advance_transaction(struct acpi_ec *ec) ...@@ -208,7 +210,20 @@ static bool advance_transaction(struct acpi_ec *ec)
} }
return wakeup; return wakeup;
} else { } else {
if ((status & ACPI_EC_FLAG_IBF) == 0) { /*
* 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) &&
(t->command == ACPI_EC_COMMAND_QUERY)) {
t->flags |= ACPI_EC_COMMAND_POLL;
t->rdata[t->ri++] = 0x00;
t->flags |= ACPI_EC_COMMAND_COMPLETE;
pr_debug("software QR_EC completion\n");
wakeup = true;
} else if ((status & ACPI_EC_FLAG_IBF) == 0) {
acpi_ec_write_cmd(ec, t->command); acpi_ec_write_cmd(ec, t->command);
t->flags |= ACPI_EC_COMMAND_POLL; t->flags |= ACPI_EC_COMMAND_POLL;
} else } else
......
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