diff options
author | Josh Boyer <jwboyer@redhat.com> | 2014-03-07 07:45:51 -0500 |
---|---|---|
committer | Josh Boyer <jwboyer@redhat.com> | 2014-03-07 07:45:54 -0500 |
commit | 9009e1772442ff2b5a2fea7a63d12214262fe42c (patch) | |
tree | cc8b0fae7ed945bb0bea6be0419a300e75c8d7fe | |
parent | 5a77287012c36ca39549f2f745d6c3a2e2879ffa (diff) | |
download | kernel-9009e1772442ff2b5a2fea7a63d12214262fe42c.tar.gz kernel-9009e1772442ff2b5a2fea7a63d12214262fe42c.tar.xz kernel-9009e1772442ff2b5a2fea7a63d12214262fe42c.zip |
Fix stale EC events on Samsung systems (rhbz 1003602)
-rw-r--r-- | ACPI-EC-Clear-stale-EC-events-on-Samsung-systems.patch | 175 | ||||
-rw-r--r-- | kernel.spec | 7 |
2 files changed, 182 insertions, 0 deletions
diff --git a/ACPI-EC-Clear-stale-EC-events-on-Samsung-systems.patch b/ACPI-EC-Clear-stale-EC-events-on-Samsung-systems.patch new file mode 100644 index 000000000..de1367bfa --- /dev/null +++ b/ACPI-EC-Clear-stale-EC-events-on-Samsung-systems.patch @@ -0,0 +1,175 @@ +Bugzilla: 1003602 +Upstream-status: Queued for 3.15 https://git.kernel.org/cgit/linux/kernel/git/rafael/linux-pm.git/commit/?id=27095111cbafd3212c7e9a4a8cef1099b7520ca8 + +From 27095111cbafd3212c7e9a4a8cef1099b7520ca8 Mon Sep 17 00:00:00 2001 +From: Kieran Clancy <clancy.kieran@gmail.com> +Date: Fri, 28 Feb 2014 14:12:28 +0000 +Subject: ACPI / EC: Clear stale EC events on Samsung systems + +A number of Samsung notebooks (530Uxx/535Uxx/540Uxx/550Pxx/900Xxx/etc) +continue to log events during sleep (lid open/close, AC plug/unplug, +battery level change), which accumulate in the EC until a buffer fills. +After the buffer is full (tests suggest it holds 8 events), GPEs stop +being triggered for new events. This state persists on wake or even on +power cycle, and prevents new events from being registered until the EC +is manually polled. + +This is the root cause of a number of bugs, including AC not being +detected properly, lid close not triggering suspend, and low ambient +light not triggering the keyboard backlight. The bug also seemed to be +responsible for performance issues on at least one user's machine. + +Juan Manuel Cabo found the cause of bug and the workaround of polling +the EC manually on wake. + +The loop which clears the stale events is based on an earlier patch by +Lan Tianyu (see referenced attachment). + +This patch: + - Adds a function acpi_ec_clear() which polls the EC for stale _Q + events at most ACPI_EC_CLEAR_MAX (currently 100) times. A warning is + logged if this limit is reached. + - Adds a flag EC_FLAGS_CLEAR_ON_RESUME which is set to 1 if the DMI + system vendor is Samsung. This check could be replaced by several + more specific DMI vendor/product pairs, but it's likely that the bug + affects more Samsung products than just the five series mentioned + above. Further, it should not be harmful to run acpi_ec_clear() on + systems without the bug; it will return immediately after finding no + data waiting. + - Runs acpi_ec_clear() on initialisation (boot), from acpi_ec_add() + - Runs acpi_ec_clear() on wake, from acpi_ec_unblock_transactions() + +References: https://bugzilla.kernel.org/show_bug.cgi?id=44161 +References: https://bugzilla.kernel.org/show_bug.cgi?id=45461 +References: https://bugzilla.kernel.org/show_bug.cgi?id=57271 +References: https://bugzilla.kernel.org/attachment.cgi?id=126801 +Suggested-by: Juan Manuel Cabo <juanmanuel.cabo@gmail.com> +Signed-off-by: Kieran Clancy <clancy.kieran@gmail.com> +Reviewed-by: Lan Tianyu <tianyu.lan@intel.com> +Reviewed-by: Dennis Jansen <dennis.jansen@web.de> +Tested-by: Kieran Clancy <clancy.kieran@gmail.com> +Tested-by: Juan Manuel Cabo <juanmanuel.cabo@gmail.com> +Tested-by: Dennis Jansen <dennis.jansen@web.de> +Tested-by: Maurizio D'Addona <mauritiusdadd@gmail.com> +Tested-by: San Zamoyski <san@plusnet.pl> +Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> +--- +diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c +index 959d41a..d7d32c2 100644 +--- a/drivers/acpi/ec.c ++++ b/drivers/acpi/ec.c +@@ -67,6 +67,8 @@ enum ec_command { + #define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */ + #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ + #define ACPI_EC_MSI_UDELAY 550 /* Wait 550us for MSI EC */ ++#define ACPI_EC_CLEAR_MAX 100 /* Maximum number of events to query ++ * when trying to clear the EC */ + + enum { + EC_FLAGS_QUERY_PENDING, /* Query is pending */ +@@ -116,6 +118,7 @@ EXPORT_SYMBOL(first_ec); + 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 */ + + /* -------------------------------------------------------------------------- + Transaction Management +@@ -440,6 +443,29 @@ acpi_handle ec_get_handle(void) + + EXPORT_SYMBOL(ec_get_handle); + ++static int acpi_ec_query_unlocked(struct acpi_ec *ec, u8 *data); ++ ++/* ++ * Clears stale _Q events that might have accumulated in the EC. ++ * Run with locked ec mutex. ++ */ ++static void acpi_ec_clear(struct acpi_ec *ec) ++{ ++ int i, status; ++ u8 value = 0; ++ ++ for (i = 0; i < ACPI_EC_CLEAR_MAX; i++) { ++ status = acpi_ec_query_unlocked(ec, &value); ++ if (status || !value) ++ break; ++ } ++ ++ if (unlikely(i == ACPI_EC_CLEAR_MAX)) ++ pr_warn("Warning: Maximum of %d stale EC events cleared\n", i); ++ else ++ pr_info("%d stale EC events cleared\n", i); ++} ++ + void acpi_ec_block_transactions(void) + { + struct acpi_ec *ec = first_ec; +@@ -463,6 +489,10 @@ void acpi_ec_unblock_transactions(void) + mutex_lock(&ec->mutex); + /* Allow transactions to be carried out again */ + clear_bit(EC_FLAGS_BLOCKED, &ec->flags); ++ ++ if (EC_FLAGS_CLEAR_ON_RESUME) ++ acpi_ec_clear(ec); ++ + mutex_unlock(&ec->mutex); + } + +@@ -821,6 +851,13 @@ static int acpi_ec_add(struct acpi_device *device) + + /* EC is fully operational, allow queries */ + clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); ++ ++ /* Clear stale _Q events if hardware might require that */ ++ if (EC_FLAGS_CLEAR_ON_RESUME) { ++ mutex_lock(&ec->mutex); ++ acpi_ec_clear(ec); ++ mutex_unlock(&ec->mutex); ++ } + return ret; + } + +@@ -922,6 +959,30 @@ static int ec_enlarge_storm_threshold(const struct dmi_system_id *id) + 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 ++ * many events are accumulated. (e.g. Samsung Series 5/9 notebooks) ++ * ++ * https://bugzilla.kernel.org/show_bug.cgi?id=44161 ++ * ++ * Ideally, the EC should also be instructed NOT to accumulate events during ++ * sleep (which Windows seems to do somehow), but the interface to control this ++ * behaviour is not known at this time. ++ * ++ * Models known to be affected are Samsung 530Uxx/535Uxx/540Uxx/550Pxx/900Xxx, ++ * however it is very likely that other Samsung models are affected. ++ * ++ * On systems which don't accumulate _Q events during sleep, this extra check ++ * should be harmless. ++ */ ++static int ec_clear_on_resume(const struct dmi_system_id *id) ++{ ++ pr_debug("Detected system needing EC poll on resume.\n"); ++ EC_FLAGS_CLEAR_ON_RESUME = 1; ++ return 0; ++} ++ + static struct dmi_system_id ec_dmi_table[] __initdata = { + { + ec_skip_dsdt_scan, "Compal JFL92", { +@@ -965,6 +1026,9 @@ static struct dmi_system_id ec_dmi_table[] __initdata = { + ec_validate_ecdt, "ASUS hardware", { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTek Computer Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "L4R"),}, NULL}, ++ { ++ ec_clear_on_resume, "Samsung hardware", { ++ DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD.")}, NULL}, + {}, + }; + +-- +cgit v0.9.2 diff --git a/kernel.spec b/kernel.spec index 86102a6c8..d2443387a 100644 --- a/kernel.spec +++ b/kernel.spec @@ -652,6 +652,9 @@ Patch25035: Bluetooth-allocate-static-minor-for-vhci.patch #Fixes module loading on ppc64le Patch25036: ppc64le_module_fix.patch +#rhbz 1003602 +Patch25037: ACPI-EC-Clear-stale-EC-events-on-Samsung-systems.patch + # END OF PATCH DEFINITIONS %endif @@ -1311,6 +1314,9 @@ ApplyPatch Bluetooth-allocate-static-minor-for-vhci.patch # Fixes module loading on ppc64le ApplyPatch ppc64le_module_fix.patch +#rhbz 1003602 +ApplyPatch ACPI-EC-Clear-stale-EC-events-on-Samsung-systems.patch + # END OF PATCH APPLICATIONS %endif @@ -2091,6 +2097,7 @@ fi # || || %changelog * Thu Mar 06 2014 Josh Boyer <jwboyer@fedoraproject.org> +- Fix stale EC events on Samsung systems (rhbz 1003602) - Add ppc64le support from Brent Baude (rhbz 1073102) - Fix depmod error message from hci_vhci module (rhbz 1051748) - Fix bogus WARN in iwlwifi (rhbz 1071998) |