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

ACPI / EC: Fix EC_FLAGS_QUERY_HANDSHAKE platforms using new event clearing timing.

It is reported that on several platforms, EC firmware will not respond
non-expected QR_EC (see EC_FLAGS_QUERY_HANDSHAKE, only write QR_EC when
SCI_EVT is set).

Unfortunately, ACPI specification doesn't define when the SCI_EVT should be
cleared by the firmware, thus the original implementation queued up second
QR_EC right after writing QR_EC command and before reading the returned
event value as at that time the SCI_EVT is ensured not cleared. This
behavior is also based on the assumption that the firmware should be able
to return 0x00 to indicate "no outstanding event". This behavior did fix
issues on Samsung platforms where the spurious query value of 0x00 is
supported and didn't break platforms in my test queue.

But recently, specific Acer, Asus, Lenovo platforms keep on blaming this
change.

This patch changes the behavior to re-check the SCI_EVT a bit later and
removes EC_FLAGS_QUERY_HANDSHAKE quirks, hoping this is the Windows
compliant EC driver behavior.

In order to be robust to the possible regressions, instead of removing the
quirk directly, this patch keeps the quirk code, removes the quirk users
and keeps old behavior for Samsung platforms.

Cc: 3.16+ <stable@vger.kernel.org> # 3.16+
Link: https://bugzilla.kernel.org/show_bug.cgi?id=94411
Link: https://bugzilla.kernel.org/show_bug.cgi?id=97381
Link: https://bugzilla.kernel.org/show_bug.cgi?id=98111Reported-and-tested-by: default avatarGabriele Mazzotta <gabriele.mzt@gmail.com>
Reported-and-tested-by: default avatarTigran Gabrielyan <tigrangab@gmail.com>
Reported-and-tested-by: default avatarAdrien D <ghbdtn@openmailbox.org>
Signed-off-by: default avatarLv Zheng <lv.zheng@intel.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 1d68d261
...@@ -133,7 +133,7 @@ static unsigned int ec_polling_guard __read_mostly = ACPI_EC_UDELAY_POLL; ...@@ -133,7 +133,7 @@ static unsigned int ec_polling_guard __read_mostly = ACPI_EC_UDELAY_POLL;
module_param(ec_polling_guard, uint, 0644); module_param(ec_polling_guard, uint, 0644);
MODULE_PARM_DESC(ec_polling_guard, "Guard time(us) between EC accesses in polling modes"); MODULE_PARM_DESC(ec_polling_guard, "Guard time(us) between EC accesses in polling modes");
static unsigned int ec_event_clearing __read_mostly = ACPI_EC_EVT_TIMING_STATUS; static unsigned int ec_event_clearing __read_mostly = ACPI_EC_EVT_TIMING_QUERY;
/* /*
* If the number of false interrupts per one transaction exceeds * If the number of false interrupts per one transaction exceeds
...@@ -1381,10 +1381,13 @@ static int ec_validate_ecdt(const struct dmi_system_id *id) ...@@ -1381,10 +1381,13 @@ static int ec_validate_ecdt(const struct dmi_system_id *id)
return 0; return 0;
} }
#if 0
/* /*
* Acer EC firmware refuses to respond QR_EC when SCI_EVT is not set, for * Some EC firmware variations refuses to respond QR_EC when SCI_EVT is not
* which case, we complete the QR_EC without issuing it to the firmware. * set, for which case, we complete the QR_EC without issuing it to the
* https://bugzilla.kernel.org/show_bug.cgi?id=86211 * firmware.
* https://bugzilla.kernel.org/show_bug.cgi?id=82611
* https://bugzilla.kernel.org/show_bug.cgi?id=97381
*/ */
static int ec_flag_query_handshake(const struct dmi_system_id *id) static int ec_flag_query_handshake(const struct dmi_system_id *id)
{ {
...@@ -1392,6 +1395,7 @@ static int ec_flag_query_handshake(const struct dmi_system_id *id) ...@@ -1392,6 +1395,7 @@ static int ec_flag_query_handshake(const struct dmi_system_id *id)
EC_FLAGS_QUERY_HANDSHAKE = 1; EC_FLAGS_QUERY_HANDSHAKE = 1;
return 0; return 0;
} }
#endif
/* /*
* On some hardware it is necessary to clear events accumulated by the EC during * On some hardware it is necessary to clear events accumulated by the EC during
...@@ -1414,6 +1418,7 @@ static int ec_clear_on_resume(const struct dmi_system_id *id) ...@@ -1414,6 +1418,7 @@ static int ec_clear_on_resume(const struct dmi_system_id *id)
{ {
pr_debug("Detected system needing EC poll on resume.\n"); pr_debug("Detected system needing EC poll on resume.\n");
EC_FLAGS_CLEAR_ON_RESUME = 1; EC_FLAGS_CLEAR_ON_RESUME = 1;
ec_event_clearing = ACPI_EC_EVT_TIMING_STATUS;
return 0; return 0;
} }
...@@ -1443,9 +1448,6 @@ static struct dmi_system_id ec_dmi_table[] __initdata = { ...@@ -1443,9 +1448,6 @@ static struct dmi_system_id ec_dmi_table[] __initdata = {
{ {
ec_clear_on_resume, "Samsung hardware", { ec_clear_on_resume, "Samsung hardware", {
DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD.")}, NULL}, DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD.")}, NULL},
{
ec_flag_query_handshake, "Acer hardware", {
DMI_MATCH(DMI_SYS_VENDOR, "Acer"), }, NULL},
{}, {},
}; };
......
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