Dear Kamal,<div><br></div><div>please wait for now as a slight regression was reported for one system and the patch will be changed.</div><div><br></div><div>Best,</div><div><br></div><div>Dennis<br><br>Am Freitag, 28. März 2014 schrieb Kamal Mostafa :<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">This is a note to let you know that I have just added a patch titled<br>
<br>
ACPI / EC: Clear stale EC events on Samsung systems<br>
<br>
to the linux-3.8.y-queue branch of the 3.8.y.z extended stable tree<br>
which can be found at:<br>
<br>
<a href="http://kernel.ubuntu.com/git?p=ubuntu/linux.git;a=shortlog;h=refs/heads/linux-3.8.y-queue" target="_blank">http://kernel.ubuntu.com/git?p=ubuntu/linux.git;a=shortlog;h=refs/heads/linux-3.8.y-queue</a><br>
<br>
This patch is scheduled to be released in version 3.8.13.21.<br>
<br>
If you, or anyone else, feels it should not be added to this tree, please<br>
reply to this email.<br>
<br>
For more information about the 3.8.y.z tree, see<br>
<a href="https://wiki.ubuntu.com/Kernel/Dev/ExtendedStable" target="_blank">https://wiki.ubuntu.com/Kernel/Dev/ExtendedStable</a><br>
<br>
Thanks.<br>
-Kamal<br>
<br>
------<br>
<br>
>From 1393f3f58ecb25d9ce797d30baf41eeccf975516 Mon Sep 17 00:00:00 2001<br>
From: Kieran Clancy <<a href="javascript:;" onclick="_e(event, 'cvml', 'clancy.kieran@gmail.com')">clancy.kieran@gmail.com</a>><br>
Date: Sat, 1 Mar 2014 00:42:28 +1030<br>
Subject: ACPI / EC: Clear stale EC events on Samsung systems<br>
<br>
commit ad332c8a45330d170bb38b95209de449b31cd1b4 upstream.<br>
<br>
A number of Samsung notebooks (530Uxx/535Uxx/540Uxx/550Pxx/900Xxx/etc)<br>
continue to log events during sleep (lid open/close, AC plug/unplug,<br>
battery level change), which accumulate in the EC until a buffer fills.<br>
After the buffer is full (tests suggest it holds 8 events), GPEs stop<br>
being triggered for new events. This state persists on wake or even on<br>
power cycle, and prevents new events from being registered until the EC<br>
is manually polled.<br>
<br>
This is the root cause of a number of bugs, including AC not being<br>
detected properly, lid close not triggering suspend, and low ambient<br>
light not triggering the keyboard backlight. The bug also seemed to be<br>
responsible for performance issues on at least one user's machine.<br>
<br>
Juan Manuel Cabo found the cause of bug and the workaround of polling<br>
the EC manually on wake.<br>
<br>
The loop which clears the stale events is based on an earlier patch by<br>
Lan Tianyu (see referenced attachment).<br>
<br>
This patch:<br>
- Adds a function acpi_ec_clear() which polls the EC for stale _Q<br>
events at most ACPI_EC_CLEAR_MAX (currently 100) times. A warning is<br>
logged if this limit is reached.<br>
- Adds a flag EC_FLAGS_CLEAR_ON_RESUME which is set to 1 if the DMI<br>
system vendor is Samsung. This check could be replaced by several<br>
more specific DMI vendor/product pairs, but it's likely that the bug<br>
affects more Samsung products than just the five series mentioned<br>
above. Further, it should not be harmful to run acpi_ec_clear() on<br>
systems without the bug; it will return immediately after finding no<br>
data waiting.<br>
- Runs acpi_ec_clear() on initialisation (boot), from acpi_ec_add()<br>
- Runs acpi_ec_clear() on wake, from acpi_ec_unblock_transactions()<br>
<br>
References: <a href="https://bugzilla.kernel.org/show_bug.cgi?id=44161" target="_blank">https://bugzilla.kernel.org/show_bug.cgi?id=44161</a><br>
References: <a href="https://bugzilla.kernel.org/show_bug.cgi?id=45461" target="_blank">https://bugzilla.kernel.org/show_bug.cgi?id=45461</a><br>
References: <a href="https://bugzilla.kernel.org/show_bug.cgi?id=57271" target="_blank">https://bugzilla.kernel.org/show_bug.cgi?id=57271</a><br>
References: <a href="https://bugzilla.kernel.org/attachment.cgi?id=126801
Suggested-by" target="_blank">https://bugzilla.kernel.org/attachment.cgi?id=126801<br>
Suggested-by</a>: Juan Manuel Cabo <<a href="javascript:;" onclick="_e(event, 'cvml', 'juanmanuel.cabo@gmail.com')">juanmanuel.cabo@gmail.com</a>><br>
Signed-off-by: Kieran Clancy <<a href="javascript:;" onclick="_e(event, 'cvml', 'clancy.kieran@gmail.com')">clancy.kieran@gmail.com</a>><br>
Reviewed-by: Lan Tianyu <<a href="javascript:;" onclick="_e(event, 'cvml', 'tianyu.lan@intel.com')">tianyu.lan@intel.com</a>><br>
Reviewed-by: Dennis Jansen <<a href="javascript:;" onclick="_e(event, 'cvml', 'dennis.jansen@web.de')">dennis.jansen@web.de</a>><br>
Tested-by: Kieran Clancy <<a href="javascript:;" onclick="_e(event, 'cvml', 'clancy.kieran@gmail.com')">clancy.kieran@gmail.com</a>><br>
Tested-by: Juan Manuel Cabo <<a href="javascript:;" onclick="_e(event, 'cvml', 'juanmanuel.cabo@gmail.com')">juanmanuel.cabo@gmail.com</a>><br>
Tested-by: Dennis Jansen <<a href="javascript:;" onclick="_e(event, 'cvml', 'dennis.jansen@web.de')">dennis.jansen@web.de</a>><br>
Tested-by: Maurizio D'Addona <<a href="javascript:;" onclick="_e(event, 'cvml', 'mauritiusdadd@gmail.com')">mauritiusdadd@gmail.com</a>><br>
Tested-by: San Zamoyski <<a href="javascript:;" onclick="_e(event, 'cvml', 'san@plusnet.pl')">san@plusnet.pl</a>><br>
Signed-off-by: Rafael J. Wysocki <<a href="javascript:;" onclick="_e(event, 'cvml', 'rafael.j.wysocki@intel.com')">rafael.j.wysocki@intel.com</a>><br>
[ kamal: backport to 3.8 (context) ]<br>
Signed-off-by: Kamal Mostafa <<a href="javascript:;" onclick="_e(event, 'cvml', 'kamal@canonical.com')">kamal@canonical.com</a>><br>
---<br>
drivers/acpi/ec.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++<br>
1 file changed, 64 insertions(+)<br>
<br>
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c<br>
index 97fcfb0..092f862 100644<br>
--- a/drivers/acpi/ec.c<br>
+++ b/drivers/acpi/ec.c<br>
@@ -70,6 +70,8 @@ enum ec_command {<br>
#define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */<br>
#define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */<br>
#define ACPI_EC_MSI_UDELAY 550 /* Wait 550us for MSI EC */<br>
+#define ACPI_EC_CLEAR_MAX 100 /* Maximum number of events to query<br>
+ * when trying to clear the EC */<br>
<br>
enum {<br>
EC_FLAGS_QUERY_PENDING, /* Query is pending */<br>
@@ -123,6 +125,7 @@ EXPORT_SYMBOL(first_ec);<br>
static int EC_FLAGS_MSI; /* Out-of-spec MSI controller */<br>
static int EC_FLAGS_VALIDATE_ECDT; /* ASUStec ECDTs need to be validated */<br>
static int EC_FLAGS_SKIP_DSDT_SCAN; /* Not all BIOS survive early DSDT scan */<br>
+static int EC_FLAGS_CLEAR_ON_RESUME; /* Needs acpi_ec_clear() on boot/resume */<br>
<br>
/* --------------------------------------------------------------------------<br>
Transaction Management<br>
@@ -468,6 +471,29 @@ acpi_handle ec_get_handle(void)<br>
<br>
EXPORT_SYMBOL(ec_get_handle);<br>
<br>
+static int acpi_ec_query_unlocked(struct acpi_ec *ec, u8 *data);<br>
+<br>
+/*<br>
+ * Clears stale _Q events that might have accumulated in the EC.<br>
+ * Run with locked ec mutex.<br>
+ */<br>
+static void acpi_ec_clear(struct acpi_ec *ec)<br>
+{<br>
+ int i, status;<br>
+ u8 value = 0;<br>
+<br>
+ for (i = 0; i < ACPI_EC_CLEAR_MAX; i++) {<br>
+ status = acpi_ec_query_unlocked(ec, &value);<br>
+ if (status || !value)<br>
+ break;<br>
+ }<br>
+<br>
+ if (unlikely(i == ACPI_EC_CLEAR_MAX))<br>
+ pr_warn("Warning: Maximum of %d stale EC events cleared\n", i);<br>
+ else<br>
+ pr_info("%d stale EC events cleared\n", i);<br>
+}<br>
+<br>
void acpi_ec_block_transactions(void)<br>
{<br>
struct acpi_ec *ec = first_ec;<br>
@@ -491,6 +517,10 @@ void acpi_ec_unblock_transactions(void)<br>
mutex_lock(&ec->mutex);<br>
/* Allow transactions to be carried out again */<br>
clear_bit(EC_FLAGS_BLOCKED, &ec->flags);<br>
+<br>
+ if (EC_FLAGS_CLEAR_ON_RESUME)<br>
+ acpi_ec_clear(ec);<br>
+<br>
mutex_unlock(&ec->mutex);<br>
}<br>
<br>
@@ -848,6 +878,13 @@ static int acpi_ec_add(struct acpi_device *device)<br>
<br>
/* EC is fully operational, allow queries */<br>
clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);<br>
+<br>
+ /* Clear stale _Q events if hardware might require that */<br>
+ if (EC_FLAGS_CLEAR_ON_RESUME) {<br>
+ mutex_lock(&ec->mutex);<br>
+ acpi_ec_clear(ec);<br>
+ mutex_unlock(&ec->mutex);<br>
+ }<br>
return ret;<br>
}<br>
<br>
@@ -949,6 +986,30 @@ static int ec_enlarge_storm_threshold(const struct dmi_system_id *id)<br>
return 0;<br>
}<br>
<br>
+/*<br>
+ * On some hardware it is necessary to clear events accumulated by the EC during<br>
+ * sleep. These ECs stop reporting GPEs until they are manually polled, if too<br>
+ * many events are accumulated. (e.g. Samsung Series 5/9 notebooks)<br>
+ *<br>
+ * <a href="https://bugzilla.kernel.org/show_bug.cgi?id=44161" target="_blank">https://bugzilla.kernel.org/show_bug.cgi?id=44161</a><br>
+ *<br>
+ * Ideally, the EC should also be instructed NOT to accumulate events during<br>
+ * sleep (which Windows seems to do somehow), but the interface to control this<br>
+ * behaviour is not known at this time.<br>
+ *<br>
+ * Models known to be affected are Samsung 530Uxx/535Uxx/540Uxx/550Pxx/900Xxx,<br>
+ * however it is very likely that other Samsung models are affected.<br>
+ *<br>
+ * On systems which don't accumulate _Q events during sleep, this extra check<br>
+ * should be harmless.<br>
+ */<br>
+static int ec_clear_on_resume(const struct dmi_system_id *id)<br>
+{<br>
+ pr_debug("Detected system needing EC poll on resume.\n");<br>
+ EC_FLAGS_CLEAR_ON_RESUME = 1;<br>
+ return 0;<br>
+}<br>
+<br>
static struct dmi_system_id __initdata ec_dmi_table[] = {<br>
{<br>
ec_skip_dsdt_scan, "Compal JFL92", {<br>
@@ -992,6 +1053,9 @@ static struct dmi_system_id __initdata ec_dmi_table[] = {<br>
ec_validate_ecdt, "ASUS hardware", {<br>
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTek Computer Inc."),<br>
DMI_MATCH(DMI_PRODUCT_NAME, "L4R"),}, NULL},<br>
+ {<br>
+ ec_clear_on_resume, "Samsung hardware", {<br>
+ DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD.")}, NULL},<br>
{},<br>
};<br>
<br>
--<br>
1.8.3.2<br>
<br>
</blockquote></div><br><br>-- <br><div dir="ltr">Dipl.-Jur. Dennis G. Jansen, LL.M. (Berkeley)<div>Tel. 0163 834 8558 | <a href="https://www.linkedin.com/in/dennisgjansen/en" target="_blank">LinkedIn</a><div><font color="#999999">Master of Laws, University of California, Berkeley, School of Law ("Boalt Hall")</font></div>
<div><font color="#999999">Certificate in Law and Technology, University of California, Berkeley</font><span style="color:rgb(153,153,153)">, School of Law ("Boalt Hall")</span></div><div><font color="#999999">Certificate in Transnational Legal Studies, Georgetown University Law Center</font></div>
<div><font color="#999999">Certificate in Internationalization of Law, Free University Berlin</font></div><div><font color="#999999">Diploma of Law, Free University Berlin</font></div></div></div><br>