linux/drivers/acpi/ec.c

2390 lines
61 KiB

treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 157 Based on 3 normalized pattern(s): this program is free software you can redistribute it and or modify it under the terms of the gnu general public license as published by the free software foundation either version 2 of the license or at your option any later version this program is distributed in the hope that it will be useful but without any warranty without even the implied warranty of merchantability or fitness for a particular purpose see the gnu general public license for more details this program is free software you can redistribute it and or modify it under the terms of the gnu general public license as published by the free software foundation either version 2 of the license or at your option any later version [author] [kishon] [vijay] [abraham] [i] [kishon]@[ti] [com] this program is distributed in the hope that it will be useful but without any warranty without even the implied warranty of merchantability or fitness for a particular purpose see the gnu general public license for more details this program is free software you can redistribute it and or modify it under the terms of the gnu general public license as published by the free software foundation either version 2 of the license or at your option any later version [author] [graeme] [gregory] [gg]@[slimlogic] [co] [uk] [author] [kishon] [vijay] [abraham] [i] [kishon]@[ti] [com] [based] [on] [twl6030]_[usb] [c] [author] [hema] [hk] [hemahk]@[ti] [com] this program is distributed in the hope that it will be useful but without any warranty without even the implied warranty of merchantability or fitness for a particular purpose see the gnu general public license for more details extracted by the scancode license scanner the SPDX license identifier GPL-2.0-or-later has been chosen to replace the boilerplate/reference in 1105 file(s). Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Allison Randal <allison@lohutok.net> Reviewed-by: Richard Fontana <rfontana@redhat.com> Reviewed-by: Kate Stewart <kstewart@linuxfoundation.org> Cc: linux-spdx@vger.kernel.org Link: https://lkml.kernel.org/r/20190527070033.202006027@linutronix.de Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-05-27 08:55:06 +02:00
include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h percpu.h is included by sched.h and module.h and thus ends up being included when building most .c files. percpu.h includes slab.h which in turn includes gfp.h making everything defined by the two files universally available and complicating inclusion dependencies. percpu.h -> slab.h dependency is about to be removed. Prepare for this change by updating users of gfp and slab facilities include those headers directly instead of assuming availability. As this conversion needs to touch large number of source files, the following script is used as the basis of conversion. http://userweb.kernel.org/~tj/misc/slabh-sweep.py The script does the followings. * Scan files for gfp and slab usages and update includes such that only the necessary includes are there. ie. if only gfp is used, gfp.h, if slab is used, slab.h. * When the script inserts a new include, it looks at the include blocks and try to put the new include such that its order conforms to its surrounding. It's put in the include block which contains core kernel includes, in the same order that the rest are ordered - alphabetical, Christmas tree, rev-Xmas-tree or at the end if there doesn't seem to be any matching order. * If the script can't find a place to put a new include (mostly because the file doesn't have fitting include block), it prints out an error message indicating which .h file needs to be added to the file. The conversion was done in the following steps. 1. The initial automatic conversion of all .c files updated slightly over 4000 files, deleting around 700 includes and adding ~480 gfp.h and ~3000 slab.h inclusions. The script emitted errors for ~400 files. 2. Each error was manually checked. Some didn't need the inclusion, some needed manual addition while adding it to implementation .h or embedding .c file was more appropriate for others. This step added inclusions to around 150 files. 3. The script was run again and the output was compared to the edits from #2 to make sure no file was left behind. 4. Several build tests were done and a couple of problems were fixed. e.g. lib/decompress_*.c used malloc/free() wrappers around slab APIs requiring slab.h to be added manually. 5. The script was run on all .h files but without automatically editing them as sprinkling gfp.h and slab.h inclusions around .h files could easily lead to inclusion dependency hell. Most gfp.h inclusion directives were ignored as stuff from gfp.h was usually wildly available and often used in preprocessor macros. Each slab.h inclusion directive was examined and added manually as necessary. 6. percpu.h was updated not to include slab.h. 7. Build test were done on the following configurations and failures were fixed. CONFIG_GCOV_KERNEL was turned off for all tests (as my distributed build env didn't work with gcov compiles) and a few more options had to be turned off depending on archs to make things build (like ipr on powerpc/64 which failed due to missing writeq). * x86 and x86_64 UP and SMP allmodconfig and a custom test config. * powerpc and powerpc64 SMP allmodconfig * sparc and sparc64 SMP allmodconfig * ia64 SMP allmodconfig * s390 SMP allmodconfig * alpha SMP allmodconfig * um on x86_64 SMP allmodconfig 8. percpu.h modifications were reverted so that it could be applied as a separate patch and serve as bisection point. Given the fact that I had only a couple of failures from tests on step 6, I'm fairly confident about the coverage of this conversion patch. If there is a breakage, it's likely to be something in one of the arch headers which should be easily discoverable easily on most builds of the specific arch. Signed-off-by: Tejun Heo <tj@kernel.org> Guess-its-ok-by: Christoph Lameter <cl@linux-foundation.org> Cc: Ingo Molnar <mingo@redhat.com> Cc: Lee Schermerhorn <Lee.Schermerhorn@hp.com>
2010-03-24 17:04:11 +09:00
ACPI: Clean up inclusions of ACPI header files Replace direct inclusions of <acpi/acpi.h>, <acpi/acpi_bus.h> and <acpi/acpi_drivers.h>, which are incorrect, with <linux/acpi.h> inclusions and remove some inclusions of those files that aren't necessary. First of all, <acpi/acpi.h>, <acpi/acpi_bus.h> and <acpi/acpi_drivers.h> should not be included directly from any files that are built for CONFIG_ACPI unset, because that generally leads to build warnings about undefined symbols in !CONFIG_ACPI builds. For CONFIG_ACPI set, <linux/acpi.h> includes those files and for CONFIG_ACPI unset it provides stub ACPI symbols to be used in that case. Second, there are ordering dependencies between those files that always have to be met. Namely, it is required that <acpi/acpi_bus.h> be included prior to <acpi/acpi_drivers.h> so that the acpi_pci_root declarations the latter depends on are always there. And <acpi/acpi.h> which provides basic ACPICA type declarations should always be included prior to any other ACPI headers in CONFIG_ACPI builds. That also is taken care of including <linux/acpi.h> as appropriate. Signed-off-by: Lv Zheng <lv.zheng@intel.com> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: Matthew Garrett <mjg59@srcf.ucam.org> Cc: Tony Luck <tony.luck@intel.com> Cc: "H. Peter Anvin" <hpa@zytor.com> Acked-by: Bjorn Helgaas <bhelgaas@google.com> (drivers/pci stuff) Acked-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> (Xen stuff) Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2013-12-03 08:49:16 +08:00
ACPI: Clean up inclusions of ACPI header files Replace direct inclusions of <acpi/acpi.h>, <acpi/acpi_bus.h> and <acpi/acpi_drivers.h>, which are incorrect, with <linux/acpi.h> inclusions and remove some inclusions of those files that aren't necessary. First of all, <acpi/acpi.h>, <acpi/acpi_bus.h> and <acpi/acpi_drivers.h> should not be included directly from any files that are built for CONFIG_ACPI unset, because that generally leads to build warnings about undefined symbols in !CONFIG_ACPI builds. For CONFIG_ACPI set, <linux/acpi.h> includes those files and for CONFIG_ACPI unset it provides stub ACPI symbols to be used in that case. Second, there are ordering dependencies between those files that always have to be met. Namely, it is required that <acpi/acpi_bus.h> be included prior to <acpi/acpi_drivers.h> so that the acpi_pci_root declarations the latter depends on are always there. And <acpi/acpi.h> which provides basic ACPICA type declarations should always be included prior to any other ACPI headers in CONFIG_ACPI builds. That also is taken care of including <linux/acpi.h> as appropriate. Signed-off-by: Lv Zheng <lv.zheng@intel.com> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: Matthew Garrett <mjg59@srcf.ucam.org> Cc: Tony Luck <tony.luck@intel.com> Cc: "H. Peter Anvin" <hpa@zytor.com> Acked-by: Bjorn Helgaas <bhelgaas@google.com> (drivers/pci stuff) Acked-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> (Xen stuff) Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2013-12-03 08:49:16 +08:00
ACPI / EC: Add event clearing variation support. We've been suffering from the uncertainty of the SCI_EVT clearing timing. This patch implements 3 of 4 possible modes to handle SCI_EVT clearing variations. The old behavior is kept in this patch. Status: QR_EC is re-checked as early as possible after checking previous SCI_EVT. This always leads to 2 QR_EC transactions per SCI_EVT indication and the target may implement event queue which returns 0x00 indicating "no outstanding event". This is proven to be a conflict against Windows behavior, but is still kept in this patch to make the EC driver robust to the possible regressions that may occur on Samsung platforms. Query: QR_EC is re-checked after the target has handled the QR_EC query request command pushed by the host. Event: QR_EC is re-checked after the target has noticed the query event response data pulled by the host. This timing is not determined by any IRQs, so we may need to use a guard period in this mode, which may explain the existence of the ec_guard() code used by the old EC driver where the re-check timing is implemented in the similar way as this mode. Method: QR_EC is re-checked as late as possible after completing the _Qxx evaluation. The target may implement SCI_EVT like a level triggered interrupt. It is proven on kernel bugzilla 94411 that, Windows will have all _Qxx evaluations parallelized. Thus unless required by further evidences, we needn't implement this mode as it is a conflict of the _Qxx parallelism requirement. Note that, according to the reports, there are platforms that cannot be handled using the "Status" mode without enabling the EC_FLAGS_QUERY_HANDSHAKE quirk. But they can be handled with the other modes according to the tests (kernel bugzilla 97381). The following log entry can be used to confirm the differences of the 3 modes as it should appear at the different positions for the 3 modes: Command(QR_EC) unblocked Status: appearing after EC_SC(W) = 0x84 Query: appearing after EC_DATA(R) = 0xXX where XX is the event number used to determine _QXX Event: appearing after first EC_SC(R) = 0xX0 SCI_EVT=x BURST=0 CMD=0 IBF=0 OBF=0 that is next to the following log entry: Command(QR_EC) completed by hardware 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=98111 Reported-and-tested-by: Gabriele Mazzotta <gabriele.mzt@gmail.com> Reported-and-tested-by: Tigran Gabrielyan <tigrangab@gmail.com> Reported-and-tested-by: Adrien D <ghbdtn@openmailbox.org> Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-06-11 13:21:38 +08:00
ACPI / EC: Fix and clean up register access guarding logics. In the polling mode, EC driver shouldn't access the EC registers too frequently. Though this statement is concluded from the non-root caused bugs (see links below), we've maintained the register access guarding logics in the current EC driver. The guarding logics can be found here and there, makes it hard to root cause real timing issues. This patch collects the guarding logics into one single function so that all hidden logics related to this can be seen clearly. The current guarding related code also has several issues: 1. Per-transaction timestamp prevents inter-transaction guarding from being implemented in the same place. We have an inter-transaction udelay() in acpi_ec_transaction_unblocked(), this logic can be merged into ec_poll() if we can use per-device timestamp. This patch completes such merge to form a new ec_guard() function and collects all guarding related hidden logics in it. One hidden logic is: there is no inter-transaction guarding performed for non MSI quirk (wait polling mode), this patch skips inter-transaction guarding before wait_event_timeout() for the wait polling mode to reveal the hidden logic. The other hidden logic is: there is msleep() inter-transaction guarding performed when the GPE storming is observed. As after merging this commit: Commit: e1d4d90fc0313d3d58cbd7912c90f8ef24df45ff Subject: ACPI / EC: Refine command storm prevention support EC_FLAGS_COMMAND_STORM is ensured to be cleared after invoking acpi_ec_transaction_unlocked(), the msleep() guard logic will never happen now. Since no one complains such change, this logic is likely added during the old times where the EC race issues are not fixed and the bugs are false root-caused to the timing issue. This patch simply removes the out-dated logic. We can restore it by stop skipping inter-transaction guarding for wait polling mode. Two different delay values are defined for msleep() and udelay() while they are merged in this patch to 550us. 2. time_after() causes additional delay in the polling mode (can only be observed in noirq suspend/resume processes where polling mode is always used) before advance_transaction() is invoked ("wait polling" log is added before wait_event_timeout()). We can see 2 wait_event_timeout() invocations. This is because time_after() ensures a ">" validation while we only need a ">=" validation here: [ 86.739909] ACPI: Waking up from system sleep state S3 [ 86.742857] ACPI : EC: 2: Increase command [ 86.742859] ACPI : EC: ***** Command(RD_EC) started ***** [ 86.742861] ACPI : EC: ===== TASK (0) ===== [ 86.742871] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 86.742873] ACPI : EC: EC_SC(W) = 0x80 [ 86.742876] ACPI : EC: ***** Event started ***** [ 86.742880] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.743972] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.747966] ACPI : EC: ===== TASK (0) ===== [ 86.747977] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 86.747978] ACPI : EC: EC_DATA(W) = 0x06 [ 86.747981] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.751971] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.755969] ACPI : EC: ===== TASK (0) ===== [ 86.755991] ACPI : EC: EC_SC(R) = 0x21 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=1 [ 86.755993] ACPI : EC: EC_DATA(R) = 0x03 [ 86.755994] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.755995] ACPI : EC: ***** Command(RD_EC) stopped ***** [ 86.755996] ACPI : EC: 1: Decrease command This patch corrects this by using time_before() instead in ec_guard(): [ 54.283146] ACPI: Waking up from system sleep state S3 [ 54.285414] ACPI : EC: 2: Increase command [ 54.285415] ACPI : EC: ***** Command(RD_EC) started ***** [ 54.285416] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.285417] ACPI : EC: ===== TASK (0) ===== [ 54.285424] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 54.285425] ACPI : EC: EC_SC(W) = 0x80 [ 54.285427] ACPI : EC: ***** Event started ***** [ 54.285429] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.287209] ACPI : EC: ===== TASK (0) ===== [ 54.287218] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 54.287219] ACPI : EC: EC_DATA(W) = 0x06 [ 54.287222] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.291190] ACPI : EC: ===== TASK (0) ===== [ 54.291210] ACPI : EC: EC_SC(R) = 0x21 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=1 [ 54.291213] ACPI : EC: EC_DATA(R) = 0x03 [ 54.291214] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.291215] ACPI : EC: ***** Command(RD_EC) stopped ***** [ 54.291216] ACPI : EC: 1: Decrease command After cleaning up all guarding logics, we have one single function ec_guard() collecting all old, non-root-caused, hidden logics. Then we can easily tune the logics in one place to respond to the bug reports. Except the time_before() change, all other changes do not change the behavior of the EC driver. Link: https://bugzilla.kernel.org/show_bug.cgi?id=12011 Link: https://bugzilla.kernel.org/show_bug.cgi?id=20242 Link: https://bugzilla.kernel.org/show_bug.cgi?id=77431 Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-05-15 14:16:42 +08:00
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> Cc: All applicable <stable@vger.kernel.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2014-03-01 00:42:28 +10:30
ACPI: EC: Fix ECDT probe ordering issues ACPI-2.0 says that the EC OpRegion handler must be available immediately (like the standard default OpRegion handlers): Quoting from the ACPI spec version 6.3: "6.5.4 _REG (Region) ... 2. OSPM must make Embedded Controller operation regions, accessed via the Embedded Controllers described in ECDT, available before executing any control method. These operation regions may become inaccessible after OSPM runs _REG(EmbeddedControl, 0)." So acpi_bus_init() calls acpi_ec_ecdt_probe(), which calls acpi_install_address_space_handler() to install the EC's OpRegion handler, early on. This not only installs the OpRegion handler, but also calls the EC's _REG method. The _REG method call is a problem because it may rely on initialization done by the _INI methods of one of the PCI / _SB root devs, see for example: https://bugzilla.kernel.org/show_bug.cgi?id=214899 . Generally speaking _REG methods are executed when the ACPI-device they are part of has a driver bound to it. Where as _INI methods must be executed at table load time (according to the spec). The problem here is that the early acpi_install_address_space_handler() call causes the _REG handler to run too early. To allow fixing this the ACPICA code now allows to split the OpRegion handler installation and the executing of _REG into 2 separate steps. This commit uses this ACPICA functionality to fix the EC probe ordering by delaying the executing of _REG for ECDT described ECs till the matching EC device in the DSDT gets parsed and acpi_ec_add() for it gets called. This moves the calling of _REG for the EC on devices with an ECDT to the same point in time where it is called on devices without an ECDT table. BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=214899 Reported-and-tested-by: Johannes Penßel <johannespenssel@posteo.net> Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2022-12-08 15:23:35 +01:00
ACPI / EC: Add asynchronous command byte write support Move the first command byte write into advance_transaction() so that all EC register accesses that can affect the command processing state machine can happen in this asynchronous state machine advancement function. The advance_transaction() function then can be a complete implementation of an asyncrhonous transaction for a single command so that: 1. The first command byte can be written in the interrupt context; 2. The command completion waiter can also be used to wait the first command byte's timeout; 3. In BURST mode, the follow-up command bytes can be written in the interrupt context directly, so that it doesn't need to return to the task context. Returning to the task context reduces the throughput of the BURST mode and in the worst cases where the system workload is very high, this leads to the hardware driven automatic BURST mode exit. In order not to increase memory consumption, convert 'done' into 'flags' to contain multiple indications: 1. ACPI_EC_COMMAND_COMPLETE: converting from original 'done' condition, indicating the completion of the command transaction. 2. ACPI_EC_COMMAND_POLL: indicating the availability of writing the first command byte. A new command can utilize this flag to compete for the right of accessing the underlying hardware. There is a follow-up bug fix that has utilized this new flag. The 2 flags are important because it also reflects a key concept of IO programs' design used in the system softwares. Normally an IO program running in the kernel should first be implemented in the asynchronous way. And the 2 flags are the most common way to implement its synchronous operations on top of the asynchronous operations: 1. POLL: This flag can be used to block until the asynchronous operations can happen. 2. COMPLETE: This flag can be used to block until the asynchronous operations have completed. By constructing code cleanly in this way, many difficult problems can be solved smoothly. Link: https://bugzilla.kernel.org/show_bug.cgi?id=70891 Link: https://bugzilla.kernel.org/show_bug.cgi?id=63931 Link: https://bugzilla.kernel.org/show_bug.cgi?id=59911 Reported-and-tested-by: Gareth Williams <gareth@garethwilliams.me.uk> Reported-and-tested-by: Hans de Goede <jwrdegoede@fedoraproject.org> Reported-by: Barton Xu <tank.xuhan@gmail.com> Tested-by: Steffen Weber <steffen.weber@gmail.com> Tested-by: Arthur Chen <axchen@nvidia.com> Signed-off-by: Lv Zheng <lv.zheng@intel.com> Cc: All applicable <stable@vger.kernel.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2014-06-15 08:41:35 +08:00
ACPI / EC: Add module params for polling modes. We have 2 polling modes in the EC driver: 1. busy polling: originally used for the MSI quirks. udelay() is used to perform register access guarding. 2. wait polling: normal code path uses wait_event_timeout() and it can be woken up as soon as the transaction is completed in the interrupt mode. It also contains the register acces guarding logic in case the interrupt doesn't arrive and the EC driver is about to advance the transaction in task context (the polling mode). The wait polling is useful for interrupt mode to allow other tasks to use the CPU during the wait. But for the polling mode, the busy polling takes less time than the wait polling, because if no interrupt arrives, the wait polling has to wait the minimal HZ interval. We have a new use case for using the busy polling mode. Some GPIO drivers initialize PIN configuration which cause a GPIO multiplexed EC GPE to be disabled out of the GPE register's control. Busy polling mode is useful here as it takes less time than the wait polling. But the guarding logic prevents it from responding even faster. We should spinning around the EC status rather than spinning around the nop execution lasted a determined period. This patch introduces 2 module params for the polling mode switch and the guard time, so that users can use the busy polling mode without the guarding in case the guarding is not necessary. This is an example to use the 2 module params for this purpose: acpi.ec_busy_polling acpi.ec_polling_guard=0 We've tested the patch on a test platform. The platform suffers from such kind of the GPIO PIN issue. The GPIO driver resets all PIN configuration and after that, EC interrupt cannot arrive because of the multiplexing. Then the platform suffers from a long delay carried out by the wait_event_timeout() as all further EC transactions will run in the polling mode. We switched the EC driver to use the busy polling mechanism instead of the wait timeout polling mechanism and the delay is still high: [ 44.283005] calling PNP0C0B:00+ @ 1305, parent: platform [ 44.417548] call PNP0C0B:00+ returned 0 after 131323 usecs And this patch can significantly reduce the delay: [ 44.502625] calling PNP0C0B:00+ @ 1308, parent: platform [ 44.503760] call PNP0C0B:00+ returned 0 after 1103 usecs Tested-by: Chen Yu <yu.c.chen@intel.com> Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-05-15 14:16:48 +08:00
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=98111 Reported-and-tested-by: Gabriele Mazzotta <gabriele.mzt@gmail.com> Reported-and-tested-by: Tigran Gabrielyan <tigrangab@gmail.com> Reported-and-tested-by: Adrien D <ghbdtn@openmailbox.org> Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-06-11 13:21:45 +08:00
ACPI / EC: Add event clearing variation support. We've been suffering from the uncertainty of the SCI_EVT clearing timing. This patch implements 3 of 4 possible modes to handle SCI_EVT clearing variations. The old behavior is kept in this patch. Status: QR_EC is re-checked as early as possible after checking previous SCI_EVT. This always leads to 2 QR_EC transactions per SCI_EVT indication and the target may implement event queue which returns 0x00 indicating "no outstanding event". This is proven to be a conflict against Windows behavior, but is still kept in this patch to make the EC driver robust to the possible regressions that may occur on Samsung platforms. Query: QR_EC is re-checked after the target has handled the QR_EC query request command pushed by the host. Event: QR_EC is re-checked after the target has noticed the query event response data pulled by the host. This timing is not determined by any IRQs, so we may need to use a guard period in this mode, which may explain the existence of the ec_guard() code used by the old EC driver where the re-check timing is implemented in the similar way as this mode. Method: QR_EC is re-checked as late as possible after completing the _Qxx evaluation. The target may implement SCI_EVT like a level triggered interrupt. It is proven on kernel bugzilla 94411 that, Windows will have all _Qxx evaluations parallelized. Thus unless required by further evidences, we needn't implement this mode as it is a conflict of the _Qxx parallelism requirement. Note that, according to the reports, there are platforms that cannot be handled using the "Status" mode without enabling the EC_FLAGS_QUERY_HANDSHAKE quirk. But they can be handled with the other modes according to the tests (kernel bugzilla 97381). The following log entry can be used to confirm the differences of the 3 modes as it should appear at the different positions for the 3 modes: Command(QR_EC) unblocked Status: appearing after EC_SC(W) = 0x84 Query: appearing after EC_DATA(R) = 0xXX where XX is the event number used to determine _QXX Event: appearing after first EC_SC(R) = 0xX0 SCI_EVT=x BURST=0 CMD=0 IBF=0 OBF=0 that is next to the following log entry: Command(QR_EC) completed by hardware 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=98111 Reported-and-tested-by: Gabriele Mazzotta <gabriele.mzt@gmail.com> Reported-and-tested-by: Tigran Gabrielyan <tigrangab@gmail.com> Reported-and-tested-by: Adrien D <ghbdtn@openmailbox.org> Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-06-11 13:21:38 +08:00
ACPI / EC: Add PM operations to improve event handling for suspend process In the original EC driver, though the event handling is not explicitly stopped, the EC driver is actually not able to handle events during the noirq stage as the EC driver is not prepared to handle the EC events in the polling mode. So if there is no advance_transaction() triggered, the EC driver couldn't notice the EC events. However, do we actually need to handle EC events during suspend/resume stage? EC events are mostly useless for the suspend/resume period (key strokes and battery/thermal updates, etc.,), and the useful ones (lid close, power/sleep button press) should have already been delivered to the OSPM to trigger the power saving operations. Thus this patch implements acpi_ec_disable_event() to be a reverse call of acpi_ec_enable_event(), with which, the EC driver is able to stop handling the EC events in a position before entering the noirq stage. Since there are actually 2 choices for us: 1. implement event handling in polling mode; 2. stop event handling before entering noirq stage. And this patch only implements the second choice using .suspend() callback. Thus this is experimental (first choice is better? or different hook position is better?). This patch finally keeps the old behavior by default and prepares a boot parameter to enable this feature. The differences of the event handling availability between the old behavior (this patch is not applied) and the new behavior (this patch is applied) are as follows: !FreezeEvents FreezeEvents before suspend Y Y suspend before EC Y Y suspend after EC Y N suspend_late Y N suspend_noirq Y (actually N) N resume_noirq Y (actually N) N resume_late Y (actually N) N resume before EC Y (actually N) N resume after EC Y Y after resume Y Y Where "actually N" means if there is no EC transactions, the EC driver is actually not able to notice the pending events. We can see that FreezeEvents is the only approach now can actually flush the EC event handling with both query commands and _Qxx evaluations flushed, other modes can only flush the EC event handling with only query commands flushed, _Qxx evaluations occurred after stopping the EC driver may end up failure due to the failure of the EC transaction carried out in the _Qxx control methods. We also can see that this feature should be able to trigger some platform notifications later than resuming other drivers. Signed-off-by: Lv Zheng <lv.zheng@intel.com> Tested-by: Todd E Brandt <todd.e.brandt@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2016-08-03 16:01:43 +08:00
ACPI / EC: Add asynchronous command byte write support Move the first command byte write into advance_transaction() so that all EC register accesses that can affect the command processing state machine can happen in this asynchronous state machine advancement function. The advance_transaction() function then can be a complete implementation of an asyncrhonous transaction for a single command so that: 1. The first command byte can be written in the interrupt context; 2. The command completion waiter can also be used to wait the first command byte's timeout; 3. In BURST mode, the follow-up command bytes can be written in the interrupt context directly, so that it doesn't need to return to the task context. Returning to the task context reduces the throughput of the BURST mode and in the worst cases where the system workload is very high, this leads to the hardware driven automatic BURST mode exit. In order not to increase memory consumption, convert 'done' into 'flags' to contain multiple indications: 1. ACPI_EC_COMMAND_COMPLETE: converting from original 'done' condition, indicating the completion of the command transaction. 2. ACPI_EC_COMMAND_POLL: indicating the availability of writing the first command byte. A new command can utilize this flag to compete for the right of accessing the underlying hardware. There is a follow-up bug fix that has utilized this new flag. The 2 flags are important because it also reflects a key concept of IO programs' design used in the system softwares. Normally an IO program running in the kernel should first be implemented in the asynchronous way. And the 2 flags are the most common way to implement its synchronous operations on top of the asynchronous operations: 1. POLL: This flag can be used to block until the asynchronous operations can happen. 2. COMPLETE: This flag can be used to block until the asynchronous operations have completed. By constructing code cleanly in this way, many difficult problems can be solved smoothly. Link: https://bugzilla.kernel.org/show_bug.cgi?id=70891 Link: https://bugzilla.kernel.org/show_bug.cgi?id=63931 Link: https://bugzilla.kernel.org/show_bug.cgi?id=59911 Reported-and-tested-by: Gareth Williams <gareth@garethwilliams.me.uk> Reported-and-tested-by: Hans de Goede <jwrdegoede@fedoraproject.org> Reported-by: Barton Xu <tank.xuhan@gmail.com> Tested-by: Steffen Weber <steffen.weber@gmail.com> Tested-by: Arthur Chen <axchen@nvidia.com> Signed-off-by: Lv Zheng <lv.zheng@intel.com> Cc: All applicable <stable@vger.kernel.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2014-06-15 08:41:35 +08:00
ACPI: EC: Rework flushing of EC work while suspended to idle The flushing of pending work in the EC driver uses drain_workqueue() to flush the event handling work that can requeue itself via advance_transaction(), but this is problematic, because that work may also be requeued from the query workqueue. Namely, if an EC transaction is carried out during the execution of a query handler, it involves calling advance_transaction() which may queue up the event handling work again. This causes the kernel to complain about attempts to add a work item to the EC event workqueue while it is being drained and worst-case it may cause a valid event to be skipped. To avoid this problem, introduce two new counters, events_in_progress and queries_in_progress, incremented when a work item is queued on the event workqueue or the query workqueue, respectively, and decremented at the end of the corresponding work function, and make acpi_ec_dispatch_gpe() the workqueues in a loop until the both of these counters are zero (or system wakeup is pending) instead of calling acpi_ec_flush_work(). At the same time, change __acpi_ec_flush_work() to call flush_workqueue() instead of drain_workqueue() to flush the event workqueue. While at it, use the observation that the work item queued in acpi_ec_query() cannot be pending at that time, because it is used only once, to simplify the code in there. Additionally, clean up a comment in acpi_ec_query() and adjust white space in acpi_ec_event_processor(). Fixes: f0ac20c3f613 ("ACPI: EC: Fix flushing of pending work") Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-11-23 19:36:51 +01:00
ACPI / EC: Fix issues related to the SCI_EVT handling This patch fixes 2 issues related to the draining behavior. But it doesn't implement the draining support, it only cleans up code so that further draining support is possible. The draining behavior is expected by some platforms (for example, Samsung) where SCI_EVT is set only once for a set of events and might be cleared for the very first QR_EC command issued after SCI_EVT is set. EC firmware on such platforms will return 0x00 to indicate "no outstanding event". Thus after seeing an SCI_EVT indication, EC driver need to fetch events until 0x00 returned (see acpi_ec_clear()). Issue 1 - acpi_ec_submit_query(): It's reported on Samsung laptops that SCI_EVT isn't checked when the transactions are advanced in ec_poll(), which leads to SCI_EVT triggering source lost: If no EC GPE IRQs are arrived after that, EC driver cannot detect this event and handle it. See comment 244/247 for kernel bugzilla 44161. This patch fixes this issue by moving SCI_EVT checks into advance_transaction(). So that SCI_EVT is checked each time we are going to handle the EC firmware indications. And this check will happen for both IRQ context and task context. Since after doing that, SCI_EVT is also checked after completing a transaction, ec_check_sci() and ec_check_sci_sync() can be removed. Issue 2 - acpi_ec_complete_query(): We expect to clear EC_FLAGS_QUERY_PENDING to allow queuing another draining QR_EC after writing a QR_EC command and before reading the event. After reading the event, SCI_EVT might be cleared by the firmware, thus it may not be possible to queue such a draining QR_EC at that time. But putting the EC_FLAGS_QUERY_PENDING clearing code after start_transaction() is wrong as there are chances that after start_transaction(), QR_EC can fail to be sent. If this happens, EC_FLAG_QUERY_PENDING will be cleared earlier. As a consequence, the draining QR_EC will also be queued earlier than expected. This patch also moves this code into advance_transaction() where QR_EC is just sent (ACPI_EC_COMMAND_POLL flagged) to fix this issue. Notes: 1. After introducing the 2 SCI_EVT related handlings into advance_transaction(), a next QR_EC can be queued right after writing the current QR_EC command and before reading the event. But this still hasn't implemented the draining behavior as the draining support requires: If a previous returned event value isn't 0x00, a draining QR_EC need to be issued even when SCI_EVT isn't set. 2. In this patch, acpi_os_execute() is also converted into a seperate work item to avoid invoking kmalloc() in the atomic context. We can do this because of the previous global lock fix. 3. Originally, EC_FLAGS_EVENT_PENDING is also used to avoid queuing up multiple work items (created by acpi_os_execute()), this can be covered by only using a single work item. But this patch still keeps this flag as there are different usages in the driver initialization steps relying on this flag. Link: https://bugzilla.kernel.org/show_bug.cgi?id=44161 Reported-by: Kieran Clancy <clancy.kieran@gmail.com> Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-01-14 19:28:47 +08:00
ACPI: EC: Fix flushing of pending work Commit 016b87ca5c8c ("ACPI: EC: Rework flushing of pending work") introduced a subtle bug into the flushing of pending EC work while suspended to idle, which may cause the EC driver to fail to re-enable the EC GPE after handling a non-wakeup event (like a battery status change event, for example). The problem is that the work item flushed by flush_scheduled_work() in __acpi_ec_flush_work() may disable the EC GPE and schedule another work item expected to re-enable it, but that new work item is not flushed, so __acpi_ec_flush_work() returns with the EC GPE disabled and the CPU running it goes into an idle state subsequently. If all of the other CPUs are in idle states at that point, the EC GPE won't be re-enabled until at least one CPU is woken up by another interrupt source, so system wakeup events that would normally come from the EC then don't work. This is reproducible on a Dell XPS13 9360 in my office which sometimes stops reacting to power button and lid events (triggered by the EC on that machine) after switching from AC power to battery power or vice versa while suspended to idle (each of those switches causes the EC GPE to trigger for several times in a row, but they are not system wakeup events). To avoid this problem, it is necessary to drain the workqueue entirely in __acpi_ec_flush_work(), but that cannot be done with respect to system_wq, because work items may be added to it from other places while __acpi_ec_flush_work() is running. For this reason, make the EC driver use a dedicated workqueue for EC events processing (let that workqueue be ordered so that EC events are processed sequentially) and use drain_workqueue() on it in __acpi_ec_flush_work(). Fixes: 016b87ca5c8c ("ACPI: EC: Rework flushing of pending work") Cc: 5.4+ <stable@vger.kernel.org> # 5.4+ Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2020-02-11 10:07:43 +01:00
ACPI 2.0 / ECDT: Remove early namespace reference from EC All operation region accesses are allowed by AML interpreter when AML is executed, so actually BIOSen are responsible to avoid the operation region accesses in AML before OSPM has prepared an operation region driver. This is done via _REG control method. So AML code normally sets a global named object REGC to 1 when _REG(3, 1) is evaluated. Then what is ECDT? Quoting from ACPI spec 6.0, 5.2.15 Embedded Controller Boot Resources Table (ECDT): "The presence of this table allows OSPM to provide Embedded Controller operation region space access before the namespace has been evaluated." Spec also suggests a compatible mean to indicate the early EC access availability: Device (EC) { Name (REGC, Ones) Method (_REG, 2) { If (LEqual (Arg0, 3)) { Store (Arg1, REGC) } } Method (ECAV) { If (LEqual (REGC, Ones)) { If (LGreaterEqual (_REV, 2)) { Return (One) } Else { Return (Zero) } } Else { Return (REGC) } } } In this way, it allows EC accesses to happen before EC._REG(3, 1) is invoked. But ECAV is not the only way practical BIOSen using to indicate the early EC access availibility, the known variations include: 1. Setting REGC to One in \_SB._INI when _REV >= 2. Since \_SB._INI is the first control method evaluated by OSPM during the enumeration, this allows EC accesses to happen for the entire enumeration process before the namespace EC is enumerated. 2. Initialize REGC to One by default, this even allows EC accesses to happen during the table loading. Linux is now broken around ECDT support during the long term bug fixing work because it has merged many wrong ECDT bug fixes (see details below). Linux currently uses namespace EC's settings instead of ECDT settings when ECDT is detected. This apparently will result in namespace walk and _CRS/_GPE/_REG evaluations. Such stuffs could only happen after namespace is ready, while ECDT is purposely to be used before namespace is ready. The wrong bug fixing story is: 1. Link 1: At Linux ACPI early stages, "no _Lxx/_Exx/_Qxx evaluation can happen before the namespace is ready" are not ensured by ACPICA core and Linux. This is currently ensured by deferred enabling of GPE and defered registering of EC query methods (acpi_ec_register_query_methods). 2. Link 2: Reporters reported buggy ECDTs, expecting quirks for the platform. Originally, the quirk is simple, only doing things with ECDT. Bug 9399 and 12461 are platforms (Asus L4R, Asus M6R, MSI MS-171F) reported to have wrong ECDT IO port addresses, the port addresses are reversed. Bug 11880 is a platform (Asus X50GL) reported to have 0 valued port addresses, we can see that all EC accesses are protected by ECAV on this platform, so actually no early EC accesses is required by this platform. 3. Link 3: But when the bug fixing developer was requested to provide a handy and non-quirk bug fix, he tried to use correct EC settings from namespace and broke the spec purpose. We can even see that the developer was suffered from many regrssions. One interesting one is 14086, where the actual root cause obviously should be: _REG is evaluated too early. But unfortunately, the bug is fixed in a totally wrong way. So everything goes wrong from these commits: Commit: c6cb0e878446c79f42e7833d7bb69ed6bfbb381f Subject: ACPI: EC: Don't trust ECDT tables from ASUS Commit: a5032bfdd9c80e0231a6324661e123818eb46ecd Subject: ACPI: EC: Always parse EC device This patch reverts Linux behavior to simple ECDT quirk support in order to stop early _CRS/_GPE/_REG evaluations. For Bug 9399, 12461, since it is reported that the platforms require early EC accesses, this patch restores the simple ECDT quirks for them. For Bug 11880, since it is not reported that the platform requires early EC accesses and its ACPI tables contain correct ECAV, we choose an ECDT enumeration failure for this platform. Link 1: https://bugzilla.kernel.org/show_bug.cgi?id=9916 http://bugzilla.kernel.org/show_bug.cgi?id=10100 https://lkml.org/lkml/2008/2/25/282 Link 2: https://bugzilla.kernel.org/show_bug.cgi?id=9399 https://bugzilla.kernel.org/show_bug.cgi?id=12461 https://bugzilla.kernel.org/show_bug.cgi?id=11880 Link 3: https://bugzilla.kernel.org/show_bug.cgi?id=11884 https://bugzilla.kernel.org/show_bug.cgi?id=14081 https://bugzilla.kernel.org/show_bug.cgi?id=14086 https://bugzilla.kernel.org/show_bug.cgi?id=14446 Link 4: https://bugzilla.kernel.org/show_bug.cgi?id=112911 Signed-off-by: Lv Zheng <lv.zheng@intel.com> Tested-by: Chris Bainbridge <chris.bainbridge@gmail.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2016-03-24 10:42:53 +08:00
ACPI / EC: Add PM operations to improve event handling for suspend process In the original EC driver, though the event handling is not explicitly stopped, the EC driver is actually not able to handle events during the noirq stage as the EC driver is not prepared to handle the EC events in the polling mode. So if there is no advance_transaction() triggered, the EC driver couldn't notice the EC events. However, do we actually need to handle EC events during suspend/resume stage? EC events are mostly useless for the suspend/resume period (key strokes and battery/thermal updates, etc.,), and the useful ones (lid close, power/sleep button press) should have already been delivered to the OSPM to trigger the power saving operations. Thus this patch implements acpi_ec_disable_event() to be a reverse call of acpi_ec_enable_event(), with which, the EC driver is able to stop handling the EC events in a position before entering the noirq stage. Since there are actually 2 choices for us: 1. implement event handling in polling mode; 2. stop event handling before entering noirq stage. And this patch only implements the second choice using .suspend() callback. Thus this is experimental (first choice is better? or different hook position is better?). This patch finally keeps the old behavior by default and prepares a boot parameter to enable this feature. The differences of the event handling availability between the old behavior (this patch is not applied) and the new behavior (this patch is applied) are as follows: !FreezeEvents FreezeEvents before suspend Y Y suspend before EC Y Y suspend after EC Y N suspend_late Y N suspend_noirq Y (actually N) N resume_noirq Y (actually N) N resume_late Y (actually N) N resume before EC Y (actually N) N resume after EC Y Y after resume Y Y Where "actually N" means if there is no EC transactions, the EC driver is actually not able to notice the pending events. We can see that FreezeEvents is the only approach now can actually flush the EC event handling with both query commands and _Qxx evaluations flushed, other modes can only flush the EC event handling with only query commands flushed, _Qxx evaluations occurred after stopping the EC driver may end up failure due to the failure of the EC transaction carried out in the _Qxx control methods. We also can see that this feature should be able to trigger some platform notifications later than resuming other drivers. Signed-off-by: Lv Zheng <lv.zheng@intel.com> Tested-by: Todd E Brandt <todd.e.brandt@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2016-08-03 16:01:43 +08:00
ACPI / EC: Add PM operations to improve event handling for suspend process In the original EC driver, though the event handling is not explicitly stopped, the EC driver is actually not able to handle events during the noirq stage as the EC driver is not prepared to handle the EC events in the polling mode. So if there is no advance_transaction() triggered, the EC driver couldn't notice the EC events. However, do we actually need to handle EC events during suspend/resume stage? EC events are mostly useless for the suspend/resume period (key strokes and battery/thermal updates, etc.,), and the useful ones (lid close, power/sleep button press) should have already been delivered to the OSPM to trigger the power saving operations. Thus this patch implements acpi_ec_disable_event() to be a reverse call of acpi_ec_enable_event(), with which, the EC driver is able to stop handling the EC events in a position before entering the noirq stage. Since there are actually 2 choices for us: 1. implement event handling in polling mode; 2. stop event handling before entering noirq stage. And this patch only implements the second choice using .suspend() callback. Thus this is experimental (first choice is better? or different hook position is better?). This patch finally keeps the old behavior by default and prepares a boot parameter to enable this feature. The differences of the event handling availability between the old behavior (this patch is not applied) and the new behavior (this patch is applied) are as follows: !FreezeEvents FreezeEvents before suspend Y Y suspend before EC Y Y suspend after EC Y N suspend_late Y N suspend_noirq Y (actually N) N resume_noirq Y (actually N) N resume_late Y (actually N) N resume before EC Y (actually N) N resume after EC Y Y after resume Y Y Where "actually N" means if there is no EC transactions, the EC driver is actually not able to notice the pending events. We can see that FreezeEvents is the only approach now can actually flush the EC event handling with both query commands and _Qxx evaluations flushed, other modes can only flush the EC event handling with only query commands flushed, _Qxx evaluations occurred after stopping the EC driver may end up failure due to the failure of the EC transaction carried out in the _Qxx control methods. We also can see that this feature should be able to trigger some platform notifications later than resuming other drivers. Signed-off-by: Lv Zheng <lv.zheng@intel.com> Tested-by: Todd E Brandt <todd.e.brandt@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2016-08-03 16:01:43 +08:00
ACPI / EC: Fix several GPE handling issues by deploying ACPI_GPE_DISPATCH_RAW_HANDLER mode. This patch switches EC driver into ACPI_GPE_DISPATCH_RAW_HANDLER mode where the GPE lock is not held for acpi_ec_gpe_handler() and the ACPICA internal GPE enabling/disabling/clearing operations are bypassed so that further improvements are possible with the GPE APIs. There are 2 strong reasons for deploying raw GPE handler mode in the EC driver: 1. Some hardware logics can control their interrupts via their own registers, so their interrupts can be disabled/enabled/acknowledged without using the super IRQ controller provided functions. While there is no mean (EC commands) for the EC driver to achieve this. 2. During suspending, the EC driver is still working for a while to complete the platform firmware provided functionailities using ec_poll() after all GPEs are disabled (see acpi_ec_block_transactions()), which means the EC driver will drive the EC GPE out of the GPE core's control. Without deploying the raw GPE handler mode, we can see many races between the EC driver and the GPE core due to the above restrictions: 1. There is a race condition due to ACPICA internal GPE disabling/clearing/enabling logics in acpi_ev_gpe_dispatch(): Orignally EC GPE is disabled (EN=0), cleared (STS=0) before invoking a GPE handler and re-enabled (EN=1) after invoking a GPE handler in acpi_ev_gpe_dispatch(). When re-enabling appears, GPE may be flagged (STS=1). ================================================================= (event pending A) ================================================================= acpi_ev_gpe_dispatch() ec_poll() EN=0 STS=0 acpi_ec_gpe_handler() ***************************************************************** (event handling A) Lock(EC) advance_transaction() EC_SC read ================================================================= (event pending B) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** ***************************************************************** (event handling B) Lock(EC) advance_transaction() EC_SC read ================================================================= (event pending C) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** EN=1 This race condition is the root cause of different issues on different silicon variations. A. Silicon variation A: On some platforms, GPE will be triggered due to "writing 1 to EN when STS=1". This is because both EN and STS lines are wired to the GPE trigger line. 1. Issue 1: We can see no-op acpi_ec_gpe_handler() invoked on such platforms. This is because: a. event pending B: An event can arrive after ACPICA's GPE clearing performed in acpi_ev_gpe_dispatch(), this event may fail to be detected by EC_SC read that is performed before its arrival; b. event handling B: The event can be handled in ec_poll() because EC lock is released after acpi_ec_gpe_handler() invocation; c. There is no code in ec_poll() to clear STS but the GPE can still be triggered by the EN=1 write performed in acpi_ev_finish_gpe(), this leads to a no-op EC GPE handler invocation; d. As no-op GPE handler invocations are counted by the EC driver to trigger the command storming conditions, the wrong no-op GPE handler invocations thus can easily trigger wrong command storming conditions. Note 1: If we removed GPE disabling/enabling code from acpi_ev_gpe_dispatch(), we could still see no-op GPE handlers triggered by the event arriving after the GPE clearing and before the GPE handling on both silicon variation A and B. This can only occur if the CPU is very slow (timing slice between STS=0 write and EC_SC read should be short enough before hardware sets another GPE indication). Thus this is very rare and is not what we need to fix. B. Silicon variation B: On other platforms, GPE may not be triggered due to "writing 1 to EN when STS=1". This is because only STS line is wired to the GPE trigger line. 2. Issue 2: We can see GPE loss on such platforms. This is because: a. event pending B vs. event handling A: An event can arrive after ACPICA's GPE handling performed in acpi_ev_gpe_dispatch(), or event pending C vs. event handling B: An event can arrive after Linux's GPE handling performed in ec_poll(), these events may fail to be detected by EC_SC read that is performed before their arrival; b. The GPE cannot be triggered by EN=1 write performed in acpi_ev_finish_gpe(); c. If no polling mechanism is implemented in the driver for the pending event (for example, SCI_EVT), this event is lost due to no GPE being triggered. Note 2: On most platforms, there might be another rule that GPE may not be triggered due to "writing 1 to STS when STS=1 and EN=1". Then on silicon variation B, an even worse case is if the issue 2 event loss happens, further events may never trigger GPE again on such platforms due to being blocked by the current STS=1. Unless someone clears STS, all events have to be polled. 2. There is a race condition due to lacking in GPE status checking in EC driver: Originally, GPE status is checked in ACPICA core but not checked in the GPE handler. Thus since the status checking and handling is not locked, it can be interrupted by another handling path. ================================================================= (event pending A) ================================================================= acpi_ev_gpe_detect() ec_poll() if (EN==1 && STS==1) ***************************************************************** (event handling A) Lock(EC) advance_transaction() EC_SC read EC_SC handled Unlock(EC) ***************************************************************** acpi_ev_gpe_dispatch() EN=0 STS=0 acpi_ec_gpe_handler() ***************************************************************** (event handling B) Lock(EC) advance_transaction() EC_SC read Unlock(EC) ***************************************************************** 3. Issue 3: We can see no-op acpi_ec_gpe_handler() invoked on both silicon variation A and B. This is because: a. event pending A: An event can arrive to trigger an EC GPE and ACPICA checks it and is about to invoke the EC GPE handler; b. event handling A: The event can be handled in ec_poll() because EC lock is not held after the GPE status checking; c. event handling B: Then when the EC GPE handler is invoked, it becomes a no-op GPE handler invocation. d. As no-op GPE handler invocations are counted by the EC driver to trigger the command storming conditions, the wrong no-op GPE handler invocations thus can easily trigger wrong command storming conditions. Note 3: This no-op GPE handler invocation is rare because the time between the IRQ arrival and the acpi_ec_gpe_handler() invocation is less than the timeout value waited in ec_poll(). So most of the no-op GPE handler invocations are caused by the reason described in issue 1. 3. There is a race condition due to ACPICA internal GPE clearing logic in acpi_enable_gpe(): During runtime, acpi_enable_gpe() can be invoked by the EC storming prevention code. When it is invoked, GPE may be flagged (STS=1). ================================================================= (event pending A) ================================================================= acpi_ev_gpe_dispatch() acpi_ec_transaction() EN=0 STS=0 acpi_ec_gpe_handler() ***************************************************************** (event handling A) Lock(EC) advance_transaction() EC_SC read EC_SC handled Unlock(EC) ***************************************************************** EN=1 ? Lock(EC) Unlock(EC) ================================================================= (event pending B) ================================================================= acpi_enable_gpe() STS=0 EN=1 4. Issue 4: We can see GPE loss on both silicon variation A and B platforms. This is because: a. event pending B: An event can arrive right before ACPICA's GPE clearing performed in acpi_enable_gpe(); b. If the GPE is cleared when GPE is disabled, then EN=1 write in acpi_enable_gpe() cannot trigger this GPE; c. If no polling mechanism is implemented in the driver for this event (for example, SCI_EVT), this event is lost due to no GPE being triggered. Note 4: Currently we don't have this issue, but after we switch the EC driver into ACPI_GPE_DISPATCH_RAW_HANDLER mode, we need to take care of handling this because the EN=1 write in acpi_ev_gpe_dispatch() will be abandoned. There might be more race issues for the current GPE handler usages. This is because the EC IRQ's enabling/disabling/checking/clearing/handling operations should be locked by a single lock that is under the EC driver's control to achieve the serialization. Which means we need to invoke GPE APIs with EC driver's lock held and all ACPICA internal GPE operations related to the GPE handler should be abandoned. Invoking GPE APIs inside of the EC driver lock and bypassing ACPICA internal GPE operations requires the ACPI_GPE_DISPATCH_RAW_HANDLER mode where the same lock used by the APIs are released prior than invoking the handlers. Otherwise, we can see dead locks due to circular locking dependencies (see Reference below). This patch then switches the EC driver into the ACPI_GPE_DISPATCH_RAW_HANDLER mode so that it can perform correct GPE operations using the GPE APIs: 1. Bypasses EN modifications performed in acpi_ev_gpe_dispatch() by using acpi_install_gpe_raw_handler() and invoking all GPE APIs with EC spin lock held. This can fix issue 1 as it makes a non frequent GPE enabling/disabling environment. 2. Bypasses STS clearing performed in acpi_enable_gpe() by replacing acpi_enable_gpe()/acpi_disable_gpe() with acpi_set_gpe(). This can fix issue 4. And this can also help to fix issue 1 as it makes a no sudden GPE clearing environment when GPE is frequently enabled/disabled. 3. Ensures STS acknowledged before handling by invoking acpi_clear_gpe() in advance_transaction(). This can finally fix issue 1 even in a frequent GPE enabling/disabling environment. And this can also finally fix issue 3 when issue 2 is fixed. Note 3: GPE clearing is edge triggered W1C, which means we can clear it right before handling it. Since all EC GPE indications are handled in advance_transaction() by previous commits, we can now move GPE clearing into it to implement the correct GPE clearing. Note 4: We can use acpi_set_gpe() which is not shared GPE safer instead of acpi_enable_gpe()/acpi_disable_gpe() because EC GPE is not shared by other hardware, which is mentioned in the ACPI specification 5.0, 12.6 Interrupt Model: "OSPM driver treats this as an edge event (the EC SCI cannot be shared)". So we can stop using shared GPE safer APIs acpi_enable_gpe()/acpi_disable_gpe() in the EC driver. Otherwise cleanups need to be made in acpi_ev_enable_gpe() to bypass the GPE clearing logic before keeping acpi_enable_gpe(). This patch also invokes advance_transaction() when GPE is re-enabled in the task context which: 1. Ensures EN=1 can trigger GPE by checking and handling EC status register right after EN=1 writes. This can fix issue 2. After applying this patch, without frequent GPE enablings considered: ================================================================= (event pending A) ================================================================= acpi_ec_gpe_handler() ec_poll() ***************************************************************** (event handling A) Lock(EC) advance_transaction() if STS==1 STS=0 EC_SC read ================================================================= (event pending B) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** ***************************************************************** (event handling B) Lock(EC) advance_transaction() if STS==1 STS=0 EC_SC read ================================================================= (event pending C) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** The event pending for issue 1 (event pending B) can arrive as a next GPE due to the previous IRQ context STS=0 write. And if it is handled by ec_poll() (event handling B), as it is also acknowledged by ec_poll(), the event pending for issue 2 (event pending C) can properly arrive as a next GPE after the task context STS=0 write. So no GPE will be lost and never triggered due to GPE clearing performed in the wrong position. And since all GPE handling is performed after a locked GPE status checking, we can hardly see no-op GPE handler invocations due to issue 1 and 3. We may still see no-op GPE handler invocations due to "Note 1", but as it is inevitable, it needn't be fixed. After applying this patch, with frequent GPE enablings considered: ================================================================= (event pending A) ================================================================= acpi_ec_gpe_handler() acpi_ec_transaction() ***************************************************************** (event handling A) Lock(EC) advance_transaction() if STS==1 STS=0 EC_SC read ================================================================= (event pending B) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** ***************************************************************** (event handling B) Lock(EC) EN=1 if STS==1 advance_transaction() if STS==1 STS=0 EC_SC read ================================================================= (event pending C) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** The event pending for issue 2 can be manually handled by advance_transaction(). And after the STS=0 write performed in the manual triggered advance_transaction(), GPE can always arrive. So no GPE will be lost due to frequent GPE disabling/enabling performed in the driver like issue 4. Note 5: It's ideally when EN=1 write occurred, an IRQ thread should be woken up to handle the GPE when the GPE was raised. But this requires the IRQ thread to contain the poller code for all EC GPE indications, while currently some of the indications are handled in the user tasks. It then is very hard for the code to determine whether a user task should be invoked or the poller work item should be scheduled. So we have to invoke advance_transaction() directly now and it leaves us such a restriction for the GPE re-enabling: it must be performed in the task context to avoid starving the GPEs. As a conclusion: we can see the EC GPE is always handled in serial after deploying the raw GPE handler mode: Lock(EC) if (STS==1) STS=0 EC_SC read EC_SC handled Unlock(EC) The EC driver specific lock is responsible to make the EC GPE handling processes serialized so that EC can handle its GPE from both IRQ and task contexts and the next IRQ can be ensured to arrive after this process. Note 6: We have many EC_FLAGS_MSI qurik users in the current driver. They all seem to be suffering from unexpected GPE triggering source lost. And they are false root caused to a timing issue. Since EC communication protocol has already flow control defined, timing shouldn't be the root cause, while this fix might be fixing the root cause of the old bugs. Link: https://lkml.org/lkml/2014/11/4/974 Link: https://lkml.org/lkml/2014/11/18/316 Link: https://www.spinics.net/lists/linux-acpi/msg54340.html Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-02-05 16:27:22 +08:00
ACPI / EC: Fix and clean up register access guarding logics. In the polling mode, EC driver shouldn't access the EC registers too frequently. Though this statement is concluded from the non-root caused bugs (see links below), we've maintained the register access guarding logics in the current EC driver. The guarding logics can be found here and there, makes it hard to root cause real timing issues. This patch collects the guarding logics into one single function so that all hidden logics related to this can be seen clearly. The current guarding related code also has several issues: 1. Per-transaction timestamp prevents inter-transaction guarding from being implemented in the same place. We have an inter-transaction udelay() in acpi_ec_transaction_unblocked(), this logic can be merged into ec_poll() if we can use per-device timestamp. This patch completes such merge to form a new ec_guard() function and collects all guarding related hidden logics in it. One hidden logic is: there is no inter-transaction guarding performed for non MSI quirk (wait polling mode), this patch skips inter-transaction guarding before wait_event_timeout() for the wait polling mode to reveal the hidden logic. The other hidden logic is: there is msleep() inter-transaction guarding performed when the GPE storming is observed. As after merging this commit: Commit: e1d4d90fc0313d3d58cbd7912c90f8ef24df45ff Subject: ACPI / EC: Refine command storm prevention support EC_FLAGS_COMMAND_STORM is ensured to be cleared after invoking acpi_ec_transaction_unlocked(), the msleep() guard logic will never happen now. Since no one complains such change, this logic is likely added during the old times where the EC race issues are not fixed and the bugs are false root-caused to the timing issue. This patch simply removes the out-dated logic. We can restore it by stop skipping inter-transaction guarding for wait polling mode. Two different delay values are defined for msleep() and udelay() while they are merged in this patch to 550us. 2. time_after() causes additional delay in the polling mode (can only be observed in noirq suspend/resume processes where polling mode is always used) before advance_transaction() is invoked ("wait polling" log is added before wait_event_timeout()). We can see 2 wait_event_timeout() invocations. This is because time_after() ensures a ">" validation while we only need a ">=" validation here: [ 86.739909] ACPI: Waking up from system sleep state S3 [ 86.742857] ACPI : EC: 2: Increase command [ 86.742859] ACPI : EC: ***** Command(RD_EC) started ***** [ 86.742861] ACPI : EC: ===== TASK (0) ===== [ 86.742871] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 86.742873] ACPI : EC: EC_SC(W) = 0x80 [ 86.742876] ACPI : EC: ***** Event started ***** [ 86.742880] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.743972] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.747966] ACPI : EC: ===== TASK (0) ===== [ 86.747977] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 86.747978] ACPI : EC: EC_DATA(W) = 0x06 [ 86.747981] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.751971] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.755969] ACPI : EC: ===== TASK (0) ===== [ 86.755991] ACPI : EC: EC_SC(R) = 0x21 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=1 [ 86.755993] ACPI : EC: EC_DATA(R) = 0x03 [ 86.755994] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.755995] ACPI : EC: ***** Command(RD_EC) stopped ***** [ 86.755996] ACPI : EC: 1: Decrease command This patch corrects this by using time_before() instead in ec_guard(): [ 54.283146] ACPI: Waking up from system sleep state S3 [ 54.285414] ACPI : EC: 2: Increase command [ 54.285415] ACPI : EC: ***** Command(RD_EC) started ***** [ 54.285416] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.285417] ACPI : EC: ===== TASK (0) ===== [ 54.285424] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 54.285425] ACPI : EC: EC_SC(W) = 0x80 [ 54.285427] ACPI : EC: ***** Event started ***** [ 54.285429] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.287209] ACPI : EC: ===== TASK (0) ===== [ 54.287218] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 54.287219] ACPI : EC: EC_DATA(W) = 0x06 [ 54.287222] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.291190] ACPI : EC: ===== TASK (0) ===== [ 54.291210] ACPI : EC: EC_SC(R) = 0x21 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=1 [ 54.291213] ACPI : EC: EC_DATA(R) = 0x03 [ 54.291214] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.291215] ACPI : EC: ***** Command(RD_EC) stopped ***** [ 54.291216] ACPI : EC: 1: Decrease command After cleaning up all guarding logics, we have one single function ec_guard() collecting all old, non-root-caused, hidden logics. Then we can easily tune the logics in one place to respond to the bug reports. Except the time_before() change, all other changes do not change the behavior of the EC driver. Link: https://bugzilla.kernel.org/show_bug.cgi?id=12011 Link: https://bugzilla.kernel.org/show_bug.cgi?id=20242 Link: https://bugzilla.kernel.org/show_bug.cgi?id=77431 Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-05-15 14:16:42 +08:00
ACPI / EC: Fix and clean up register access guarding logics. In the polling mode, EC driver shouldn't access the EC registers too frequently. Though this statement is concluded from the non-root caused bugs (see links below), we've maintained the register access guarding logics in the current EC driver. The guarding logics can be found here and there, makes it hard to root cause real timing issues. This patch collects the guarding logics into one single function so that all hidden logics related to this can be seen clearly. The current guarding related code also has several issues: 1. Per-transaction timestamp prevents inter-transaction guarding from being implemented in the same place. We have an inter-transaction udelay() in acpi_ec_transaction_unblocked(), this logic can be merged into ec_poll() if we can use per-device timestamp. This patch completes such merge to form a new ec_guard() function and collects all guarding related hidden logics in it. One hidden logic is: there is no inter-transaction guarding performed for non MSI quirk (wait polling mode), this patch skips inter-transaction guarding before wait_event_timeout() for the wait polling mode to reveal the hidden logic. The other hidden logic is: there is msleep() inter-transaction guarding performed when the GPE storming is observed. As after merging this commit: Commit: e1d4d90fc0313d3d58cbd7912c90f8ef24df45ff Subject: ACPI / EC: Refine command storm prevention support EC_FLAGS_COMMAND_STORM is ensured to be cleared after invoking acpi_ec_transaction_unlocked(), the msleep() guard logic will never happen now. Since no one complains such change, this logic is likely added during the old times where the EC race issues are not fixed and the bugs are false root-caused to the timing issue. This patch simply removes the out-dated logic. We can restore it by stop skipping inter-transaction guarding for wait polling mode. Two different delay values are defined for msleep() and udelay() while they are merged in this patch to 550us. 2. time_after() causes additional delay in the polling mode (can only be observed in noirq suspend/resume processes where polling mode is always used) before advance_transaction() is invoked ("wait polling" log is added before wait_event_timeout()). We can see 2 wait_event_timeout() invocations. This is because time_after() ensures a ">" validation while we only need a ">=" validation here: [ 86.739909] ACPI: Waking up from system sleep state S3 [ 86.742857] ACPI : EC: 2: Increase command [ 86.742859] ACPI : EC: ***** Command(RD_EC) started ***** [ 86.742861] ACPI : EC: ===== TASK (0) ===== [ 86.742871] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 86.742873] ACPI : EC: EC_SC(W) = 0x80 [ 86.742876] ACPI : EC: ***** Event started ***** [ 86.742880] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.743972] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.747966] ACPI : EC: ===== TASK (0) ===== [ 86.747977] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 86.747978] ACPI : EC: EC_DATA(W) = 0x06 [ 86.747981] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.751971] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.755969] ACPI : EC: ===== TASK (0) ===== [ 86.755991] ACPI : EC: EC_SC(R) = 0x21 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=1 [ 86.755993] ACPI : EC: EC_DATA(R) = 0x03 [ 86.755994] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.755995] ACPI : EC: ***** Command(RD_EC) stopped ***** [ 86.755996] ACPI : EC: 1: Decrease command This patch corrects this by using time_before() instead in ec_guard(): [ 54.283146] ACPI: Waking up from system sleep state S3 [ 54.285414] ACPI : EC: 2: Increase command [ 54.285415] ACPI : EC: ***** Command(RD_EC) started ***** [ 54.285416] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.285417] ACPI : EC: ===== TASK (0) ===== [ 54.285424] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 54.285425] ACPI : EC: EC_SC(W) = 0x80 [ 54.285427] ACPI : EC: ***** Event started ***** [ 54.285429] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.287209] ACPI : EC: ===== TASK (0) ===== [ 54.287218] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 54.287219] ACPI : EC: EC_DATA(W) = 0x06 [ 54.287222] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.291190] ACPI : EC: ===== TASK (0) ===== [ 54.291210] ACPI : EC: EC_SC(R) = 0x21 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=1 [ 54.291213] ACPI : EC: EC_DATA(R) = 0x03 [ 54.291214] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.291215] ACPI : EC: ***** Command(RD_EC) stopped ***** [ 54.291216] ACPI : EC: 1: Decrease command After cleaning up all guarding logics, we have one single function ec_guard() collecting all old, non-root-caused, hidden logics. Then we can easily tune the logics in one place to respond to the bug reports. Except the time_before() change, all other changes do not change the behavior of the EC driver. Link: https://bugzilla.kernel.org/show_bug.cgi?id=12011 Link: https://bugzilla.kernel.org/show_bug.cgi?id=20242 Link: https://bugzilla.kernel.org/show_bug.cgi?id=77431 Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-05-15 14:16:42 +08:00
ACPI / EC: Fix and clean up register access guarding logics. In the polling mode, EC driver shouldn't access the EC registers too frequently. Though this statement is concluded from the non-root caused bugs (see links below), we've maintained the register access guarding logics in the current EC driver. The guarding logics can be found here and there, makes it hard to root cause real timing issues. This patch collects the guarding logics into one single function so that all hidden logics related to this can be seen clearly. The current guarding related code also has several issues: 1. Per-transaction timestamp prevents inter-transaction guarding from being implemented in the same place. We have an inter-transaction udelay() in acpi_ec_transaction_unblocked(), this logic can be merged into ec_poll() if we can use per-device timestamp. This patch completes such merge to form a new ec_guard() function and collects all guarding related hidden logics in it. One hidden logic is: there is no inter-transaction guarding performed for non MSI quirk (wait polling mode), this patch skips inter-transaction guarding before wait_event_timeout() for the wait polling mode to reveal the hidden logic. The other hidden logic is: there is msleep() inter-transaction guarding performed when the GPE storming is observed. As after merging this commit: Commit: e1d4d90fc0313d3d58cbd7912c90f8ef24df45ff Subject: ACPI / EC: Refine command storm prevention support EC_FLAGS_COMMAND_STORM is ensured to be cleared after invoking acpi_ec_transaction_unlocked(), the msleep() guard logic will never happen now. Since no one complains such change, this logic is likely added during the old times where the EC race issues are not fixed and the bugs are false root-caused to the timing issue. This patch simply removes the out-dated logic. We can restore it by stop skipping inter-transaction guarding for wait polling mode. Two different delay values are defined for msleep() and udelay() while they are merged in this patch to 550us. 2. time_after() causes additional delay in the polling mode (can only be observed in noirq suspend/resume processes where polling mode is always used) before advance_transaction() is invoked ("wait polling" log is added before wait_event_timeout()). We can see 2 wait_event_timeout() invocations. This is because time_after() ensures a ">" validation while we only need a ">=" validation here: [ 86.739909] ACPI: Waking up from system sleep state S3 [ 86.742857] ACPI : EC: 2: Increase command [ 86.742859] ACPI : EC: ***** Command(RD_EC) started ***** [ 86.742861] ACPI : EC: ===== TASK (0) ===== [ 86.742871] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 86.742873] ACPI : EC: EC_SC(W) = 0x80 [ 86.742876] ACPI : EC: ***** Event started ***** [ 86.742880] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.743972] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.747966] ACPI : EC: ===== TASK (0) ===== [ 86.747977] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 86.747978] ACPI : EC: EC_DATA(W) = 0x06 [ 86.747981] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.751971] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.755969] ACPI : EC: ===== TASK (0) ===== [ 86.755991] ACPI : EC: EC_SC(R) = 0x21 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=1 [ 86.755993] ACPI : EC: EC_DATA(R) = 0x03 [ 86.755994] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.755995] ACPI : EC: ***** Command(RD_EC) stopped ***** [ 86.755996] ACPI : EC: 1: Decrease command This patch corrects this by using time_before() instead in ec_guard(): [ 54.283146] ACPI: Waking up from system sleep state S3 [ 54.285414] ACPI : EC: 2: Increase command [ 54.285415] ACPI : EC: ***** Command(RD_EC) started ***** [ 54.285416] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.285417] ACPI : EC: ===== TASK (0) ===== [ 54.285424] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 54.285425] ACPI : EC: EC_SC(W) = 0x80 [ 54.285427] ACPI : EC: ***** Event started ***** [ 54.285429] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.287209] ACPI : EC: ===== TASK (0) ===== [ 54.287218] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 54.287219] ACPI : EC: EC_DATA(W) = 0x06 [ 54.287222] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.291190] ACPI : EC: ===== TASK (0) ===== [ 54.291210] ACPI : EC: EC_SC(R) = 0x21 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=1 [ 54.291213] ACPI : EC: EC_DATA(R) = 0x03 [ 54.291214] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.291215] ACPI : EC: ***** Command(RD_EC) stopped ***** [ 54.291216] ACPI : EC: 1: Decrease command After cleaning up all guarding logics, we have one single function ec_guard() collecting all old, non-root-caused, hidden logics. Then we can easily tune the logics in one place to respond to the bug reports. Except the time_before() change, all other changes do not change the behavior of the EC driver. Link: https://bugzilla.kernel.org/show_bug.cgi?id=12011 Link: https://bugzilla.kernel.org/show_bug.cgi?id=20242 Link: https://bugzilla.kernel.org/show_bug.cgi?id=77431 Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-05-15 14:16:42 +08:00
ACPI / EC: Fix several GPE handling issues by deploying ACPI_GPE_DISPATCH_RAW_HANDLER mode. This patch switches EC driver into ACPI_GPE_DISPATCH_RAW_HANDLER mode where the GPE lock is not held for acpi_ec_gpe_handler() and the ACPICA internal GPE enabling/disabling/clearing operations are bypassed so that further improvements are possible with the GPE APIs. There are 2 strong reasons for deploying raw GPE handler mode in the EC driver: 1. Some hardware logics can control their interrupts via their own registers, so their interrupts can be disabled/enabled/acknowledged without using the super IRQ controller provided functions. While there is no mean (EC commands) for the EC driver to achieve this. 2. During suspending, the EC driver is still working for a while to complete the platform firmware provided functionailities using ec_poll() after all GPEs are disabled (see acpi_ec_block_transactions()), which means the EC driver will drive the EC GPE out of the GPE core's control. Without deploying the raw GPE handler mode, we can see many races between the EC driver and the GPE core due to the above restrictions: 1. There is a race condition due to ACPICA internal GPE disabling/clearing/enabling logics in acpi_ev_gpe_dispatch(): Orignally EC GPE is disabled (EN=0), cleared (STS=0) before invoking a GPE handler and re-enabled (EN=1) after invoking a GPE handler in acpi_ev_gpe_dispatch(). When re-enabling appears, GPE may be flagged (STS=1). ================================================================= (event pending A) ================================================================= acpi_ev_gpe_dispatch() ec_poll() EN=0 STS=0 acpi_ec_gpe_handler() ***************************************************************** (event handling A) Lock(EC) advance_transaction() EC_SC read ================================================================= (event pending B) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** ***************************************************************** (event handling B) Lock(EC) advance_transaction() EC_SC read ================================================================= (event pending C) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** EN=1 This race condition is the root cause of different issues on different silicon variations. A. Silicon variation A: On some platforms, GPE will be triggered due to "writing 1 to EN when STS=1". This is because both EN and STS lines are wired to the GPE trigger line. 1. Issue 1: We can see no-op acpi_ec_gpe_handler() invoked on such platforms. This is because: a. event pending B: An event can arrive after ACPICA's GPE clearing performed in acpi_ev_gpe_dispatch(), this event may fail to be detected by EC_SC read that is performed before its arrival; b. event handling B: The event can be handled in ec_poll() because EC lock is released after acpi_ec_gpe_handler() invocation; c. There is no code in ec_poll() to clear STS but the GPE can still be triggered by the EN=1 write performed in acpi_ev_finish_gpe(), this leads to a no-op EC GPE handler invocation; d. As no-op GPE handler invocations are counted by the EC driver to trigger the command storming conditions, the wrong no-op GPE handler invocations thus can easily trigger wrong command storming conditions. Note 1: If we removed GPE disabling/enabling code from acpi_ev_gpe_dispatch(), we could still see no-op GPE handlers triggered by the event arriving after the GPE clearing and before the GPE handling on both silicon variation A and B. This can only occur if the CPU is very slow (timing slice between STS=0 write and EC_SC read should be short enough before hardware sets another GPE indication). Thus this is very rare and is not what we need to fix. B. Silicon variation B: On other platforms, GPE may not be triggered due to "writing 1 to EN when STS=1". This is because only STS line is wired to the GPE trigger line. 2. Issue 2: We can see GPE loss on such platforms. This is because: a. event pending B vs. event handling A: An event can arrive after ACPICA's GPE handling performed in acpi_ev_gpe_dispatch(), or event pending C vs. event handling B: An event can arrive after Linux's GPE handling performed in ec_poll(), these events may fail to be detected by EC_SC read that is performed before their arrival; b. The GPE cannot be triggered by EN=1 write performed in acpi_ev_finish_gpe(); c. If no polling mechanism is implemented in the driver for the pending event (for example, SCI_EVT), this event is lost due to no GPE being triggered. Note 2: On most platforms, there might be another rule that GPE may not be triggered due to "writing 1 to STS when STS=1 and EN=1". Then on silicon variation B, an even worse case is if the issue 2 event loss happens, further events may never trigger GPE again on such platforms due to being blocked by the current STS=1. Unless someone clears STS, all events have to be polled. 2. There is a race condition due to lacking in GPE status checking in EC driver: Originally, GPE status is checked in ACPICA core but not checked in the GPE handler. Thus since the status checking and handling is not locked, it can be interrupted by another handling path. ================================================================= (event pending A) ================================================================= acpi_ev_gpe_detect() ec_poll() if (EN==1 && STS==1) ***************************************************************** (event handling A) Lock(EC) advance_transaction() EC_SC read EC_SC handled Unlock(EC) ***************************************************************** acpi_ev_gpe_dispatch() EN=0 STS=0 acpi_ec_gpe_handler() ***************************************************************** (event handling B) Lock(EC) advance_transaction() EC_SC read Unlock(EC) ***************************************************************** 3. Issue 3: We can see no-op acpi_ec_gpe_handler() invoked on both silicon variation A and B. This is because: a. event pending A: An event can arrive to trigger an EC GPE and ACPICA checks it and is about to invoke the EC GPE handler; b. event handling A: The event can be handled in ec_poll() because EC lock is not held after the GPE status checking; c. event handling B: Then when the EC GPE handler is invoked, it becomes a no-op GPE handler invocation. d. As no-op GPE handler invocations are counted by the EC driver to trigger the command storming conditions, the wrong no-op GPE handler invocations thus can easily trigger wrong command storming conditions. Note 3: This no-op GPE handler invocation is rare because the time between the IRQ arrival and the acpi_ec_gpe_handler() invocation is less than the timeout value waited in ec_poll(). So most of the no-op GPE handler invocations are caused by the reason described in issue 1. 3. There is a race condition due to ACPICA internal GPE clearing logic in acpi_enable_gpe(): During runtime, acpi_enable_gpe() can be invoked by the EC storming prevention code. When it is invoked, GPE may be flagged (STS=1). ================================================================= (event pending A) ================================================================= acpi_ev_gpe_dispatch() acpi_ec_transaction() EN=0 STS=0 acpi_ec_gpe_handler() ***************************************************************** (event handling A) Lock(EC) advance_transaction() EC_SC read EC_SC handled Unlock(EC) ***************************************************************** EN=1 ? Lock(EC) Unlock(EC) ================================================================= (event pending B) ================================================================= acpi_enable_gpe() STS=0 EN=1 4. Issue 4: We can see GPE loss on both silicon variation A and B platforms. This is because: a. event pending B: An event can arrive right before ACPICA's GPE clearing performed in acpi_enable_gpe(); b. If the GPE is cleared when GPE is disabled, then EN=1 write in acpi_enable_gpe() cannot trigger this GPE; c. If no polling mechanism is implemented in the driver for this event (for example, SCI_EVT), this event is lost due to no GPE being triggered. Note 4: Currently we don't have this issue, but after we switch the EC driver into ACPI_GPE_DISPATCH_RAW_HANDLER mode, we need to take care of handling this because the EN=1 write in acpi_ev_gpe_dispatch() will be abandoned. There might be more race issues for the current GPE handler usages. This is because the EC IRQ's enabling/disabling/checking/clearing/handling operations should be locked by a single lock that is under the EC driver's control to achieve the serialization. Which means we need to invoke GPE APIs with EC driver's lock held and all ACPICA internal GPE operations related to the GPE handler should be abandoned. Invoking GPE APIs inside of the EC driver lock and bypassing ACPICA internal GPE operations requires the ACPI_GPE_DISPATCH_RAW_HANDLER mode where the same lock used by the APIs are released prior than invoking the handlers. Otherwise, we can see dead locks due to circular locking dependencies (see Reference below). This patch then switches the EC driver into the ACPI_GPE_DISPATCH_RAW_HANDLER mode so that it can perform correct GPE operations using the GPE APIs: 1. Bypasses EN modifications performed in acpi_ev_gpe_dispatch() by using acpi_install_gpe_raw_handler() and invoking all GPE APIs with EC spin lock held. This can fix issue 1 as it makes a non frequent GPE enabling/disabling environment. 2. Bypasses STS clearing performed in acpi_enable_gpe() by replacing acpi_enable_gpe()/acpi_disable_gpe() with acpi_set_gpe(). This can fix issue 4. And this can also help to fix issue 1 as it makes a no sudden GPE clearing environment when GPE is frequently enabled/disabled. 3. Ensures STS acknowledged before handling by invoking acpi_clear_gpe() in advance_transaction(). This can finally fix issue 1 even in a frequent GPE enabling/disabling environment. And this can also finally fix issue 3 when issue 2 is fixed. Note 3: GPE clearing is edge triggered W1C, which means we can clear it right before handling it. Since all EC GPE indications are handled in advance_transaction() by previous commits, we can now move GPE clearing into it to implement the correct GPE clearing. Note 4: We can use acpi_set_gpe() which is not shared GPE safer instead of acpi_enable_gpe()/acpi_disable_gpe() because EC GPE is not shared by other hardware, which is mentioned in the ACPI specification 5.0, 12.6 Interrupt Model: "OSPM driver treats this as an edge event (the EC SCI cannot be shared)". So we can stop using shared GPE safer APIs acpi_enable_gpe()/acpi_disable_gpe() in the EC driver. Otherwise cleanups need to be made in acpi_ev_enable_gpe() to bypass the GPE clearing logic before keeping acpi_enable_gpe(). This patch also invokes advance_transaction() when GPE is re-enabled in the task context which: 1. Ensures EN=1 can trigger GPE by checking and handling EC status register right after EN=1 writes. This can fix issue 2. After applying this patch, without frequent GPE enablings considered: ================================================================= (event pending A) ================================================================= acpi_ec_gpe_handler() ec_poll() ***************************************************************** (event handling A) Lock(EC) advance_transaction() if STS==1 STS=0 EC_SC read ================================================================= (event pending B) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** ***************************************************************** (event handling B) Lock(EC) advance_transaction() if STS==1 STS=0 EC_SC read ================================================================= (event pending C) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** The event pending for issue 1 (event pending B) can arrive as a next GPE due to the previous IRQ context STS=0 write. And if it is handled by ec_poll() (event handling B), as it is also acknowledged by ec_poll(), the event pending for issue 2 (event pending C) can properly arrive as a next GPE after the task context STS=0 write. So no GPE will be lost and never triggered due to GPE clearing performed in the wrong position. And since all GPE handling is performed after a locked GPE status checking, we can hardly see no-op GPE handler invocations due to issue 1 and 3. We may still see no-op GPE handler invocations due to "Note 1", but as it is inevitable, it needn't be fixed. After applying this patch, with frequent GPE enablings considered: ================================================================= (event pending A) ================================================================= acpi_ec_gpe_handler() acpi_ec_transaction() ***************************************************************** (event handling A) Lock(EC) advance_transaction() if STS==1 STS=0 EC_SC read ================================================================= (event pending B) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** ***************************************************************** (event handling B) Lock(EC) EN=1 if STS==1 advance_transaction() if STS==1 STS=0 EC_SC read ================================================================= (event pending C) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** The event pending for issue 2 can be manually handled by advance_transaction(). And after the STS=0 write performed in the manual triggered advance_transaction(), GPE can always arrive. So no GPE will be lost due to frequent GPE disabling/enabling performed in the driver like issue 4. Note 5: It's ideally when EN=1 write occurred, an IRQ thread should be woken up to handle the GPE when the GPE was raised. But this requires the IRQ thread to contain the poller code for all EC GPE indications, while currently some of the indications are handled in the user tasks. It then is very hard for the code to determine whether a user task should be invoked or the poller work item should be scheduled. So we have to invoke advance_transaction() directly now and it leaves us such a restriction for the GPE re-enabling: it must be performed in the task context to avoid starving the GPEs. As a conclusion: we can see the EC GPE is always handled in serial after deploying the raw GPE handler mode: Lock(EC) if (STS==1) STS=0 EC_SC read EC_SC handled Unlock(EC) The EC driver specific lock is responsible to make the EC GPE handling processes serialized so that EC can handle its GPE from both IRQ and task contexts and the next IRQ can be ensured to arrive after this process. Note 6: We have many EC_FLAGS_MSI qurik users in the current driver. They all seem to be suffering from unexpected GPE triggering source lost. And they are false root caused to a timing issue. Since EC communication protocol has already flow control defined, timing shouldn't be the root cause, while this fix might be fixing the root cause of the old bugs. Link: https://lkml.org/lkml/2014/11/4/974 Link: https://lkml.org/lkml/2014/11/18/316 Link: https://www.spinics.net/lists/linux-acpi/msg54340.html Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-02-05 16:27:22 +08:00
ACPI / EC: Fix several GPE handling issues by deploying ACPI_GPE_DISPATCH_RAW_HANDLER mode. This patch switches EC driver into ACPI_GPE_DISPATCH_RAW_HANDLER mode where the GPE lock is not held for acpi_ec_gpe_handler() and the ACPICA internal GPE enabling/disabling/clearing operations are bypassed so that further improvements are possible with the GPE APIs. There are 2 strong reasons for deploying raw GPE handler mode in the EC driver: 1. Some hardware logics can control their interrupts via their own registers, so their interrupts can be disabled/enabled/acknowledged without using the super IRQ controller provided functions. While there is no mean (EC commands) for the EC driver to achieve this. 2. During suspending, the EC driver is still working for a while to complete the platform firmware provided functionailities using ec_poll() after all GPEs are disabled (see acpi_ec_block_transactions()), which means the EC driver will drive the EC GPE out of the GPE core's control. Without deploying the raw GPE handler mode, we can see many races between the EC driver and the GPE core due to the above restrictions: 1. There is a race condition due to ACPICA internal GPE disabling/clearing/enabling logics in acpi_ev_gpe_dispatch(): Orignally EC GPE is disabled (EN=0), cleared (STS=0) before invoking a GPE handler and re-enabled (EN=1) after invoking a GPE handler in acpi_ev_gpe_dispatch(). When re-enabling appears, GPE may be flagged (STS=1). ================================================================= (event pending A) ================================================================= acpi_ev_gpe_dispatch() ec_poll() EN=0 STS=0 acpi_ec_gpe_handler() ***************************************************************** (event handling A) Lock(EC) advance_transaction() EC_SC read ================================================================= (event pending B) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** ***************************************************************** (event handling B) Lock(EC) advance_transaction() EC_SC read ================================================================= (event pending C) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** EN=1 This race condition is the root cause of different issues on different silicon variations. A. Silicon variation A: On some platforms, GPE will be triggered due to "writing 1 to EN when STS=1". This is because both EN and STS lines are wired to the GPE trigger line. 1. Issue 1: We can see no-op acpi_ec_gpe_handler() invoked on such platforms. This is because: a. event pending B: An event can arrive after ACPICA's GPE clearing performed in acpi_ev_gpe_dispatch(), this event may fail to be detected by EC_SC read that is performed before its arrival; b. event handling B: The event can be handled in ec_poll() because EC lock is released after acpi_ec_gpe_handler() invocation; c. There is no code in ec_poll() to clear STS but the GPE can still be triggered by the EN=1 write performed in acpi_ev_finish_gpe(), this leads to a no-op EC GPE handler invocation; d. As no-op GPE handler invocations are counted by the EC driver to trigger the command storming conditions, the wrong no-op GPE handler invocations thus can easily trigger wrong command storming conditions. Note 1: If we removed GPE disabling/enabling code from acpi_ev_gpe_dispatch(), we could still see no-op GPE handlers triggered by the event arriving after the GPE clearing and before the GPE handling on both silicon variation A and B. This can only occur if the CPU is very slow (timing slice between STS=0 write and EC_SC read should be short enough before hardware sets another GPE indication). Thus this is very rare and is not what we need to fix. B. Silicon variation B: On other platforms, GPE may not be triggered due to "writing 1 to EN when STS=1". This is because only STS line is wired to the GPE trigger line. 2. Issue 2: We can see GPE loss on such platforms. This is because: a. event pending B vs. event handling A: An event can arrive after ACPICA's GPE handling performed in acpi_ev_gpe_dispatch(), or event pending C vs. event handling B: An event can arrive after Linux's GPE handling performed in ec_poll(), these events may fail to be detected by EC_SC read that is performed before their arrival; b. The GPE cannot be triggered by EN=1 write performed in acpi_ev_finish_gpe(); c. If no polling mechanism is implemented in the driver for the pending event (for example, SCI_EVT), this event is lost due to no GPE being triggered. Note 2: On most platforms, there might be another rule that GPE may not be triggered due to "writing 1 to STS when STS=1 and EN=1". Then on silicon variation B, an even worse case is if the issue 2 event loss happens, further events may never trigger GPE again on such platforms due to being blocked by the current STS=1. Unless someone clears STS, all events have to be polled. 2. There is a race condition due to lacking in GPE status checking in EC driver: Originally, GPE status is checked in ACPICA core but not checked in the GPE handler. Thus since the status checking and handling is not locked, it can be interrupted by another handling path. ================================================================= (event pending A) ================================================================= acpi_ev_gpe_detect() ec_poll() if (EN==1 && STS==1) ***************************************************************** (event handling A) Lock(EC) advance_transaction() EC_SC read EC_SC handled Unlock(EC) ***************************************************************** acpi_ev_gpe_dispatch() EN=0 STS=0 acpi_ec_gpe_handler() ***************************************************************** (event handling B) Lock(EC) advance_transaction() EC_SC read Unlock(EC) ***************************************************************** 3. Issue 3: We can see no-op acpi_ec_gpe_handler() invoked on both silicon variation A and B. This is because: a. event pending A: An event can arrive to trigger an EC GPE and ACPICA checks it and is about to invoke the EC GPE handler; b. event handling A: The event can be handled in ec_poll() because EC lock is not held after the GPE status checking; c. event handling B: Then when the EC GPE handler is invoked, it becomes a no-op GPE handler invocation. d. As no-op GPE handler invocations are counted by the EC driver to trigger the command storming conditions, the wrong no-op GPE handler invocations thus can easily trigger wrong command storming conditions. Note 3: This no-op GPE handler invocation is rare because the time between the IRQ arrival and the acpi_ec_gpe_handler() invocation is less than the timeout value waited in ec_poll(). So most of the no-op GPE handler invocations are caused by the reason described in issue 1. 3. There is a race condition due to ACPICA internal GPE clearing logic in acpi_enable_gpe(): During runtime, acpi_enable_gpe() can be invoked by the EC storming prevention code. When it is invoked, GPE may be flagged (STS=1). ================================================================= (event pending A) ================================================================= acpi_ev_gpe_dispatch() acpi_ec_transaction() EN=0 STS=0 acpi_ec_gpe_handler() ***************************************************************** (event handling A) Lock(EC) advance_transaction() EC_SC read EC_SC handled Unlock(EC) ***************************************************************** EN=1 ? Lock(EC) Unlock(EC) ================================================================= (event pending B) ================================================================= acpi_enable_gpe() STS=0 EN=1 4. Issue 4: We can see GPE loss on both silicon variation A and B platforms. This is because: a. event pending B: An event can arrive right before ACPICA's GPE clearing performed in acpi_enable_gpe(); b. If the GPE is cleared when GPE is disabled, then EN=1 write in acpi_enable_gpe() cannot trigger this GPE; c. If no polling mechanism is implemented in the driver for this event (for example, SCI_EVT), this event is lost due to no GPE being triggered. Note 4: Currently we don't have this issue, but after we switch the EC driver into ACPI_GPE_DISPATCH_RAW_HANDLER mode, we need to take care of handling this because the EN=1 write in acpi_ev_gpe_dispatch() will be abandoned. There might be more race issues for the current GPE handler usages. This is because the EC IRQ's enabling/disabling/checking/clearing/handling operations should be locked by a single lock that is under the EC driver's control to achieve the serialization. Which means we need to invoke GPE APIs with EC driver's lock held and all ACPICA internal GPE operations related to the GPE handler should be abandoned. Invoking GPE APIs inside of the EC driver lock and bypassing ACPICA internal GPE operations requires the ACPI_GPE_DISPATCH_RAW_HANDLER mode where the same lock used by the APIs are released prior than invoking the handlers. Otherwise, we can see dead locks due to circular locking dependencies (see Reference below). This patch then switches the EC driver into the ACPI_GPE_DISPATCH_RAW_HANDLER mode so that it can perform correct GPE operations using the GPE APIs: 1. Bypasses EN modifications performed in acpi_ev_gpe_dispatch() by using acpi_install_gpe_raw_handler() and invoking all GPE APIs with EC spin lock held. This can fix issue 1 as it makes a non frequent GPE enabling/disabling environment. 2. Bypasses STS clearing performed in acpi_enable_gpe() by replacing acpi_enable_gpe()/acpi_disable_gpe() with acpi_set_gpe(). This can fix issue 4. And this can also help to fix issue 1 as it makes a no sudden GPE clearing environment when GPE is frequently enabled/disabled. 3. Ensures STS acknowledged before handling by invoking acpi_clear_gpe() in advance_transaction(). This can finally fix issue 1 even in a frequent GPE enabling/disabling environment. And this can also finally fix issue 3 when issue 2 is fixed. Note 3: GPE clearing is edge triggered W1C, which means we can clear it right before handling it. Since all EC GPE indications are handled in advance_transaction() by previous commits, we can now move GPE clearing into it to implement the correct GPE clearing. Note 4: We can use acpi_set_gpe() which is not shared GPE safer instead of acpi_enable_gpe()/acpi_disable_gpe() because EC GPE is not shared by other hardware, which is mentioned in the ACPI specification 5.0, 12.6 Interrupt Model: "OSPM driver treats this as an edge event (the EC SCI cannot be shared)". So we can stop using shared GPE safer APIs acpi_enable_gpe()/acpi_disable_gpe() in the EC driver. Otherwise cleanups need to be made in acpi_ev_enable_gpe() to bypass the GPE clearing logic before keeping acpi_enable_gpe(). This patch also invokes advance_transaction() when GPE is re-enabled in the task context which: 1. Ensures EN=1 can trigger GPE by checking and handling EC status register right after EN=1 writes. This can fix issue 2. After applying this patch, without frequent GPE enablings considered: ================================================================= (event pending A) ================================================================= acpi_ec_gpe_handler() ec_poll() ***************************************************************** (event handling A) Lock(EC) advance_transaction() if STS==1 STS=0 EC_SC read ================================================================= (event pending B) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** ***************************************************************** (event handling B) Lock(EC) advance_transaction() if STS==1 STS=0 EC_SC read ================================================================= (event pending C) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** The event pending for issue 1 (event pending B) can arrive as a next GPE due to the previous IRQ context STS=0 write. And if it is handled by ec_poll() (event handling B), as it is also acknowledged by ec_poll(), the event pending for issue 2 (event pending C) can properly arrive as a next GPE after the task context STS=0 write. So no GPE will be lost and never triggered due to GPE clearing performed in the wrong position. And since all GPE handling is performed after a locked GPE status checking, we can hardly see no-op GPE handler invocations due to issue 1 and 3. We may still see no-op GPE handler invocations due to "Note 1", but as it is inevitable, it needn't be fixed. After applying this patch, with frequent GPE enablings considered: ================================================================= (event pending A) ================================================================= acpi_ec_gpe_handler() acpi_ec_transaction() ***************************************************************** (event handling A) Lock(EC) advance_transaction() if STS==1 STS=0 EC_SC read ================================================================= (event pending B) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** ***************************************************************** (event handling B) Lock(EC) EN=1 if STS==1 advance_transaction() if STS==1 STS=0 EC_SC read ================================================================= (event pending C) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** The event pending for issue 2 can be manually handled by advance_transaction(). And after the STS=0 write performed in the manual triggered advance_transaction(), GPE can always arrive. So no GPE will be lost due to frequent GPE disabling/enabling performed in the driver like issue 4. Note 5: It's ideally when EN=1 write occurred, an IRQ thread should be woken up to handle the GPE when the GPE was raised. But this requires the IRQ thread to contain the poller code for all EC GPE indications, while currently some of the indications are handled in the user tasks. It then is very hard for the code to determine whether a user task should be invoked or the poller work item should be scheduled. So we have to invoke advance_transaction() directly now and it leaves us such a restriction for the GPE re-enabling: it must be performed in the task context to avoid starving the GPEs. As a conclusion: we can see the EC GPE is always handled in serial after deploying the raw GPE handler mode: Lock(EC) if (STS==1) STS=0 EC_SC read EC_SC handled Unlock(EC) The EC driver specific lock is responsible to make the EC GPE handling processes serialized so that EC can handle its GPE from both IRQ and task contexts and the next IRQ can be ensured to arrive after this process. Note 6: We have many EC_FLAGS_MSI qurik users in the current driver. They all seem to be suffering from unexpected GPE triggering source lost. And they are false root caused to a timing issue. Since EC communication protocol has already flow control defined, timing shouldn't be the root cause, while this fix might be fixing the root cause of the old bugs. Link: https://lkml.org/lkml/2014/11/4/974 Link: https://lkml.org/lkml/2014/11/18/316 Link: https://www.spinics.net/lists/linux-acpi/msg54340.html Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-02-05 16:27:22 +08:00
ACPI / EC: Fix several GPE handling issues by deploying ACPI_GPE_DISPATCH_RAW_HANDLER mode. This patch switches EC driver into ACPI_GPE_DISPATCH_RAW_HANDLER mode where the GPE lock is not held for acpi_ec_gpe_handler() and the ACPICA internal GPE enabling/disabling/clearing operations are bypassed so that further improvements are possible with the GPE APIs. There are 2 strong reasons for deploying raw GPE handler mode in the EC driver: 1. Some hardware logics can control their interrupts via their own registers, so their interrupts can be disabled/enabled/acknowledged without using the super IRQ controller provided functions. While there is no mean (EC commands) for the EC driver to achieve this. 2. During suspending, the EC driver is still working for a while to complete the platform firmware provided functionailities using ec_poll() after all GPEs are disabled (see acpi_ec_block_transactions()), which means the EC driver will drive the EC GPE out of the GPE core's control. Without deploying the raw GPE handler mode, we can see many races between the EC driver and the GPE core due to the above restrictions: 1. There is a race condition due to ACPICA internal GPE disabling/clearing/enabling logics in acpi_ev_gpe_dispatch(): Orignally EC GPE is disabled (EN=0), cleared (STS=0) before invoking a GPE handler and re-enabled (EN=1) after invoking a GPE handler in acpi_ev_gpe_dispatch(). When re-enabling appears, GPE may be flagged (STS=1). ================================================================= (event pending A) ================================================================= acpi_ev_gpe_dispatch() ec_poll() EN=0 STS=0 acpi_ec_gpe_handler() ***************************************************************** (event handling A) Lock(EC) advance_transaction() EC_SC read ================================================================= (event pending B) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** ***************************************************************** (event handling B) Lock(EC) advance_transaction() EC_SC read ================================================================= (event pending C) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** EN=1 This race condition is the root cause of different issues on different silicon variations. A. Silicon variation A: On some platforms, GPE will be triggered due to "writing 1 to EN when STS=1". This is because both EN and STS lines are wired to the GPE trigger line. 1. Issue 1: We can see no-op acpi_ec_gpe_handler() invoked on such platforms. This is because: a. event pending B: An event can arrive after ACPICA's GPE clearing performed in acpi_ev_gpe_dispatch(), this event may fail to be detected by EC_SC read that is performed before its arrival; b. event handling B: The event can be handled in ec_poll() because EC lock is released after acpi_ec_gpe_handler() invocation; c. There is no code in ec_poll() to clear STS but the GPE can still be triggered by the EN=1 write performed in acpi_ev_finish_gpe(), this leads to a no-op EC GPE handler invocation; d. As no-op GPE handler invocations are counted by the EC driver to trigger the command storming conditions, the wrong no-op GPE handler invocations thus can easily trigger wrong command storming conditions. Note 1: If we removed GPE disabling/enabling code from acpi_ev_gpe_dispatch(), we could still see no-op GPE handlers triggered by the event arriving after the GPE clearing and before the GPE handling on both silicon variation A and B. This can only occur if the CPU is very slow (timing slice between STS=0 write and EC_SC read should be short enough before hardware sets another GPE indication). Thus this is very rare and is not what we need to fix. B. Silicon variation B: On other platforms, GPE may not be triggered due to "writing 1 to EN when STS=1". This is because only STS line is wired to the GPE trigger line. 2. Issue 2: We can see GPE loss on such platforms. This is because: a. event pending B vs. event handling A: An event can arrive after ACPICA's GPE handling performed in acpi_ev_gpe_dispatch(), or event pending C vs. event handling B: An event can arrive after Linux's GPE handling performed in ec_poll(), these events may fail to be detected by EC_SC read that is performed before their arrival; b. The GPE cannot be triggered by EN=1 write performed in acpi_ev_finish_gpe(); c. If no polling mechanism is implemented in the driver for the pending event (for example, SCI_EVT), this event is lost due to no GPE being triggered. Note 2: On most platforms, there might be another rule that GPE may not be triggered due to "writing 1 to STS when STS=1 and EN=1". Then on silicon variation B, an even worse case is if the issue 2 event loss happens, further events may never trigger GPE again on such platforms due to being blocked by the current STS=1. Unless someone clears STS, all events have to be polled. 2. There is a race condition due to lacking in GPE status checking in EC driver: Originally, GPE status is checked in ACPICA core but not checked in the GPE handler. Thus since the status checking and handling is not locked, it can be interrupted by another handling path. ================================================================= (event pending A) ================================================================= acpi_ev_gpe_detect() ec_poll() if (EN==1 && STS==1) ***************************************************************** (event handling A) Lock(EC) advance_transaction() EC_SC read EC_SC handled Unlock(EC) ***************************************************************** acpi_ev_gpe_dispatch() EN=0 STS=0 acpi_ec_gpe_handler() ***************************************************************** (event handling B) Lock(EC) advance_transaction() EC_SC read Unlock(EC) ***************************************************************** 3. Issue 3: We can see no-op acpi_ec_gpe_handler() invoked on both silicon variation A and B. This is because: a. event pending A: An event can arrive to trigger an EC GPE and ACPICA checks it and is about to invoke the EC GPE handler; b. event handling A: The event can be handled in ec_poll() because EC lock is not held after the GPE status checking; c. event handling B: Then when the EC GPE handler is invoked, it becomes a no-op GPE handler invocation. d. As no-op GPE handler invocations are counted by the EC driver to trigger the command storming conditions, the wrong no-op GPE handler invocations thus can easily trigger wrong command storming conditions. Note 3: This no-op GPE handler invocation is rare because the time between the IRQ arrival and the acpi_ec_gpe_handler() invocation is less than the timeout value waited in ec_poll(). So most of the no-op GPE handler invocations are caused by the reason described in issue 1. 3. There is a race condition due to ACPICA internal GPE clearing logic in acpi_enable_gpe(): During runtime, acpi_enable_gpe() can be invoked by the EC storming prevention code. When it is invoked, GPE may be flagged (STS=1). ================================================================= (event pending A) ================================================================= acpi_ev_gpe_dispatch() acpi_ec_transaction() EN=0 STS=0 acpi_ec_gpe_handler() ***************************************************************** (event handling A) Lock(EC) advance_transaction() EC_SC read EC_SC handled Unlock(EC) ***************************************************************** EN=1 ? Lock(EC) Unlock(EC) ================================================================= (event pending B) ================================================================= acpi_enable_gpe() STS=0 EN=1 4. Issue 4: We can see GPE loss on both silicon variation A and B platforms. This is because: a. event pending B: An event can arrive right before ACPICA's GPE clearing performed in acpi_enable_gpe(); b. If the GPE is cleared when GPE is disabled, then EN=1 write in acpi_enable_gpe() cannot trigger this GPE; c. If no polling mechanism is implemented in the driver for this event (for example, SCI_EVT), this event is lost due to no GPE being triggered. Note 4: Currently we don't have this issue, but after we switch the EC driver into ACPI_GPE_DISPATCH_RAW_HANDLER mode, we need to take care of handling this because the EN=1 write in acpi_ev_gpe_dispatch() will be abandoned. There might be more race issues for the current GPE handler usages. This is because the EC IRQ's enabling/disabling/checking/clearing/handling operations should be locked by a single lock that is under the EC driver's control to achieve the serialization. Which means we need to invoke GPE APIs with EC driver's lock held and all ACPICA internal GPE operations related to the GPE handler should be abandoned. Invoking GPE APIs inside of the EC driver lock and bypassing ACPICA internal GPE operations requires the ACPI_GPE_DISPATCH_RAW_HANDLER mode where the same lock used by the APIs are released prior than invoking the handlers. Otherwise, we can see dead locks due to circular locking dependencies (see Reference below). This patch then switches the EC driver into the ACPI_GPE_DISPATCH_RAW_HANDLER mode so that it can perform correct GPE operations using the GPE APIs: 1. Bypasses EN modifications performed in acpi_ev_gpe_dispatch() by using acpi_install_gpe_raw_handler() and invoking all GPE APIs with EC spin lock held. This can fix issue 1 as it makes a non frequent GPE enabling/disabling environment. 2. Bypasses STS clearing performed in acpi_enable_gpe() by replacing acpi_enable_gpe()/acpi_disable_gpe() with acpi_set_gpe(). This can fix issue 4. And this can also help to fix issue 1 as it makes a no sudden GPE clearing environment when GPE is frequently enabled/disabled. 3. Ensures STS acknowledged before handling by invoking acpi_clear_gpe() in advance_transaction(). This can finally fix issue 1 even in a frequent GPE enabling/disabling environment. And this can also finally fix issue 3 when issue 2 is fixed. Note 3: GPE clearing is edge triggered W1C, which means we can clear it right before handling it. Since all EC GPE indications are handled in advance_transaction() by previous commits, we can now move GPE clearing into it to implement the correct GPE clearing. Note 4: We can use acpi_set_gpe() which is not shared GPE safer instead of acpi_enable_gpe()/acpi_disable_gpe() because EC GPE is not shared by other hardware, which is mentioned in the ACPI specification 5.0, 12.6 Interrupt Model: "OSPM driver treats this as an edge event (the EC SCI cannot be shared)". So we can stop using shared GPE safer APIs acpi_enable_gpe()/acpi_disable_gpe() in the EC driver. Otherwise cleanups need to be made in acpi_ev_enable_gpe() to bypass the GPE clearing logic before keeping acpi_enable_gpe(). This patch also invokes advance_transaction() when GPE is re-enabled in the task context which: 1. Ensures EN=1 can trigger GPE by checking and handling EC status register right after EN=1 writes. This can fix issue 2. After applying this patch, without frequent GPE enablings considered: ================================================================= (event pending A) ================================================================= acpi_ec_gpe_handler() ec_poll() ***************************************************************** (event handling A) Lock(EC) advance_transaction() if STS==1 STS=0 EC_SC read ================================================================= (event pending B) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** ***************************************************************** (event handling B) Lock(EC) advance_transaction() if STS==1 STS=0 EC_SC read ================================================================= (event pending C) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** The event pending for issue 1 (event pending B) can arrive as a next GPE due to the previous IRQ context STS=0 write. And if it is handled by ec_poll() (event handling B), as it is also acknowledged by ec_poll(), the event pending for issue 2 (event pending C) can properly arrive as a next GPE after the task context STS=0 write. So no GPE will be lost and never triggered due to GPE clearing performed in the wrong position. And since all GPE handling is performed after a locked GPE status checking, we can hardly see no-op GPE handler invocations due to issue 1 and 3. We may still see no-op GPE handler invocations due to "Note 1", but as it is inevitable, it needn't be fixed. After applying this patch, with frequent GPE enablings considered: ================================================================= (event pending A) ================================================================= acpi_ec_gpe_handler() acpi_ec_transaction() ***************************************************************** (event handling A) Lock(EC) advance_transaction() if STS==1 STS=0 EC_SC read ================================================================= (event pending B) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** ***************************************************************** (event handling B) Lock(EC) EN=1 if STS==1 advance_transaction() if STS==1 STS=0 EC_SC read ================================================================= (event pending C) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** The event pending for issue 2 can be manually handled by advance_transaction(). And after the STS=0 write performed in the manual triggered advance_transaction(), GPE can always arrive. So no GPE will be lost due to frequent GPE disabling/enabling performed in the driver like issue 4. Note 5: It's ideally when EN=1 write occurred, an IRQ thread should be woken up to handle the GPE when the GPE was raised. But this requires the IRQ thread to contain the poller code for all EC GPE indications, while currently some of the indications are handled in the user tasks. It then is very hard for the code to determine whether a user task should be invoked or the poller work item should be scheduled. So we have to invoke advance_transaction() directly now and it leaves us such a restriction for the GPE re-enabling: it must be performed in the task context to avoid starving the GPEs. As a conclusion: we can see the EC GPE is always handled in serial after deploying the raw GPE handler mode: Lock(EC) if (STS==1) STS=0 EC_SC read EC_SC handled Unlock(EC) The EC driver specific lock is responsible to make the EC GPE handling processes serialized so that EC can handle its GPE from both IRQ and task contexts and the next IRQ can be ensured to arrive after this process. Note 6: We have many EC_FLAGS_MSI qurik users in the current driver. They all seem to be suffering from unexpected GPE triggering source lost. And they are false root caused to a timing issue. Since EC communication protocol has already flow control defined, timing shouldn't be the root cause, while this fix might be fixing the root cause of the old bugs. Link: https://lkml.org/lkml/2014/11/4/974 Link: https://lkml.org/lkml/2014/11/18/316 Link: https://www.spinics.net/lists/linux-acpi/msg54340.html Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-02-05 16:27:22 +08:00
ACPI / EC: Refine command storm prevention support This patch refines EC command storm prevention support. Current command storming code is wrong, when the storming condition is detected, it only flags the condition without doing anything for the current command but performing storming prevention for the follow-up commands. So: 1. The first command which suffers from the storming still suffers from storming. 2. The follow-up commands which may not suffer from the storming are unconditionally forced into the storming prevention mode. Ideally, we should only enable storm prevention immediately after detection for the current command so that the next command can try the power/performance efficient interrupt mode again. This patch improves the command storm prevention by disabling GPE right after the detection and re-enabling it right before completing the command transaction using the GPE storming prevention APIs. This thus deploys the following GPE handling model: 1. acpi_enable_gpe()/acpi_disable_gpe() for reference count changes: This set of APIs are used for EC usage reference counting. 2. acpi_set_gpe(ACPI_GPE_ENABLE)/acpi_set_gpe(ACPI_GPE_DISABLE): This set of APIs are used for preventing GPE storm. They must be invoked when the reference count > 0. Note that as the storming prevention should always happen when there is an outstanding request, or GPE enabling value will be messed up by the races. This patch also adds BUG_ON() to enforces this rule to prevent future bugs. The msleep(1) used after completing a transaction is useless now as this sounds like a guard time only useful for platforms that need the EC_FLAGS_MSI quirks while we have fixed GPE race issues using the previous raw handler mode enabling. It is kept to avoid regressions. A seperate patch which deletes EC_FLAGS_MSI quirks should take care of deleting it. Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-02-06 08:58:05 +08:00
ACPI / EC: Fix several GPE handling issues by deploying ACPI_GPE_DISPATCH_RAW_HANDLER mode. This patch switches EC driver into ACPI_GPE_DISPATCH_RAW_HANDLER mode where the GPE lock is not held for acpi_ec_gpe_handler() and the ACPICA internal GPE enabling/disabling/clearing operations are bypassed so that further improvements are possible with the GPE APIs. There are 2 strong reasons for deploying raw GPE handler mode in the EC driver: 1. Some hardware logics can control their interrupts via their own registers, so their interrupts can be disabled/enabled/acknowledged without using the super IRQ controller provided functions. While there is no mean (EC commands) for the EC driver to achieve this. 2. During suspending, the EC driver is still working for a while to complete the platform firmware provided functionailities using ec_poll() after all GPEs are disabled (see acpi_ec_block_transactions()), which means the EC driver will drive the EC GPE out of the GPE core's control. Without deploying the raw GPE handler mode, we can see many races between the EC driver and the GPE core due to the above restrictions: 1. There is a race condition due to ACPICA internal GPE disabling/clearing/enabling logics in acpi_ev_gpe_dispatch(): Orignally EC GPE is disabled (EN=0), cleared (STS=0) before invoking a GPE handler and re-enabled (EN=1) after invoking a GPE handler in acpi_ev_gpe_dispatch(). When re-enabling appears, GPE may be flagged (STS=1). ================================================================= (event pending A) ================================================================= acpi_ev_gpe_dispatch() ec_poll() EN=0 STS=0 acpi_ec_gpe_handler() ***************************************************************** (event handling A) Lock(EC) advance_transaction() EC_SC read ================================================================= (event pending B) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** ***************************************************************** (event handling B) Lock(EC) advance_transaction() EC_SC read ================================================================= (event pending C) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** EN=1 This race condition is the root cause of different issues on different silicon variations. A. Silicon variation A: On some platforms, GPE will be triggered due to "writing 1 to EN when STS=1". This is because both EN and STS lines are wired to the GPE trigger line. 1. Issue 1: We can see no-op acpi_ec_gpe_handler() invoked on such platforms. This is because: a. event pending B: An event can arrive after ACPICA's GPE clearing performed in acpi_ev_gpe_dispatch(), this event may fail to be detected by EC_SC read that is performed before its arrival; b. event handling B: The event can be handled in ec_poll() because EC lock is released after acpi_ec_gpe_handler() invocation; c. There is no code in ec_poll() to clear STS but the GPE can still be triggered by the EN=1 write performed in acpi_ev_finish_gpe(), this leads to a no-op EC GPE handler invocation; d. As no-op GPE handler invocations are counted by the EC driver to trigger the command storming conditions, the wrong no-op GPE handler invocations thus can easily trigger wrong command storming conditions. Note 1: If we removed GPE disabling/enabling code from acpi_ev_gpe_dispatch(), we could still see no-op GPE handlers triggered by the event arriving after the GPE clearing and before the GPE handling on both silicon variation A and B. This can only occur if the CPU is very slow (timing slice between STS=0 write and EC_SC read should be short enough before hardware sets another GPE indication). Thus this is very rare and is not what we need to fix. B. Silicon variation B: On other platforms, GPE may not be triggered due to "writing 1 to EN when STS=1". This is because only STS line is wired to the GPE trigger line. 2. Issue 2: We can see GPE loss on such platforms. This is because: a. event pending B vs. event handling A: An event can arrive after ACPICA's GPE handling performed in acpi_ev_gpe_dispatch(), or event pending C vs. event handling B: An event can arrive after Linux's GPE handling performed in ec_poll(), these events may fail to be detected by EC_SC read that is performed before their arrival; b. The GPE cannot be triggered by EN=1 write performed in acpi_ev_finish_gpe(); c. If no polling mechanism is implemented in the driver for the pending event (for example, SCI_EVT), this event is lost due to no GPE being triggered. Note 2: On most platforms, there might be another rule that GPE may not be triggered due to "writing 1 to STS when STS=1 and EN=1". Then on silicon variation B, an even worse case is if the issue 2 event loss happens, further events may never trigger GPE again on such platforms due to being blocked by the current STS=1. Unless someone clears STS, all events have to be polled. 2. There is a race condition due to lacking in GPE status checking in EC driver: Originally, GPE status is checked in ACPICA core but not checked in the GPE handler. Thus since the status checking and handling is not locked, it can be interrupted by another handling path. ================================================================= (event pending A) ================================================================= acpi_ev_gpe_detect() ec_poll() if (EN==1 && STS==1) ***************************************************************** (event handling A) Lock(EC) advance_transaction() EC_SC read EC_SC handled Unlock(EC) ***************************************************************** acpi_ev_gpe_dispatch() EN=0 STS=0 acpi_ec_gpe_handler() ***************************************************************** (event handling B) Lock(EC) advance_transaction() EC_SC read Unlock(EC) ***************************************************************** 3. Issue 3: We can see no-op acpi_ec_gpe_handler() invoked on both silicon variation A and B. This is because: a. event pending A: An event can arrive to trigger an EC GPE and ACPICA checks it and is about to invoke the EC GPE handler; b. event handling A: The event can be handled in ec_poll() because EC lock is not held after the GPE status checking; c. event handling B: Then when the EC GPE handler is invoked, it becomes a no-op GPE handler invocation. d. As no-op GPE handler invocations are counted by the EC driver to trigger the command storming conditions, the wrong no-op GPE handler invocations thus can easily trigger wrong command storming conditions. Note 3: This no-op GPE handler invocation is rare because the time between the IRQ arrival and the acpi_ec_gpe_handler() invocation is less than the timeout value waited in ec_poll(). So most of the no-op GPE handler invocations are caused by the reason described in issue 1. 3. There is a race condition due to ACPICA internal GPE clearing logic in acpi_enable_gpe(): During runtime, acpi_enable_gpe() can be invoked by the EC storming prevention code. When it is invoked, GPE may be flagged (STS=1). ================================================================= (event pending A) ================================================================= acpi_ev_gpe_dispatch() acpi_ec_transaction() EN=0 STS=0 acpi_ec_gpe_handler() ***************************************************************** (event handling A) Lock(EC) advance_transaction() EC_SC read EC_SC handled Unlock(EC) ***************************************************************** EN=1 ? Lock(EC) Unlock(EC) ================================================================= (event pending B) ================================================================= acpi_enable_gpe() STS=0 EN=1 4. Issue 4: We can see GPE loss on both silicon variation A and B platforms. This is because: a. event pending B: An event can arrive right before ACPICA's GPE clearing performed in acpi_enable_gpe(); b. If the GPE is cleared when GPE is disabled, then EN=1 write in acpi_enable_gpe() cannot trigger this GPE; c. If no polling mechanism is implemented in the driver for this event (for example, SCI_EVT), this event is lost due to no GPE being triggered. Note 4: Currently we don't have this issue, but after we switch the EC driver into ACPI_GPE_DISPATCH_RAW_HANDLER mode, we need to take care of handling this because the EN=1 write in acpi_ev_gpe_dispatch() will be abandoned. There might be more race issues for the current GPE handler usages. This is because the EC IRQ's enabling/disabling/checking/clearing/handling operations should be locked by a single lock that is under the EC driver's control to achieve the serialization. Which means we need to invoke GPE APIs with EC driver's lock held and all ACPICA internal GPE operations related to the GPE handler should be abandoned. Invoking GPE APIs inside of the EC driver lock and bypassing ACPICA internal GPE operations requires the ACPI_GPE_DISPATCH_RAW_HANDLER mode where the same lock used by the APIs are released prior than invoking the handlers. Otherwise, we can see dead locks due to circular locking dependencies (see Reference below). This patch then switches the EC driver into the ACPI_GPE_DISPATCH_RAW_HANDLER mode so that it can perform correct GPE operations using the GPE APIs: 1. Bypasses EN modifications performed in acpi_ev_gpe_dispatch() by using acpi_install_gpe_raw_handler() and invoking all GPE APIs with EC spin lock held. This can fix issue 1 as it makes a non frequent GPE enabling/disabling environment. 2. Bypasses STS clearing performed in acpi_enable_gpe() by replacing acpi_enable_gpe()/acpi_disable_gpe() with acpi_set_gpe(). This can fix issue 4. And this can also help to fix issue 1 as it makes a no sudden GPE clearing environment when GPE is frequently enabled/disabled. 3. Ensures STS acknowledged before handling by invoking acpi_clear_gpe() in advance_transaction(). This can finally fix issue 1 even in a frequent GPE enabling/disabling environment. And this can also finally fix issue 3 when issue 2 is fixed. Note 3: GPE clearing is edge triggered W1C, which means we can clear it right before handling it. Since all EC GPE indications are handled in advance_transaction() by previous commits, we can now move GPE clearing into it to implement the correct GPE clearing. Note 4: We can use acpi_set_gpe() which is not shared GPE safer instead of acpi_enable_gpe()/acpi_disable_gpe() because EC GPE is not shared by other hardware, which is mentioned in the ACPI specification 5.0, 12.6 Interrupt Model: "OSPM driver treats this as an edge event (the EC SCI cannot be shared)". So we can stop using shared GPE safer APIs acpi_enable_gpe()/acpi_disable_gpe() in the EC driver. Otherwise cleanups need to be made in acpi_ev_enable_gpe() to bypass the GPE clearing logic before keeping acpi_enable_gpe(). This patch also invokes advance_transaction() when GPE is re-enabled in the task context which: 1. Ensures EN=1 can trigger GPE by checking and handling EC status register right after EN=1 writes. This can fix issue 2. After applying this patch, without frequent GPE enablings considered: ================================================================= (event pending A) ================================================================= acpi_ec_gpe_handler() ec_poll() ***************************************************************** (event handling A) Lock(EC) advance_transaction() if STS==1 STS=0 EC_SC read ================================================================= (event pending B) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** ***************************************************************** (event handling B) Lock(EC) advance_transaction() if STS==1 STS=0 EC_SC read ================================================================= (event pending C) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** The event pending for issue 1 (event pending B) can arrive as a next GPE due to the previous IRQ context STS=0 write. And if it is handled by ec_poll() (event handling B), as it is also acknowledged by ec_poll(), the event pending for issue 2 (event pending C) can properly arrive as a next GPE after the task context STS=0 write. So no GPE will be lost and never triggered due to GPE clearing performed in the wrong position. And since all GPE handling is performed after a locked GPE status checking, we can hardly see no-op GPE handler invocations due to issue 1 and 3. We may still see no-op GPE handler invocations due to "Note 1", but as it is inevitable, it needn't be fixed. After applying this patch, with frequent GPE enablings considered: ================================================================= (event pending A) ================================================================= acpi_ec_gpe_handler() acpi_ec_transaction() ***************************************************************** (event handling A) Lock(EC) advance_transaction() if STS==1 STS=0 EC_SC read ================================================================= (event pending B) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** ***************************************************************** (event handling B) Lock(EC) EN=1 if STS==1 advance_transaction() if STS==1 STS=0 EC_SC read ================================================================= (event pending C) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** The event pending for issue 2 can be manually handled by advance_transaction(). And after the STS=0 write performed in the manual triggered advance_transaction(), GPE can always arrive. So no GPE will be lost due to frequent GPE disabling/enabling performed in the driver like issue 4. Note 5: It's ideally when EN=1 write occurred, an IRQ thread should be woken up to handle the GPE when the GPE was raised. But this requires the IRQ thread to contain the poller code for all EC GPE indications, while currently some of the indications are handled in the user tasks. It then is very hard for the code to determine whether a user task should be invoked or the poller work item should be scheduled. So we have to invoke advance_transaction() directly now and it leaves us such a restriction for the GPE re-enabling: it must be performed in the task context to avoid starving the GPEs. As a conclusion: we can see the EC GPE is always handled in serial after deploying the raw GPE handler mode: Lock(EC) if (STS==1) STS=0 EC_SC read EC_SC handled Unlock(EC) The EC driver specific lock is responsible to make the EC GPE handling processes serialized so that EC can handle its GPE from both IRQ and task contexts and the next IRQ can be ensured to arrive after this process. Note 6: We have many EC_FLAGS_MSI qurik users in the current driver. They all seem to be suffering from unexpected GPE triggering source lost. And they are false root caused to a timing issue. Since EC communication protocol has already flow control defined, timing shouldn't be the root cause, while this fix might be fixing the root cause of the old bugs. Link: https://lkml.org/lkml/2014/11/4/974 Link: https://lkml.org/lkml/2014/11/18/316 Link: https://www.spinics.net/lists/linux-acpi/msg54340.html Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-02-05 16:27:22 +08:00
ACPI / EC: Refine command storm prevention support This patch refines EC command storm prevention support. Current command storming code is wrong, when the storming condition is detected, it only flags the condition without doing anything for the current command but performing storming prevention for the follow-up commands. So: 1. The first command which suffers from the storming still suffers from storming. 2. The follow-up commands which may not suffer from the storming are unconditionally forced into the storming prevention mode. Ideally, we should only enable storm prevention immediately after detection for the current command so that the next command can try the power/performance efficient interrupt mode again. This patch improves the command storm prevention by disabling GPE right after the detection and re-enabling it right before completing the command transaction using the GPE storming prevention APIs. This thus deploys the following GPE handling model: 1. acpi_enable_gpe()/acpi_disable_gpe() for reference count changes: This set of APIs are used for EC usage reference counting. 2. acpi_set_gpe(ACPI_GPE_ENABLE)/acpi_set_gpe(ACPI_GPE_DISABLE): This set of APIs are used for preventing GPE storm. They must be invoked when the reference count > 0. Note that as the storming prevention should always happen when there is an outstanding request, or GPE enabling value will be messed up by the races. This patch also adds BUG_ON() to enforces this rule to prevent future bugs. The msleep(1) used after completing a transaction is useless now as this sounds like a guard time only useful for platforms that need the EC_FLAGS_MSI quirks while we have fixed GPE race issues using the previous raw handler mode enabling. It is kept to avoid regressions. A seperate patch which deletes EC_FLAGS_MSI quirks should take care of deleting it. Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-02-06 08:58:05 +08:00
ACPI / EC: Fix several GPE handling issues by deploying ACPI_GPE_DISPATCH_RAW_HANDLER mode. This patch switches EC driver into ACPI_GPE_DISPATCH_RAW_HANDLER mode where the GPE lock is not held for acpi_ec_gpe_handler() and the ACPICA internal GPE enabling/disabling/clearing operations are bypassed so that further improvements are possible with the GPE APIs. There are 2 strong reasons for deploying raw GPE handler mode in the EC driver: 1. Some hardware logics can control their interrupts via their own registers, so their interrupts can be disabled/enabled/acknowledged without using the super IRQ controller provided functions. While there is no mean (EC commands) for the EC driver to achieve this. 2. During suspending, the EC driver is still working for a while to complete the platform firmware provided functionailities using ec_poll() after all GPEs are disabled (see acpi_ec_block_transactions()), which means the EC driver will drive the EC GPE out of the GPE core's control. Without deploying the raw GPE handler mode, we can see many races between the EC driver and the GPE core due to the above restrictions: 1. There is a race condition due to ACPICA internal GPE disabling/clearing/enabling logics in acpi_ev_gpe_dispatch(): Orignally EC GPE is disabled (EN=0), cleared (STS=0) before invoking a GPE handler and re-enabled (EN=1) after invoking a GPE handler in acpi_ev_gpe_dispatch(). When re-enabling appears, GPE may be flagged (STS=1). ================================================================= (event pending A) ================================================================= acpi_ev_gpe_dispatch() ec_poll() EN=0 STS=0 acpi_ec_gpe_handler() ***************************************************************** (event handling A) Lock(EC) advance_transaction() EC_SC read ================================================================= (event pending B) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** ***************************************************************** (event handling B) Lock(EC) advance_transaction() EC_SC read ================================================================= (event pending C) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** EN=1 This race condition is the root cause of different issues on different silicon variations. A. Silicon variation A: On some platforms, GPE will be triggered due to "writing 1 to EN when STS=1". This is because both EN and STS lines are wired to the GPE trigger line. 1. Issue 1: We can see no-op acpi_ec_gpe_handler() invoked on such platforms. This is because: a. event pending B: An event can arrive after ACPICA's GPE clearing performed in acpi_ev_gpe_dispatch(), this event may fail to be detected by EC_SC read that is performed before its arrival; b. event handling B: The event can be handled in ec_poll() because EC lock is released after acpi_ec_gpe_handler() invocation; c. There is no code in ec_poll() to clear STS but the GPE can still be triggered by the EN=1 write performed in acpi_ev_finish_gpe(), this leads to a no-op EC GPE handler invocation; d. As no-op GPE handler invocations are counted by the EC driver to trigger the command storming conditions, the wrong no-op GPE handler invocations thus can easily trigger wrong command storming conditions. Note 1: If we removed GPE disabling/enabling code from acpi_ev_gpe_dispatch(), we could still see no-op GPE handlers triggered by the event arriving after the GPE clearing and before the GPE handling on both silicon variation A and B. This can only occur if the CPU is very slow (timing slice between STS=0 write and EC_SC read should be short enough before hardware sets another GPE indication). Thus this is very rare and is not what we need to fix. B. Silicon variation B: On other platforms, GPE may not be triggered due to "writing 1 to EN when STS=1". This is because only STS line is wired to the GPE trigger line. 2. Issue 2: We can see GPE loss on such platforms. This is because: a. event pending B vs. event handling A: An event can arrive after ACPICA's GPE handling performed in acpi_ev_gpe_dispatch(), or event pending C vs. event handling B: An event can arrive after Linux's GPE handling performed in ec_poll(), these events may fail to be detected by EC_SC read that is performed before their arrival; b. The GPE cannot be triggered by EN=1 write performed in acpi_ev_finish_gpe(); c. If no polling mechanism is implemented in the driver for the pending event (for example, SCI_EVT), this event is lost due to no GPE being triggered. Note 2: On most platforms, there might be another rule that GPE may not be triggered due to "writing 1 to STS when STS=1 and EN=1". Then on silicon variation B, an even worse case is if the issue 2 event loss happens, further events may never trigger GPE again on such platforms due to being blocked by the current STS=1. Unless someone clears STS, all events have to be polled. 2. There is a race condition due to lacking in GPE status checking in EC driver: Originally, GPE status is checked in ACPICA core but not checked in the GPE handler. Thus since the status checking and handling is not locked, it can be interrupted by another handling path. ================================================================= (event pending A) ================================================================= acpi_ev_gpe_detect() ec_poll() if (EN==1 && STS==1) ***************************************************************** (event handling A) Lock(EC) advance_transaction() EC_SC read EC_SC handled Unlock(EC) ***************************************************************** acpi_ev_gpe_dispatch() EN=0 STS=0 acpi_ec_gpe_handler() ***************************************************************** (event handling B) Lock(EC) advance_transaction() EC_SC read Unlock(EC) ***************************************************************** 3. Issue 3: We can see no-op acpi_ec_gpe_handler() invoked on both silicon variation A and B. This is because: a. event pending A: An event can arrive to trigger an EC GPE and ACPICA checks it and is about to invoke the EC GPE handler; b. event handling A: The event can be handled in ec_poll() because EC lock is not held after the GPE status checking; c. event handling B: Then when the EC GPE handler is invoked, it becomes a no-op GPE handler invocation. d. As no-op GPE handler invocations are counted by the EC driver to trigger the command storming conditions, the wrong no-op GPE handler invocations thus can easily trigger wrong command storming conditions. Note 3: This no-op GPE handler invocation is rare because the time between the IRQ arrival and the acpi_ec_gpe_handler() invocation is less than the timeout value waited in ec_poll(). So most of the no-op GPE handler invocations are caused by the reason described in issue 1. 3. There is a race condition due to ACPICA internal GPE clearing logic in acpi_enable_gpe(): During runtime, acpi_enable_gpe() can be invoked by the EC storming prevention code. When it is invoked, GPE may be flagged (STS=1). ================================================================= (event pending A) ================================================================= acpi_ev_gpe_dispatch() acpi_ec_transaction() EN=0 STS=0 acpi_ec_gpe_handler() ***************************************************************** (event handling A) Lock(EC) advance_transaction() EC_SC read EC_SC handled Unlock(EC) ***************************************************************** EN=1 ? Lock(EC) Unlock(EC) ================================================================= (event pending B) ================================================================= acpi_enable_gpe() STS=0 EN=1 4. Issue 4: We can see GPE loss on both silicon variation A and B platforms. This is because: a. event pending B: An event can arrive right before ACPICA's GPE clearing performed in acpi_enable_gpe(); b. If the GPE is cleared when GPE is disabled, then EN=1 write in acpi_enable_gpe() cannot trigger this GPE; c. If no polling mechanism is implemented in the driver for this event (for example, SCI_EVT), this event is lost due to no GPE being triggered. Note 4: Currently we don't have this issue, but after we switch the EC driver into ACPI_GPE_DISPATCH_RAW_HANDLER mode, we need to take care of handling this because the EN=1 write in acpi_ev_gpe_dispatch() will be abandoned. There might be more race issues for the current GPE handler usages. This is because the EC IRQ's enabling/disabling/checking/clearing/handling operations should be locked by a single lock that is under the EC driver's control to achieve the serialization. Which means we need to invoke GPE APIs with EC driver's lock held and all ACPICA internal GPE operations related to the GPE handler should be abandoned. Invoking GPE APIs inside of the EC driver lock and bypassing ACPICA internal GPE operations requires the ACPI_GPE_DISPATCH_RAW_HANDLER mode where the same lock used by the APIs are released prior than invoking the handlers. Otherwise, we can see dead locks due to circular locking dependencies (see Reference below). This patch then switches the EC driver into the ACPI_GPE_DISPATCH_RAW_HANDLER mode so that it can perform correct GPE operations using the GPE APIs: 1. Bypasses EN modifications performed in acpi_ev_gpe_dispatch() by using acpi_install_gpe_raw_handler() and invoking all GPE APIs with EC spin lock held. This can fix issue 1 as it makes a non frequent GPE enabling/disabling environment. 2. Bypasses STS clearing performed in acpi_enable_gpe() by replacing acpi_enable_gpe()/acpi_disable_gpe() with acpi_set_gpe(). This can fix issue 4. And this can also help to fix issue 1 as it makes a no sudden GPE clearing environment when GPE is frequently enabled/disabled. 3. Ensures STS acknowledged before handling by invoking acpi_clear_gpe() in advance_transaction(). This can finally fix issue 1 even in a frequent GPE enabling/disabling environment. And this can also finally fix issue 3 when issue 2 is fixed. Note 3: GPE clearing is edge triggered W1C, which means we can clear it right before handling it. Since all EC GPE indications are handled in advance_transaction() by previous commits, we can now move GPE clearing into it to implement the correct GPE clearing. Note 4: We can use acpi_set_gpe() which is not shared GPE safer instead of acpi_enable_gpe()/acpi_disable_gpe() because EC GPE is not shared by other hardware, which is mentioned in the ACPI specification 5.0, 12.6 Interrupt Model: "OSPM driver treats this as an edge event (the EC SCI cannot be shared)". So we can stop using shared GPE safer APIs acpi_enable_gpe()/acpi_disable_gpe() in the EC driver. Otherwise cleanups need to be made in acpi_ev_enable_gpe() to bypass the GPE clearing logic before keeping acpi_enable_gpe(). This patch also invokes advance_transaction() when GPE is re-enabled in the task context which: 1. Ensures EN=1 can trigger GPE by checking and handling EC status register right after EN=1 writes. This can fix issue 2. After applying this patch, without frequent GPE enablings considered: ================================================================= (event pending A) ================================================================= acpi_ec_gpe_handler() ec_poll() ***************************************************************** (event handling A) Lock(EC) advance_transaction() if STS==1 STS=0 EC_SC read ================================================================= (event pending B) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** ***************************************************************** (event handling B) Lock(EC) advance_transaction() if STS==1 STS=0 EC_SC read ================================================================= (event pending C) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** The event pending for issue 1 (event pending B) can arrive as a next GPE due to the previous IRQ context STS=0 write. And if it is handled by ec_poll() (event handling B), as it is also acknowledged by ec_poll(), the event pending for issue 2 (event pending C) can properly arrive as a next GPE after the task context STS=0 write. So no GPE will be lost and never triggered due to GPE clearing performed in the wrong position. And since all GPE handling is performed after a locked GPE status checking, we can hardly see no-op GPE handler invocations due to issue 1 and 3. We may still see no-op GPE handler invocations due to "Note 1", but as it is inevitable, it needn't be fixed. After applying this patch, with frequent GPE enablings considered: ================================================================= (event pending A) ================================================================= acpi_ec_gpe_handler() acpi_ec_transaction() ***************************************************************** (event handling A) Lock(EC) advance_transaction() if STS==1 STS=0 EC_SC read ================================================================= (event pending B) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** ***************************************************************** (event handling B) Lock(EC) EN=1 if STS==1 advance_transaction() if STS==1 STS=0 EC_SC read ================================================================= (event pending C) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** The event pending for issue 2 can be manually handled by advance_transaction(). And after the STS=0 write performed in the manual triggered advance_transaction(), GPE can always arrive. So no GPE will be lost due to frequent GPE disabling/enabling performed in the driver like issue 4. Note 5: It's ideally when EN=1 write occurred, an IRQ thread should be woken up to handle the GPE when the GPE was raised. But this requires the IRQ thread to contain the poller code for all EC GPE indications, while currently some of the indications are handled in the user tasks. It then is very hard for the code to determine whether a user task should be invoked or the poller work item should be scheduled. So we have to invoke advance_transaction() directly now and it leaves us such a restriction for the GPE re-enabling: it must be performed in the task context to avoid starving the GPEs. As a conclusion: we can see the EC GPE is always handled in serial after deploying the raw GPE handler mode: Lock(EC) if (STS==1) STS=0 EC_SC read EC_SC handled Unlock(EC) The EC driver specific lock is responsible to make the EC GPE handling processes serialized so that EC can handle its GPE from both IRQ and task contexts and the next IRQ can be ensured to arrive after this process. Note 6: We have many EC_FLAGS_MSI qurik users in the current driver. They all seem to be suffering from unexpected GPE triggering source lost. And they are false root caused to a timing issue. Since EC communication protocol has already flow control defined, timing shouldn't be the root cause, while this fix might be fixing the root cause of the old bugs. Link: https://lkml.org/lkml/2014/11/4/974 Link: https://lkml.org/lkml/2014/11/18/316 Link: https://www.spinics.net/lists/linux-acpi/msg54340.html Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-02-05 16:27:22 +08:00
ACPI / EC: Fix several GPE handling issues by deploying ACPI_GPE_DISPATCH_RAW_HANDLER mode. This patch switches EC driver into ACPI_GPE_DISPATCH_RAW_HANDLER mode where the GPE lock is not held for acpi_ec_gpe_handler() and the ACPICA internal GPE enabling/disabling/clearing operations are bypassed so that further improvements are possible with the GPE APIs. There are 2 strong reasons for deploying raw GPE handler mode in the EC driver: 1. Some hardware logics can control their interrupts via their own registers, so their interrupts can be disabled/enabled/acknowledged without using the super IRQ controller provided functions. While there is no mean (EC commands) for the EC driver to achieve this. 2. During suspending, the EC driver is still working for a while to complete the platform firmware provided functionailities using ec_poll() after all GPEs are disabled (see acpi_ec_block_transactions()), which means the EC driver will drive the EC GPE out of the GPE core's control. Without deploying the raw GPE handler mode, we can see many races between the EC driver and the GPE core due to the above restrictions: 1. There is a race condition due to ACPICA internal GPE disabling/clearing/enabling logics in acpi_ev_gpe_dispatch(): Orignally EC GPE is disabled (EN=0), cleared (STS=0) before invoking a GPE handler and re-enabled (EN=1) after invoking a GPE handler in acpi_ev_gpe_dispatch(). When re-enabling appears, GPE may be flagged (STS=1). ================================================================= (event pending A) ================================================================= acpi_ev_gpe_dispatch() ec_poll() EN=0 STS=0 acpi_ec_gpe_handler() ***************************************************************** (event handling A) Lock(EC) advance_transaction() EC_SC read ================================================================= (event pending B) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** ***************************************************************** (event handling B) Lock(EC) advance_transaction() EC_SC read ================================================================= (event pending C) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** EN=1 This race condition is the root cause of different issues on different silicon variations. A. Silicon variation A: On some platforms, GPE will be triggered due to "writing 1 to EN when STS=1". This is because both EN and STS lines are wired to the GPE trigger line. 1. Issue 1: We can see no-op acpi_ec_gpe_handler() invoked on such platforms. This is because: a. event pending B: An event can arrive after ACPICA's GPE clearing performed in acpi_ev_gpe_dispatch(), this event may fail to be detected by EC_SC read that is performed before its arrival; b. event handling B: The event can be handled in ec_poll() because EC lock is released after acpi_ec_gpe_handler() invocation; c. There is no code in ec_poll() to clear STS but the GPE can still be triggered by the EN=1 write performed in acpi_ev_finish_gpe(), this leads to a no-op EC GPE handler invocation; d. As no-op GPE handler invocations are counted by the EC driver to trigger the command storming conditions, the wrong no-op GPE handler invocations thus can easily trigger wrong command storming conditions. Note 1: If we removed GPE disabling/enabling code from acpi_ev_gpe_dispatch(), we could still see no-op GPE handlers triggered by the event arriving after the GPE clearing and before the GPE handling on both silicon variation A and B. This can only occur if the CPU is very slow (timing slice between STS=0 write and EC_SC read should be short enough before hardware sets another GPE indication). Thus this is very rare and is not what we need to fix. B. Silicon variation B: On other platforms, GPE may not be triggered due to "writing 1 to EN when STS=1". This is because only STS line is wired to the GPE trigger line. 2. Issue 2: We can see GPE loss on such platforms. This is because: a. event pending B vs. event handling A: An event can arrive after ACPICA's GPE handling performed in acpi_ev_gpe_dispatch(), or event pending C vs. event handling B: An event can arrive after Linux's GPE handling performed in ec_poll(), these events may fail to be detected by EC_SC read that is performed before their arrival; b. The GPE cannot be triggered by EN=1 write performed in acpi_ev_finish_gpe(); c. If no polling mechanism is implemented in the driver for the pending event (for example, SCI_EVT), this event is lost due to no GPE being triggered. Note 2: On most platforms, there might be another rule that GPE may not be triggered due to "writing 1 to STS when STS=1 and EN=1". Then on silicon variation B, an even worse case is if the issue 2 event loss happens, further events may never trigger GPE again on such platforms due to being blocked by the current STS=1. Unless someone clears STS, all events have to be polled. 2. There is a race condition due to lacking in GPE status checking in EC driver: Originally, GPE status is checked in ACPICA core but not checked in the GPE handler. Thus since the status checking and handling is not locked, it can be interrupted by another handling path. ================================================================= (event pending A) ================================================================= acpi_ev_gpe_detect() ec_poll() if (EN==1 && STS==1) ***************************************************************** (event handling A) Lock(EC) advance_transaction() EC_SC read EC_SC handled Unlock(EC) ***************************************************************** acpi_ev_gpe_dispatch() EN=0 STS=0 acpi_ec_gpe_handler() ***************************************************************** (event handling B) Lock(EC) advance_transaction() EC_SC read Unlock(EC) ***************************************************************** 3. Issue 3: We can see no-op acpi_ec_gpe_handler() invoked on both silicon variation A and B. This is because: a. event pending A: An event can arrive to trigger an EC GPE and ACPICA checks it and is about to invoke the EC GPE handler; b. event handling A: The event can be handled in ec_poll() because EC lock is not held after the GPE status checking; c. event handling B: Then when the EC GPE handler is invoked, it becomes a no-op GPE handler invocation. d. As no-op GPE handler invocations are counted by the EC driver to trigger the command storming conditions, the wrong no-op GPE handler invocations thus can easily trigger wrong command storming conditions. Note 3: This no-op GPE handler invocation is rare because the time between the IRQ arrival and the acpi_ec_gpe_handler() invocation is less than the timeout value waited in ec_poll(). So most of the no-op GPE handler invocations are caused by the reason described in issue 1. 3. There is a race condition due to ACPICA internal GPE clearing logic in acpi_enable_gpe(): During runtime, acpi_enable_gpe() can be invoked by the EC storming prevention code. When it is invoked, GPE may be flagged (STS=1). ================================================================= (event pending A) ================================================================= acpi_ev_gpe_dispatch() acpi_ec_transaction() EN=0 STS=0 acpi_ec_gpe_handler() ***************************************************************** (event handling A) Lock(EC) advance_transaction() EC_SC read EC_SC handled Unlock(EC) ***************************************************************** EN=1 ? Lock(EC) Unlock(EC) ================================================================= (event pending B) ================================================================= acpi_enable_gpe() STS=0 EN=1 4. Issue 4: We can see GPE loss on both silicon variation A and B platforms. This is because: a. event pending B: An event can arrive right before ACPICA's GPE clearing performed in acpi_enable_gpe(); b. If the GPE is cleared when GPE is disabled, then EN=1 write in acpi_enable_gpe() cannot trigger this GPE; c. If no polling mechanism is implemented in the driver for this event (for example, SCI_EVT), this event is lost due to no GPE being triggered. Note 4: Currently we don't have this issue, but after we switch the EC driver into ACPI_GPE_DISPATCH_RAW_HANDLER mode, we need to take care of handling this because the EN=1 write in acpi_ev_gpe_dispatch() will be abandoned. There might be more race issues for the current GPE handler usages. This is because the EC IRQ's enabling/disabling/checking/clearing/handling operations should be locked by a single lock that is under the EC driver's control to achieve the serialization. Which means we need to invoke GPE APIs with EC driver's lock held and all ACPICA internal GPE operations related to the GPE handler should be abandoned. Invoking GPE APIs inside of the EC driver lock and bypassing ACPICA internal GPE operations requires the ACPI_GPE_DISPATCH_RAW_HANDLER mode where the same lock used by the APIs are released prior than invoking the handlers. Otherwise, we can see dead locks due to circular locking dependencies (see Reference below). This patch then switches the EC driver into the ACPI_GPE_DISPATCH_RAW_HANDLER mode so that it can perform correct GPE operations using the GPE APIs: 1. Bypasses EN modifications performed in acpi_ev_gpe_dispatch() by using acpi_install_gpe_raw_handler() and invoking all GPE APIs with EC spin lock held. This can fix issue 1 as it makes a non frequent GPE enabling/disabling environment. 2. Bypasses STS clearing performed in acpi_enable_gpe() by replacing acpi_enable_gpe()/acpi_disable_gpe() with acpi_set_gpe(). This can fix issue 4. And this can also help to fix issue 1 as it makes a no sudden GPE clearing environment when GPE is frequently enabled/disabled. 3. Ensures STS acknowledged before handling by invoking acpi_clear_gpe() in advance_transaction(). This can finally fix issue 1 even in a frequent GPE enabling/disabling environment. And this can also finally fix issue 3 when issue 2 is fixed. Note 3: GPE clearing is edge triggered W1C, which means we can clear it right before handling it. Since all EC GPE indications are handled in advance_transaction() by previous commits, we can now move GPE clearing into it to implement the correct GPE clearing. Note 4: We can use acpi_set_gpe() which is not shared GPE safer instead of acpi_enable_gpe()/acpi_disable_gpe() because EC GPE is not shared by other hardware, which is mentioned in the ACPI specification 5.0, 12.6 Interrupt Model: "OSPM driver treats this as an edge event (the EC SCI cannot be shared)". So we can stop using shared GPE safer APIs acpi_enable_gpe()/acpi_disable_gpe() in the EC driver. Otherwise cleanups need to be made in acpi_ev_enable_gpe() to bypass the GPE clearing logic before keeping acpi_enable_gpe(). This patch also invokes advance_transaction() when GPE is re-enabled in the task context which: 1. Ensures EN=1 can trigger GPE by checking and handling EC status register right after EN=1 writes. This can fix issue 2. After applying this patch, without frequent GPE enablings considered: ================================================================= (event pending A) ================================================================= acpi_ec_gpe_handler() ec_poll() ***************************************************************** (event handling A) Lock(EC) advance_transaction() if STS==1 STS=0 EC_SC read ================================================================= (event pending B) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** ***************************************************************** (event handling B) Lock(EC) advance_transaction() if STS==1 STS=0 EC_SC read ================================================================= (event pending C) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** The event pending for issue 1 (event pending B) can arrive as a next GPE due to the previous IRQ context STS=0 write. And if it is handled by ec_poll() (event handling B), as it is also acknowledged by ec_poll(), the event pending for issue 2 (event pending C) can properly arrive as a next GPE after the task context STS=0 write. So no GPE will be lost and never triggered due to GPE clearing performed in the wrong position. And since all GPE handling is performed after a locked GPE status checking, we can hardly see no-op GPE handler invocations due to issue 1 and 3. We may still see no-op GPE handler invocations due to "Note 1", but as it is inevitable, it needn't be fixed. After applying this patch, with frequent GPE enablings considered: ================================================================= (event pending A) ================================================================= acpi_ec_gpe_handler() acpi_ec_transaction() ***************************************************************** (event handling A) Lock(EC) advance_transaction() if STS==1 STS=0 EC_SC read ================================================================= (event pending B) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** ***************************************************************** (event handling B) Lock(EC) EN=1 if STS==1 advance_transaction() if STS==1 STS=0 EC_SC read ================================================================= (event pending C) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** The event pending for issue 2 can be manually handled by advance_transaction(). And after the STS=0 write performed in the manual triggered advance_transaction(), GPE can always arrive. So no GPE will be lost due to frequent GPE disabling/enabling performed in the driver like issue 4. Note 5: It's ideally when EN=1 write occurred, an IRQ thread should be woken up to handle the GPE when the GPE was raised. But this requires the IRQ thread to contain the poller code for all EC GPE indications, while currently some of the indications are handled in the user tasks. It then is very hard for the code to determine whether a user task should be invoked or the poller work item should be scheduled. So we have to invoke advance_transaction() directly now and it leaves us such a restriction for the GPE re-enabling: it must be performed in the task context to avoid starving the GPEs. As a conclusion: we can see the EC GPE is always handled in serial after deploying the raw GPE handler mode: Lock(EC) if (STS==1) STS=0 EC_SC read EC_SC handled Unlock(EC) The EC driver specific lock is responsible to make the EC GPE handling processes serialized so that EC can handle its GPE from both IRQ and task contexts and the next IRQ can be ensured to arrive after this process. Note 6: We have many EC_FLAGS_MSI qurik users in the current driver. They all seem to be suffering from unexpected GPE triggering source lost. And they are false root caused to a timing issue. Since EC communication protocol has already flow control defined, timing shouldn't be the root cause, while this fix might be fixing the root cause of the old bugs. Link: https://lkml.org/lkml/2014/11/4/974 Link: https://lkml.org/lkml/2014/11/18/316 Link: https://www.spinics.net/lists/linux-acpi/msg54340.html Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-02-05 16:27:22 +08:00
ACPI / EC: Refine command storm prevention support This patch refines EC command storm prevention support. Current command storming code is wrong, when the storming condition is detected, it only flags the condition without doing anything for the current command but performing storming prevention for the follow-up commands. So: 1. The first command which suffers from the storming still suffers from storming. 2. The follow-up commands which may not suffer from the storming are unconditionally forced into the storming prevention mode. Ideally, we should only enable storm prevention immediately after detection for the current command so that the next command can try the power/performance efficient interrupt mode again. This patch improves the command storm prevention by disabling GPE right after the detection and re-enabling it right before completing the command transaction using the GPE storming prevention APIs. This thus deploys the following GPE handling model: 1. acpi_enable_gpe()/acpi_disable_gpe() for reference count changes: This set of APIs are used for EC usage reference counting. 2. acpi_set_gpe(ACPI_GPE_ENABLE)/acpi_set_gpe(ACPI_GPE_DISABLE): This set of APIs are used for preventing GPE storm. They must be invoked when the reference count > 0. Note that as the storming prevention should always happen when there is an outstanding request, or GPE enabling value will be messed up by the races. This patch also adds BUG_ON() to enforces this rule to prevent future bugs. The msleep(1) used after completing a transaction is useless now as this sounds like a guard time only useful for platforms that need the EC_FLAGS_MSI quirks while we have fixed GPE race issues using the previous raw handler mode enabling. It is kept to avoid regressions. A seperate patch which deletes EC_FLAGS_MSI quirks should take care of deleting it. Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-02-06 08:58:05 +08:00
ACPI / EC: Fix several GPE handling issues by deploying ACPI_GPE_DISPATCH_RAW_HANDLER mode. This patch switches EC driver into ACPI_GPE_DISPATCH_RAW_HANDLER mode where the GPE lock is not held for acpi_ec_gpe_handler() and the ACPICA internal GPE enabling/disabling/clearing operations are bypassed so that further improvements are possible with the GPE APIs. There are 2 strong reasons for deploying raw GPE handler mode in the EC driver: 1. Some hardware logics can control their interrupts via their own registers, so their interrupts can be disabled/enabled/acknowledged without using the super IRQ controller provided functions. While there is no mean (EC commands) for the EC driver to achieve this. 2. During suspending, the EC driver is still working for a while to complete the platform firmware provided functionailities using ec_poll() after all GPEs are disabled (see acpi_ec_block_transactions()), which means the EC driver will drive the EC GPE out of the GPE core's control. Without deploying the raw GPE handler mode, we can see many races between the EC driver and the GPE core due to the above restrictions: 1. There is a race condition due to ACPICA internal GPE disabling/clearing/enabling logics in acpi_ev_gpe_dispatch(): Orignally EC GPE is disabled (EN=0), cleared (STS=0) before invoking a GPE handler and re-enabled (EN=1) after invoking a GPE handler in acpi_ev_gpe_dispatch(). When re-enabling appears, GPE may be flagged (STS=1). ================================================================= (event pending A) ================================================================= acpi_ev_gpe_dispatch() ec_poll() EN=0 STS=0 acpi_ec_gpe_handler() ***************************************************************** (event handling A) Lock(EC) advance_transaction() EC_SC read ================================================================= (event pending B) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** ***************************************************************** (event handling B) Lock(EC) advance_transaction() EC_SC read ================================================================= (event pending C) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** EN=1 This race condition is the root cause of different issues on different silicon variations. A. Silicon variation A: On some platforms, GPE will be triggered due to "writing 1 to EN when STS=1". This is because both EN and STS lines are wired to the GPE trigger line. 1. Issue 1: We can see no-op acpi_ec_gpe_handler() invoked on such platforms. This is because: a. event pending B: An event can arrive after ACPICA's GPE clearing performed in acpi_ev_gpe_dispatch(), this event may fail to be detected by EC_SC read that is performed before its arrival; b. event handling B: The event can be handled in ec_poll() because EC lock is released after acpi_ec_gpe_handler() invocation; c. There is no code in ec_poll() to clear STS but the GPE can still be triggered by the EN=1 write performed in acpi_ev_finish_gpe(), this leads to a no-op EC GPE handler invocation; d. As no-op GPE handler invocations are counted by the EC driver to trigger the command storming conditions, the wrong no-op GPE handler invocations thus can easily trigger wrong command storming conditions. Note 1: If we removed GPE disabling/enabling code from acpi_ev_gpe_dispatch(), we could still see no-op GPE handlers triggered by the event arriving after the GPE clearing and before the GPE handling on both silicon variation A and B. This can only occur if the CPU is very slow (timing slice between STS=0 write and EC_SC read should be short enough before hardware sets another GPE indication). Thus this is very rare and is not what we need to fix. B. Silicon variation B: On other platforms, GPE may not be triggered due to "writing 1 to EN when STS=1". This is because only STS line is wired to the GPE trigger line. 2. Issue 2: We can see GPE loss on such platforms. This is because: a. event pending B vs. event handling A: An event can arrive after ACPICA's GPE handling performed in acpi_ev_gpe_dispatch(), or event pending C vs. event handling B: An event can arrive after Linux's GPE handling performed in ec_poll(), these events may fail to be detected by EC_SC read that is performed before their arrival; b. The GPE cannot be triggered by EN=1 write performed in acpi_ev_finish_gpe(); c. If no polling mechanism is implemented in the driver for the pending event (for example, SCI_EVT), this event is lost due to no GPE being triggered. Note 2: On most platforms, there might be another rule that GPE may not be triggered due to "writing 1 to STS when STS=1 and EN=1". Then on silicon variation B, an even worse case is if the issue 2 event loss happens, further events may never trigger GPE again on such platforms due to being blocked by the current STS=1. Unless someone clears STS, all events have to be polled. 2. There is a race condition due to lacking in GPE status checking in EC driver: Originally, GPE status is checked in ACPICA core but not checked in the GPE handler. Thus since the status checking and handling is not locked, it can be interrupted by another handling path. ================================================================= (event pending A) ================================================================= acpi_ev_gpe_detect() ec_poll() if (EN==1 && STS==1) ***************************************************************** (event handling A) Lock(EC) advance_transaction() EC_SC read EC_SC handled Unlock(EC) ***************************************************************** acpi_ev_gpe_dispatch() EN=0 STS=0 acpi_ec_gpe_handler() ***************************************************************** (event handling B) Lock(EC) advance_transaction() EC_SC read Unlock(EC) ***************************************************************** 3. Issue 3: We can see no-op acpi_ec_gpe_handler() invoked on both silicon variation A and B. This is because: a. event pending A: An event can arrive to trigger an EC GPE and ACPICA checks it and is about to invoke the EC GPE handler; b. event handling A: The event can be handled in ec_poll() because EC lock is not held after the GPE status checking; c. event handling B: Then when the EC GPE handler is invoked, it becomes a no-op GPE handler invocation. d. As no-op GPE handler invocations are counted by the EC driver to trigger the command storming conditions, the wrong no-op GPE handler invocations thus can easily trigger wrong command storming conditions. Note 3: This no-op GPE handler invocation is rare because the time between the IRQ arrival and the acpi_ec_gpe_handler() invocation is less than the timeout value waited in ec_poll(). So most of the no-op GPE handler invocations are caused by the reason described in issue 1. 3. There is a race condition due to ACPICA internal GPE clearing logic in acpi_enable_gpe(): During runtime, acpi_enable_gpe() can be invoked by the EC storming prevention code. When it is invoked, GPE may be flagged (STS=1). ================================================================= (event pending A) ================================================================= acpi_ev_gpe_dispatch() acpi_ec_transaction() EN=0 STS=0 acpi_ec_gpe_handler() ***************************************************************** (event handling A) Lock(EC) advance_transaction() EC_SC read EC_SC handled Unlock(EC) ***************************************************************** EN=1 ? Lock(EC) Unlock(EC) ================================================================= (event pending B) ================================================================= acpi_enable_gpe() STS=0 EN=1 4. Issue 4: We can see GPE loss on both silicon variation A and B platforms. This is because: a. event pending B: An event can arrive right before ACPICA's GPE clearing performed in acpi_enable_gpe(); b. If the GPE is cleared when GPE is disabled, then EN=1 write in acpi_enable_gpe() cannot trigger this GPE; c. If no polling mechanism is implemented in the driver for this event (for example, SCI_EVT), this event is lost due to no GPE being triggered. Note 4: Currently we don't have this issue, but after we switch the EC driver into ACPI_GPE_DISPATCH_RAW_HANDLER mode, we need to take care of handling this because the EN=1 write in acpi_ev_gpe_dispatch() will be abandoned. There might be more race issues for the current GPE handler usages. This is because the EC IRQ's enabling/disabling/checking/clearing/handling operations should be locked by a single lock that is under the EC driver's control to achieve the serialization. Which means we need to invoke GPE APIs with EC driver's lock held and all ACPICA internal GPE operations related to the GPE handler should be abandoned. Invoking GPE APIs inside of the EC driver lock and bypassing ACPICA internal GPE operations requires the ACPI_GPE_DISPATCH_RAW_HANDLER mode where the same lock used by the APIs are released prior than invoking the handlers. Otherwise, we can see dead locks due to circular locking dependencies (see Reference below). This patch then switches the EC driver into the ACPI_GPE_DISPATCH_RAW_HANDLER mode so that it can perform correct GPE operations using the GPE APIs: 1. Bypasses EN modifications performed in acpi_ev_gpe_dispatch() by using acpi_install_gpe_raw_handler() and invoking all GPE APIs with EC spin lock held. This can fix issue 1 as it makes a non frequent GPE enabling/disabling environment. 2. Bypasses STS clearing performed in acpi_enable_gpe() by replacing acpi_enable_gpe()/acpi_disable_gpe() with acpi_set_gpe(). This can fix issue 4. And this can also help to fix issue 1 as it makes a no sudden GPE clearing environment when GPE is frequently enabled/disabled. 3. Ensures STS acknowledged before handling by invoking acpi_clear_gpe() in advance_transaction(). This can finally fix issue 1 even in a frequent GPE enabling/disabling environment. And this can also finally fix issue 3 when issue 2 is fixed. Note 3: GPE clearing is edge triggered W1C, which means we can clear it right before handling it. Since all EC GPE indications are handled in advance_transaction() by previous commits, we can now move GPE clearing into it to implement the correct GPE clearing. Note 4: We can use acpi_set_gpe() which is not shared GPE safer instead of acpi_enable_gpe()/acpi_disable_gpe() because EC GPE is not shared by other hardware, which is mentioned in the ACPI specification 5.0, 12.6 Interrupt Model: "OSPM driver treats this as an edge event (the EC SCI cannot be shared)". So we can stop using shared GPE safer APIs acpi_enable_gpe()/acpi_disable_gpe() in the EC driver. Otherwise cleanups need to be made in acpi_ev_enable_gpe() to bypass the GPE clearing logic before keeping acpi_enable_gpe(). This patch also invokes advance_transaction() when GPE is re-enabled in the task context which: 1. Ensures EN=1 can trigger GPE by checking and handling EC status register right after EN=1 writes. This can fix issue 2. After applying this patch, without frequent GPE enablings considered: ================================================================= (event pending A) ================================================================= acpi_ec_gpe_handler() ec_poll() ***************************************************************** (event handling A) Lock(EC) advance_transaction() if STS==1 STS=0 EC_SC read ================================================================= (event pending B) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** ***************************************************************** (event handling B) Lock(EC) advance_transaction() if STS==1 STS=0 EC_SC read ================================================================= (event pending C) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** The event pending for issue 1 (event pending B) can arrive as a next GPE due to the previous IRQ context STS=0 write. And if it is handled by ec_poll() (event handling B), as it is also acknowledged by ec_poll(), the event pending for issue 2 (event pending C) can properly arrive as a next GPE after the task context STS=0 write. So no GPE will be lost and never triggered due to GPE clearing performed in the wrong position. And since all GPE handling is performed after a locked GPE status checking, we can hardly see no-op GPE handler invocations due to issue 1 and 3. We may still see no-op GPE handler invocations due to "Note 1", but as it is inevitable, it needn't be fixed. After applying this patch, with frequent GPE enablings considered: ================================================================= (event pending A) ================================================================= acpi_ec_gpe_handler() acpi_ec_transaction() ***************************************************************** (event handling A) Lock(EC) advance_transaction() if STS==1 STS=0 EC_SC read ================================================================= (event pending B) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** ***************************************************************** (event handling B) Lock(EC) EN=1 if STS==1 advance_transaction() if STS==1 STS=0 EC_SC read ================================================================= (event pending C) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** The event pending for issue 2 can be manually handled by advance_transaction(). And after the STS=0 write performed in the manual triggered advance_transaction(), GPE can always arrive. So no GPE will be lost due to frequent GPE disabling/enabling performed in the driver like issue 4. Note 5: It's ideally when EN=1 write occurred, an IRQ thread should be woken up to handle the GPE when the GPE was raised. But this requires the IRQ thread to contain the poller code for all EC GPE indications, while currently some of the indications are handled in the user tasks. It then is very hard for the code to determine whether a user task should be invoked or the poller work item should be scheduled. So we have to invoke advance_transaction() directly now and it leaves us such a restriction for the GPE re-enabling: it must be performed in the task context to avoid starving the GPEs. As a conclusion: we can see the EC GPE is always handled in serial after deploying the raw GPE handler mode: Lock(EC) if (STS==1) STS=0 EC_SC read EC_SC handled Unlock(EC) The EC driver specific lock is responsible to make the EC GPE handling processes serialized so that EC can handle its GPE from both IRQ and task contexts and the next IRQ can be ensured to arrive after this process. Note 6: We have many EC_FLAGS_MSI qurik users in the current driver. They all seem to be suffering from unexpected GPE triggering source lost. And they are false root caused to a timing issue. Since EC communication protocol has already flow control defined, timing shouldn't be the root cause, while this fix might be fixing the root cause of the old bugs. Link: https://lkml.org/lkml/2014/11/4/974 Link: https://lkml.org/lkml/2014/11/18/316 Link: https://www.spinics.net/lists/linux-acpi/msg54340.html Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-02-05 16:27:22 +08:00
ACPI / EC: Refine command storm prevention support This patch refines EC command storm prevention support. Current command storming code is wrong, when the storming condition is detected, it only flags the condition without doing anything for the current command but performing storming prevention for the follow-up commands. So: 1. The first command which suffers from the storming still suffers from storming. 2. The follow-up commands which may not suffer from the storming are unconditionally forced into the storming prevention mode. Ideally, we should only enable storm prevention immediately after detection for the current command so that the next command can try the power/performance efficient interrupt mode again. This patch improves the command storm prevention by disabling GPE right after the detection and re-enabling it right before completing the command transaction using the GPE storming prevention APIs. This thus deploys the following GPE handling model: 1. acpi_enable_gpe()/acpi_disable_gpe() for reference count changes: This set of APIs are used for EC usage reference counting. 2. acpi_set_gpe(ACPI_GPE_ENABLE)/acpi_set_gpe(ACPI_GPE_DISABLE): This set of APIs are used for preventing GPE storm. They must be invoked when the reference count > 0. Note that as the storming prevention should always happen when there is an outstanding request, or GPE enabling value will be messed up by the races. This patch also adds BUG_ON() to enforces this rule to prevent future bugs. The msleep(1) used after completing a transaction is useless now as this sounds like a guard time only useful for platforms that need the EC_FLAGS_MSI quirks while we have fixed GPE race issues using the previous raw handler mode enabling. It is kept to avoid regressions. A seperate patch which deletes EC_FLAGS_MSI quirks should take care of deleting it. Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-02-06 08:58:05 +08:00
ACPI / EC: Fix several GPE handling issues by deploying ACPI_GPE_DISPATCH_RAW_HANDLER mode. This patch switches EC driver into ACPI_GPE_DISPATCH_RAW_HANDLER mode where the GPE lock is not held for acpi_ec_gpe_handler() and the ACPICA internal GPE enabling/disabling/clearing operations are bypassed so that further improvements are possible with the GPE APIs. There are 2 strong reasons for deploying raw GPE handler mode in the EC driver: 1. Some hardware logics can control their interrupts via their own registers, so their interrupts can be disabled/enabled/acknowledged without using the super IRQ controller provided functions. While there is no mean (EC commands) for the EC driver to achieve this. 2. During suspending, the EC driver is still working for a while to complete the platform firmware provided functionailities using ec_poll() after all GPEs are disabled (see acpi_ec_block_transactions()), which means the EC driver will drive the EC GPE out of the GPE core's control. Without deploying the raw GPE handler mode, we can see many races between the EC driver and the GPE core due to the above restrictions: 1. There is a race condition due to ACPICA internal GPE disabling/clearing/enabling logics in acpi_ev_gpe_dispatch(): Orignally EC GPE is disabled (EN=0), cleared (STS=0) before invoking a GPE handler and re-enabled (EN=1) after invoking a GPE handler in acpi_ev_gpe_dispatch(). When re-enabling appears, GPE may be flagged (STS=1). ================================================================= (event pending A) ================================================================= acpi_ev_gpe_dispatch() ec_poll() EN=0 STS=0 acpi_ec_gpe_handler() ***************************************************************** (event handling A) Lock(EC) advance_transaction() EC_SC read ================================================================= (event pending B) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** ***************************************************************** (event handling B) Lock(EC) advance_transaction() EC_SC read ================================================================= (event pending C) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** EN=1 This race condition is the root cause of different issues on different silicon variations. A. Silicon variation A: On some platforms, GPE will be triggered due to "writing 1 to EN when STS=1". This is because both EN and STS lines are wired to the GPE trigger line. 1. Issue 1: We can see no-op acpi_ec_gpe_handler() invoked on such platforms. This is because: a. event pending B: An event can arrive after ACPICA's GPE clearing performed in acpi_ev_gpe_dispatch(), this event may fail to be detected by EC_SC read that is performed before its arrival; b. event handling B: The event can be handled in ec_poll() because EC lock is released after acpi_ec_gpe_handler() invocation; c. There is no code in ec_poll() to clear STS but the GPE can still be triggered by the EN=1 write performed in acpi_ev_finish_gpe(), this leads to a no-op EC GPE handler invocation; d. As no-op GPE handler invocations are counted by the EC driver to trigger the command storming conditions, the wrong no-op GPE handler invocations thus can easily trigger wrong command storming conditions. Note 1: If we removed GPE disabling/enabling code from acpi_ev_gpe_dispatch(), we could still see no-op GPE handlers triggered by the event arriving after the GPE clearing and before the GPE handling on both silicon variation A and B. This can only occur if the CPU is very slow (timing slice between STS=0 write and EC_SC read should be short enough before hardware sets another GPE indication). Thus this is very rare and is not what we need to fix. B. Silicon variation B: On other platforms, GPE may not be triggered due to "writing 1 to EN when STS=1". This is because only STS line is wired to the GPE trigger line. 2. Issue 2: We can see GPE loss on such platforms. This is because: a. event pending B vs. event handling A: An event can arrive after ACPICA's GPE handling performed in acpi_ev_gpe_dispatch(), or event pending C vs. event handling B: An event can arrive after Linux's GPE handling performed in ec_poll(), these events may fail to be detected by EC_SC read that is performed before their arrival; b. The GPE cannot be triggered by EN=1 write performed in acpi_ev_finish_gpe(); c. If no polling mechanism is implemented in the driver for the pending event (for example, SCI_EVT), this event is lost due to no GPE being triggered. Note 2: On most platforms, there might be another rule that GPE may not be triggered due to "writing 1 to STS when STS=1 and EN=1". Then on silicon variation B, an even worse case is if the issue 2 event loss happens, further events may never trigger GPE again on such platforms due to being blocked by the current STS=1. Unless someone clears STS, all events have to be polled. 2. There is a race condition due to lacking in GPE status checking in EC driver: Originally, GPE status is checked in ACPICA core but not checked in the GPE handler. Thus since the status checking and handling is not locked, it can be interrupted by another handling path. ================================================================= (event pending A) ================================================================= acpi_ev_gpe_detect() ec_poll() if (EN==1 && STS==1) ***************************************************************** (event handling A) Lock(EC) advance_transaction() EC_SC read EC_SC handled Unlock(EC) ***************************************************************** acpi_ev_gpe_dispatch() EN=0 STS=0 acpi_ec_gpe_handler() ***************************************************************** (event handling B) Lock(EC) advance_transaction() EC_SC read Unlock(EC) ***************************************************************** 3. Issue 3: We can see no-op acpi_ec_gpe_handler() invoked on both silicon variation A and B. This is because: a. event pending A: An event can arrive to trigger an EC GPE and ACPICA checks it and is about to invoke the EC GPE handler; b. event handling A: The event can be handled in ec_poll() because EC lock is not held after the GPE status checking; c. event handling B: Then when the EC GPE handler is invoked, it becomes a no-op GPE handler invocation. d. As no-op GPE handler invocations are counted by the EC driver to trigger the command storming conditions, the wrong no-op GPE handler invocations thus can easily trigger wrong command storming conditions. Note 3: This no-op GPE handler invocation is rare because the time between the IRQ arrival and the acpi_ec_gpe_handler() invocation is less than the timeout value waited in ec_poll(). So most of the no-op GPE handler invocations are caused by the reason described in issue 1. 3. There is a race condition due to ACPICA internal GPE clearing logic in acpi_enable_gpe(): During runtime, acpi_enable_gpe() can be invoked by the EC storming prevention code. When it is invoked, GPE may be flagged (STS=1). ================================================================= (event pending A) ================================================================= acpi_ev_gpe_dispatch() acpi_ec_transaction() EN=0 STS=0 acpi_ec_gpe_handler() ***************************************************************** (event handling A) Lock(EC) advance_transaction() EC_SC read EC_SC handled Unlock(EC) ***************************************************************** EN=1 ? Lock(EC) Unlock(EC) ================================================================= (event pending B) ================================================================= acpi_enable_gpe() STS=0 EN=1 4. Issue 4: We can see GPE loss on both silicon variation A and B platforms. This is because: a. event pending B: An event can arrive right before ACPICA's GPE clearing performed in acpi_enable_gpe(); b. If the GPE is cleared when GPE is disabled, then EN=1 write in acpi_enable_gpe() cannot trigger this GPE; c. If no polling mechanism is implemented in the driver for this event (for example, SCI_EVT), this event is lost due to no GPE being triggered. Note 4: Currently we don't have this issue, but after we switch the EC driver into ACPI_GPE_DISPATCH_RAW_HANDLER mode, we need to take care of handling this because the EN=1 write in acpi_ev_gpe_dispatch() will be abandoned. There might be more race issues for the current GPE handler usages. This is because the EC IRQ's enabling/disabling/checking/clearing/handling operations should be locked by a single lock that is under the EC driver's control to achieve the serialization. Which means we need to invoke GPE APIs with EC driver's lock held and all ACPICA internal GPE operations related to the GPE handler should be abandoned. Invoking GPE APIs inside of the EC driver lock and bypassing ACPICA internal GPE operations requires the ACPI_GPE_DISPATCH_RAW_HANDLER mode where the same lock used by the APIs are released prior than invoking the handlers. Otherwise, we can see dead locks due to circular locking dependencies (see Reference below). This patch then switches the EC driver into the ACPI_GPE_DISPATCH_RAW_HANDLER mode so that it can perform correct GPE operations using the GPE APIs: 1. Bypasses EN modifications performed in acpi_ev_gpe_dispatch() by using acpi_install_gpe_raw_handler() and invoking all GPE APIs with EC spin lock held. This can fix issue 1 as it makes a non frequent GPE enabling/disabling environment. 2. Bypasses STS clearing performed in acpi_enable_gpe() by replacing acpi_enable_gpe()/acpi_disable_gpe() with acpi_set_gpe(). This can fix issue 4. And this can also help to fix issue 1 as it makes a no sudden GPE clearing environment when GPE is frequently enabled/disabled. 3. Ensures STS acknowledged before handling by invoking acpi_clear_gpe() in advance_transaction(). This can finally fix issue 1 even in a frequent GPE enabling/disabling environment. And this can also finally fix issue 3 when issue 2 is fixed. Note 3: GPE clearing is edge triggered W1C, which means we can clear it right before handling it. Since all EC GPE indications are handled in advance_transaction() by previous commits, we can now move GPE clearing into it to implement the correct GPE clearing. Note 4: We can use acpi_set_gpe() which is not shared GPE safer instead of acpi_enable_gpe()/acpi_disable_gpe() because EC GPE is not shared by other hardware, which is mentioned in the ACPI specification 5.0, 12.6 Interrupt Model: "OSPM driver treats this as an edge event (the EC SCI cannot be shared)". So we can stop using shared GPE safer APIs acpi_enable_gpe()/acpi_disable_gpe() in the EC driver. Otherwise cleanups need to be made in acpi_ev_enable_gpe() to bypass the GPE clearing logic before keeping acpi_enable_gpe(). This patch also invokes advance_transaction() when GPE is re-enabled in the task context which: 1. Ensures EN=1 can trigger GPE by checking and handling EC status register right after EN=1 writes. This can fix issue 2. After applying this patch, without frequent GPE enablings considered: ================================================================= (event pending A) ================================================================= acpi_ec_gpe_handler() ec_poll() ***************************************************************** (event handling A) Lock(EC) advance_transaction() if STS==1 STS=0 EC_SC read ================================================================= (event pending B) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** ***************************************************************** (event handling B) Lock(EC) advance_transaction() if STS==1 STS=0 EC_SC read ================================================================= (event pending C) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** The event pending for issue 1 (event pending B) can arrive as a next GPE due to the previous IRQ context STS=0 write. And if it is handled by ec_poll() (event handling B), as it is also acknowledged by ec_poll(), the event pending for issue 2 (event pending C) can properly arrive as a next GPE after the task context STS=0 write. So no GPE will be lost and never triggered due to GPE clearing performed in the wrong position. And since all GPE handling is performed after a locked GPE status checking, we can hardly see no-op GPE handler invocations due to issue 1 and 3. We may still see no-op GPE handler invocations due to "Note 1", but as it is inevitable, it needn't be fixed. After applying this patch, with frequent GPE enablings considered: ================================================================= (event pending A) ================================================================= acpi_ec_gpe_handler() acpi_ec_transaction() ***************************************************************** (event handling A) Lock(EC) advance_transaction() if STS==1 STS=0 EC_SC read ================================================================= (event pending B) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** ***************************************************************** (event handling B) Lock(EC) EN=1 if STS==1 advance_transaction() if STS==1 STS=0 EC_SC read ================================================================= (event pending C) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** The event pending for issue 2 can be manually handled by advance_transaction(). And after the STS=0 write performed in the manual triggered advance_transaction(), GPE can always arrive. So no GPE will be lost due to frequent GPE disabling/enabling performed in the driver like issue 4. Note 5: It's ideally when EN=1 write occurred, an IRQ thread should be woken up to handle the GPE when the GPE was raised. But this requires the IRQ thread to contain the poller code for all EC GPE indications, while currently some of the indications are handled in the user tasks. It then is very hard for the code to determine whether a user task should be invoked or the poller work item should be scheduled. So we have to invoke advance_transaction() directly now and it leaves us such a restriction for the GPE re-enabling: it must be performed in the task context to avoid starving the GPEs. As a conclusion: we can see the EC GPE is always handled in serial after deploying the raw GPE handler mode: Lock(EC) if (STS==1) STS=0 EC_SC read EC_SC handled Unlock(EC) The EC driver specific lock is responsible to make the EC GPE handling processes serialized so that EC can handle its GPE from both IRQ and task contexts and the next IRQ can be ensured to arrive after this process. Note 6: We have many EC_FLAGS_MSI qurik users in the current driver. They all seem to be suffering from unexpected GPE triggering source lost. And they are false root caused to a timing issue. Since EC communication protocol has already flow control defined, timing shouldn't be the root cause, while this fix might be fixing the root cause of the old bugs. Link: https://lkml.org/lkml/2014/11/4/974 Link: https://lkml.org/lkml/2014/11/18/316 Link: https://www.spinics.net/lists/linux-acpi/msg54340.html Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-02-05 16:27:22 +08:00
ACPI / EC: Refine command storm prevention support This patch refines EC command storm prevention support. Current command storming code is wrong, when the storming condition is detected, it only flags the condition without doing anything for the current command but performing storming prevention for the follow-up commands. So: 1. The first command which suffers from the storming still suffers from storming. 2. The follow-up commands which may not suffer from the storming are unconditionally forced into the storming prevention mode. Ideally, we should only enable storm prevention immediately after detection for the current command so that the next command can try the power/performance efficient interrupt mode again. This patch improves the command storm prevention by disabling GPE right after the detection and re-enabling it right before completing the command transaction using the GPE storming prevention APIs. This thus deploys the following GPE handling model: 1. acpi_enable_gpe()/acpi_disable_gpe() for reference count changes: This set of APIs are used for EC usage reference counting. 2. acpi_set_gpe(ACPI_GPE_ENABLE)/acpi_set_gpe(ACPI_GPE_DISABLE): This set of APIs are used for preventing GPE storm. They must be invoked when the reference count > 0. Note that as the storming prevention should always happen when there is an outstanding request, or GPE enabling value will be messed up by the races. This patch also adds BUG_ON() to enforces this rule to prevent future bugs. The msleep(1) used after completing a transaction is useless now as this sounds like a guard time only useful for platforms that need the EC_FLAGS_MSI quirks while we have fixed GPE race issues using the previous raw handler mode enabling. It is kept to avoid regressions. A seperate patch which deletes EC_FLAGS_MSI quirks should take care of deleting it. Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-02-06 08:58:05 +08:00
ACPI / EC: Refine command storm prevention support This patch refines EC command storm prevention support. Current command storming code is wrong, when the storming condition is detected, it only flags the condition without doing anything for the current command but performing storming prevention for the follow-up commands. So: 1. The first command which suffers from the storming still suffers from storming. 2. The follow-up commands which may not suffer from the storming are unconditionally forced into the storming prevention mode. Ideally, we should only enable storm prevention immediately after detection for the current command so that the next command can try the power/performance efficient interrupt mode again. This patch improves the command storm prevention by disabling GPE right after the detection and re-enabling it right before completing the command transaction using the GPE storming prevention APIs. This thus deploys the following GPE handling model: 1. acpi_enable_gpe()/acpi_disable_gpe() for reference count changes: This set of APIs are used for EC usage reference counting. 2. acpi_set_gpe(ACPI_GPE_ENABLE)/acpi_set_gpe(ACPI_GPE_DISABLE): This set of APIs are used for preventing GPE storm. They must be invoked when the reference count > 0. Note that as the storming prevention should always happen when there is an outstanding request, or GPE enabling value will be messed up by the races. This patch also adds BUG_ON() to enforces this rule to prevent future bugs. The msleep(1) used after completing a transaction is useless now as this sounds like a guard time only useful for platforms that need the EC_FLAGS_MSI quirks while we have fixed GPE race issues using the previous raw handler mode enabling. It is kept to avoid regressions. A seperate patch which deletes EC_FLAGS_MSI quirks should take care of deleting it. Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-02-06 08:58:05 +08:00
ACPI / EC: Refine command storm prevention support This patch refines EC command storm prevention support. Current command storming code is wrong, when the storming condition is detected, it only flags the condition without doing anything for the current command but performing storming prevention for the follow-up commands. So: 1. The first command which suffers from the storming still suffers from storming. 2. The follow-up commands which may not suffer from the storming are unconditionally forced into the storming prevention mode. Ideally, we should only enable storm prevention immediately after detection for the current command so that the next command can try the power/performance efficient interrupt mode again. This patch improves the command storm prevention by disabling GPE right after the detection and re-enabling it right before completing the command transaction using the GPE storming prevention APIs. This thus deploys the following GPE handling model: 1. acpi_enable_gpe()/acpi_disable_gpe() for reference count changes: This set of APIs are used for EC usage reference counting. 2. acpi_set_gpe(ACPI_GPE_ENABLE)/acpi_set_gpe(ACPI_GPE_DISABLE): This set of APIs are used for preventing GPE storm. They must be invoked when the reference count > 0. Note that as the storming prevention should always happen when there is an outstanding request, or GPE enabling value will be messed up by the races. This patch also adds BUG_ON() to enforces this rule to prevent future bugs. The msleep(1) used after completing a transaction is useless now as this sounds like a guard time only useful for platforms that need the EC_FLAGS_MSI quirks while we have fixed GPE race issues using the previous raw handler mode enabling. It is kept to avoid regressions. A seperate patch which deletes EC_FLAGS_MSI quirks should take care of deleting it. Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-02-06 08:58:05 +08:00
ACPI / EC: Refine command storm prevention support This patch refines EC command storm prevention support. Current command storming code is wrong, when the storming condition is detected, it only flags the condition without doing anything for the current command but performing storming prevention for the follow-up commands. So: 1. The first command which suffers from the storming still suffers from storming. 2. The follow-up commands which may not suffer from the storming are unconditionally forced into the storming prevention mode. Ideally, we should only enable storm prevention immediately after detection for the current command so that the next command can try the power/performance efficient interrupt mode again. This patch improves the command storm prevention by disabling GPE right after the detection and re-enabling it right before completing the command transaction using the GPE storming prevention APIs. This thus deploys the following GPE handling model: 1. acpi_enable_gpe()/acpi_disable_gpe() for reference count changes: This set of APIs are used for EC usage reference counting. 2. acpi_set_gpe(ACPI_GPE_ENABLE)/acpi_set_gpe(ACPI_GPE_DISABLE): This set of APIs are used for preventing GPE storm. They must be invoked when the reference count > 0. Note that as the storming prevention should always happen when there is an outstanding request, or GPE enabling value will be messed up by the races. This patch also adds BUG_ON() to enforces this rule to prevent future bugs. The msleep(1) used after completing a transaction is useless now as this sounds like a guard time only useful for platforms that need the EC_FLAGS_MSI quirks while we have fixed GPE race issues using the previous raw handler mode enabling. It is kept to avoid regressions. A seperate patch which deletes EC_FLAGS_MSI quirks should take care of deleting it. Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-02-06 08:58:05 +08:00
ACPI / EC: Fix issues related to the SCI_EVT handling This patch fixes 2 issues related to the draining behavior. But it doesn't implement the draining support, it only cleans up code so that further draining support is possible. The draining behavior is expected by some platforms (for example, Samsung) where SCI_EVT is set only once for a set of events and might be cleared for the very first QR_EC command issued after SCI_EVT is set. EC firmware on such platforms will return 0x00 to indicate "no outstanding event". Thus after seeing an SCI_EVT indication, EC driver need to fetch events until 0x00 returned (see acpi_ec_clear()). Issue 1 - acpi_ec_submit_query(): It's reported on Samsung laptops that SCI_EVT isn't checked when the transactions are advanced in ec_poll(), which leads to SCI_EVT triggering source lost: If no EC GPE IRQs are arrived after that, EC driver cannot detect this event and handle it. See comment 244/247 for kernel bugzilla 44161. This patch fixes this issue by moving SCI_EVT checks into advance_transaction(). So that SCI_EVT is checked each time we are going to handle the EC firmware indications. And this check will happen for both IRQ context and task context. Since after doing that, SCI_EVT is also checked after completing a transaction, ec_check_sci() and ec_check_sci_sync() can be removed. Issue 2 - acpi_ec_complete_query(): We expect to clear EC_FLAGS_QUERY_PENDING to allow queuing another draining QR_EC after writing a QR_EC command and before reading the event. After reading the event, SCI_EVT might be cleared by the firmware, thus it may not be possible to queue such a draining QR_EC at that time. But putting the EC_FLAGS_QUERY_PENDING clearing code after start_transaction() is wrong as there are chances that after start_transaction(), QR_EC can fail to be sent. If this happens, EC_FLAG_QUERY_PENDING will be cleared earlier. As a consequence, the draining QR_EC will also be queued earlier than expected. This patch also moves this code into advance_transaction() where QR_EC is just sent (ACPI_EC_COMMAND_POLL flagged) to fix this issue. Notes: 1. After introducing the 2 SCI_EVT related handlings into advance_transaction(), a next QR_EC can be queued right after writing the current QR_EC command and before reading the event. But this still hasn't implemented the draining behavior as the draining support requires: If a previous returned event value isn't 0x00, a draining QR_EC need to be issued even when SCI_EVT isn't set. 2. In this patch, acpi_os_execute() is also converted into a seperate work item to avoid invoking kmalloc() in the atomic context. We can do this because of the previous global lock fix. 3. Originally, EC_FLAGS_EVENT_PENDING is also used to avoid queuing up multiple work items (created by acpi_os_execute()), this can be covered by only using a single work item. But this patch still keeps this flag as there are different usages in the driver initialization steps relying on this flag. Link: https://bugzilla.kernel.org/show_bug.cgi?id=44161 Reported-by: Kieran Clancy <clancy.kieran@gmail.com> Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-01-14 19:28:47 +08:00
ACPI: EC: Fix an EC event IRQ storming issue The EC event IRQ (SCI_EVT) can only be handled by submitting QR_EC. As the EC driver handles SCI_EVT in a workqueue, after SCI_EVT is flagged and before QR_EC is submitted, there is a period risking IRQ storming. EC IRQ must be masked for this period but linux EC driver never does so. No end user notices the IRQ storming and no developer fixes this known issue because: 1. The EC IRQ is always edge triggered GPE, and 2. The kernel can execute no-op EC IRQ handler very fast. For edge-triggered EC GPE platforms, it is only reported of post-resume EC event lost issues, there won't be an IRQ storming. For level triggered EC GPE platforms, fortunately the kernel is always fast enough to execute such a no-op EC IRQ handler so that the IRQ handler won't be accumulated to starve the task contexts, causing a real IRQ storming. But the IRQ storming actually can still happen when: 1. The EC IRQ performs like level triggered GPE, and 2. The kernel EC debugging log is turned on but the console is slow enough. There are more and more platforms using EC GPE as wake GPE where the EC GPE is likely designed as level triggered. Then when EC debugging log is enabled, the EC IRQ handler is no longer a no-op but dumps IRQ status to the consoles. If the consoles are slow enough, the EC IRQs can arrive much faster than executing the handler. Finally the accumulated EC event IRQ handlers starve the task contexts, causing the IRQ storming to occur, and the kernel hangs can be observed during boot/resume. This patch fixes this issue by masking EC IRQ for this period: 1. Begins when there is an SCI_EVT IRQ pending, and 2. Ends when there is a QR_EC completed (SCI_EVT acknowledged). Tested-by: Wang Wendy <wendy.wang@intel.com> Tested-by: Feng Chenzhou <chenzhoux.feng@intel.com> Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2017-06-14 13:59:09 +08:00
ACPI: EC: Make the event work state machine visible The EC driver uses a relatively simple state machine for the event work handling, but it is not really straightforward to figure out. The states are as follows: "Ready": The event handling work can be submitted. In this state, the EC_FLAGS_QUERY_PENDING flag is clear. "In progress": The event handling work is pending or is being processed. It cannot be submitted again. In ths state, the EC_FLAGS_QUERY_PENDING flag is set and both the events_to_process count is nonzero and the EC_FLAGS_QUERY_GUARDING flag is clear. "Complete": The event handling work has been completed, but it still cannot be submitted again. In ths state, the EC_FLAGS_QUERY_PENDING flag is set and the events_to_process count is zero or the EC_FLAGS_QUERY_GUARDING flag is set. The state changes from "Ready" to "In progress" when new event is detected by advance_transaction() and acpi_ec_submit_event() is called by it. Next, the state can change from "In progress" directly to "Ready" in the following situations: * ec_event_clearing is ACPI_EC_EVT_TIMING_STATUS and the state of an ACPI_EC_COMMAND_QUERY transaction becomes ACPI_EC_COMMAND_POLL. * ec_event_clearing is ACPI_EC_EVT_TIMING_QUERY and the state of an ACPI_EC_COMMAND_QUERY transaction becomes ACPI_EC_COMMAND_COMPLETE. * ec_event_clearing is either ACPI_EC_EVT_TIMING_STATUS or ACPI_EC_EVT_TIMING_QUERY and there are no more events to process (ie. ec->events_to_process becomes 0). If ec_event_clearing is ACPI_EC_EVT_TIMING_EVENT, however, the state must change from "In progress" to "Complete" before it can change to "Ready". The changes from "In progress" to "Complete" in that case occur in the following situations: * The state of an ACPI_EC_COMMAND_QUERY transaction becomes ACPI_EC_COMMAND_COMPLETE. * There are no more events to process (ie. ec->events_to_process becomes 0). Finally, the state changes from "Complete" to "Ready" when advance_transaction() is invoked when the state is "Complete" and the state of the current transaction is not ACPI_EC_COMMAND_POLL. To make this state machine visible in the code, add a new event_state field to struct acpi_ec and modify the code to use it istead the EC_FLAGS_QUERY_PENDING and EC_FLAGS_QUERY_GUARDING flags. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-11-23 19:44:46 +01:00
ACPI / EC: Add query flushing support This patch implementes the QR_EC flushing support. Grace periods are implemented from the detection of an SCI_EVT to the submission/completion of the QR_EC transaction. During this period, all EC command transactions are allowed to be submitted. Note that query periods and event periods are intentionally distiguished to allow further improvements. 1. Query period: from the detection of an SCI_EVT to the sumission of the QR_EC command. This period is used for storming prevention, as currently QR_EC is deferred to a work queue rather than directly issued from the IRQ context even there is no other transactions pending, so malicous SCI_EVT GPE can act like "level triggered" to trigger a GPE storm. We need to be prepared for this. And in the future, we may change it to be a part of the advance_transaction() where we will try QR_EC submission in appropriate positions to avoid such GPE storming. 2. Event period: from the detection of an SCI_EVT to the completion of the QR_EC command. We may extend it to the completion of _Qxx evaluation. This is actually a grace period for event flushing, but we only flush queries due to the reason stated in known issue 1. That's also why we use EC_FLAGS_EVENT_xxx. During this period, QR_EC transactions need to pass the flushable submission check. In this patch, the following flags are implemented: 1. EC_FLAGS_EVENT_ENABLED: this is derived from the old EC_FLAGS_QUERY_PENDING flag which can block SCI_EVT handlings. With this flag, the logics implemented by the original flag are extended: 1. Old logic: unless both of the flags are set, the event poller will not be scheduled, and 2. New logic: as soon as both of the flags are set, the evet poller will be scheduled. 2. EC_FLAGS_EVENT_DETECTED: this is also derived from the old EC_FLAGS_QUERY_PENDING flag which can block SCI_EVT detection. It thus can be used to indicate the storming prevention period for query submission. acpi_ec_submit_request()/acpi_ec_complete_request() are invoked to implement this period so that acpi_set_gpe() can be invoked under the "reference count > 0" condition. 3. EC_FLAGS_EVENT_PENDING: this is newly added to indicate the grace period for event flushing (query flushing for now). acpi_ec_submit_request()/acpi_ec_complete_request() are invoked to implement this period so that the flushing process can wait until the event handling (query transaction for now) to be completed. Link: https://bugzilla.kernel.org/show_bug.cgi?id=82611 Link: https://bugzilla.kernel.org/show_bug.cgi?id=77431 Signed-off-by: Lv Zheng <lv.zheng@intel.com> Tested-by: Ortwin Glück <odi@odi.ch> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-02-06 08:58:10 +08:00
ACPI: EC: Make the event work state machine visible The EC driver uses a relatively simple state machine for the event work handling, but it is not really straightforward to figure out. The states are as follows: "Ready": The event handling work can be submitted. In this state, the EC_FLAGS_QUERY_PENDING flag is clear. "In progress": The event handling work is pending or is being processed. It cannot be submitted again. In ths state, the EC_FLAGS_QUERY_PENDING flag is set and both the events_to_process count is nonzero and the EC_FLAGS_QUERY_GUARDING flag is clear. "Complete": The event handling work has been completed, but it still cannot be submitted again. In ths state, the EC_FLAGS_QUERY_PENDING flag is set and the events_to_process count is zero or the EC_FLAGS_QUERY_GUARDING flag is set. The state changes from "Ready" to "In progress" when new event is detected by advance_transaction() and acpi_ec_submit_event() is called by it. Next, the state can change from "In progress" directly to "Ready" in the following situations: * ec_event_clearing is ACPI_EC_EVT_TIMING_STATUS and the state of an ACPI_EC_COMMAND_QUERY transaction becomes ACPI_EC_COMMAND_POLL. * ec_event_clearing is ACPI_EC_EVT_TIMING_QUERY and the state of an ACPI_EC_COMMAND_QUERY transaction becomes ACPI_EC_COMMAND_COMPLETE. * ec_event_clearing is either ACPI_EC_EVT_TIMING_STATUS or ACPI_EC_EVT_TIMING_QUERY and there are no more events to process (ie. ec->events_to_process becomes 0). If ec_event_clearing is ACPI_EC_EVT_TIMING_EVENT, however, the state must change from "In progress" to "Complete" before it can change to "Ready". The changes from "In progress" to "Complete" in that case occur in the following situations: * The state of an ACPI_EC_COMMAND_QUERY transaction becomes ACPI_EC_COMMAND_COMPLETE. * There are no more events to process (ie. ec->events_to_process becomes 0). Finally, the state changes from "Complete" to "Ready" when advance_transaction() is invoked when the state is "Complete" and the state of the current transaction is not ACPI_EC_COMMAND_POLL. To make this state machine visible in the code, add a new event_state field to struct acpi_ec and modify the code to use it istead the EC_FLAGS_QUERY_PENDING and EC_FLAGS_QUERY_GUARDING flags. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-11-23 19:44:46 +01:00
ACPI / EC: Add query flushing support This patch implementes the QR_EC flushing support. Grace periods are implemented from the detection of an SCI_EVT to the submission/completion of the QR_EC transaction. During this period, all EC command transactions are allowed to be submitted. Note that query periods and event periods are intentionally distiguished to allow further improvements. 1. Query period: from the detection of an SCI_EVT to the sumission of the QR_EC command. This period is used for storming prevention, as currently QR_EC is deferred to a work queue rather than directly issued from the IRQ context even there is no other transactions pending, so malicous SCI_EVT GPE can act like "level triggered" to trigger a GPE storm. We need to be prepared for this. And in the future, we may change it to be a part of the advance_transaction() where we will try QR_EC submission in appropriate positions to avoid such GPE storming. 2. Event period: from the detection of an SCI_EVT to the completion of the QR_EC command. We may extend it to the completion of _Qxx evaluation. This is actually a grace period for event flushing, but we only flush queries due to the reason stated in known issue 1. That's also why we use EC_FLAGS_EVENT_xxx. During this period, QR_EC transactions need to pass the flushable submission check. In this patch, the following flags are implemented: 1. EC_FLAGS_EVENT_ENABLED: this is derived from the old EC_FLAGS_QUERY_PENDING flag which can block SCI_EVT handlings. With this flag, the logics implemented by the original flag are extended: 1. Old logic: unless both of the flags are set, the event poller will not be scheduled, and 2. New logic: as soon as both of the flags are set, the evet poller will be scheduled. 2. EC_FLAGS_EVENT_DETECTED: this is also derived from the old EC_FLAGS_QUERY_PENDING flag which can block SCI_EVT detection. It thus can be used to indicate the storming prevention period for query submission. acpi_ec_submit_request()/acpi_ec_complete_request() are invoked to implement this period so that acpi_set_gpe() can be invoked under the "reference count > 0" condition. 3. EC_FLAGS_EVENT_PENDING: this is newly added to indicate the grace period for event flushing (query flushing for now). acpi_ec_submit_request()/acpi_ec_complete_request() are invoked to implement this period so that the flushing process can wait until the event handling (query transaction for now) to be completed. Link: https://bugzilla.kernel.org/show_bug.cgi?id=82611 Link: https://bugzilla.kernel.org/show_bug.cgi?id=77431 Signed-off-by: Lv Zheng <lv.zheng@intel.com> Tested-by: Ortwin Glück <odi@odi.ch> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-02-06 08:58:10 +08:00
ACPI: EC: Make the event work state machine visible The EC driver uses a relatively simple state machine for the event work handling, but it is not really straightforward to figure out. The states are as follows: "Ready": The event handling work can be submitted. In this state, the EC_FLAGS_QUERY_PENDING flag is clear. "In progress": The event handling work is pending or is being processed. It cannot be submitted again. In ths state, the EC_FLAGS_QUERY_PENDING flag is set and both the events_to_process count is nonzero and the EC_FLAGS_QUERY_GUARDING flag is clear. "Complete": The event handling work has been completed, but it still cannot be submitted again. In ths state, the EC_FLAGS_QUERY_PENDING flag is set and the events_to_process count is zero or the EC_FLAGS_QUERY_GUARDING flag is set. The state changes from "Ready" to "In progress" when new event is detected by advance_transaction() and acpi_ec_submit_event() is called by it. Next, the state can change from "In progress" directly to "Ready" in the following situations: * ec_event_clearing is ACPI_EC_EVT_TIMING_STATUS and the state of an ACPI_EC_COMMAND_QUERY transaction becomes ACPI_EC_COMMAND_POLL. * ec_event_clearing is ACPI_EC_EVT_TIMING_QUERY and the state of an ACPI_EC_COMMAND_QUERY transaction becomes ACPI_EC_COMMAND_COMPLETE. * ec_event_clearing is either ACPI_EC_EVT_TIMING_STATUS or ACPI_EC_EVT_TIMING_QUERY and there are no more events to process (ie. ec->events_to_process becomes 0). If ec_event_clearing is ACPI_EC_EVT_TIMING_EVENT, however, the state must change from "In progress" to "Complete" before it can change to "Ready". The changes from "In progress" to "Complete" in that case occur in the following situations: * The state of an ACPI_EC_COMMAND_QUERY transaction becomes ACPI_EC_COMMAND_COMPLETE. * There are no more events to process (ie. ec->events_to_process becomes 0). Finally, the state changes from "Complete" to "Ready" when advance_transaction() is invoked when the state is "Complete" and the state of the current transaction is not ACPI_EC_COMMAND_POLL. To make this state machine visible in the code, add a new event_state field to struct acpi_ec and modify the code to use it istead the EC_FLAGS_QUERY_PENDING and EC_FLAGS_QUERY_GUARDING flags. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-11-23 19:44:46 +01:00
ACPI: EC: Make the event work state machine visible The EC driver uses a relatively simple state machine for the event work handling, but it is not really straightforward to figure out. The states are as follows: "Ready": The event handling work can be submitted. In this state, the EC_FLAGS_QUERY_PENDING flag is clear. "In progress": The event handling work is pending or is being processed. It cannot be submitted again. In ths state, the EC_FLAGS_QUERY_PENDING flag is set and both the events_to_process count is nonzero and the EC_FLAGS_QUERY_GUARDING flag is clear. "Complete": The event handling work has been completed, but it still cannot be submitted again. In ths state, the EC_FLAGS_QUERY_PENDING flag is set and the events_to_process count is zero or the EC_FLAGS_QUERY_GUARDING flag is set. The state changes from "Ready" to "In progress" when new event is detected by advance_transaction() and acpi_ec_submit_event() is called by it. Next, the state can change from "In progress" directly to "Ready" in the following situations: * ec_event_clearing is ACPI_EC_EVT_TIMING_STATUS and the state of an ACPI_EC_COMMAND_QUERY transaction becomes ACPI_EC_COMMAND_POLL. * ec_event_clearing is ACPI_EC_EVT_TIMING_QUERY and the state of an ACPI_EC_COMMAND_QUERY transaction becomes ACPI_EC_COMMAND_COMPLETE. * ec_event_clearing is either ACPI_EC_EVT_TIMING_STATUS or ACPI_EC_EVT_TIMING_QUERY and there are no more events to process (ie. ec->events_to_process becomes 0). If ec_event_clearing is ACPI_EC_EVT_TIMING_EVENT, however, the state must change from "In progress" to "Complete" before it can change to "Ready". The changes from "In progress" to "Complete" in that case occur in the following situations: * The state of an ACPI_EC_COMMAND_QUERY transaction becomes ACPI_EC_COMMAND_COMPLETE. * There are no more events to process (ie. ec->events_to_process becomes 0). Finally, the state changes from "Complete" to "Ready" when advance_transaction() is invoked when the state is "Complete" and the state of the current transaction is not ACPI_EC_COMMAND_POLL. To make this state machine visible in the code, add a new event_state field to struct acpi_ec and modify the code to use it istead the EC_FLAGS_QUERY_PENDING and EC_FLAGS_QUERY_GUARDING flags. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-11-23 19:44:46 +01:00
ACPI / EC: Fix issues related to the SCI_EVT handling This patch fixes 2 issues related to the draining behavior. But it doesn't implement the draining support, it only cleans up code so that further draining support is possible. The draining behavior is expected by some platforms (for example, Samsung) where SCI_EVT is set only once for a set of events and might be cleared for the very first QR_EC command issued after SCI_EVT is set. EC firmware on such platforms will return 0x00 to indicate "no outstanding event". Thus after seeing an SCI_EVT indication, EC driver need to fetch events until 0x00 returned (see acpi_ec_clear()). Issue 1 - acpi_ec_submit_query(): It's reported on Samsung laptops that SCI_EVT isn't checked when the transactions are advanced in ec_poll(), which leads to SCI_EVT triggering source lost: If no EC GPE IRQs are arrived after that, EC driver cannot detect this event and handle it. See comment 244/247 for kernel bugzilla 44161. This patch fixes this issue by moving SCI_EVT checks into advance_transaction(). So that SCI_EVT is checked each time we are going to handle the EC firmware indications. And this check will happen for both IRQ context and task context. Since after doing that, SCI_EVT is also checked after completing a transaction, ec_check_sci() and ec_check_sci_sync() can be removed. Issue 2 - acpi_ec_complete_query(): We expect to clear EC_FLAGS_QUERY_PENDING to allow queuing another draining QR_EC after writing a QR_EC command and before reading the event. After reading the event, SCI_EVT might be cleared by the firmware, thus it may not be possible to queue such a draining QR_EC at that time. But putting the EC_FLAGS_QUERY_PENDING clearing code after start_transaction() is wrong as there are chances that after start_transaction(), QR_EC can fail to be sent. If this happens, EC_FLAG_QUERY_PENDING will be cleared earlier. As a consequence, the draining QR_EC will also be queued earlier than expected. This patch also moves this code into advance_transaction() where QR_EC is just sent (ACPI_EC_COMMAND_POLL flagged) to fix this issue. Notes: 1. After introducing the 2 SCI_EVT related handlings into advance_transaction(), a next QR_EC can be queued right after writing the current QR_EC command and before reading the event. But this still hasn't implemented the draining behavior as the draining support requires: If a previous returned event value isn't 0x00, a draining QR_EC need to be issued even when SCI_EVT isn't set. 2. In this patch, acpi_os_execute() is also converted into a seperate work item to avoid invoking kmalloc() in the atomic context. We can do this because of the previous global lock fix. 3. Originally, EC_FLAGS_EVENT_PENDING is also used to avoid queuing up multiple work items (created by acpi_os_execute()), this can be covered by only using a single work item. But this patch still keeps this flag as there are different usages in the driver initialization steps relying on this flag. Link: https://bugzilla.kernel.org/show_bug.cgi?id=44161 Reported-by: Kieran Clancy <clancy.kieran@gmail.com> Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-01-14 19:28:47 +08:00
ACPI / EC: Fix regression related to triggering source of EC event handling Originally the Samsung quirks removed by commit 4c237371 can be covered by commit e923e8e7 and ec_freeze_events=Y mode. But commit 9c40f956 changed ec_freeze_events=Y back to N, making this problem re-surface. Actually, if commit e923e8e7 is robust enough, we can freely change ec_freeze_events mode, so this patch fixes the issue by improving commit e923e8e7. Related commits listed in the merged order: Commit: e923e8e79e18fd6be9162f1be6b99a002e9df2cb Subject: ACPI / EC: Fix an issue that SCI_EVT cannot be detected after event is enabled Commit: 4c237371f290d1ed3b2071dd43554362137b1cce Subject: ACPI / EC: Remove old CLEAR_ON_RESUME quirk Commit: 9c40f956ce9b331493347d1b3cb7e384f7dc0581 Subject: Revert "ACPI / EC: Enable event freeze mode..." to fix a regression This patch not only fixes the reported post-resume EC event triggering source issue, but also fixes an unreported similar issue related to the driver bind by adding EC event triggering source in ec_install_handlers(). Fixes: e923e8e79e18 (ACPI / EC: Fix an issue that SCI_EVT cannot be detected after event is enabled) Fixes: 4c237371f290 (ACPI / EC: Remove old CLEAR_ON_RESUME quirk) Fixes: 9c40f956ce9b (Revert "ACPI / EC: Enable event freeze mode..." to fix a regression) Link: https://bugzilla.kernel.org/show_bug.cgi?id=196833 Signed-off-by: Lv Zheng <lv.zheng@intel.com> Reported-by: Alistair Hamilton <ahpatent@gmail.com> Tested-by: Alistair Hamilton <ahpatent@gmail.com> Cc: 4.11+ <stable@vger.kernel.org> # 4.11+ Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2017-09-26 16:54:03 +08:00
ACPI: EC: Rework flushing of pending work There is a race condition in the ACPI EC driver, between __acpi_ec_flush_event() and acpi_ec_event_handler(), that may cause systems to stay in suspended-to-idle forever after a wakeup event coming from the EC. Namely, acpi_s2idle_wake() calls acpi_ec_flush_work() to wait until the delayed work resulting from the handling of the EC GPE in acpi_ec_dispatch_gpe() is processed, and that function invokes __acpi_ec_flush_event() which uses wait_event() to wait for ec->nr_pending_queries to become zero on ec->wait, and that wait queue may be woken up too early. Suppose that acpi_ec_dispatch_gpe() has caused acpi_ec_gpe_handler() to run, so advance_transaction() has been called and it has invoked acpi_ec_submit_query() to queue up an event work item, so ec->nr_pending_queries has been incremented (under ec->lock). The work function of that work item, acpi_ec_event_handler() runs later and calls acpi_ec_query() to process the event. That function calls acpi_ec_transaction() which invokes acpi_ec_transaction_unlocked() and the latter wakes up ec->wait under ec->lock, but it drops that lock before returning. When acpi_ec_query() returns, acpi_ec_event_handler() acquires ec->lock and decrements ec->nr_pending_queries, but at that point __acpi_ec_flush_event() (woken up previously) may already have acquired ec->lock, checked the value of ec->nr_pending_queries (and it would not have been zero then) and decided to go back to sleep. Next, if ec->nr_pending_queries is equal to zero now, the loop in acpi_ec_event_handler() terminates, ec->lock is released and acpi_ec_check_event() is called, but it does nothing unless ec_event_clearing is equal to ACPI_EC_EVT_TIMING_EVENT (which is not the case by default). In the end, if no more event work items have been queued up while executing acpi_ec_transaction_unlocked(), there is nothing to wake up __acpi_ec_flush_event() again and it sleeps forever, so the suspend-to-idle loop cannot make progress and the system is permanently suspended. To avoid this issue, notice that it actually is not necessary to wait for ec->nr_pending_queries to become zero in every case in which __acpi_ec_flush_event() is used. First, during platform-based system suspend (not suspend-to-idle), __acpi_ec_flush_event() is called by acpi_ec_disable_event() after clearing the EC_FLAGS_QUERY_ENABLED flag, which prevents acpi_ec_submit_query() from submitting any new event work items, so calling flush_scheduled_work() and flushing ec_query_wq subsequently (in order to wait until all of the queries in that queue have been processed) would be sufficient to flush all of the pending EC work in that case. Second, the purpose of the flushing of pending EC work while suspended-to-idle described above really is to wait until the first event work item coming from acpi_ec_dispatch_gpe() is complete, because it should produce system wakeup events if that is a valid EC-based system wakeup, so calling flush_scheduled_work() followed by flushing ec_query_wq is also sufficient for that purpose. Rework the code to follow the above observations. Fixes: 56b9918490 ("PM: sleep: Simplify suspend-to-idle control flow") Reported-by: Kenneth R. Crudup <kenny@panix.com> Tested-by: Kenneth R. Crudup <kenny@panix.com> Cc: 5.4+ <stable@vger.kernel.org> # 5.4+ Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2019-11-28 23:47:51 +01:00
ACPI / EC: Add PM operations to improve event handling for suspend process In the original EC driver, though the event handling is not explicitly stopped, the EC driver is actually not able to handle events during the noirq stage as the EC driver is not prepared to handle the EC events in the polling mode. So if there is no advance_transaction() triggered, the EC driver couldn't notice the EC events. However, do we actually need to handle EC events during suspend/resume stage? EC events are mostly useless for the suspend/resume period (key strokes and battery/thermal updates, etc.,), and the useful ones (lid close, power/sleep button press) should have already been delivered to the OSPM to trigger the power saving operations. Thus this patch implements acpi_ec_disable_event() to be a reverse call of acpi_ec_enable_event(), with which, the EC driver is able to stop handling the EC events in a position before entering the noirq stage. Since there are actually 2 choices for us: 1. implement event handling in polling mode; 2. stop event handling before entering noirq stage. And this patch only implements the second choice using .suspend() callback. Thus this is experimental (first choice is better? or different hook position is better?). This patch finally keeps the old behavior by default and prepares a boot parameter to enable this feature. The differences of the event handling availability between the old behavior (this patch is not applied) and the new behavior (this patch is applied) are as follows: !FreezeEvents FreezeEvents before suspend Y Y suspend before EC Y Y suspend after EC Y N suspend_late Y N suspend_noirq Y (actually N) N resume_noirq Y (actually N) N resume_late Y (actually N) N resume before EC Y (actually N) N resume after EC Y Y after resume Y Y Where "actually N" means if there is no EC transactions, the EC driver is actually not able to notice the pending events. We can see that FreezeEvents is the only approach now can actually flush the EC event handling with both query commands and _Qxx evaluations flushed, other modes can only flush the EC event handling with only query commands flushed, _Qxx evaluations occurred after stopping the EC driver may end up failure due to the failure of the EC transaction carried out in the _Qxx control methods. We also can see that this feature should be able to trigger some platform notifications later than resuming other drivers. Signed-off-by: Lv Zheng <lv.zheng@intel.com> Tested-by: Todd E Brandt <todd.e.brandt@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2016-08-03 16:01:43 +08:00
ACPI: EC: Rework flushing of EC work while suspended to idle The flushing of pending work in the EC driver uses drain_workqueue() to flush the event handling work that can requeue itself via advance_transaction(), but this is problematic, because that work may also be requeued from the query workqueue. Namely, if an EC transaction is carried out during the execution of a query handler, it involves calling advance_transaction() which may queue up the event handling work again. This causes the kernel to complain about attempts to add a work item to the EC event workqueue while it is being drained and worst-case it may cause a valid event to be skipped. To avoid this problem, introduce two new counters, events_in_progress and queries_in_progress, incremented when a work item is queued on the event workqueue or the query workqueue, respectively, and decremented at the end of the corresponding work function, and make acpi_ec_dispatch_gpe() the workqueues in a loop until the both of these counters are zero (or system wakeup is pending) instead of calling acpi_ec_flush_work(). At the same time, change __acpi_ec_flush_work() to call flush_workqueue() instead of drain_workqueue() to flush the event workqueue. While at it, use the observation that the work item queued in acpi_ec_query() cannot be pending at that time, because it is used only once, to simplify the code in there. Additionally, clean up a comment in acpi_ec_query() and adjust white space in acpi_ec_event_processor(). Fixes: f0ac20c3f613 ("ACPI: EC: Fix flushing of pending work") Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-11-23 19:36:51 +01:00
ACPI: EC: Rework flushing of pending work There is a race condition in the ACPI EC driver, between __acpi_ec_flush_event() and acpi_ec_event_handler(), that may cause systems to stay in suspended-to-idle forever after a wakeup event coming from the EC. Namely, acpi_s2idle_wake() calls acpi_ec_flush_work() to wait until the delayed work resulting from the handling of the EC GPE in acpi_ec_dispatch_gpe() is processed, and that function invokes __acpi_ec_flush_event() which uses wait_event() to wait for ec->nr_pending_queries to become zero on ec->wait, and that wait queue may be woken up too early. Suppose that acpi_ec_dispatch_gpe() has caused acpi_ec_gpe_handler() to run, so advance_transaction() has been called and it has invoked acpi_ec_submit_query() to queue up an event work item, so ec->nr_pending_queries has been incremented (under ec->lock). The work function of that work item, acpi_ec_event_handler() runs later and calls acpi_ec_query() to process the event. That function calls acpi_ec_transaction() which invokes acpi_ec_transaction_unlocked() and the latter wakes up ec->wait under ec->lock, but it drops that lock before returning. When acpi_ec_query() returns, acpi_ec_event_handler() acquires ec->lock and decrements ec->nr_pending_queries, but at that point __acpi_ec_flush_event() (woken up previously) may already have acquired ec->lock, checked the value of ec->nr_pending_queries (and it would not have been zero then) and decided to go back to sleep. Next, if ec->nr_pending_queries is equal to zero now, the loop in acpi_ec_event_handler() terminates, ec->lock is released and acpi_ec_check_event() is called, but it does nothing unless ec_event_clearing is equal to ACPI_EC_EVT_TIMING_EVENT (which is not the case by default). In the end, if no more event work items have been queued up while executing acpi_ec_transaction_unlocked(), there is nothing to wake up __acpi_ec_flush_event() again and it sleeps forever, so the suspend-to-idle loop cannot make progress and the system is permanently suspended. To avoid this issue, notice that it actually is not necessary to wait for ec->nr_pending_queries to become zero in every case in which __acpi_ec_flush_event() is used. First, during platform-based system suspend (not suspend-to-idle), __acpi_ec_flush_event() is called by acpi_ec_disable_event() after clearing the EC_FLAGS_QUERY_ENABLED flag, which prevents acpi_ec_submit_query() from submitting any new event work items, so calling flush_scheduled_work() and flushing ec_query_wq subsequently (in order to wait until all of the queries in that queue have been processed) would be sufficient to flush all of the pending EC work in that case. Second, the purpose of the flushing of pending EC work while suspended-to-idle described above really is to wait until the first event work item coming from acpi_ec_dispatch_gpe() is complete, because it should produce system wakeup events if that is a valid EC-based system wakeup, so calling flush_scheduled_work() followed by flushing ec_query_wq is also sufficient for that purpose. Rework the code to follow the above observations. Fixes: 56b9918490 ("PM: sleep: Simplify suspend-to-idle control flow") Reported-by: Kenneth R. Crudup <kenny@panix.com> Tested-by: Kenneth R. Crudup <kenny@panix.com> Cc: 5.4+ <stable@vger.kernel.org> # 5.4+ Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2019-11-28 23:47:51 +01:00
ACPI / EC: Add PM operations to improve event handling for suspend process In the original EC driver, though the event handling is not explicitly stopped, the EC driver is actually not able to handle events during the noirq stage as the EC driver is not prepared to handle the EC events in the polling mode. So if there is no advance_transaction() triggered, the EC driver couldn't notice the EC events. However, do we actually need to handle EC events during suspend/resume stage? EC events are mostly useless for the suspend/resume period (key strokes and battery/thermal updates, etc.,), and the useful ones (lid close, power/sleep button press) should have already been delivered to the OSPM to trigger the power saving operations. Thus this patch implements acpi_ec_disable_event() to be a reverse call of acpi_ec_enable_event(), with which, the EC driver is able to stop handling the EC events in a position before entering the noirq stage. Since there are actually 2 choices for us: 1. implement event handling in polling mode; 2. stop event handling before entering noirq stage. And this patch only implements the second choice using .suspend() callback. Thus this is experimental (first choice is better? or different hook position is better?). This patch finally keeps the old behavior by default and prepares a boot parameter to enable this feature. The differences of the event handling availability between the old behavior (this patch is not applied) and the new behavior (this patch is applied) are as follows: !FreezeEvents FreezeEvents before suspend Y Y suspend before EC Y Y suspend after EC Y N suspend_late Y N suspend_noirq Y (actually N) N resume_noirq Y (actually N) N resume_late Y (actually N) N resume before EC Y (actually N) N resume after EC Y Y after resume Y Y Where "actually N" means if there is no EC transactions, the EC driver is actually not able to notice the pending events. We can see that FreezeEvents is the only approach now can actually flush the EC event handling with both query commands and _Qxx evaluations flushed, other modes can only flush the EC event handling with only query commands flushed, _Qxx evaluations occurred after stopping the EC driver may end up failure due to the failure of the EC transaction carried out in the _Qxx control methods. We also can see that this feature should be able to trigger some platform notifications later than resuming other drivers. Signed-off-by: Lv Zheng <lv.zheng@intel.com> Tested-by: Todd E Brandt <todd.e.brandt@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2016-08-03 16:01:43 +08:00
ACPI / EC: Add PM operations to improve event handling for suspend process In the original EC driver, though the event handling is not explicitly stopped, the EC driver is actually not able to handle events during the noirq stage as the EC driver is not prepared to handle the EC events in the polling mode. So if there is no advance_transaction() triggered, the EC driver couldn't notice the EC events. However, do we actually need to handle EC events during suspend/resume stage? EC events are mostly useless for the suspend/resume period (key strokes and battery/thermal updates, etc.,), and the useful ones (lid close, power/sleep button press) should have already been delivered to the OSPM to trigger the power saving operations. Thus this patch implements acpi_ec_disable_event() to be a reverse call of acpi_ec_enable_event(), with which, the EC driver is able to stop handling the EC events in a position before entering the noirq stage. Since there are actually 2 choices for us: 1. implement event handling in polling mode; 2. stop event handling before entering noirq stage. And this patch only implements the second choice using .suspend() callback. Thus this is experimental (first choice is better? or different hook position is better?). This patch finally keeps the old behavior by default and prepares a boot parameter to enable this feature. The differences of the event handling availability between the old behavior (this patch is not applied) and the new behavior (this patch is applied) are as follows: !FreezeEvents FreezeEvents before suspend Y Y suspend before EC Y Y suspend after EC Y N suspend_late Y N suspend_noirq Y (actually N) N resume_noirq Y (actually N) N resume_late Y (actually N) N resume before EC Y (actually N) N resume after EC Y Y after resume Y Y Where "actually N" means if there is no EC transactions, the EC driver is actually not able to notice the pending events. We can see that FreezeEvents is the only approach now can actually flush the EC event handling with both query commands and _Qxx evaluations flushed, other modes can only flush the EC event handling with only query commands flushed, _Qxx evaluations occurred after stopping the EC driver may end up failure due to the failure of the EC transaction carried out in the _Qxx control methods. We also can see that this feature should be able to trigger some platform notifications later than resuming other drivers. Signed-off-by: Lv Zheng <lv.zheng@intel.com> Tested-by: Todd E Brandt <todd.e.brandt@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2016-08-03 16:01:43 +08:00
ACPI: EC: Rework flushing of pending work There is a race condition in the ACPI EC driver, between __acpi_ec_flush_event() and acpi_ec_event_handler(), that may cause systems to stay in suspended-to-idle forever after a wakeup event coming from the EC. Namely, acpi_s2idle_wake() calls acpi_ec_flush_work() to wait until the delayed work resulting from the handling of the EC GPE in acpi_ec_dispatch_gpe() is processed, and that function invokes __acpi_ec_flush_event() which uses wait_event() to wait for ec->nr_pending_queries to become zero on ec->wait, and that wait queue may be woken up too early. Suppose that acpi_ec_dispatch_gpe() has caused acpi_ec_gpe_handler() to run, so advance_transaction() has been called and it has invoked acpi_ec_submit_query() to queue up an event work item, so ec->nr_pending_queries has been incremented (under ec->lock). The work function of that work item, acpi_ec_event_handler() runs later and calls acpi_ec_query() to process the event. That function calls acpi_ec_transaction() which invokes acpi_ec_transaction_unlocked() and the latter wakes up ec->wait under ec->lock, but it drops that lock before returning. When acpi_ec_query() returns, acpi_ec_event_handler() acquires ec->lock and decrements ec->nr_pending_queries, but at that point __acpi_ec_flush_event() (woken up previously) may already have acquired ec->lock, checked the value of ec->nr_pending_queries (and it would not have been zero then) and decided to go back to sleep. Next, if ec->nr_pending_queries is equal to zero now, the loop in acpi_ec_event_handler() terminates, ec->lock is released and acpi_ec_check_event() is called, but it does nothing unless ec_event_clearing is equal to ACPI_EC_EVT_TIMING_EVENT (which is not the case by default). In the end, if no more event work items have been queued up while executing acpi_ec_transaction_unlocked(), there is nothing to wake up __acpi_ec_flush_event() again and it sleeps forever, so the suspend-to-idle loop cannot make progress and the system is permanently suspended. To avoid this issue, notice that it actually is not necessary to wait for ec->nr_pending_queries to become zero in every case in which __acpi_ec_flush_event() is used. First, during platform-based system suspend (not suspend-to-idle), __acpi_ec_flush_event() is called by acpi_ec_disable_event() after clearing the EC_FLAGS_QUERY_ENABLED flag, which prevents acpi_ec_submit_query() from submitting any new event work items, so calling flush_scheduled_work() and flushing ec_query_wq subsequently (in order to wait until all of the queries in that queue have been processed) would be sufficient to flush all of the pending EC work in that case. Second, the purpose of the flushing of pending EC work while suspended-to-idle described above really is to wait until the first event work item coming from acpi_ec_dispatch_gpe() is complete, because it should produce system wakeup events if that is a valid EC-based system wakeup, so calling flush_scheduled_work() followed by flushing ec_query_wq is also sufficient for that purpose. Rework the code to follow the above observations. Fixes: 56b9918490 ("PM: sleep: Simplify suspend-to-idle control flow") Reported-by: Kenneth R. Crudup <kenny@panix.com> Tested-by: Kenneth R. Crudup <kenny@panix.com> Cc: 5.4+ <stable@vger.kernel.org> # 5.4+ Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2019-11-28 23:47:51 +01:00
ACPI / EC: Add PM operations to improve event handling for suspend process In the original EC driver, though the event handling is not explicitly stopped, the EC driver is actually not able to handle events during the noirq stage as the EC driver is not prepared to handle the EC events in the polling mode. So if there is no advance_transaction() triggered, the EC driver couldn't notice the EC events. However, do we actually need to handle EC events during suspend/resume stage? EC events are mostly useless for the suspend/resume period (key strokes and battery/thermal updates, etc.,), and the useful ones (lid close, power/sleep button press) should have already been delivered to the OSPM to trigger the power saving operations. Thus this patch implements acpi_ec_disable_event() to be a reverse call of acpi_ec_enable_event(), with which, the EC driver is able to stop handling the EC events in a position before entering the noirq stage. Since there are actually 2 choices for us: 1. implement event handling in polling mode; 2. stop event handling before entering noirq stage. And this patch only implements the second choice using .suspend() callback. Thus this is experimental (first choice is better? or different hook position is better?). This patch finally keeps the old behavior by default and prepares a boot parameter to enable this feature. The differences of the event handling availability between the old behavior (this patch is not applied) and the new behavior (this patch is applied) are as follows: !FreezeEvents FreezeEvents before suspend Y Y suspend before EC Y Y suspend after EC Y N suspend_late Y N suspend_noirq Y (actually N) N resume_noirq Y (actually N) N resume_late Y (actually N) N resume before EC Y (actually N) N resume after EC Y Y after resume Y Y Where "actually N" means if there is no EC transactions, the EC driver is actually not able to notice the pending events. We can see that FreezeEvents is the only approach now can actually flush the EC event handling with both query commands and _Qxx evaluations flushed, other modes can only flush the EC event handling with only query commands flushed, _Qxx evaluations occurred after stopping the EC driver may end up failure due to the failure of the EC transaction carried out in the _Qxx control methods. We also can see that this feature should be able to trigger some platform notifications later than resuming other drivers. Signed-off-by: Lv Zheng <lv.zheng@intel.com> Tested-by: Todd E Brandt <todd.e.brandt@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2016-08-03 16:01:43 +08:00
ACPI: EC: Fix flushing of pending work Commit 016b87ca5c8c ("ACPI: EC: Rework flushing of pending work") introduced a subtle bug into the flushing of pending EC work while suspended to idle, which may cause the EC driver to fail to re-enable the EC GPE after handling a non-wakeup event (like a battery status change event, for example). The problem is that the work item flushed by flush_scheduled_work() in __acpi_ec_flush_work() may disable the EC GPE and schedule another work item expected to re-enable it, but that new work item is not flushed, so __acpi_ec_flush_work() returns with the EC GPE disabled and the CPU running it goes into an idle state subsequently. If all of the other CPUs are in idle states at that point, the EC GPE won't be re-enabled until at least one CPU is woken up by another interrupt source, so system wakeup events that would normally come from the EC then don't work. This is reproducible on a Dell XPS13 9360 in my office which sometimes stops reacting to power button and lid events (triggered by the EC on that machine) after switching from AC power to battery power or vice versa while suspended to idle (each of those switches causes the EC GPE to trigger for several times in a row, but they are not system wakeup events). To avoid this problem, it is necessary to drain the workqueue entirely in __acpi_ec_flush_work(), but that cannot be done with respect to system_wq, because work items may be added to it from other places while __acpi_ec_flush_work() is running. For this reason, make the EC driver use a dedicated workqueue for EC events processing (let that workqueue be ordered so that EC events are processed sequentially) and use drain_workqueue() on it in __acpi_ec_flush_work(). Fixes: 016b87ca5c8c ("ACPI: EC: Rework flushing of pending work") Cc: 5.4+ <stable@vger.kernel.org> # 5.4+ Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2020-02-11 10:07:43 +01:00
ACPI: EC: Rework flushing of pending work There is a race condition in the ACPI EC driver, between __acpi_ec_flush_event() and acpi_ec_event_handler(), that may cause systems to stay in suspended-to-idle forever after a wakeup event coming from the EC. Namely, acpi_s2idle_wake() calls acpi_ec_flush_work() to wait until the delayed work resulting from the handling of the EC GPE in acpi_ec_dispatch_gpe() is processed, and that function invokes __acpi_ec_flush_event() which uses wait_event() to wait for ec->nr_pending_queries to become zero on ec->wait, and that wait queue may be woken up too early. Suppose that acpi_ec_dispatch_gpe() has caused acpi_ec_gpe_handler() to run, so advance_transaction() has been called and it has invoked acpi_ec_submit_query() to queue up an event work item, so ec->nr_pending_queries has been incremented (under ec->lock). The work function of that work item, acpi_ec_event_handler() runs later and calls acpi_ec_query() to process the event. That function calls acpi_ec_transaction() which invokes acpi_ec_transaction_unlocked() and the latter wakes up ec->wait under ec->lock, but it drops that lock before returning. When acpi_ec_query() returns, acpi_ec_event_handler() acquires ec->lock and decrements ec->nr_pending_queries, but at that point __acpi_ec_flush_event() (woken up previously) may already have acquired ec->lock, checked the value of ec->nr_pending_queries (and it would not have been zero then) and decided to go back to sleep. Next, if ec->nr_pending_queries is equal to zero now, the loop in acpi_ec_event_handler() terminates, ec->lock is released and acpi_ec_check_event() is called, but it does nothing unless ec_event_clearing is equal to ACPI_EC_EVT_TIMING_EVENT (which is not the case by default). In the end, if no more event work items have been queued up while executing acpi_ec_transaction_unlocked(), there is nothing to wake up __acpi_ec_flush_event() again and it sleeps forever, so the suspend-to-idle loop cannot make progress and the system is permanently suspended. To avoid this issue, notice that it actually is not necessary to wait for ec->nr_pending_queries to become zero in every case in which __acpi_ec_flush_event() is used. First, during platform-based system suspend (not suspend-to-idle), __acpi_ec_flush_event() is called by acpi_ec_disable_event() after clearing the EC_FLAGS_QUERY_ENABLED flag, which prevents acpi_ec_submit_query() from submitting any new event work items, so calling flush_scheduled_work() and flushing ec_query_wq subsequently (in order to wait until all of the queries in that queue have been processed) would be sufficient to flush all of the pending EC work in that case. Second, the purpose of the flushing of pending EC work while suspended-to-idle described above really is to wait until the first event work item coming from acpi_ec_dispatch_gpe() is complete, because it should produce system wakeup events if that is a valid EC-based system wakeup, so calling flush_scheduled_work() followed by flushing ec_query_wq is also sufficient for that purpose. Rework the code to follow the above observations. Fixes: 56b9918490 ("PM: sleep: Simplify suspend-to-idle control flow") Reported-by: Kenneth R. Crudup <kenny@panix.com> Tested-by: Kenneth R. Crudup <kenny@panix.com> Cc: 5.4+ <stable@vger.kernel.org> # 5.4+ Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2019-11-28 23:47:51 +01:00
ACPI: EC: Rework flushing of pending work There is a race condition in the ACPI EC driver, between __acpi_ec_flush_event() and acpi_ec_event_handler(), that may cause systems to stay in suspended-to-idle forever after a wakeup event coming from the EC. Namely, acpi_s2idle_wake() calls acpi_ec_flush_work() to wait until the delayed work resulting from the handling of the EC GPE in acpi_ec_dispatch_gpe() is processed, and that function invokes __acpi_ec_flush_event() which uses wait_event() to wait for ec->nr_pending_queries to become zero on ec->wait, and that wait queue may be woken up too early. Suppose that acpi_ec_dispatch_gpe() has caused acpi_ec_gpe_handler() to run, so advance_transaction() has been called and it has invoked acpi_ec_submit_query() to queue up an event work item, so ec->nr_pending_queries has been incremented (under ec->lock). The work function of that work item, acpi_ec_event_handler() runs later and calls acpi_ec_query() to process the event. That function calls acpi_ec_transaction() which invokes acpi_ec_transaction_unlocked() and the latter wakes up ec->wait under ec->lock, but it drops that lock before returning. When acpi_ec_query() returns, acpi_ec_event_handler() acquires ec->lock and decrements ec->nr_pending_queries, but at that point __acpi_ec_flush_event() (woken up previously) may already have acquired ec->lock, checked the value of ec->nr_pending_queries (and it would not have been zero then) and decided to go back to sleep. Next, if ec->nr_pending_queries is equal to zero now, the loop in acpi_ec_event_handler() terminates, ec->lock is released and acpi_ec_check_event() is called, but it does nothing unless ec_event_clearing is equal to ACPI_EC_EVT_TIMING_EVENT (which is not the case by default). In the end, if no more event work items have been queued up while executing acpi_ec_transaction_unlocked(), there is nothing to wake up __acpi_ec_flush_event() again and it sleeps forever, so the suspend-to-idle loop cannot make progress and the system is permanently suspended. To avoid this issue, notice that it actually is not necessary to wait for ec->nr_pending_queries to become zero in every case in which __acpi_ec_flush_event() is used. First, during platform-based system suspend (not suspend-to-idle), __acpi_ec_flush_event() is called by acpi_ec_disable_event() after clearing the EC_FLAGS_QUERY_ENABLED flag, which prevents acpi_ec_submit_query() from submitting any new event work items, so calling flush_scheduled_work() and flushing ec_query_wq subsequently (in order to wait until all of the queries in that queue have been processed) would be sufficient to flush all of the pending EC work in that case. Second, the purpose of the flushing of pending EC work while suspended-to-idle described above really is to wait until the first event work item coming from acpi_ec_dispatch_gpe() is complete, because it should produce system wakeup events if that is a valid EC-based system wakeup, so calling flush_scheduled_work() followed by flushing ec_query_wq is also sufficient for that purpose. Rework the code to follow the above observations. Fixes: 56b9918490 ("PM: sleep: Simplify suspend-to-idle control flow") Reported-by: Kenneth R. Crudup <kenny@panix.com> Tested-by: Kenneth R. Crudup <kenny@panix.com> Cc: 5.4+ <stable@vger.kernel.org> # 5.4+ Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2019-11-28 23:47:51 +01:00
ACPI / EC: Add PM operations to improve event handling for suspend process In the original EC driver, though the event handling is not explicitly stopped, the EC driver is actually not able to handle events during the noirq stage as the EC driver is not prepared to handle the EC events in the polling mode. So if there is no advance_transaction() triggered, the EC driver couldn't notice the EC events. However, do we actually need to handle EC events during suspend/resume stage? EC events are mostly useless for the suspend/resume period (key strokes and battery/thermal updates, etc.,), and the useful ones (lid close, power/sleep button press) should have already been delivered to the OSPM to trigger the power saving operations. Thus this patch implements acpi_ec_disable_event() to be a reverse call of acpi_ec_enable_event(), with which, the EC driver is able to stop handling the EC events in a position before entering the noirq stage. Since there are actually 2 choices for us: 1. implement event handling in polling mode; 2. stop event handling before entering noirq stage. And this patch only implements the second choice using .suspend() callback. Thus this is experimental (first choice is better? or different hook position is better?). This patch finally keeps the old behavior by default and prepares a boot parameter to enable this feature. The differences of the event handling availability between the old behavior (this patch is not applied) and the new behavior (this patch is applied) are as follows: !FreezeEvents FreezeEvents before suspend Y Y suspend before EC Y Y suspend after EC Y N suspend_late Y N suspend_noirq Y (actually N) N resume_noirq Y (actually N) N resume_late Y (actually N) N resume before EC Y (actually N) N resume after EC Y Y after resume Y Y Where "actually N" means if there is no EC transactions, the EC driver is actually not able to notice the pending events. We can see that FreezeEvents is the only approach now can actually flush the EC event handling with both query commands and _Qxx evaluations flushed, other modes can only flush the EC event handling with only query commands flushed, _Qxx evaluations occurred after stopping the EC driver may end up failure due to the failure of the EC transaction carried out in the _Qxx control methods. We also can see that this feature should be able to trigger some platform notifications later than resuming other drivers. Signed-off-by: Lv Zheng <lv.zheng@intel.com> Tested-by: Todd E Brandt <todd.e.brandt@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2016-08-03 16:01:43 +08:00
ACPI / EC: Add event clearing variation support. We've been suffering from the uncertainty of the SCI_EVT clearing timing. This patch implements 3 of 4 possible modes to handle SCI_EVT clearing variations. The old behavior is kept in this patch. Status: QR_EC is re-checked as early as possible after checking previous SCI_EVT. This always leads to 2 QR_EC transactions per SCI_EVT indication and the target may implement event queue which returns 0x00 indicating "no outstanding event". This is proven to be a conflict against Windows behavior, but is still kept in this patch to make the EC driver robust to the possible regressions that may occur on Samsung platforms. Query: QR_EC is re-checked after the target has handled the QR_EC query request command pushed by the host. Event: QR_EC is re-checked after the target has noticed the query event response data pulled by the host. This timing is not determined by any IRQs, so we may need to use a guard period in this mode, which may explain the existence of the ec_guard() code used by the old EC driver where the re-check timing is implemented in the similar way as this mode. Method: QR_EC is re-checked as late as possible after completing the _Qxx evaluation. The target may implement SCI_EVT like a level triggered interrupt. It is proven on kernel bugzilla 94411 that, Windows will have all _Qxx evaluations parallelized. Thus unless required by further evidences, we needn't implement this mode as it is a conflict of the _Qxx parallelism requirement. Note that, according to the reports, there are platforms that cannot be handled using the "Status" mode without enabling the EC_FLAGS_QUERY_HANDSHAKE quirk. But they can be handled with the other modes according to the tests (kernel bugzilla 97381). The following log entry can be used to confirm the differences of the 3 modes as it should appear at the different positions for the 3 modes: Command(QR_EC) unblocked Status: appearing after EC_SC(W) = 0x84 Query: appearing after EC_DATA(R) = 0xXX where XX is the event number used to determine _QXX Event: appearing after first EC_SC(R) = 0xX0 SCI_EVT=x BURST=0 CMD=0 IBF=0 OBF=0 that is next to the following log entry: Command(QR_EC) completed by hardware 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=98111 Reported-and-tested-by: Gabriele Mazzotta <gabriele.mzt@gmail.com> Reported-and-tested-by: Tigran Gabrielyan <tigrangab@gmail.com> Reported-and-tested-by: Adrien D <ghbdtn@openmailbox.org> Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-06-11 13:21:38 +08:00
ACPI: EC: Make the event work state machine visible The EC driver uses a relatively simple state machine for the event work handling, but it is not really straightforward to figure out. The states are as follows: "Ready": The event handling work can be submitted. In this state, the EC_FLAGS_QUERY_PENDING flag is clear. "In progress": The event handling work is pending or is being processed. It cannot be submitted again. In ths state, the EC_FLAGS_QUERY_PENDING flag is set and both the events_to_process count is nonzero and the EC_FLAGS_QUERY_GUARDING flag is clear. "Complete": The event handling work has been completed, but it still cannot be submitted again. In ths state, the EC_FLAGS_QUERY_PENDING flag is set and the events_to_process count is zero or the EC_FLAGS_QUERY_GUARDING flag is set. The state changes from "Ready" to "In progress" when new event is detected by advance_transaction() and acpi_ec_submit_event() is called by it. Next, the state can change from "In progress" directly to "Ready" in the following situations: * ec_event_clearing is ACPI_EC_EVT_TIMING_STATUS and the state of an ACPI_EC_COMMAND_QUERY transaction becomes ACPI_EC_COMMAND_POLL. * ec_event_clearing is ACPI_EC_EVT_TIMING_QUERY and the state of an ACPI_EC_COMMAND_QUERY transaction becomes ACPI_EC_COMMAND_COMPLETE. * ec_event_clearing is either ACPI_EC_EVT_TIMING_STATUS or ACPI_EC_EVT_TIMING_QUERY and there are no more events to process (ie. ec->events_to_process becomes 0). If ec_event_clearing is ACPI_EC_EVT_TIMING_EVENT, however, the state must change from "In progress" to "Complete" before it can change to "Ready". The changes from "In progress" to "Complete" in that case occur in the following situations: * The state of an ACPI_EC_COMMAND_QUERY transaction becomes ACPI_EC_COMMAND_COMPLETE. * There are no more events to process (ie. ec->events_to_process becomes 0). Finally, the state changes from "Complete" to "Ready" when advance_transaction() is invoked when the state is "Complete" and the state of the current transaction is not ACPI_EC_COMMAND_POLL. To make this state machine visible in the code, add a new event_state field to struct acpi_ec and modify the code to use it istead the EC_FLAGS_QUERY_PENDING and EC_FLAGS_QUERY_GUARDING flags. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-11-23 19:44:46 +01:00
ACPI: EC: Make the event work state machine visible The EC driver uses a relatively simple state machine for the event work handling, but it is not really straightforward to figure out. The states are as follows: "Ready": The event handling work can be submitted. In this state, the EC_FLAGS_QUERY_PENDING flag is clear. "In progress": The event handling work is pending or is being processed. It cannot be submitted again. In ths state, the EC_FLAGS_QUERY_PENDING flag is set and both the events_to_process count is nonzero and the EC_FLAGS_QUERY_GUARDING flag is clear. "Complete": The event handling work has been completed, but it still cannot be submitted again. In ths state, the EC_FLAGS_QUERY_PENDING flag is set and the events_to_process count is zero or the EC_FLAGS_QUERY_GUARDING flag is set. The state changes from "Ready" to "In progress" when new event is detected by advance_transaction() and acpi_ec_submit_event() is called by it. Next, the state can change from "In progress" directly to "Ready" in the following situations: * ec_event_clearing is ACPI_EC_EVT_TIMING_STATUS and the state of an ACPI_EC_COMMAND_QUERY transaction becomes ACPI_EC_COMMAND_POLL. * ec_event_clearing is ACPI_EC_EVT_TIMING_QUERY and the state of an ACPI_EC_COMMAND_QUERY transaction becomes ACPI_EC_COMMAND_COMPLETE. * ec_event_clearing is either ACPI_EC_EVT_TIMING_STATUS or ACPI_EC_EVT_TIMING_QUERY and there are no more events to process (ie. ec->events_to_process becomes 0). If ec_event_clearing is ACPI_EC_EVT_TIMING_EVENT, however, the state must change from "In progress" to "Complete" before it can change to "Ready". The changes from "In progress" to "Complete" in that case occur in the following situations: * The state of an ACPI_EC_COMMAND_QUERY transaction becomes ACPI_EC_COMMAND_COMPLETE. * There are no more events to process (ie. ec->events_to_process becomes 0). Finally, the state changes from "Complete" to "Ready" when advance_transaction() is invoked when the state is "Complete" and the state of the current transaction is not ACPI_EC_COMMAND_POLL. To make this state machine visible in the code, add a new event_state field to struct acpi_ec and modify the code to use it istead the EC_FLAGS_QUERY_PENDING and EC_FLAGS_QUERY_GUARDING flags. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-11-23 19:44:46 +01:00
ACPI: EC: Make the event work state machine visible The EC driver uses a relatively simple state machine for the event work handling, but it is not really straightforward to figure out. The states are as follows: "Ready": The event handling work can be submitted. In this state, the EC_FLAGS_QUERY_PENDING flag is clear. "In progress": The event handling work is pending or is being processed. It cannot be submitted again. In ths state, the EC_FLAGS_QUERY_PENDING flag is set and both the events_to_process count is nonzero and the EC_FLAGS_QUERY_GUARDING flag is clear. "Complete": The event handling work has been completed, but it still cannot be submitted again. In ths state, the EC_FLAGS_QUERY_PENDING flag is set and the events_to_process count is zero or the EC_FLAGS_QUERY_GUARDING flag is set. The state changes from "Ready" to "In progress" when new event is detected by advance_transaction() and acpi_ec_submit_event() is called by it. Next, the state can change from "In progress" directly to "Ready" in the following situations: * ec_event_clearing is ACPI_EC_EVT_TIMING_STATUS and the state of an ACPI_EC_COMMAND_QUERY transaction becomes ACPI_EC_COMMAND_POLL. * ec_event_clearing is ACPI_EC_EVT_TIMING_QUERY and the state of an ACPI_EC_COMMAND_QUERY transaction becomes ACPI_EC_COMMAND_COMPLETE. * ec_event_clearing is either ACPI_EC_EVT_TIMING_STATUS or ACPI_EC_EVT_TIMING_QUERY and there are no more events to process (ie. ec->events_to_process becomes 0). If ec_event_clearing is ACPI_EC_EVT_TIMING_EVENT, however, the state must change from "In progress" to "Complete" before it can change to "Ready". The changes from "In progress" to "Complete" in that case occur in the following situations: * The state of an ACPI_EC_COMMAND_QUERY transaction becomes ACPI_EC_COMMAND_COMPLETE. * There are no more events to process (ie. ec->events_to_process becomes 0). Finally, the state changes from "Complete" to "Ready" when advance_transaction() is invoked when the state is "Complete" and the state of the current transaction is not ACPI_EC_COMMAND_POLL. To make this state machine visible in the code, add a new event_state field to struct acpi_ec and modify the code to use it istead the EC_FLAGS_QUERY_PENDING and EC_FLAGS_QUERY_GUARDING flags. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-11-23 19:44:46 +01:00
ACPI / EC: Add event clearing variation support. We've been suffering from the uncertainty of the SCI_EVT clearing timing. This patch implements 3 of 4 possible modes to handle SCI_EVT clearing variations. The old behavior is kept in this patch. Status: QR_EC is re-checked as early as possible after checking previous SCI_EVT. This always leads to 2 QR_EC transactions per SCI_EVT indication and the target may implement event queue which returns 0x00 indicating "no outstanding event". This is proven to be a conflict against Windows behavior, but is still kept in this patch to make the EC driver robust to the possible regressions that may occur on Samsung platforms. Query: QR_EC is re-checked after the target has handled the QR_EC query request command pushed by the host. Event: QR_EC is re-checked after the target has noticed the query event response data pulled by the host. This timing is not determined by any IRQs, so we may need to use a guard period in this mode, which may explain the existence of the ec_guard() code used by the old EC driver where the re-check timing is implemented in the similar way as this mode. Method: QR_EC is re-checked as late as possible after completing the _Qxx evaluation. The target may implement SCI_EVT like a level triggered interrupt. It is proven on kernel bugzilla 94411 that, Windows will have all _Qxx evaluations parallelized. Thus unless required by further evidences, we needn't implement this mode as it is a conflict of the _Qxx parallelism requirement. Note that, according to the reports, there are platforms that cannot be handled using the "Status" mode without enabling the EC_FLAGS_QUERY_HANDSHAKE quirk. But they can be handled with the other modes according to the tests (kernel bugzilla 97381). The following log entry can be used to confirm the differences of the 3 modes as it should appear at the different positions for the 3 modes: Command(QR_EC) unblocked Status: appearing after EC_SC(W) = 0x84 Query: appearing after EC_DATA(R) = 0xXX where XX is the event number used to determine _QXX Event: appearing after first EC_SC(R) = 0xX0 SCI_EVT=x BURST=0 CMD=0 IBF=0 OBF=0 that is next to the following log entry: Command(QR_EC) completed by hardware 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=98111 Reported-and-tested-by: Gabriele Mazzotta <gabriele.mzt@gmail.com> Reported-and-tested-by: Tigran Gabrielyan <tigrangab@gmail.com> Reported-and-tested-by: Adrien D <ghbdtn@openmailbox.org> Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-06-11 13:21:38 +08:00
ACPI / EC: Fix and clean up register access guarding logics. In the polling mode, EC driver shouldn't access the EC registers too frequently. Though this statement is concluded from the non-root caused bugs (see links below), we've maintained the register access guarding logics in the current EC driver. The guarding logics can be found here and there, makes it hard to root cause real timing issues. This patch collects the guarding logics into one single function so that all hidden logics related to this can be seen clearly. The current guarding related code also has several issues: 1. Per-transaction timestamp prevents inter-transaction guarding from being implemented in the same place. We have an inter-transaction udelay() in acpi_ec_transaction_unblocked(), this logic can be merged into ec_poll() if we can use per-device timestamp. This patch completes such merge to form a new ec_guard() function and collects all guarding related hidden logics in it. One hidden logic is: there is no inter-transaction guarding performed for non MSI quirk (wait polling mode), this patch skips inter-transaction guarding before wait_event_timeout() for the wait polling mode to reveal the hidden logic. The other hidden logic is: there is msleep() inter-transaction guarding performed when the GPE storming is observed. As after merging this commit: Commit: e1d4d90fc0313d3d58cbd7912c90f8ef24df45ff Subject: ACPI / EC: Refine command storm prevention support EC_FLAGS_COMMAND_STORM is ensured to be cleared after invoking acpi_ec_transaction_unlocked(), the msleep() guard logic will never happen now. Since no one complains such change, this logic is likely added during the old times where the EC race issues are not fixed and the bugs are false root-caused to the timing issue. This patch simply removes the out-dated logic. We can restore it by stop skipping inter-transaction guarding for wait polling mode. Two different delay values are defined for msleep() and udelay() while they are merged in this patch to 550us. 2. time_after() causes additional delay in the polling mode (can only be observed in noirq suspend/resume processes where polling mode is always used) before advance_transaction() is invoked ("wait polling" log is added before wait_event_timeout()). We can see 2 wait_event_timeout() invocations. This is because time_after() ensures a ">" validation while we only need a ">=" validation here: [ 86.739909] ACPI: Waking up from system sleep state S3 [ 86.742857] ACPI : EC: 2: Increase command [ 86.742859] ACPI : EC: ***** Command(RD_EC) started ***** [ 86.742861] ACPI : EC: ===== TASK (0) ===== [ 86.742871] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 86.742873] ACPI : EC: EC_SC(W) = 0x80 [ 86.742876] ACPI : EC: ***** Event started ***** [ 86.742880] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.743972] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.747966] ACPI : EC: ===== TASK (0) ===== [ 86.747977] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 86.747978] ACPI : EC: EC_DATA(W) = 0x06 [ 86.747981] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.751971] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.755969] ACPI : EC: ===== TASK (0) ===== [ 86.755991] ACPI : EC: EC_SC(R) = 0x21 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=1 [ 86.755993] ACPI : EC: EC_DATA(R) = 0x03 [ 86.755994] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.755995] ACPI : EC: ***** Command(RD_EC) stopped ***** [ 86.755996] ACPI : EC: 1: Decrease command This patch corrects this by using time_before() instead in ec_guard(): [ 54.283146] ACPI: Waking up from system sleep state S3 [ 54.285414] ACPI : EC: 2: Increase command [ 54.285415] ACPI : EC: ***** Command(RD_EC) started ***** [ 54.285416] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.285417] ACPI : EC: ===== TASK (0) ===== [ 54.285424] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 54.285425] ACPI : EC: EC_SC(W) = 0x80 [ 54.285427] ACPI : EC: ***** Event started ***** [ 54.285429] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.287209] ACPI : EC: ===== TASK (0) ===== [ 54.287218] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 54.287219] ACPI : EC: EC_DATA(W) = 0x06 [ 54.287222] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.291190] ACPI : EC: ===== TASK (0) ===== [ 54.291210] ACPI : EC: EC_SC(R) = 0x21 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=1 [ 54.291213] ACPI : EC: EC_DATA(R) = 0x03 [ 54.291214] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.291215] ACPI : EC: ***** Command(RD_EC) stopped ***** [ 54.291216] ACPI : EC: 1: Decrease command After cleaning up all guarding logics, we have one single function ec_guard() collecting all old, non-root-caused, hidden logics. Then we can easily tune the logics in one place to respond to the bug reports. Except the time_before() change, all other changes do not change the behavior of the EC driver. Link: https://bugzilla.kernel.org/show_bug.cgi?id=12011 Link: https://bugzilla.kernel.org/show_bug.cgi?id=20242 Link: https://bugzilla.kernel.org/show_bug.cgi?id=77431 Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-05-15 14:16:42 +08:00
ACPI / EC: Fix and clean up register access guarding logics. In the polling mode, EC driver shouldn't access the EC registers too frequently. Though this statement is concluded from the non-root caused bugs (see links below), we've maintained the register access guarding logics in the current EC driver. The guarding logics can be found here and there, makes it hard to root cause real timing issues. This patch collects the guarding logics into one single function so that all hidden logics related to this can be seen clearly. The current guarding related code also has several issues: 1. Per-transaction timestamp prevents inter-transaction guarding from being implemented in the same place. We have an inter-transaction udelay() in acpi_ec_transaction_unblocked(), this logic can be merged into ec_poll() if we can use per-device timestamp. This patch completes such merge to form a new ec_guard() function and collects all guarding related hidden logics in it. One hidden logic is: there is no inter-transaction guarding performed for non MSI quirk (wait polling mode), this patch skips inter-transaction guarding before wait_event_timeout() for the wait polling mode to reveal the hidden logic. The other hidden logic is: there is msleep() inter-transaction guarding performed when the GPE storming is observed. As after merging this commit: Commit: e1d4d90fc0313d3d58cbd7912c90f8ef24df45ff Subject: ACPI / EC: Refine command storm prevention support EC_FLAGS_COMMAND_STORM is ensured to be cleared after invoking acpi_ec_transaction_unlocked(), the msleep() guard logic will never happen now. Since no one complains such change, this logic is likely added during the old times where the EC race issues are not fixed and the bugs are false root-caused to the timing issue. This patch simply removes the out-dated logic. We can restore it by stop skipping inter-transaction guarding for wait polling mode. Two different delay values are defined for msleep() and udelay() while they are merged in this patch to 550us. 2. time_after() causes additional delay in the polling mode (can only be observed in noirq suspend/resume processes where polling mode is always used) before advance_transaction() is invoked ("wait polling" log is added before wait_event_timeout()). We can see 2 wait_event_timeout() invocations. This is because time_after() ensures a ">" validation while we only need a ">=" validation here: [ 86.739909] ACPI: Waking up from system sleep state S3 [ 86.742857] ACPI : EC: 2: Increase command [ 86.742859] ACPI : EC: ***** Command(RD_EC) started ***** [ 86.742861] ACPI : EC: ===== TASK (0) ===== [ 86.742871] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 86.742873] ACPI : EC: EC_SC(W) = 0x80 [ 86.742876] ACPI : EC: ***** Event started ***** [ 86.742880] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.743972] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.747966] ACPI : EC: ===== TASK (0) ===== [ 86.747977] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 86.747978] ACPI : EC: EC_DATA(W) = 0x06 [ 86.747981] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.751971] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.755969] ACPI : EC: ===== TASK (0) ===== [ 86.755991] ACPI : EC: EC_SC(R) = 0x21 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=1 [ 86.755993] ACPI : EC: EC_DATA(R) = 0x03 [ 86.755994] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.755995] ACPI : EC: ***** Command(RD_EC) stopped ***** [ 86.755996] ACPI : EC: 1: Decrease command This patch corrects this by using time_before() instead in ec_guard(): [ 54.283146] ACPI: Waking up from system sleep state S3 [ 54.285414] ACPI : EC: 2: Increase command [ 54.285415] ACPI : EC: ***** Command(RD_EC) started ***** [ 54.285416] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.285417] ACPI : EC: ===== TASK (0) ===== [ 54.285424] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 54.285425] ACPI : EC: EC_SC(W) = 0x80 [ 54.285427] ACPI : EC: ***** Event started ***** [ 54.285429] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.287209] ACPI : EC: ===== TASK (0) ===== [ 54.287218] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 54.287219] ACPI : EC: EC_DATA(W) = 0x06 [ 54.287222] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.291190] ACPI : EC: ===== TASK (0) ===== [ 54.291210] ACPI : EC: EC_SC(R) = 0x21 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=1 [ 54.291213] ACPI : EC: EC_DATA(R) = 0x03 [ 54.291214] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.291215] ACPI : EC: ***** Command(RD_EC) stopped ***** [ 54.291216] ACPI : EC: 1: Decrease command After cleaning up all guarding logics, we have one single function ec_guard() collecting all old, non-root-caused, hidden logics. Then we can easily tune the logics in one place to respond to the bug reports. Except the time_before() change, all other changes do not change the behavior of the EC driver. Link: https://bugzilla.kernel.org/show_bug.cgi?id=12011 Link: https://bugzilla.kernel.org/show_bug.cgi?id=20242 Link: https://bugzilla.kernel.org/show_bug.cgi?id=77431 Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-05-15 14:16:42 +08:00
ACPI / EC: Fix and clean up register access guarding logics. In the polling mode, EC driver shouldn't access the EC registers too frequently. Though this statement is concluded from the non-root caused bugs (see links below), we've maintained the register access guarding logics in the current EC driver. The guarding logics can be found here and there, makes it hard to root cause real timing issues. This patch collects the guarding logics into one single function so that all hidden logics related to this can be seen clearly. The current guarding related code also has several issues: 1. Per-transaction timestamp prevents inter-transaction guarding from being implemented in the same place. We have an inter-transaction udelay() in acpi_ec_transaction_unblocked(), this logic can be merged into ec_poll() if we can use per-device timestamp. This patch completes such merge to form a new ec_guard() function and collects all guarding related hidden logics in it. One hidden logic is: there is no inter-transaction guarding performed for non MSI quirk (wait polling mode), this patch skips inter-transaction guarding before wait_event_timeout() for the wait polling mode to reveal the hidden logic. The other hidden logic is: there is msleep() inter-transaction guarding performed when the GPE storming is observed. As after merging this commit: Commit: e1d4d90fc0313d3d58cbd7912c90f8ef24df45ff Subject: ACPI / EC: Refine command storm prevention support EC_FLAGS_COMMAND_STORM is ensured to be cleared after invoking acpi_ec_transaction_unlocked(), the msleep() guard logic will never happen now. Since no one complains such change, this logic is likely added during the old times where the EC race issues are not fixed and the bugs are false root-caused to the timing issue. This patch simply removes the out-dated logic. We can restore it by stop skipping inter-transaction guarding for wait polling mode. Two different delay values are defined for msleep() and udelay() while they are merged in this patch to 550us. 2. time_after() causes additional delay in the polling mode (can only be observed in noirq suspend/resume processes where polling mode is always used) before advance_transaction() is invoked ("wait polling" log is added before wait_event_timeout()). We can see 2 wait_event_timeout() invocations. This is because time_after() ensures a ">" validation while we only need a ">=" validation here: [ 86.739909] ACPI: Waking up from system sleep state S3 [ 86.742857] ACPI : EC: 2: Increase command [ 86.742859] ACPI : EC: ***** Command(RD_EC) started ***** [ 86.742861] ACPI : EC: ===== TASK (0) ===== [ 86.742871] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 86.742873] ACPI : EC: EC_SC(W) = 0x80 [ 86.742876] ACPI : EC: ***** Event started ***** [ 86.742880] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.743972] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.747966] ACPI : EC: ===== TASK (0) ===== [ 86.747977] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 86.747978] ACPI : EC: EC_DATA(W) = 0x06 [ 86.747981] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.751971] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.755969] ACPI : EC: ===== TASK (0) ===== [ 86.755991] ACPI : EC: EC_SC(R) = 0x21 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=1 [ 86.755993] ACPI : EC: EC_DATA(R) = 0x03 [ 86.755994] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.755995] ACPI : EC: ***** Command(RD_EC) stopped ***** [ 86.755996] ACPI : EC: 1: Decrease command This patch corrects this by using time_before() instead in ec_guard(): [ 54.283146] ACPI: Waking up from system sleep state S3 [ 54.285414] ACPI : EC: 2: Increase command [ 54.285415] ACPI : EC: ***** Command(RD_EC) started ***** [ 54.285416] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.285417] ACPI : EC: ===== TASK (0) ===== [ 54.285424] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 54.285425] ACPI : EC: EC_SC(W) = 0x80 [ 54.285427] ACPI : EC: ***** Event started ***** [ 54.285429] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.287209] ACPI : EC: ===== TASK (0) ===== [ 54.287218] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 54.287219] ACPI : EC: EC_DATA(W) = 0x06 [ 54.287222] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.291190] ACPI : EC: ===== TASK (0) ===== [ 54.291210] ACPI : EC: EC_SC(R) = 0x21 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=1 [ 54.291213] ACPI : EC: EC_DATA(R) = 0x03 [ 54.291214] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.291215] ACPI : EC: ***** Command(RD_EC) stopped ***** [ 54.291216] ACPI : EC: 1: Decrease command After cleaning up all guarding logics, we have one single function ec_guard() collecting all old, non-root-caused, hidden logics. Then we can easily tune the logics in one place to respond to the bug reports. Except the time_before() change, all other changes do not change the behavior of the EC driver. Link: https://bugzilla.kernel.org/show_bug.cgi?id=12011 Link: https://bugzilla.kernel.org/show_bug.cgi?id=20242 Link: https://bugzilla.kernel.org/show_bug.cgi?id=77431 Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-05-15 14:16:42 +08:00
ACPI / EC: Fix and clean up register access guarding logics. In the polling mode, EC driver shouldn't access the EC registers too frequently. Though this statement is concluded from the non-root caused bugs (see links below), we've maintained the register access guarding logics in the current EC driver. The guarding logics can be found here and there, makes it hard to root cause real timing issues. This patch collects the guarding logics into one single function so that all hidden logics related to this can be seen clearly. The current guarding related code also has several issues: 1. Per-transaction timestamp prevents inter-transaction guarding from being implemented in the same place. We have an inter-transaction udelay() in acpi_ec_transaction_unblocked(), this logic can be merged into ec_poll() if we can use per-device timestamp. This patch completes such merge to form a new ec_guard() function and collects all guarding related hidden logics in it. One hidden logic is: there is no inter-transaction guarding performed for non MSI quirk (wait polling mode), this patch skips inter-transaction guarding before wait_event_timeout() for the wait polling mode to reveal the hidden logic. The other hidden logic is: there is msleep() inter-transaction guarding performed when the GPE storming is observed. As after merging this commit: Commit: e1d4d90fc0313d3d58cbd7912c90f8ef24df45ff Subject: ACPI / EC: Refine command storm prevention support EC_FLAGS_COMMAND_STORM is ensured to be cleared after invoking acpi_ec_transaction_unlocked(), the msleep() guard logic will never happen now. Since no one complains such change, this logic is likely added during the old times where the EC race issues are not fixed and the bugs are false root-caused to the timing issue. This patch simply removes the out-dated logic. We can restore it by stop skipping inter-transaction guarding for wait polling mode. Two different delay values are defined for msleep() and udelay() while they are merged in this patch to 550us. 2. time_after() causes additional delay in the polling mode (can only be observed in noirq suspend/resume processes where polling mode is always used) before advance_transaction() is invoked ("wait polling" log is added before wait_event_timeout()). We can see 2 wait_event_timeout() invocations. This is because time_after() ensures a ">" validation while we only need a ">=" validation here: [ 86.739909] ACPI: Waking up from system sleep state S3 [ 86.742857] ACPI : EC: 2: Increase command [ 86.742859] ACPI : EC: ***** Command(RD_EC) started ***** [ 86.742861] ACPI : EC: ===== TASK (0) ===== [ 86.742871] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 86.742873] ACPI : EC: EC_SC(W) = 0x80 [ 86.742876] ACPI : EC: ***** Event started ***** [ 86.742880] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.743972] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.747966] ACPI : EC: ===== TASK (0) ===== [ 86.747977] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 86.747978] ACPI : EC: EC_DATA(W) = 0x06 [ 86.747981] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.751971] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.755969] ACPI : EC: ===== TASK (0) ===== [ 86.755991] ACPI : EC: EC_SC(R) = 0x21 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=1 [ 86.755993] ACPI : EC: EC_DATA(R) = 0x03 [ 86.755994] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.755995] ACPI : EC: ***** Command(RD_EC) stopped ***** [ 86.755996] ACPI : EC: 1: Decrease command This patch corrects this by using time_before() instead in ec_guard(): [ 54.283146] ACPI: Waking up from system sleep state S3 [ 54.285414] ACPI : EC: 2: Increase command [ 54.285415] ACPI : EC: ***** Command(RD_EC) started ***** [ 54.285416] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.285417] ACPI : EC: ===== TASK (0) ===== [ 54.285424] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 54.285425] ACPI : EC: EC_SC(W) = 0x80 [ 54.285427] ACPI : EC: ***** Event started ***** [ 54.285429] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.287209] ACPI : EC: ===== TASK (0) ===== [ 54.287218] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 54.287219] ACPI : EC: EC_DATA(W) = 0x06 [ 54.287222] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.291190] ACPI : EC: ===== TASK (0) ===== [ 54.291210] ACPI : EC: EC_SC(R) = 0x21 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=1 [ 54.291213] ACPI : EC: EC_DATA(R) = 0x03 [ 54.291214] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.291215] ACPI : EC: ***** Command(RD_EC) stopped ***** [ 54.291216] ACPI : EC: 1: Decrease command After cleaning up all guarding logics, we have one single function ec_guard() collecting all old, non-root-caused, hidden logics. Then we can easily tune the logics in one place to respond to the bug reports. Except the time_before() change, all other changes do not change the behavior of the EC driver. Link: https://bugzilla.kernel.org/show_bug.cgi?id=12011 Link: https://bugzilla.kernel.org/show_bug.cgi?id=20242 Link: https://bugzilla.kernel.org/show_bug.cgi?id=77431 Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-05-15 14:16:42 +08:00
ACPI / EC: Add asynchronous command byte write support Move the first command byte write into advance_transaction() so that all EC register accesses that can affect the command processing state machine can happen in this asynchronous state machine advancement function. The advance_transaction() function then can be a complete implementation of an asyncrhonous transaction for a single command so that: 1. The first command byte can be written in the interrupt context; 2. The command completion waiter can also be used to wait the first command byte's timeout; 3. In BURST mode, the follow-up command bytes can be written in the interrupt context directly, so that it doesn't need to return to the task context. Returning to the task context reduces the throughput of the BURST mode and in the worst cases where the system workload is very high, this leads to the hardware driven automatic BURST mode exit. In order not to increase memory consumption, convert 'done' into 'flags' to contain multiple indications: 1. ACPI_EC_COMMAND_COMPLETE: converting from original 'done' condition, indicating the completion of the command transaction. 2. ACPI_EC_COMMAND_POLL: indicating the availability of writing the first command byte. A new command can utilize this flag to compete for the right of accessing the underlying hardware. There is a follow-up bug fix that has utilized this new flag. The 2 flags are important because it also reflects a key concept of IO programs' design used in the system softwares. Normally an IO program running in the kernel should first be implemented in the asynchronous way. And the 2 flags are the most common way to implement its synchronous operations on top of the asynchronous operations: 1. POLL: This flag can be used to block until the asynchronous operations can happen. 2. COMPLETE: This flag can be used to block until the asynchronous operations have completed. By constructing code cleanly in this way, many difficult problems can be solved smoothly. Link: https://bugzilla.kernel.org/show_bug.cgi?id=70891 Link: https://bugzilla.kernel.org/show_bug.cgi?id=63931 Link: https://bugzilla.kernel.org/show_bug.cgi?id=59911 Reported-and-tested-by: Gareth Williams <gareth@garethwilliams.me.uk> Reported-and-tested-by: Hans de Goede <jwrdegoede@fedoraproject.org> Reported-by: Barton Xu <tank.xuhan@gmail.com> Tested-by: Steffen Weber <steffen.weber@gmail.com> Tested-by: Arthur Chen <axchen@nvidia.com> Signed-off-by: Lv Zheng <lv.zheng@intel.com> Cc: All applicable <stable@vger.kernel.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2014-06-15 08:41:35 +08:00
ACPI: EC: Make the event work state machine visible The EC driver uses a relatively simple state machine for the event work handling, but it is not really straightforward to figure out. The states are as follows: "Ready": The event handling work can be submitted. In this state, the EC_FLAGS_QUERY_PENDING flag is clear. "In progress": The event handling work is pending or is being processed. It cannot be submitted again. In ths state, the EC_FLAGS_QUERY_PENDING flag is set and both the events_to_process count is nonzero and the EC_FLAGS_QUERY_GUARDING flag is clear. "Complete": The event handling work has been completed, but it still cannot be submitted again. In ths state, the EC_FLAGS_QUERY_PENDING flag is set and the events_to_process count is zero or the EC_FLAGS_QUERY_GUARDING flag is set. The state changes from "Ready" to "In progress" when new event is detected by advance_transaction() and acpi_ec_submit_event() is called by it. Next, the state can change from "In progress" directly to "Ready" in the following situations: * ec_event_clearing is ACPI_EC_EVT_TIMING_STATUS and the state of an ACPI_EC_COMMAND_QUERY transaction becomes ACPI_EC_COMMAND_POLL. * ec_event_clearing is ACPI_EC_EVT_TIMING_QUERY and the state of an ACPI_EC_COMMAND_QUERY transaction becomes ACPI_EC_COMMAND_COMPLETE. * ec_event_clearing is either ACPI_EC_EVT_TIMING_STATUS or ACPI_EC_EVT_TIMING_QUERY and there are no more events to process (ie. ec->events_to_process becomes 0). If ec_event_clearing is ACPI_EC_EVT_TIMING_EVENT, however, the state must change from "In progress" to "Complete" before it can change to "Ready". The changes from "In progress" to "Complete" in that case occur in the following situations: * The state of an ACPI_EC_COMMAND_QUERY transaction becomes ACPI_EC_COMMAND_COMPLETE. * There are no more events to process (ie. ec->events_to_process becomes 0). Finally, the state changes from "Complete" to "Ready" when advance_transaction() is invoked when the state is "Complete" and the state of the current transaction is not ACPI_EC_COMMAND_POLL. To make this state machine visible in the code, add a new event_state field to struct acpi_ec and modify the code to use it istead the EC_FLAGS_QUERY_PENDING and EC_FLAGS_QUERY_GUARDING flags. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-11-23 19:44:46 +01:00
ACPI: EC: Make the event work state machine visible The EC driver uses a relatively simple state machine for the event work handling, but it is not really straightforward to figure out. The states are as follows: "Ready": The event handling work can be submitted. In this state, the EC_FLAGS_QUERY_PENDING flag is clear. "In progress": The event handling work is pending or is being processed. It cannot be submitted again. In ths state, the EC_FLAGS_QUERY_PENDING flag is set and both the events_to_process count is nonzero and the EC_FLAGS_QUERY_GUARDING flag is clear. "Complete": The event handling work has been completed, but it still cannot be submitted again. In ths state, the EC_FLAGS_QUERY_PENDING flag is set and the events_to_process count is zero or the EC_FLAGS_QUERY_GUARDING flag is set. The state changes from "Ready" to "In progress" when new event is detected by advance_transaction() and acpi_ec_submit_event() is called by it. Next, the state can change from "In progress" directly to "Ready" in the following situations: * ec_event_clearing is ACPI_EC_EVT_TIMING_STATUS and the state of an ACPI_EC_COMMAND_QUERY transaction becomes ACPI_EC_COMMAND_POLL. * ec_event_clearing is ACPI_EC_EVT_TIMING_QUERY and the state of an ACPI_EC_COMMAND_QUERY transaction becomes ACPI_EC_COMMAND_COMPLETE. * ec_event_clearing is either ACPI_EC_EVT_TIMING_STATUS or ACPI_EC_EVT_TIMING_QUERY and there are no more events to process (ie. ec->events_to_process becomes 0). If ec_event_clearing is ACPI_EC_EVT_TIMING_EVENT, however, the state must change from "In progress" to "Complete" before it can change to "Ready". The changes from "In progress" to "Complete" in that case occur in the following situations: * The state of an ACPI_EC_COMMAND_QUERY transaction becomes ACPI_EC_COMMAND_COMPLETE. * There are no more events to process (ie. ec->events_to_process becomes 0). Finally, the state changes from "Complete" to "Ready" when advance_transaction() is invoked when the state is "Complete" and the state of the current transaction is not ACPI_EC_COMMAND_POLL. To make this state machine visible in the code, add a new event_state field to struct acpi_ec and modify the code to use it istead the EC_FLAGS_QUERY_PENDING and EC_FLAGS_QUERY_GUARDING flags. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-11-23 19:44:46 +01:00
ACPI: EC: Make the event work state machine visible The EC driver uses a relatively simple state machine for the event work handling, but it is not really straightforward to figure out. The states are as follows: "Ready": The event handling work can be submitted. In this state, the EC_FLAGS_QUERY_PENDING flag is clear. "In progress": The event handling work is pending or is being processed. It cannot be submitted again. In ths state, the EC_FLAGS_QUERY_PENDING flag is set and both the events_to_process count is nonzero and the EC_FLAGS_QUERY_GUARDING flag is clear. "Complete": The event handling work has been completed, but it still cannot be submitted again. In ths state, the EC_FLAGS_QUERY_PENDING flag is set and the events_to_process count is zero or the EC_FLAGS_QUERY_GUARDING flag is set. The state changes from "Ready" to "In progress" when new event is detected by advance_transaction() and acpi_ec_submit_event() is called by it. Next, the state can change from "In progress" directly to "Ready" in the following situations: * ec_event_clearing is ACPI_EC_EVT_TIMING_STATUS and the state of an ACPI_EC_COMMAND_QUERY transaction becomes ACPI_EC_COMMAND_POLL. * ec_event_clearing is ACPI_EC_EVT_TIMING_QUERY and the state of an ACPI_EC_COMMAND_QUERY transaction becomes ACPI_EC_COMMAND_COMPLETE. * ec_event_clearing is either ACPI_EC_EVT_TIMING_STATUS or ACPI_EC_EVT_TIMING_QUERY and there are no more events to process (ie. ec->events_to_process becomes 0). If ec_event_clearing is ACPI_EC_EVT_TIMING_EVENT, however, the state must change from "In progress" to "Complete" before it can change to "Ready". The changes from "In progress" to "Complete" in that case occur in the following situations: * The state of an ACPI_EC_COMMAND_QUERY transaction becomes ACPI_EC_COMMAND_COMPLETE. * There are no more events to process (ie. ec->events_to_process becomes 0). Finally, the state changes from "Complete" to "Ready" when advance_transaction() is invoked when the state is "Complete" and the state of the current transaction is not ACPI_EC_COMMAND_POLL. To make this state machine visible in the code, add a new event_state field to struct acpi_ec and modify the code to use it istead the EC_FLAGS_QUERY_PENDING and EC_FLAGS_QUERY_GUARDING flags. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-11-23 19:44:46 +01:00
ACPI / EC: Avoid race condition related to advance_transaction() The advance_transaction() will be invoked from the IRQ context GPE handler and the task context ec_poll(). The handling of this function is locked so that the EC state machine are ensured to be advanced sequentially. But there is a problem. Before invoking advance_transaction(), EC_SC(R) is read. Then for advance_transaction(), there could be race condition around the lock from both contexts. The first one reading the register could fail this race and when it passes the stale register value to the state machine advancement code, the hardware condition is totally different from when the register is read. And the hardware accesses determined from the wrong hardware status can break the EC state machine. And there could be cases that the functionalities of the platform firmware are seriously affected. For example: 1. When 2 EC_DATA(W) writes compete the IBF=0, the 2nd EC_DATA(W) write may be invalid due to IBF=1 after the 1st EC_DATA(W) write. Then the hardware will either refuse to respond a next EC_SC(W) write of the next command or discard the current WR_EC command when it receives a EC_SC(W) write of the next command. 2. When 1 EC_SC(W) write and 1 EC_DATA(W) write compete the IBF=0, the EC_DATA(W) write may be invalid due to IBF=1 after the EC_SC(W) write. The next EC_DATA(R) could never be responded by the hardware. This is the root cause of the reported issue. Fix this issue by moving the EC_SC(R) access into the lock so that we can ensure that the state machine is advanced consistently. Link: https://bugzilla.kernel.org/show_bug.cgi?id=70891 Link: https://bugzilla.kernel.org/show_bug.cgi?id=63931 Link: https://bugzilla.kernel.org/show_bug.cgi?id=59911 Reported-and-tested-by: Gareth Williams <gareth@garethwilliams.me.uk> Reported-and-tested-by: Hans de Goede <jwrdegoede@fedoraproject.org> Reported-by: Barton Xu <tank.xuhan@gmail.com> Tested-by: Steffen Weber <steffen.weber@gmail.com> Tested-by: Arthur Chen <axchen@nvidia.com> Signed-off-by: Lv Zheng <lv.zheng@intel.com> Cc: All applicable <stable@vger.kernel.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2014-06-15 08:41:17 +08:00
ACPI / EC: Add event clearing variation support. We've been suffering from the uncertainty of the SCI_EVT clearing timing. This patch implements 3 of 4 possible modes to handle SCI_EVT clearing variations. The old behavior is kept in this patch. Status: QR_EC is re-checked as early as possible after checking previous SCI_EVT. This always leads to 2 QR_EC transactions per SCI_EVT indication and the target may implement event queue which returns 0x00 indicating "no outstanding event". This is proven to be a conflict against Windows behavior, but is still kept in this patch to make the EC driver robust to the possible regressions that may occur on Samsung platforms. Query: QR_EC is re-checked after the target has handled the QR_EC query request command pushed by the host. Event: QR_EC is re-checked after the target has noticed the query event response data pulled by the host. This timing is not determined by any IRQs, so we may need to use a guard period in this mode, which may explain the existence of the ec_guard() code used by the old EC driver where the re-check timing is implemented in the similar way as this mode. Method: QR_EC is re-checked as late as possible after completing the _Qxx evaluation. The target may implement SCI_EVT like a level triggered interrupt. It is proven on kernel bugzilla 94411 that, Windows will have all _Qxx evaluations parallelized. Thus unless required by further evidences, we needn't implement this mode as it is a conflict of the _Qxx parallelism requirement. Note that, according to the reports, there are platforms that cannot be handled using the "Status" mode without enabling the EC_FLAGS_QUERY_HANDSHAKE quirk. But they can be handled with the other modes according to the tests (kernel bugzilla 97381). The following log entry can be used to confirm the differences of the 3 modes as it should appear at the different positions for the 3 modes: Command(QR_EC) unblocked Status: appearing after EC_SC(W) = 0x84 Query: appearing after EC_DATA(R) = 0xXX where XX is the event number used to determine _QXX Event: appearing after first EC_SC(R) = 0xX0 SCI_EVT=x BURST=0 CMD=0 IBF=0 OBF=0 that is next to the following log entry: Command(QR_EC) completed by hardware 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=98111 Reported-and-tested-by: Gabriele Mazzotta <gabriele.mzt@gmail.com> Reported-and-tested-by: Tigran Gabrielyan <tigrangab@gmail.com> Reported-and-tested-by: Adrien D <ghbdtn@openmailbox.org> Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-06-11 13:21:38 +08:00
ACPI: EC: Make the event work state machine visible The EC driver uses a relatively simple state machine for the event work handling, but it is not really straightforward to figure out. The states are as follows: "Ready": The event handling work can be submitted. In this state, the EC_FLAGS_QUERY_PENDING flag is clear. "In progress": The event handling work is pending or is being processed. It cannot be submitted again. In ths state, the EC_FLAGS_QUERY_PENDING flag is set and both the events_to_process count is nonzero and the EC_FLAGS_QUERY_GUARDING flag is clear. "Complete": The event handling work has been completed, but it still cannot be submitted again. In ths state, the EC_FLAGS_QUERY_PENDING flag is set and the events_to_process count is zero or the EC_FLAGS_QUERY_GUARDING flag is set. The state changes from "Ready" to "In progress" when new event is detected by advance_transaction() and acpi_ec_submit_event() is called by it. Next, the state can change from "In progress" directly to "Ready" in the following situations: * ec_event_clearing is ACPI_EC_EVT_TIMING_STATUS and the state of an ACPI_EC_COMMAND_QUERY transaction becomes ACPI_EC_COMMAND_POLL. * ec_event_clearing is ACPI_EC_EVT_TIMING_QUERY and the state of an ACPI_EC_COMMAND_QUERY transaction becomes ACPI_EC_COMMAND_COMPLETE. * ec_event_clearing is either ACPI_EC_EVT_TIMING_STATUS or ACPI_EC_EVT_TIMING_QUERY and there are no more events to process (ie. ec->events_to_process becomes 0). If ec_event_clearing is ACPI_EC_EVT_TIMING_EVENT, however, the state must change from "In progress" to "Complete" before it can change to "Ready". The changes from "In progress" to "Complete" in that case occur in the following situations: * The state of an ACPI_EC_COMMAND_QUERY transaction becomes ACPI_EC_COMMAND_COMPLETE. * There are no more events to process (ie. ec->events_to_process becomes 0). Finally, the state changes from "Complete" to "Ready" when advance_transaction() is invoked when the state is "Complete" and the state of the current transaction is not ACPI_EC_COMMAND_POLL. To make this state machine visible in the code, add a new event_state field to struct acpi_ec and modify the code to use it istead the EC_FLAGS_QUERY_PENDING and EC_FLAGS_QUERY_GUARDING flags. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-11-23 19:44:46 +01:00
ACPI: EC: Make the event work state machine visible The EC driver uses a relatively simple state machine for the event work handling, but it is not really straightforward to figure out. The states are as follows: "Ready": The event handling work can be submitted. In this state, the EC_FLAGS_QUERY_PENDING flag is clear. "In progress": The event handling work is pending or is being processed. It cannot be submitted again. In ths state, the EC_FLAGS_QUERY_PENDING flag is set and both the events_to_process count is nonzero and the EC_FLAGS_QUERY_GUARDING flag is clear. "Complete": The event handling work has been completed, but it still cannot be submitted again. In ths state, the EC_FLAGS_QUERY_PENDING flag is set and the events_to_process count is zero or the EC_FLAGS_QUERY_GUARDING flag is set. The state changes from "Ready" to "In progress" when new event is detected by advance_transaction() and acpi_ec_submit_event() is called by it. Next, the state can change from "In progress" directly to "Ready" in the following situations: * ec_event_clearing is ACPI_EC_EVT_TIMING_STATUS and the state of an ACPI_EC_COMMAND_QUERY transaction becomes ACPI_EC_COMMAND_POLL. * ec_event_clearing is ACPI_EC_EVT_TIMING_QUERY and the state of an ACPI_EC_COMMAND_QUERY transaction becomes ACPI_EC_COMMAND_COMPLETE. * ec_event_clearing is either ACPI_EC_EVT_TIMING_STATUS or ACPI_EC_EVT_TIMING_QUERY and there are no more events to process (ie. ec->events_to_process becomes 0). If ec_event_clearing is ACPI_EC_EVT_TIMING_EVENT, however, the state must change from "In progress" to "Complete" before it can change to "Ready". The changes from "In progress" to "Complete" in that case occur in the following situations: * The state of an ACPI_EC_COMMAND_QUERY transaction becomes ACPI_EC_COMMAND_COMPLETE. * There are no more events to process (ie. ec->events_to_process becomes 0). Finally, the state changes from "Complete" to "Ready" when advance_transaction() is invoked when the state is "Complete" and the state of the current transaction is not ACPI_EC_COMMAND_POLL. To make this state machine visible in the code, add a new event_state field to struct acpi_ec and modify the code to use it istead the EC_FLAGS_QUERY_PENDING and EC_FLAGS_QUERY_GUARDING flags. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-11-23 19:44:46 +01:00
ACPI / EC: Add event clearing variation support. We've been suffering from the uncertainty of the SCI_EVT clearing timing. This patch implements 3 of 4 possible modes to handle SCI_EVT clearing variations. The old behavior is kept in this patch. Status: QR_EC is re-checked as early as possible after checking previous SCI_EVT. This always leads to 2 QR_EC transactions per SCI_EVT indication and the target may implement event queue which returns 0x00 indicating "no outstanding event". This is proven to be a conflict against Windows behavior, but is still kept in this patch to make the EC driver robust to the possible regressions that may occur on Samsung platforms. Query: QR_EC is re-checked after the target has handled the QR_EC query request command pushed by the host. Event: QR_EC is re-checked after the target has noticed the query event response data pulled by the host. This timing is not determined by any IRQs, so we may need to use a guard period in this mode, which may explain the existence of the ec_guard() code used by the old EC driver where the re-check timing is implemented in the similar way as this mode. Method: QR_EC is re-checked as late as possible after completing the _Qxx evaluation. The target may implement SCI_EVT like a level triggered interrupt. It is proven on kernel bugzilla 94411 that, Windows will have all _Qxx evaluations parallelized. Thus unless required by further evidences, we needn't implement this mode as it is a conflict of the _Qxx parallelism requirement. Note that, according to the reports, there are platforms that cannot be handled using the "Status" mode without enabling the EC_FLAGS_QUERY_HANDSHAKE quirk. But they can be handled with the other modes according to the tests (kernel bugzilla 97381). The following log entry can be used to confirm the differences of the 3 modes as it should appear at the different positions for the 3 modes: Command(QR_EC) unblocked Status: appearing after EC_SC(W) = 0x84 Query: appearing after EC_DATA(R) = 0xXX where XX is the event number used to determine _QXX Event: appearing after first EC_SC(R) = 0xX0 SCI_EVT=x BURST=0 CMD=0 IBF=0 OBF=0 that is next to the following log entry: Command(QR_EC) completed by hardware 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=98111 Reported-and-tested-by: Gabriele Mazzotta <gabriele.mzt@gmail.com> Reported-and-tested-by: Tigran Gabrielyan <tigrangab@gmail.com> Reported-and-tested-by: Adrien D <ghbdtn@openmailbox.org> Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-06-11 13:21:38 +08:00
ACPI / EC: Add asynchronous command byte write support Move the first command byte write into advance_transaction() so that all EC register accesses that can affect the command processing state machine can happen in this asynchronous state machine advancement function. The advance_transaction() function then can be a complete implementation of an asyncrhonous transaction for a single command so that: 1. The first command byte can be written in the interrupt context; 2. The command completion waiter can also be used to wait the first command byte's timeout; 3. In BURST mode, the follow-up command bytes can be written in the interrupt context directly, so that it doesn't need to return to the task context. Returning to the task context reduces the throughput of the BURST mode and in the worst cases where the system workload is very high, this leads to the hardware driven automatic BURST mode exit. In order not to increase memory consumption, convert 'done' into 'flags' to contain multiple indications: 1. ACPI_EC_COMMAND_COMPLETE: converting from original 'done' condition, indicating the completion of the command transaction. 2. ACPI_EC_COMMAND_POLL: indicating the availability of writing the first command byte. A new command can utilize this flag to compete for the right of accessing the underlying hardware. There is a follow-up bug fix that has utilized this new flag. The 2 flags are important because it also reflects a key concept of IO programs' design used in the system softwares. Normally an IO program running in the kernel should first be implemented in the asynchronous way. And the 2 flags are the most common way to implement its synchronous operations on top of the asynchronous operations: 1. POLL: This flag can be used to block until the asynchronous operations can happen. 2. COMPLETE: This flag can be used to block until the asynchronous operations have completed. By constructing code cleanly in this way, many difficult problems can be solved smoothly. Link: https://bugzilla.kernel.org/show_bug.cgi?id=70891 Link: https://bugzilla.kernel.org/show_bug.cgi?id=63931 Link: https://bugzilla.kernel.org/show_bug.cgi?id=59911 Reported-and-tested-by: Gareth Williams <gareth@garethwilliams.me.uk> Reported-and-tested-by: Hans de Goede <jwrdegoede@fedoraproject.org> Reported-by: Barton Xu <tank.xuhan@gmail.com> Tested-by: Steffen Weber <steffen.weber@gmail.com> Tested-by: Arthur Chen <axchen@nvidia.com> Signed-off-by: Lv Zheng <lv.zheng@intel.com> Cc: All applicable <stable@vger.kernel.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2014-06-15 08:41:35 +08:00
ACPI / EC: Add asynchronous command byte write support Move the first command byte write into advance_transaction() so that all EC register accesses that can affect the command processing state machine can happen in this asynchronous state machine advancement function. The advance_transaction() function then can be a complete implementation of an asyncrhonous transaction for a single command so that: 1. The first command byte can be written in the interrupt context; 2. The command completion waiter can also be used to wait the first command byte's timeout; 3. In BURST mode, the follow-up command bytes can be written in the interrupt context directly, so that it doesn't need to return to the task context. Returning to the task context reduces the throughput of the BURST mode and in the worst cases where the system workload is very high, this leads to the hardware driven automatic BURST mode exit. In order not to increase memory consumption, convert 'done' into 'flags' to contain multiple indications: 1. ACPI_EC_COMMAND_COMPLETE: converting from original 'done' condition, indicating the completion of the command transaction. 2. ACPI_EC_COMMAND_POLL: indicating the availability of writing the first command byte. A new command can utilize this flag to compete for the right of accessing the underlying hardware. There is a follow-up bug fix that has utilized this new flag. The 2 flags are important because it also reflects a key concept of IO programs' design used in the system softwares. Normally an IO program running in the kernel should first be implemented in the asynchronous way. And the 2 flags are the most common way to implement its synchronous operations on top of the asynchronous operations: 1. POLL: This flag can be used to block until the asynchronous operations can happen. 2. COMPLETE: This flag can be used to block until the asynchronous operations have completed. By constructing code cleanly in this way, many difficult problems can be solved smoothly. Link: https://bugzilla.kernel.org/show_bug.cgi?id=70891 Link: https://bugzilla.kernel.org/show_bug.cgi?id=63931 Link: https://bugzilla.kernel.org/show_bug.cgi?id=59911 Reported-and-tested-by: Gareth Williams <gareth@garethwilliams.me.uk> Reported-and-tested-by: Hans de Goede <jwrdegoede@fedoraproject.org> Reported-by: Barton Xu <tank.xuhan@gmail.com> Tested-by: Steffen Weber <steffen.weber@gmail.com> Tested-by: Arthur Chen <axchen@nvidia.com> Signed-off-by: Lv Zheng <lv.zheng@intel.com> Cc: All applicable <stable@vger.kernel.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2014-06-15 08:41:35 +08:00
ACPI / EC: Add asynchronous command byte write support Move the first command byte write into advance_transaction() so that all EC register accesses that can affect the command processing state machine can happen in this asynchronous state machine advancement function. The advance_transaction() function then can be a complete implementation of an asyncrhonous transaction for a single command so that: 1. The first command byte can be written in the interrupt context; 2. The command completion waiter can also be used to wait the first command byte's timeout; 3. In BURST mode, the follow-up command bytes can be written in the interrupt context directly, so that it doesn't need to return to the task context. Returning to the task context reduces the throughput of the BURST mode and in the worst cases where the system workload is very high, this leads to the hardware driven automatic BURST mode exit. In order not to increase memory consumption, convert 'done' into 'flags' to contain multiple indications: 1. ACPI_EC_COMMAND_COMPLETE: converting from original 'done' condition, indicating the completion of the command transaction. 2. ACPI_EC_COMMAND_POLL: indicating the availability of writing the first command byte. A new command can utilize this flag to compete for the right of accessing the underlying hardware. There is a follow-up bug fix that has utilized this new flag. The 2 flags are important because it also reflects a key concept of IO programs' design used in the system softwares. Normally an IO program running in the kernel should first be implemented in the asynchronous way. And the 2 flags are the most common way to implement its synchronous operations on top of the asynchronous operations: 1. POLL: This flag can be used to block until the asynchronous operations can happen. 2. COMPLETE: This flag can be used to block until the asynchronous operations have completed. By constructing code cleanly in this way, many difficult problems can be solved smoothly. Link: https://bugzilla.kernel.org/show_bug.cgi?id=70891 Link: https://bugzilla.kernel.org/show_bug.cgi?id=63931 Link: https://bugzilla.kernel.org/show_bug.cgi?id=59911 Reported-and-tested-by: Gareth Williams <gareth@garethwilliams.me.uk> Reported-and-tested-by: Hans de Goede <jwrdegoede@fedoraproject.org> Reported-by: Barton Xu <tank.xuhan@gmail.com> Tested-by: Steffen Weber <steffen.weber@gmail.com> Tested-by: Arthur Chen <axchen@nvidia.com> Signed-off-by: Lv Zheng <lv.zheng@intel.com> Cc: All applicable <stable@vger.kernel.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2014-06-15 08:41:35 +08:00
ACPI / EC: Add asynchronous command byte write support Move the first command byte write into advance_transaction() so that all EC register accesses that can affect the command processing state machine can happen in this asynchronous state machine advancement function. The advance_transaction() function then can be a complete implementation of an asyncrhonous transaction for a single command so that: 1. The first command byte can be written in the interrupt context; 2. The command completion waiter can also be used to wait the first command byte's timeout; 3. In BURST mode, the follow-up command bytes can be written in the interrupt context directly, so that it doesn't need to return to the task context. Returning to the task context reduces the throughput of the BURST mode and in the worst cases where the system workload is very high, this leads to the hardware driven automatic BURST mode exit. In order not to increase memory consumption, convert 'done' into 'flags' to contain multiple indications: 1. ACPI_EC_COMMAND_COMPLETE: converting from original 'done' condition, indicating the completion of the command transaction. 2. ACPI_EC_COMMAND_POLL: indicating the availability of writing the first command byte. A new command can utilize this flag to compete for the right of accessing the underlying hardware. There is a follow-up bug fix that has utilized this new flag. The 2 flags are important because it also reflects a key concept of IO programs' design used in the system softwares. Normally an IO program running in the kernel should first be implemented in the asynchronous way. And the 2 flags are the most common way to implement its synchronous operations on top of the asynchronous operations: 1. POLL: This flag can be used to block until the asynchronous operations can happen. 2. COMPLETE: This flag can be used to block until the asynchronous operations have completed. By constructing code cleanly in this way, many difficult problems can be solved smoothly. Link: https://bugzilla.kernel.org/show_bug.cgi?id=70891 Link: https://bugzilla.kernel.org/show_bug.cgi?id=63931 Link: https://bugzilla.kernel.org/show_bug.cgi?id=59911 Reported-and-tested-by: Gareth Williams <gareth@garethwilliams.me.uk> Reported-and-tested-by: Hans de Goede <jwrdegoede@fedoraproject.org> Reported-by: Barton Xu <tank.xuhan@gmail.com> Tested-by: Steffen Weber <steffen.weber@gmail.com> Tested-by: Arthur Chen <axchen@nvidia.com> Signed-off-by: Lv Zheng <lv.zheng@intel.com> Cc: All applicable <stable@vger.kernel.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2014-06-15 08:41:35 +08:00
ACPI / EC: Add support to disallow QR_EC to be issued when SCI_EVT isn't set 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: c0d653412fc8 ACPI / EC: Fix race condition in ec_transaction_completed() Link: https://bugzilla.kernel.org/show_bug.cgi?id=82611 Reported-and-tested-by: Alexander Mezin <mezin.alexander@gmail.com> Signed-off-by: Lv Zheng <lv.zheng@intel.com> Cc: 3.16+ <stable@vger.kernel.org> # 3.16+ Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2014-08-21 14:41:13 +08:00
ACPI / EC: Add asynchronous command byte write support Move the first command byte write into advance_transaction() so that all EC register accesses that can affect the command processing state machine can happen in this asynchronous state machine advancement function. The advance_transaction() function then can be a complete implementation of an asyncrhonous transaction for a single command so that: 1. The first command byte can be written in the interrupt context; 2. The command completion waiter can also be used to wait the first command byte's timeout; 3. In BURST mode, the follow-up command bytes can be written in the interrupt context directly, so that it doesn't need to return to the task context. Returning to the task context reduces the throughput of the BURST mode and in the worst cases where the system workload is very high, this leads to the hardware driven automatic BURST mode exit. In order not to increase memory consumption, convert 'done' into 'flags' to contain multiple indications: 1. ACPI_EC_COMMAND_COMPLETE: converting from original 'done' condition, indicating the completion of the command transaction. 2. ACPI_EC_COMMAND_POLL: indicating the availability of writing the first command byte. A new command can utilize this flag to compete for the right of accessing the underlying hardware. There is a follow-up bug fix that has utilized this new flag. The 2 flags are important because it also reflects a key concept of IO programs' design used in the system softwares. Normally an IO program running in the kernel should first be implemented in the asynchronous way. And the 2 flags are the most common way to implement its synchronous operations on top of the asynchronous operations: 1. POLL: This flag can be used to block until the asynchronous operations can happen. 2. COMPLETE: This flag can be used to block until the asynchronous operations have completed. By constructing code cleanly in this way, many difficult problems can be solved smoothly. Link: https://bugzilla.kernel.org/show_bug.cgi?id=70891 Link: https://bugzilla.kernel.org/show_bug.cgi?id=63931 Link: https://bugzilla.kernel.org/show_bug.cgi?id=59911 Reported-and-tested-by: Gareth Williams <gareth@garethwilliams.me.uk> Reported-and-tested-by: Hans de Goede <jwrdegoede@fedoraproject.org> Reported-by: Barton Xu <tank.xuhan@gmail.com> Tested-by: Steffen Weber <steffen.weber@gmail.com> Tested-by: Arthur Chen <axchen@nvidia.com> Signed-off-by: Lv Zheng <lv.zheng@intel.com> Cc: All applicable <stable@vger.kernel.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2014-06-15 08:41:35 +08:00
ACPI / EC: Fix issues related to the SCI_EVT handling This patch fixes 2 issues related to the draining behavior. But it doesn't implement the draining support, it only cleans up code so that further draining support is possible. The draining behavior is expected by some platforms (for example, Samsung) where SCI_EVT is set only once for a set of events and might be cleared for the very first QR_EC command issued after SCI_EVT is set. EC firmware on such platforms will return 0x00 to indicate "no outstanding event". Thus after seeing an SCI_EVT indication, EC driver need to fetch events until 0x00 returned (see acpi_ec_clear()). Issue 1 - acpi_ec_submit_query(): It's reported on Samsung laptops that SCI_EVT isn't checked when the transactions are advanced in ec_poll(), which leads to SCI_EVT triggering source lost: If no EC GPE IRQs are arrived after that, EC driver cannot detect this event and handle it. See comment 244/247 for kernel bugzilla 44161. This patch fixes this issue by moving SCI_EVT checks into advance_transaction(). So that SCI_EVT is checked each time we are going to handle the EC firmware indications. And this check will happen for both IRQ context and task context. Since after doing that, SCI_EVT is also checked after completing a transaction, ec_check_sci() and ec_check_sci_sync() can be removed. Issue 2 - acpi_ec_complete_query(): We expect to clear EC_FLAGS_QUERY_PENDING to allow queuing another draining QR_EC after writing a QR_EC command and before reading the event. After reading the event, SCI_EVT might be cleared by the firmware, thus it may not be possible to queue such a draining QR_EC at that time. But putting the EC_FLAGS_QUERY_PENDING clearing code after start_transaction() is wrong as there are chances that after start_transaction(), QR_EC can fail to be sent. If this happens, EC_FLAG_QUERY_PENDING will be cleared earlier. As a consequence, the draining QR_EC will also be queued earlier than expected. This patch also moves this code into advance_transaction() where QR_EC is just sent (ACPI_EC_COMMAND_POLL flagged) to fix this issue. Notes: 1. After introducing the 2 SCI_EVT related handlings into advance_transaction(), a next QR_EC can be queued right after writing the current QR_EC command and before reading the event. But this still hasn't implemented the draining behavior as the draining support requires: If a previous returned event value isn't 0x00, a draining QR_EC need to be issued even when SCI_EVT isn't set. 2. In this patch, acpi_os_execute() is also converted into a seperate work item to avoid invoking kmalloc() in the atomic context. We can do this because of the previous global lock fix. 3. Originally, EC_FLAGS_EVENT_PENDING is also used to avoid queuing up multiple work items (created by acpi_os_execute()), this can be covered by only using a single work item. But this patch still keeps this flag as there are different usages in the driver initialization steps relying on this flag. Link: https://bugzilla.kernel.org/show_bug.cgi?id=44161 Reported-by: Kieran Clancy <clancy.kieran@gmail.com> Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-01-14 19:28:47 +08:00
ACPI / EC: Add asynchronous command byte write support Move the first command byte write into advance_transaction() so that all EC register accesses that can affect the command processing state machine can happen in this asynchronous state machine advancement function. The advance_transaction() function then can be a complete implementation of an asyncrhonous transaction for a single command so that: 1. The first command byte can be written in the interrupt context; 2. The command completion waiter can also be used to wait the first command byte's timeout; 3. In BURST mode, the follow-up command bytes can be written in the interrupt context directly, so that it doesn't need to return to the task context. Returning to the task context reduces the throughput of the BURST mode and in the worst cases where the system workload is very high, this leads to the hardware driven automatic BURST mode exit. In order not to increase memory consumption, convert 'done' into 'flags' to contain multiple indications: 1. ACPI_EC_COMMAND_COMPLETE: converting from original 'done' condition, indicating the completion of the command transaction. 2. ACPI_EC_COMMAND_POLL: indicating the availability of writing the first command byte. A new command can utilize this flag to compete for the right of accessing the underlying hardware. There is a follow-up bug fix that has utilized this new flag. The 2 flags are important because it also reflects a key concept of IO programs' design used in the system softwares. Normally an IO program running in the kernel should first be implemented in the asynchronous way. And the 2 flags are the most common way to implement its synchronous operations on top of the asynchronous operations: 1. POLL: This flag can be used to block until the asynchronous operations can happen. 2. COMPLETE: This flag can be used to block until the asynchronous operations have completed. By constructing code cleanly in this way, many difficult problems can be solved smoothly. Link: https://bugzilla.kernel.org/show_bug.cgi?id=70891 Link: https://bugzilla.kernel.org/show_bug.cgi?id=63931 Link: https://bugzilla.kernel.org/show_bug.cgi?id=59911 Reported-and-tested-by: Gareth Williams <gareth@garethwilliams.me.uk> Reported-and-tested-by: Hans de Goede <jwrdegoede@fedoraproject.org> Reported-by: Barton Xu <tank.xuhan@gmail.com> Tested-by: Steffen Weber <steffen.weber@gmail.com> Tested-by: Arthur Chen <axchen@nvidia.com> Signed-off-by: Lv Zheng <lv.zheng@intel.com> Cc: All applicable <stable@vger.kernel.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2014-06-15 08:41:35 +08:00
ACPI / EC: Add asynchronous command byte write support Move the first command byte write into advance_transaction() so that all EC register accesses that can affect the command processing state machine can happen in this asynchronous state machine advancement function. The advance_transaction() function then can be a complete implementation of an asyncrhonous transaction for a single command so that: 1. The first command byte can be written in the interrupt context; 2. The command completion waiter can also be used to wait the first command byte's timeout; 3. In BURST mode, the follow-up command bytes can be written in the interrupt context directly, so that it doesn't need to return to the task context. Returning to the task context reduces the throughput of the BURST mode and in the worst cases where the system workload is very high, this leads to the hardware driven automatic BURST mode exit. In order not to increase memory consumption, convert 'done' into 'flags' to contain multiple indications: 1. ACPI_EC_COMMAND_COMPLETE: converting from original 'done' condition, indicating the completion of the command transaction. 2. ACPI_EC_COMMAND_POLL: indicating the availability of writing the first command byte. A new command can utilize this flag to compete for the right of accessing the underlying hardware. There is a follow-up bug fix that has utilized this new flag. The 2 flags are important because it also reflects a key concept of IO programs' design used in the system softwares. Normally an IO program running in the kernel should first be implemented in the asynchronous way. And the 2 flags are the most common way to implement its synchronous operations on top of the asynchronous operations: 1. POLL: This flag can be used to block until the asynchronous operations can happen. 2. COMPLETE: This flag can be used to block until the asynchronous operations have completed. By constructing code cleanly in this way, many difficult problems can be solved smoothly. Link: https://bugzilla.kernel.org/show_bug.cgi?id=70891 Link: https://bugzilla.kernel.org/show_bug.cgi?id=63931 Link: https://bugzilla.kernel.org/show_bug.cgi?id=59911 Reported-and-tested-by: Gareth Williams <gareth@garethwilliams.me.uk> Reported-and-tested-by: Hans de Goede <jwrdegoede@fedoraproject.org> Reported-by: Barton Xu <tank.xuhan@gmail.com> Tested-by: Steffen Weber <steffen.weber@gmail.com> Tested-by: Arthur Chen <axchen@nvidia.com> Signed-off-by: Lv Zheng <lv.zheng@intel.com> Cc: All applicable <stable@vger.kernel.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2014-06-15 08:41:35 +08:00
ACPI / EC: Fix and clean up register access guarding logics. In the polling mode, EC driver shouldn't access the EC registers too frequently. Though this statement is concluded from the non-root caused bugs (see links below), we've maintained the register access guarding logics in the current EC driver. The guarding logics can be found here and there, makes it hard to root cause real timing issues. This patch collects the guarding logics into one single function so that all hidden logics related to this can be seen clearly. The current guarding related code also has several issues: 1. Per-transaction timestamp prevents inter-transaction guarding from being implemented in the same place. We have an inter-transaction udelay() in acpi_ec_transaction_unblocked(), this logic can be merged into ec_poll() if we can use per-device timestamp. This patch completes such merge to form a new ec_guard() function and collects all guarding related hidden logics in it. One hidden logic is: there is no inter-transaction guarding performed for non MSI quirk (wait polling mode), this patch skips inter-transaction guarding before wait_event_timeout() for the wait polling mode to reveal the hidden logic. The other hidden logic is: there is msleep() inter-transaction guarding performed when the GPE storming is observed. As after merging this commit: Commit: e1d4d90fc0313d3d58cbd7912c90f8ef24df45ff Subject: ACPI / EC: Refine command storm prevention support EC_FLAGS_COMMAND_STORM is ensured to be cleared after invoking acpi_ec_transaction_unlocked(), the msleep() guard logic will never happen now. Since no one complains such change, this logic is likely added during the old times where the EC race issues are not fixed and the bugs are false root-caused to the timing issue. This patch simply removes the out-dated logic. We can restore it by stop skipping inter-transaction guarding for wait polling mode. Two different delay values are defined for msleep() and udelay() while they are merged in this patch to 550us. 2. time_after() causes additional delay in the polling mode (can only be observed in noirq suspend/resume processes where polling mode is always used) before advance_transaction() is invoked ("wait polling" log is added before wait_event_timeout()). We can see 2 wait_event_timeout() invocations. This is because time_after() ensures a ">" validation while we only need a ">=" validation here: [ 86.739909] ACPI: Waking up from system sleep state S3 [ 86.742857] ACPI : EC: 2: Increase command [ 86.742859] ACPI : EC: ***** Command(RD_EC) started ***** [ 86.742861] ACPI : EC: ===== TASK (0) ===== [ 86.742871] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 86.742873] ACPI : EC: EC_SC(W) = 0x80 [ 86.742876] ACPI : EC: ***** Event started ***** [ 86.742880] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.743972] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.747966] ACPI : EC: ===== TASK (0) ===== [ 86.747977] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 86.747978] ACPI : EC: EC_DATA(W) = 0x06 [ 86.747981] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.751971] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.755969] ACPI : EC: ===== TASK (0) ===== [ 86.755991] ACPI : EC: EC_SC(R) = 0x21 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=1 [ 86.755993] ACPI : EC: EC_DATA(R) = 0x03 [ 86.755994] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.755995] ACPI : EC: ***** Command(RD_EC) stopped ***** [ 86.755996] ACPI : EC: 1: Decrease command This patch corrects this by using time_before() instead in ec_guard(): [ 54.283146] ACPI: Waking up from system sleep state S3 [ 54.285414] ACPI : EC: 2: Increase command [ 54.285415] ACPI : EC: ***** Command(RD_EC) started ***** [ 54.285416] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.285417] ACPI : EC: ===== TASK (0) ===== [ 54.285424] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 54.285425] ACPI : EC: EC_SC(W) = 0x80 [ 54.285427] ACPI : EC: ***** Event started ***** [ 54.285429] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.287209] ACPI : EC: ===== TASK (0) ===== [ 54.287218] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 54.287219] ACPI : EC: EC_DATA(W) = 0x06 [ 54.287222] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.291190] ACPI : EC: ===== TASK (0) ===== [ 54.291210] ACPI : EC: EC_SC(R) = 0x21 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=1 [ 54.291213] ACPI : EC: EC_DATA(R) = 0x03 [ 54.291214] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.291215] ACPI : EC: ***** Command(RD_EC) stopped ***** [ 54.291216] ACPI : EC: 1: Decrease command After cleaning up all guarding logics, we have one single function ec_guard() collecting all old, non-root-caused, hidden logics. Then we can easily tune the logics in one place to respond to the bug reports. Except the time_before() change, all other changes do not change the behavior of the EC driver. Link: https://bugzilla.kernel.org/show_bug.cgi?id=12011 Link: https://bugzilla.kernel.org/show_bug.cgi?id=20242 Link: https://bugzilla.kernel.org/show_bug.cgi?id=77431 Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-05-15 14:16:42 +08:00
ACPI / EC: Fix and clean up register access guarding logics. In the polling mode, EC driver shouldn't access the EC registers too frequently. Though this statement is concluded from the non-root caused bugs (see links below), we've maintained the register access guarding logics in the current EC driver. The guarding logics can be found here and there, makes it hard to root cause real timing issues. This patch collects the guarding logics into one single function so that all hidden logics related to this can be seen clearly. The current guarding related code also has several issues: 1. Per-transaction timestamp prevents inter-transaction guarding from being implemented in the same place. We have an inter-transaction udelay() in acpi_ec_transaction_unblocked(), this logic can be merged into ec_poll() if we can use per-device timestamp. This patch completes such merge to form a new ec_guard() function and collects all guarding related hidden logics in it. One hidden logic is: there is no inter-transaction guarding performed for non MSI quirk (wait polling mode), this patch skips inter-transaction guarding before wait_event_timeout() for the wait polling mode to reveal the hidden logic. The other hidden logic is: there is msleep() inter-transaction guarding performed when the GPE storming is observed. As after merging this commit: Commit: e1d4d90fc0313d3d58cbd7912c90f8ef24df45ff Subject: ACPI / EC: Refine command storm prevention support EC_FLAGS_COMMAND_STORM is ensured to be cleared after invoking acpi_ec_transaction_unlocked(), the msleep() guard logic will never happen now. Since no one complains such change, this logic is likely added during the old times where the EC race issues are not fixed and the bugs are false root-caused to the timing issue. This patch simply removes the out-dated logic. We can restore it by stop skipping inter-transaction guarding for wait polling mode. Two different delay values are defined for msleep() and udelay() while they are merged in this patch to 550us. 2. time_after() causes additional delay in the polling mode (can only be observed in noirq suspend/resume processes where polling mode is always used) before advance_transaction() is invoked ("wait polling" log is added before wait_event_timeout()). We can see 2 wait_event_timeout() invocations. This is because time_after() ensures a ">" validation while we only need a ">=" validation here: [ 86.739909] ACPI: Waking up from system sleep state S3 [ 86.742857] ACPI : EC: 2: Increase command [ 86.742859] ACPI : EC: ***** Command(RD_EC) started ***** [ 86.742861] ACPI : EC: ===== TASK (0) ===== [ 86.742871] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 86.742873] ACPI : EC: EC_SC(W) = 0x80 [ 86.742876] ACPI : EC: ***** Event started ***** [ 86.742880] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.743972] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.747966] ACPI : EC: ===== TASK (0) ===== [ 86.747977] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 86.747978] ACPI : EC: EC_DATA(W) = 0x06 [ 86.747981] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.751971] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.755969] ACPI : EC: ===== TASK (0) ===== [ 86.755991] ACPI : EC: EC_SC(R) = 0x21 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=1 [ 86.755993] ACPI : EC: EC_DATA(R) = 0x03 [ 86.755994] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.755995] ACPI : EC: ***** Command(RD_EC) stopped ***** [ 86.755996] ACPI : EC: 1: Decrease command This patch corrects this by using time_before() instead in ec_guard(): [ 54.283146] ACPI: Waking up from system sleep state S3 [ 54.285414] ACPI : EC: 2: Increase command [ 54.285415] ACPI : EC: ***** Command(RD_EC) started ***** [ 54.285416] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.285417] ACPI : EC: ===== TASK (0) ===== [ 54.285424] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 54.285425] ACPI : EC: EC_SC(W) = 0x80 [ 54.285427] ACPI : EC: ***** Event started ***** [ 54.285429] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.287209] ACPI : EC: ===== TASK (0) ===== [ 54.287218] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 54.287219] ACPI : EC: EC_DATA(W) = 0x06 [ 54.287222] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.291190] ACPI : EC: ===== TASK (0) ===== [ 54.291210] ACPI : EC: EC_SC(R) = 0x21 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=1 [ 54.291213] ACPI : EC: EC_DATA(R) = 0x03 [ 54.291214] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.291215] ACPI : EC: ***** Command(RD_EC) stopped ***** [ 54.291216] ACPI : EC: 1: Decrease command After cleaning up all guarding logics, we have one single function ec_guard() collecting all old, non-root-caused, hidden logics. Then we can easily tune the logics in one place to respond to the bug reports. Except the time_before() change, all other changes do not change the behavior of the EC driver. Link: https://bugzilla.kernel.org/show_bug.cgi?id=12011 Link: https://bugzilla.kernel.org/show_bug.cgi?id=20242 Link: https://bugzilla.kernel.org/show_bug.cgi?id=77431 Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-05-15 14:16:42 +08:00
ACPI / EC: Fix and clean up register access guarding logics. In the polling mode, EC driver shouldn't access the EC registers too frequently. Though this statement is concluded from the non-root caused bugs (see links below), we've maintained the register access guarding logics in the current EC driver. The guarding logics can be found here and there, makes it hard to root cause real timing issues. This patch collects the guarding logics into one single function so that all hidden logics related to this can be seen clearly. The current guarding related code also has several issues: 1. Per-transaction timestamp prevents inter-transaction guarding from being implemented in the same place. We have an inter-transaction udelay() in acpi_ec_transaction_unblocked(), this logic can be merged into ec_poll() if we can use per-device timestamp. This patch completes such merge to form a new ec_guard() function and collects all guarding related hidden logics in it. One hidden logic is: there is no inter-transaction guarding performed for non MSI quirk (wait polling mode), this patch skips inter-transaction guarding before wait_event_timeout() for the wait polling mode to reveal the hidden logic. The other hidden logic is: there is msleep() inter-transaction guarding performed when the GPE storming is observed. As after merging this commit: Commit: e1d4d90fc0313d3d58cbd7912c90f8ef24df45ff Subject: ACPI / EC: Refine command storm prevention support EC_FLAGS_COMMAND_STORM is ensured to be cleared after invoking acpi_ec_transaction_unlocked(), the msleep() guard logic will never happen now. Since no one complains such change, this logic is likely added during the old times where the EC race issues are not fixed and the bugs are false root-caused to the timing issue. This patch simply removes the out-dated logic. We can restore it by stop skipping inter-transaction guarding for wait polling mode. Two different delay values are defined for msleep() and udelay() while they are merged in this patch to 550us. 2. time_after() causes additional delay in the polling mode (can only be observed in noirq suspend/resume processes where polling mode is always used) before advance_transaction() is invoked ("wait polling" log is added before wait_event_timeout()). We can see 2 wait_event_timeout() invocations. This is because time_after() ensures a ">" validation while we only need a ">=" validation here: [ 86.739909] ACPI: Waking up from system sleep state S3 [ 86.742857] ACPI : EC: 2: Increase command [ 86.742859] ACPI : EC: ***** Command(RD_EC) started ***** [ 86.742861] ACPI : EC: ===== TASK (0) ===== [ 86.742871] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 86.742873] ACPI : EC: EC_SC(W) = 0x80 [ 86.742876] ACPI : EC: ***** Event started ***** [ 86.742880] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.743972] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.747966] ACPI : EC: ===== TASK (0) ===== [ 86.747977] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 86.747978] ACPI : EC: EC_DATA(W) = 0x06 [ 86.747981] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.751971] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.755969] ACPI : EC: ===== TASK (0) ===== [ 86.755991] ACPI : EC: EC_SC(R) = 0x21 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=1 [ 86.755993] ACPI : EC: EC_DATA(R) = 0x03 [ 86.755994] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.755995] ACPI : EC: ***** Command(RD_EC) stopped ***** [ 86.755996] ACPI : EC: 1: Decrease command This patch corrects this by using time_before() instead in ec_guard(): [ 54.283146] ACPI: Waking up from system sleep state S3 [ 54.285414] ACPI : EC: 2: Increase command [ 54.285415] ACPI : EC: ***** Command(RD_EC) started ***** [ 54.285416] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.285417] ACPI : EC: ===== TASK (0) ===== [ 54.285424] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 54.285425] ACPI : EC: EC_SC(W) = 0x80 [ 54.285427] ACPI : EC: ***** Event started ***** [ 54.285429] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.287209] ACPI : EC: ===== TASK (0) ===== [ 54.287218] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 54.287219] ACPI : EC: EC_DATA(W) = 0x06 [ 54.287222] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.291190] ACPI : EC: ===== TASK (0) ===== [ 54.291210] ACPI : EC: EC_SC(R) = 0x21 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=1 [ 54.291213] ACPI : EC: EC_DATA(R) = 0x03 [ 54.291214] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.291215] ACPI : EC: ***** Command(RD_EC) stopped ***** [ 54.291216] ACPI : EC: 1: Decrease command After cleaning up all guarding logics, we have one single function ec_guard() collecting all old, non-root-caused, hidden logics. Then we can easily tune the logics in one place to respond to the bug reports. Except the time_before() change, all other changes do not change the behavior of the EC driver. Link: https://bugzilla.kernel.org/show_bug.cgi?id=12011 Link: https://bugzilla.kernel.org/show_bug.cgi?id=20242 Link: https://bugzilla.kernel.org/show_bug.cgi?id=77431 Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-05-15 14:16:42 +08:00
ACPI / EC: Fix and clean up register access guarding logics. In the polling mode, EC driver shouldn't access the EC registers too frequently. Though this statement is concluded from the non-root caused bugs (see links below), we've maintained the register access guarding logics in the current EC driver. The guarding logics can be found here and there, makes it hard to root cause real timing issues. This patch collects the guarding logics into one single function so that all hidden logics related to this can be seen clearly. The current guarding related code also has several issues: 1. Per-transaction timestamp prevents inter-transaction guarding from being implemented in the same place. We have an inter-transaction udelay() in acpi_ec_transaction_unblocked(), this logic can be merged into ec_poll() if we can use per-device timestamp. This patch completes such merge to form a new ec_guard() function and collects all guarding related hidden logics in it. One hidden logic is: there is no inter-transaction guarding performed for non MSI quirk (wait polling mode), this patch skips inter-transaction guarding before wait_event_timeout() for the wait polling mode to reveal the hidden logic. The other hidden logic is: there is msleep() inter-transaction guarding performed when the GPE storming is observed. As after merging this commit: Commit: e1d4d90fc0313d3d58cbd7912c90f8ef24df45ff Subject: ACPI / EC: Refine command storm prevention support EC_FLAGS_COMMAND_STORM is ensured to be cleared after invoking acpi_ec_transaction_unlocked(), the msleep() guard logic will never happen now. Since no one complains such change, this logic is likely added during the old times where the EC race issues are not fixed and the bugs are false root-caused to the timing issue. This patch simply removes the out-dated logic. We can restore it by stop skipping inter-transaction guarding for wait polling mode. Two different delay values are defined for msleep() and udelay() while they are merged in this patch to 550us. 2. time_after() causes additional delay in the polling mode (can only be observed in noirq suspend/resume processes where polling mode is always used) before advance_transaction() is invoked ("wait polling" log is added before wait_event_timeout()). We can see 2 wait_event_timeout() invocations. This is because time_after() ensures a ">" validation while we only need a ">=" validation here: [ 86.739909] ACPI: Waking up from system sleep state S3 [ 86.742857] ACPI : EC: 2: Increase command [ 86.742859] ACPI : EC: ***** Command(RD_EC) started ***** [ 86.742861] ACPI : EC: ===== TASK (0) ===== [ 86.742871] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 86.742873] ACPI : EC: EC_SC(W) = 0x80 [ 86.742876] ACPI : EC: ***** Event started ***** [ 86.742880] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.743972] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.747966] ACPI : EC: ===== TASK (0) ===== [ 86.747977] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 86.747978] ACPI : EC: EC_DATA(W) = 0x06 [ 86.747981] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.751971] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.755969] ACPI : EC: ===== TASK (0) ===== [ 86.755991] ACPI : EC: EC_SC(R) = 0x21 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=1 [ 86.755993] ACPI : EC: EC_DATA(R) = 0x03 [ 86.755994] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.755995] ACPI : EC: ***** Command(RD_EC) stopped ***** [ 86.755996] ACPI : EC: 1: Decrease command This patch corrects this by using time_before() instead in ec_guard(): [ 54.283146] ACPI: Waking up from system sleep state S3 [ 54.285414] ACPI : EC: 2: Increase command [ 54.285415] ACPI : EC: ***** Command(RD_EC) started ***** [ 54.285416] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.285417] ACPI : EC: ===== TASK (0) ===== [ 54.285424] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 54.285425] ACPI : EC: EC_SC(W) = 0x80 [ 54.285427] ACPI : EC: ***** Event started ***** [ 54.285429] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.287209] ACPI : EC: ===== TASK (0) ===== [ 54.287218] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 54.287219] ACPI : EC: EC_DATA(W) = 0x06 [ 54.287222] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.291190] ACPI : EC: ===== TASK (0) ===== [ 54.291210] ACPI : EC: EC_SC(R) = 0x21 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=1 [ 54.291213] ACPI : EC: EC_DATA(R) = 0x03 [ 54.291214] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.291215] ACPI : EC: ***** Command(RD_EC) stopped ***** [ 54.291216] ACPI : EC: 1: Decrease command After cleaning up all guarding logics, we have one single function ec_guard() collecting all old, non-root-caused, hidden logics. Then we can easily tune the logics in one place to respond to the bug reports. Except the time_before() change, all other changes do not change the behavior of the EC driver. Link: https://bugzilla.kernel.org/show_bug.cgi?id=12011 Link: https://bugzilla.kernel.org/show_bug.cgi?id=20242 Link: https://bugzilla.kernel.org/show_bug.cgi?id=77431 Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-05-15 14:16:42 +08:00
ACPI / EC: Fix and clean up register access guarding logics. In the polling mode, EC driver shouldn't access the EC registers too frequently. Though this statement is concluded from the non-root caused bugs (see links below), we've maintained the register access guarding logics in the current EC driver. The guarding logics can be found here and there, makes it hard to root cause real timing issues. This patch collects the guarding logics into one single function so that all hidden logics related to this can be seen clearly. The current guarding related code also has several issues: 1. Per-transaction timestamp prevents inter-transaction guarding from being implemented in the same place. We have an inter-transaction udelay() in acpi_ec_transaction_unblocked(), this logic can be merged into ec_poll() if we can use per-device timestamp. This patch completes such merge to form a new ec_guard() function and collects all guarding related hidden logics in it. One hidden logic is: there is no inter-transaction guarding performed for non MSI quirk (wait polling mode), this patch skips inter-transaction guarding before wait_event_timeout() for the wait polling mode to reveal the hidden logic. The other hidden logic is: there is msleep() inter-transaction guarding performed when the GPE storming is observed. As after merging this commit: Commit: e1d4d90fc0313d3d58cbd7912c90f8ef24df45ff Subject: ACPI / EC: Refine command storm prevention support EC_FLAGS_COMMAND_STORM is ensured to be cleared after invoking acpi_ec_transaction_unlocked(), the msleep() guard logic will never happen now. Since no one complains such change, this logic is likely added during the old times where the EC race issues are not fixed and the bugs are false root-caused to the timing issue. This patch simply removes the out-dated logic. We can restore it by stop skipping inter-transaction guarding for wait polling mode. Two different delay values are defined for msleep() and udelay() while they are merged in this patch to 550us. 2. time_after() causes additional delay in the polling mode (can only be observed in noirq suspend/resume processes where polling mode is always used) before advance_transaction() is invoked ("wait polling" log is added before wait_event_timeout()). We can see 2 wait_event_timeout() invocations. This is because time_after() ensures a ">" validation while we only need a ">=" validation here: [ 86.739909] ACPI: Waking up from system sleep state S3 [ 86.742857] ACPI : EC: 2: Increase command [ 86.742859] ACPI : EC: ***** Command(RD_EC) started ***** [ 86.742861] ACPI : EC: ===== TASK (0) ===== [ 86.742871] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 86.742873] ACPI : EC: EC_SC(W) = 0x80 [ 86.742876] ACPI : EC: ***** Event started ***** [ 86.742880] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.743972] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.747966] ACPI : EC: ===== TASK (0) ===== [ 86.747977] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 86.747978] ACPI : EC: EC_DATA(W) = 0x06 [ 86.747981] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.751971] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.755969] ACPI : EC: ===== TASK (0) ===== [ 86.755991] ACPI : EC: EC_SC(R) = 0x21 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=1 [ 86.755993] ACPI : EC: EC_DATA(R) = 0x03 [ 86.755994] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.755995] ACPI : EC: ***** Command(RD_EC) stopped ***** [ 86.755996] ACPI : EC: 1: Decrease command This patch corrects this by using time_before() instead in ec_guard(): [ 54.283146] ACPI: Waking up from system sleep state S3 [ 54.285414] ACPI : EC: 2: Increase command [ 54.285415] ACPI : EC: ***** Command(RD_EC) started ***** [ 54.285416] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.285417] ACPI : EC: ===== TASK (0) ===== [ 54.285424] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 54.285425] ACPI : EC: EC_SC(W) = 0x80 [ 54.285427] ACPI : EC: ***** Event started ***** [ 54.285429] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.287209] ACPI : EC: ===== TASK (0) ===== [ 54.287218] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 54.287219] ACPI : EC: EC_DATA(W) = 0x06 [ 54.287222] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.291190] ACPI : EC: ===== TASK (0) ===== [ 54.291210] ACPI : EC: EC_SC(R) = 0x21 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=1 [ 54.291213] ACPI : EC: EC_DATA(R) = 0x03 [ 54.291214] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.291215] ACPI : EC: ***** Command(RD_EC) stopped ***** [ 54.291216] ACPI : EC: 1: Decrease command After cleaning up all guarding logics, we have one single function ec_guard() collecting all old, non-root-caused, hidden logics. Then we can easily tune the logics in one place to respond to the bug reports. Except the time_before() change, all other changes do not change the behavior of the EC driver. Link: https://bugzilla.kernel.org/show_bug.cgi?id=12011 Link: https://bugzilla.kernel.org/show_bug.cgi?id=20242 Link: https://bugzilla.kernel.org/show_bug.cgi?id=77431 Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-05-15 14:16:42 +08:00
ACPI / EC: Add event clearing variation support. We've been suffering from the uncertainty of the SCI_EVT clearing timing. This patch implements 3 of 4 possible modes to handle SCI_EVT clearing variations. The old behavior is kept in this patch. Status: QR_EC is re-checked as early as possible after checking previous SCI_EVT. This always leads to 2 QR_EC transactions per SCI_EVT indication and the target may implement event queue which returns 0x00 indicating "no outstanding event". This is proven to be a conflict against Windows behavior, but is still kept in this patch to make the EC driver robust to the possible regressions that may occur on Samsung platforms. Query: QR_EC is re-checked after the target has handled the QR_EC query request command pushed by the host. Event: QR_EC is re-checked after the target has noticed the query event response data pulled by the host. This timing is not determined by any IRQs, so we may need to use a guard period in this mode, which may explain the existence of the ec_guard() code used by the old EC driver where the re-check timing is implemented in the similar way as this mode. Method: QR_EC is re-checked as late as possible after completing the _Qxx evaluation. The target may implement SCI_EVT like a level triggered interrupt. It is proven on kernel bugzilla 94411 that, Windows will have all _Qxx evaluations parallelized. Thus unless required by further evidences, we needn't implement this mode as it is a conflict of the _Qxx parallelism requirement. Note that, according to the reports, there are platforms that cannot be handled using the "Status" mode without enabling the EC_FLAGS_QUERY_HANDSHAKE quirk. But they can be handled with the other modes according to the tests (kernel bugzilla 97381). The following log entry can be used to confirm the differences of the 3 modes as it should appear at the different positions for the 3 modes: Command(QR_EC) unblocked Status: appearing after EC_SC(W) = 0x84 Query: appearing after EC_DATA(R) = 0xXX where XX is the event number used to determine _QXX Event: appearing after first EC_SC(R) = 0xX0 SCI_EVT=x BURST=0 CMD=0 IBF=0 OBF=0 that is next to the following log entry: Command(QR_EC) completed by hardware 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=98111 Reported-and-tested-by: Gabriele Mazzotta <gabriele.mzt@gmail.com> Reported-and-tested-by: Tigran Gabrielyan <tigrangab@gmail.com> Reported-and-tested-by: Adrien D <ghbdtn@openmailbox.org> Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-06-11 13:21:38 +08:00
ACPI / EC: Fix and clean up register access guarding logics. In the polling mode, EC driver shouldn't access the EC registers too frequently. Though this statement is concluded from the non-root caused bugs (see links below), we've maintained the register access guarding logics in the current EC driver. The guarding logics can be found here and there, makes it hard to root cause real timing issues. This patch collects the guarding logics into one single function so that all hidden logics related to this can be seen clearly. The current guarding related code also has several issues: 1. Per-transaction timestamp prevents inter-transaction guarding from being implemented in the same place. We have an inter-transaction udelay() in acpi_ec_transaction_unblocked(), this logic can be merged into ec_poll() if we can use per-device timestamp. This patch completes such merge to form a new ec_guard() function and collects all guarding related hidden logics in it. One hidden logic is: there is no inter-transaction guarding performed for non MSI quirk (wait polling mode), this patch skips inter-transaction guarding before wait_event_timeout() for the wait polling mode to reveal the hidden logic. The other hidden logic is: there is msleep() inter-transaction guarding performed when the GPE storming is observed. As after merging this commit: Commit: e1d4d90fc0313d3d58cbd7912c90f8ef24df45ff Subject: ACPI / EC: Refine command storm prevention support EC_FLAGS_COMMAND_STORM is ensured to be cleared after invoking acpi_ec_transaction_unlocked(), the msleep() guard logic will never happen now. Since no one complains such change, this logic is likely added during the old times where the EC race issues are not fixed and the bugs are false root-caused to the timing issue. This patch simply removes the out-dated logic. We can restore it by stop skipping inter-transaction guarding for wait polling mode. Two different delay values are defined for msleep() and udelay() while they are merged in this patch to 550us. 2. time_after() causes additional delay in the polling mode (can only be observed in noirq suspend/resume processes where polling mode is always used) before advance_transaction() is invoked ("wait polling" log is added before wait_event_timeout()). We can see 2 wait_event_timeout() invocations. This is because time_after() ensures a ">" validation while we only need a ">=" validation here: [ 86.739909] ACPI: Waking up from system sleep state S3 [ 86.742857] ACPI : EC: 2: Increase command [ 86.742859] ACPI : EC: ***** Command(RD_EC) started ***** [ 86.742861] ACPI : EC: ===== TASK (0) ===== [ 86.742871] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 86.742873] ACPI : EC: EC_SC(W) = 0x80 [ 86.742876] ACPI : EC: ***** Event started ***** [ 86.742880] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.743972] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.747966] ACPI : EC: ===== TASK (0) ===== [ 86.747977] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 86.747978] ACPI : EC: EC_DATA(W) = 0x06 [ 86.747981] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.751971] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.755969] ACPI : EC: ===== TASK (0) ===== [ 86.755991] ACPI : EC: EC_SC(R) = 0x21 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=1 [ 86.755993] ACPI : EC: EC_DATA(R) = 0x03 [ 86.755994] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.755995] ACPI : EC: ***** Command(RD_EC) stopped ***** [ 86.755996] ACPI : EC: 1: Decrease command This patch corrects this by using time_before() instead in ec_guard(): [ 54.283146] ACPI: Waking up from system sleep state S3 [ 54.285414] ACPI : EC: 2: Increase command [ 54.285415] ACPI : EC: ***** Command(RD_EC) started ***** [ 54.285416] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.285417] ACPI : EC: ===== TASK (0) ===== [ 54.285424] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 54.285425] ACPI : EC: EC_SC(W) = 0x80 [ 54.285427] ACPI : EC: ***** Event started ***** [ 54.285429] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.287209] ACPI : EC: ===== TASK (0) ===== [ 54.287218] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 54.287219] ACPI : EC: EC_DATA(W) = 0x06 [ 54.287222] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.291190] ACPI : EC: ===== TASK (0) ===== [ 54.291210] ACPI : EC: EC_SC(R) = 0x21 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=1 [ 54.291213] ACPI : EC: EC_DATA(R) = 0x03 [ 54.291214] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.291215] ACPI : EC: ***** Command(RD_EC) stopped ***** [ 54.291216] ACPI : EC: 1: Decrease command After cleaning up all guarding logics, we have one single function ec_guard() collecting all old, non-root-caused, hidden logics. Then we can easily tune the logics in one place to respond to the bug reports. Except the time_before() change, all other changes do not change the behavior of the EC driver. Link: https://bugzilla.kernel.org/show_bug.cgi?id=12011 Link: https://bugzilla.kernel.org/show_bug.cgi?id=20242 Link: https://bugzilla.kernel.org/show_bug.cgi?id=77431 Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-05-15 14:16:42 +08:00
ACPI / EC: Fix and clean up register access guarding logics. In the polling mode, EC driver shouldn't access the EC registers too frequently. Though this statement is concluded from the non-root caused bugs (see links below), we've maintained the register access guarding logics in the current EC driver. The guarding logics can be found here and there, makes it hard to root cause real timing issues. This patch collects the guarding logics into one single function so that all hidden logics related to this can be seen clearly. The current guarding related code also has several issues: 1. Per-transaction timestamp prevents inter-transaction guarding from being implemented in the same place. We have an inter-transaction udelay() in acpi_ec_transaction_unblocked(), this logic can be merged into ec_poll() if we can use per-device timestamp. This patch completes such merge to form a new ec_guard() function and collects all guarding related hidden logics in it. One hidden logic is: there is no inter-transaction guarding performed for non MSI quirk (wait polling mode), this patch skips inter-transaction guarding before wait_event_timeout() for the wait polling mode to reveal the hidden logic. The other hidden logic is: there is msleep() inter-transaction guarding performed when the GPE storming is observed. As after merging this commit: Commit: e1d4d90fc0313d3d58cbd7912c90f8ef24df45ff Subject: ACPI / EC: Refine command storm prevention support EC_FLAGS_COMMAND_STORM is ensured to be cleared after invoking acpi_ec_transaction_unlocked(), the msleep() guard logic will never happen now. Since no one complains such change, this logic is likely added during the old times where the EC race issues are not fixed and the bugs are false root-caused to the timing issue. This patch simply removes the out-dated logic. We can restore it by stop skipping inter-transaction guarding for wait polling mode. Two different delay values are defined for msleep() and udelay() while they are merged in this patch to 550us. 2. time_after() causes additional delay in the polling mode (can only be observed in noirq suspend/resume processes where polling mode is always used) before advance_transaction() is invoked ("wait polling" log is added before wait_event_timeout()). We can see 2 wait_event_timeout() invocations. This is because time_after() ensures a ">" validation while we only need a ">=" validation here: [ 86.739909] ACPI: Waking up from system sleep state S3 [ 86.742857] ACPI : EC: 2: Increase command [ 86.742859] ACPI : EC: ***** Command(RD_EC) started ***** [ 86.742861] ACPI : EC: ===== TASK (0) ===== [ 86.742871] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 86.742873] ACPI : EC: EC_SC(W) = 0x80 [ 86.742876] ACPI : EC: ***** Event started ***** [ 86.742880] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.743972] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.747966] ACPI : EC: ===== TASK (0) ===== [ 86.747977] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 86.747978] ACPI : EC: EC_DATA(W) = 0x06 [ 86.747981] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.751971] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.755969] ACPI : EC: ===== TASK (0) ===== [ 86.755991] ACPI : EC: EC_SC(R) = 0x21 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=1 [ 86.755993] ACPI : EC: EC_DATA(R) = 0x03 [ 86.755994] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.755995] ACPI : EC: ***** Command(RD_EC) stopped ***** [ 86.755996] ACPI : EC: 1: Decrease command This patch corrects this by using time_before() instead in ec_guard(): [ 54.283146] ACPI: Waking up from system sleep state S3 [ 54.285414] ACPI : EC: 2: Increase command [ 54.285415] ACPI : EC: ***** Command(RD_EC) started ***** [ 54.285416] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.285417] ACPI : EC: ===== TASK (0) ===== [ 54.285424] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 54.285425] ACPI : EC: EC_SC(W) = 0x80 [ 54.285427] ACPI : EC: ***** Event started ***** [ 54.285429] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.287209] ACPI : EC: ===== TASK (0) ===== [ 54.287218] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 54.287219] ACPI : EC: EC_DATA(W) = 0x06 [ 54.287222] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.291190] ACPI : EC: ===== TASK (0) ===== [ 54.291210] ACPI : EC: EC_SC(R) = 0x21 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=1 [ 54.291213] ACPI : EC: EC_DATA(R) = 0x03 [ 54.291214] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.291215] ACPI : EC: ***** Command(RD_EC) stopped ***** [ 54.291216] ACPI : EC: 1: Decrease command After cleaning up all guarding logics, we have one single function ec_guard() collecting all old, non-root-caused, hidden logics. Then we can easily tune the logics in one place to respond to the bug reports. Except the time_before() change, all other changes do not change the behavior of the EC driver. Link: https://bugzilla.kernel.org/show_bug.cgi?id=12011 Link: https://bugzilla.kernel.org/show_bug.cgi?id=20242 Link: https://bugzilla.kernel.org/show_bug.cgi?id=77431 Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-05-15 14:16:42 +08:00
ACPI / EC: Fix and clean up register access guarding logics. In the polling mode, EC driver shouldn't access the EC registers too frequently. Though this statement is concluded from the non-root caused bugs (see links below), we've maintained the register access guarding logics in the current EC driver. The guarding logics can be found here and there, makes it hard to root cause real timing issues. This patch collects the guarding logics into one single function so that all hidden logics related to this can be seen clearly. The current guarding related code also has several issues: 1. Per-transaction timestamp prevents inter-transaction guarding from being implemented in the same place. We have an inter-transaction udelay() in acpi_ec_transaction_unblocked(), this logic can be merged into ec_poll() if we can use per-device timestamp. This patch completes such merge to form a new ec_guard() function and collects all guarding related hidden logics in it. One hidden logic is: there is no inter-transaction guarding performed for non MSI quirk (wait polling mode), this patch skips inter-transaction guarding before wait_event_timeout() for the wait polling mode to reveal the hidden logic. The other hidden logic is: there is msleep() inter-transaction guarding performed when the GPE storming is observed. As after merging this commit: Commit: e1d4d90fc0313d3d58cbd7912c90f8ef24df45ff Subject: ACPI / EC: Refine command storm prevention support EC_FLAGS_COMMAND_STORM is ensured to be cleared after invoking acpi_ec_transaction_unlocked(), the msleep() guard logic will never happen now. Since no one complains such change, this logic is likely added during the old times where the EC race issues are not fixed and the bugs are false root-caused to the timing issue. This patch simply removes the out-dated logic. We can restore it by stop skipping inter-transaction guarding for wait polling mode. Two different delay values are defined for msleep() and udelay() while they are merged in this patch to 550us. 2. time_after() causes additional delay in the polling mode (can only be observed in noirq suspend/resume processes where polling mode is always used) before advance_transaction() is invoked ("wait polling" log is added before wait_event_timeout()). We can see 2 wait_event_timeout() invocations. This is because time_after() ensures a ">" validation while we only need a ">=" validation here: [ 86.739909] ACPI: Waking up from system sleep state S3 [ 86.742857] ACPI : EC: 2: Increase command [ 86.742859] ACPI : EC: ***** Command(RD_EC) started ***** [ 86.742861] ACPI : EC: ===== TASK (0) ===== [ 86.742871] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 86.742873] ACPI : EC: EC_SC(W) = 0x80 [ 86.742876] ACPI : EC: ***** Event started ***** [ 86.742880] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.743972] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.747966] ACPI : EC: ===== TASK (0) ===== [ 86.747977] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 86.747978] ACPI : EC: EC_DATA(W) = 0x06 [ 86.747981] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.751971] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.755969] ACPI : EC: ===== TASK (0) ===== [ 86.755991] ACPI : EC: EC_SC(R) = 0x21 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=1 [ 86.755993] ACPI : EC: EC_DATA(R) = 0x03 [ 86.755994] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.755995] ACPI : EC: ***** Command(RD_EC) stopped ***** [ 86.755996] ACPI : EC: 1: Decrease command This patch corrects this by using time_before() instead in ec_guard(): [ 54.283146] ACPI: Waking up from system sleep state S3 [ 54.285414] ACPI : EC: 2: Increase command [ 54.285415] ACPI : EC: ***** Command(RD_EC) started ***** [ 54.285416] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.285417] ACPI : EC: ===== TASK (0) ===== [ 54.285424] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 54.285425] ACPI : EC: EC_SC(W) = 0x80 [ 54.285427] ACPI : EC: ***** Event started ***** [ 54.285429] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.287209] ACPI : EC: ===== TASK (0) ===== [ 54.287218] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 54.287219] ACPI : EC: EC_DATA(W) = 0x06 [ 54.287222] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.291190] ACPI : EC: ===== TASK (0) ===== [ 54.291210] ACPI : EC: EC_SC(R) = 0x21 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=1 [ 54.291213] ACPI : EC: EC_DATA(R) = 0x03 [ 54.291214] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.291215] ACPI : EC: ***** Command(RD_EC) stopped ***** [ 54.291216] ACPI : EC: 1: Decrease command After cleaning up all guarding logics, we have one single function ec_guard() collecting all old, non-root-caused, hidden logics. Then we can easily tune the logics in one place to respond to the bug reports. Except the time_before() change, all other changes do not change the behavior of the EC driver. Link: https://bugzilla.kernel.org/show_bug.cgi?id=12011 Link: https://bugzilla.kernel.org/show_bug.cgi?id=20242 Link: https://bugzilla.kernel.org/show_bug.cgi?id=77431 Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-05-15 14:16:42 +08:00
Revert "ACPI / EC: Add support to disallow QR_EC to be issued before completing previous QR_EC" It is reported that the following commit breaks Samsung hardware: Commit: 558e4736f2e1b0e6323adf7a5e4df77ed6cfc1a4. Subject: ACPI / EC: Add support to disallow QR_EC to be issued before completing previous QR_EC Which means the Samsung behavior conflicts with the Acer behavior. 1. Samsung may behave like: [ +event 1 ] SCI_EVT set [ +event 2 ] SCI_EVT set write QR_EC read event [ -event 1 ] SCI_EVT clear Without the above commit, Samsung can work: [ +event 1 ] SCI_EVT set [ +event 2 ] SCI_EVT set write QR_EC CAN prepare next QR_EC as SCI_EVT=1 read event [ -event 1 ] SCI_EVT clear write QR_EC read event [ -event 2 ] SCI_EVT clear With the above commit, Samsung cannot work: [ +event 1 ] SCI_EVT set [ +event 2 ] SCI_EVT set write QR_EC read event [ -event 1 ] SCI_EVT clear CANNOT prepare next QR_EC as SCI_EVT=0 2. Acer may behave like: [ +event 1 ] SCI_EVT set [ +event 2 ] write QR_EC read event [ -event 1 ] SCI_EVT clear [ +event 2 ] SCI_EVT set Without the above commit, Acer cannot work when there is only 1 event: [ +event 1 ] SCI_EVT set write QR_EC can prepared next QR_EC as SCI_EVT=1 read event [ -event 1 ] SCI_EVT clear CANNOT write QR_EC as SCI_EVT=0 With the above commit, Acer can work: [ +event 1 ] SCI_EVT set [ +event 2 ] write QR_EC read event [ -event 1 ] SCI_EVT set can prepare next QR_EC because SCI_EVT=0 CAN write QR_EC as SCI_EVT=1 Since Acer can also work with only the following commit applied: Commit: 3afcf2ece453e1a8c2c6de19cdf06da3772a1b08 Subject: ACPI / EC: Add support to disallow QR_EC to be issued when SCI_EVT isn't set commit 558e4736f2e1b0e6323adf7a5e4df77ed6cfc1a4 can be reverted. Fixes: 558e4736f2e1 (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+ Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2014-10-29 11:33:43 +08:00
ACPI / EC: Fix and clean up register access guarding logics. In the polling mode, EC driver shouldn't access the EC registers too frequently. Though this statement is concluded from the non-root caused bugs (see links below), we've maintained the register access guarding logics in the current EC driver. The guarding logics can be found here and there, makes it hard to root cause real timing issues. This patch collects the guarding logics into one single function so that all hidden logics related to this can be seen clearly. The current guarding related code also has several issues: 1. Per-transaction timestamp prevents inter-transaction guarding from being implemented in the same place. We have an inter-transaction udelay() in acpi_ec_transaction_unblocked(), this logic can be merged into ec_poll() if we can use per-device timestamp. This patch completes such merge to form a new ec_guard() function and collects all guarding related hidden logics in it. One hidden logic is: there is no inter-transaction guarding performed for non MSI quirk (wait polling mode), this patch skips inter-transaction guarding before wait_event_timeout() for the wait polling mode to reveal the hidden logic. The other hidden logic is: there is msleep() inter-transaction guarding performed when the GPE storming is observed. As after merging this commit: Commit: e1d4d90fc0313d3d58cbd7912c90f8ef24df45ff Subject: ACPI / EC: Refine command storm prevention support EC_FLAGS_COMMAND_STORM is ensured to be cleared after invoking acpi_ec_transaction_unlocked(), the msleep() guard logic will never happen now. Since no one complains such change, this logic is likely added during the old times where the EC race issues are not fixed and the bugs are false root-caused to the timing issue. This patch simply removes the out-dated logic. We can restore it by stop skipping inter-transaction guarding for wait polling mode. Two different delay values are defined for msleep() and udelay() while they are merged in this patch to 550us. 2. time_after() causes additional delay in the polling mode (can only be observed in noirq suspend/resume processes where polling mode is always used) before advance_transaction() is invoked ("wait polling" log is added before wait_event_timeout()). We can see 2 wait_event_timeout() invocations. This is because time_after() ensures a ">" validation while we only need a ">=" validation here: [ 86.739909] ACPI: Waking up from system sleep state S3 [ 86.742857] ACPI : EC: 2: Increase command [ 86.742859] ACPI : EC: ***** Command(RD_EC) started ***** [ 86.742861] ACPI : EC: ===== TASK (0) ===== [ 86.742871] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 86.742873] ACPI : EC: EC_SC(W) = 0x80 [ 86.742876] ACPI : EC: ***** Event started ***** [ 86.742880] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.743972] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.747966] ACPI : EC: ===== TASK (0) ===== [ 86.747977] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 86.747978] ACPI : EC: EC_DATA(W) = 0x06 [ 86.747981] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.751971] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.755969] ACPI : EC: ===== TASK (0) ===== [ 86.755991] ACPI : EC: EC_SC(R) = 0x21 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=1 [ 86.755993] ACPI : EC: EC_DATA(R) = 0x03 [ 86.755994] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.755995] ACPI : EC: ***** Command(RD_EC) stopped ***** [ 86.755996] ACPI : EC: 1: Decrease command This patch corrects this by using time_before() instead in ec_guard(): [ 54.283146] ACPI: Waking up from system sleep state S3 [ 54.285414] ACPI : EC: 2: Increase command [ 54.285415] ACPI : EC: ***** Command(RD_EC) started ***** [ 54.285416] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.285417] ACPI : EC: ===== TASK (0) ===== [ 54.285424] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 54.285425] ACPI : EC: EC_SC(W) = 0x80 [ 54.285427] ACPI : EC: ***** Event started ***** [ 54.285429] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.287209] ACPI : EC: ===== TASK (0) ===== [ 54.287218] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 54.287219] ACPI : EC: EC_DATA(W) = 0x06 [ 54.287222] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.291190] ACPI : EC: ===== TASK (0) ===== [ 54.291210] ACPI : EC: EC_SC(R) = 0x21 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=1 [ 54.291213] ACPI : EC: EC_DATA(R) = 0x03 [ 54.291214] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.291215] ACPI : EC: ***** Command(RD_EC) stopped ***** [ 54.291216] ACPI : EC: 1: Decrease command After cleaning up all guarding logics, we have one single function ec_guard() collecting all old, non-root-caused, hidden logics. Then we can easily tune the logics in one place to respond to the bug reports. Except the time_before() change, all other changes do not change the behavior of the EC driver. Link: https://bugzilla.kernel.org/show_bug.cgi?id=12011 Link: https://bugzilla.kernel.org/show_bug.cgi?id=20242 Link: https://bugzilla.kernel.org/show_bug.cgi?id=77431 Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-05-15 14:16:42 +08:00
ACPI / EC: Refine command storm prevention support This patch refines EC command storm prevention support. Current command storming code is wrong, when the storming condition is detected, it only flags the condition without doing anything for the current command but performing storming prevention for the follow-up commands. So: 1. The first command which suffers from the storming still suffers from storming. 2. The follow-up commands which may not suffer from the storming are unconditionally forced into the storming prevention mode. Ideally, we should only enable storm prevention immediately after detection for the current command so that the next command can try the power/performance efficient interrupt mode again. This patch improves the command storm prevention by disabling GPE right after the detection and re-enabling it right before completing the command transaction using the GPE storming prevention APIs. This thus deploys the following GPE handling model: 1. acpi_enable_gpe()/acpi_disable_gpe() for reference count changes: This set of APIs are used for EC usage reference counting. 2. acpi_set_gpe(ACPI_GPE_ENABLE)/acpi_set_gpe(ACPI_GPE_DISABLE): This set of APIs are used for preventing GPE storm. They must be invoked when the reference count > 0. Note that as the storming prevention should always happen when there is an outstanding request, or GPE enabling value will be messed up by the races. This patch also adds BUG_ON() to enforces this rule to prevent future bugs. The msleep(1) used after completing a transaction is useless now as this sounds like a guard time only useful for platforms that need the EC_FLAGS_MSI quirks while we have fixed GPE race issues using the previous raw handler mode enabling. It is kept to avoid regressions. A seperate patch which deletes EC_FLAGS_MSI quirks should take care of deleting it. Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-02-06 08:58:05 +08:00
ACPI / EC: Fix and clean up register access guarding logics. In the polling mode, EC driver shouldn't access the EC registers too frequently. Though this statement is concluded from the non-root caused bugs (see links below), we've maintained the register access guarding logics in the current EC driver. The guarding logics can be found here and there, makes it hard to root cause real timing issues. This patch collects the guarding logics into one single function so that all hidden logics related to this can be seen clearly. The current guarding related code also has several issues: 1. Per-transaction timestamp prevents inter-transaction guarding from being implemented in the same place. We have an inter-transaction udelay() in acpi_ec_transaction_unblocked(), this logic can be merged into ec_poll() if we can use per-device timestamp. This patch completes such merge to form a new ec_guard() function and collects all guarding related hidden logics in it. One hidden logic is: there is no inter-transaction guarding performed for non MSI quirk (wait polling mode), this patch skips inter-transaction guarding before wait_event_timeout() for the wait polling mode to reveal the hidden logic. The other hidden logic is: there is msleep() inter-transaction guarding performed when the GPE storming is observed. As after merging this commit: Commit: e1d4d90fc0313d3d58cbd7912c90f8ef24df45ff Subject: ACPI / EC: Refine command storm prevention support EC_FLAGS_COMMAND_STORM is ensured to be cleared after invoking acpi_ec_transaction_unlocked(), the msleep() guard logic will never happen now. Since no one complains such change, this logic is likely added during the old times where the EC race issues are not fixed and the bugs are false root-caused to the timing issue. This patch simply removes the out-dated logic. We can restore it by stop skipping inter-transaction guarding for wait polling mode. Two different delay values are defined for msleep() and udelay() while they are merged in this patch to 550us. 2. time_after() causes additional delay in the polling mode (can only be observed in noirq suspend/resume processes where polling mode is always used) before advance_transaction() is invoked ("wait polling" log is added before wait_event_timeout()). We can see 2 wait_event_timeout() invocations. This is because time_after() ensures a ">" validation while we only need a ">=" validation here: [ 86.739909] ACPI: Waking up from system sleep state S3 [ 86.742857] ACPI : EC: 2: Increase command [ 86.742859] ACPI : EC: ***** Command(RD_EC) started ***** [ 86.742861] ACPI : EC: ===== TASK (0) ===== [ 86.742871] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 86.742873] ACPI : EC: EC_SC(W) = 0x80 [ 86.742876] ACPI : EC: ***** Event started ***** [ 86.742880] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.743972] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.747966] ACPI : EC: ===== TASK (0) ===== [ 86.747977] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 86.747978] ACPI : EC: EC_DATA(W) = 0x06 [ 86.747981] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.751971] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.755969] ACPI : EC: ===== TASK (0) ===== [ 86.755991] ACPI : EC: EC_SC(R) = 0x21 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=1 [ 86.755993] ACPI : EC: EC_DATA(R) = 0x03 [ 86.755994] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.755995] ACPI : EC: ***** Command(RD_EC) stopped ***** [ 86.755996] ACPI : EC: 1: Decrease command This patch corrects this by using time_before() instead in ec_guard(): [ 54.283146] ACPI: Waking up from system sleep state S3 [ 54.285414] ACPI : EC: 2: Increase command [ 54.285415] ACPI : EC: ***** Command(RD_EC) started ***** [ 54.285416] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.285417] ACPI : EC: ===== TASK (0) ===== [ 54.285424] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 54.285425] ACPI : EC: EC_SC(W) = 0x80 [ 54.285427] ACPI : EC: ***** Event started ***** [ 54.285429] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.287209] ACPI : EC: ===== TASK (0) ===== [ 54.287218] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 54.287219] ACPI : EC: EC_DATA(W) = 0x06 [ 54.287222] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.291190] ACPI : EC: ===== TASK (0) ===== [ 54.291210] ACPI : EC: EC_SC(R) = 0x21 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=1 [ 54.291213] ACPI : EC: EC_DATA(R) = 0x03 [ 54.291214] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.291215] ACPI : EC: ***** Command(RD_EC) stopped ***** [ 54.291216] ACPI : EC: 1: Decrease command After cleaning up all guarding logics, we have one single function ec_guard() collecting all old, non-root-caused, hidden logics. Then we can easily tune the logics in one place to respond to the bug reports. Except the time_before() change, all other changes do not change the behavior of the EC driver. Link: https://bugzilla.kernel.org/show_bug.cgi?id=12011 Link: https://bugzilla.kernel.org/show_bug.cgi?id=20242 Link: https://bugzilla.kernel.org/show_bug.cgi?id=77431 Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-05-15 14:16:42 +08:00
ACPI / EC: Add PM operations to improve event handling for resume process This patch makes 2 changes: 1. Restore old behavior Originally, EC driver stops handling both events and transactions in acpi_ec_block_transactions(), and restarts to handle transactions in acpi_ec_unblock_transactions_early(), restarts to handle both events and transactions in acpi_ec_unblock_transactions(). While currently, EC driver still stops handling both events and transactions in acpi_ec_block_transactions(), but restarts to handle both events and transactions in acpi_ec_unblock_transactions_early(). This patch tries to restore the old behavior by dropping __acpi_ec_enable_event() from acpi_unblock_transactions_early(). 2. Improve old behavior However this still cannot fix the real issue as both of the acpi_ec_unblock_xxx() functions are invoked in the noirq stage. Since the EC driver actually doesn't implement the event handling in the polling mode, re-enabling the event handling too early in the noirq stage could result in the problem that if there is no triggering source causing advance_transaction() to be invoked, pending SCI_EVT cannot be detected by the EC driver and _Qxx cannot be triggered. It actually makes sense to restart the event handling in any point during resuming after the noirq stage. Just like the boot stage where the event handling is enabled in .add(), this patch further moves acpi_ec_enable_event() to .resume(). After doing that, the following 2 functions can be combined: acpi_ec_unblock_transactions_early()/acpi_ec_unblock_transactions(). The differences of the event handling availability between the old behavior (this patch isn't applied) and the new behavior (this patch is applied) are as follows: !Applied Applied before suspend Y Y suspend before EC Y Y suspend after EC Y Y suspend_late Y Y suspend_noirq Y (actually N) Y (actually N) resume_noirq Y (actually N) Y (actually N) resume_late Y (actually N) Y (actually N) resume before EC Y (actually N) Y (actually N) resume after EC Y (actually N) Y after resume Y (actually N) Y Where "actually N" means if there is no triggering source, the EC driver is actually not able to notice the pending SCI_EVT occurred in the noirq stage. So we can clearly see that this patch has improved the situation. Signed-off-by: Lv Zheng <lv.zheng@intel.com> Tested-by: Todd E Brandt <todd.e.brandt@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2016-08-03 16:01:36 +08:00
ACPI / EC: Add PM operations to improve event handling for suspend process In the original EC driver, though the event handling is not explicitly stopped, the EC driver is actually not able to handle events during the noirq stage as the EC driver is not prepared to handle the EC events in the polling mode. So if there is no advance_transaction() triggered, the EC driver couldn't notice the EC events. However, do we actually need to handle EC events during suspend/resume stage? EC events are mostly useless for the suspend/resume period (key strokes and battery/thermal updates, etc.,), and the useful ones (lid close, power/sleep button press) should have already been delivered to the OSPM to trigger the power saving operations. Thus this patch implements acpi_ec_disable_event() to be a reverse call of acpi_ec_enable_event(), with which, the EC driver is able to stop handling the EC events in a position before entering the noirq stage. Since there are actually 2 choices for us: 1. implement event handling in polling mode; 2. stop event handling before entering noirq stage. And this patch only implements the second choice using .suspend() callback. Thus this is experimental (first choice is better? or different hook position is better?). This patch finally keeps the old behavior by default and prepares a boot parameter to enable this feature. The differences of the event handling availability between the old behavior (this patch is not applied) and the new behavior (this patch is applied) are as follows: !FreezeEvents FreezeEvents before suspend Y Y suspend before EC Y Y suspend after EC Y N suspend_late Y N suspend_noirq Y (actually N) N resume_noirq Y (actually N) N resume_late Y (actually N) N resume before EC Y (actually N) N resume after EC Y Y after resume Y Y Where "actually N" means if there is no EC transactions, the EC driver is actually not able to notice the pending events. We can see that FreezeEvents is the only approach now can actually flush the EC event handling with both query commands and _Qxx evaluations flushed, other modes can only flush the EC event handling with only query commands flushed, _Qxx evaluations occurred after stopping the EC driver may end up failure due to the failure of the EC transaction carried out in the _Qxx control methods. We also can see that this feature should be able to trigger some platform notifications later than resuming other drivers. Signed-off-by: Lv Zheng <lv.zheng@intel.com> Tested-by: Todd E Brandt <todd.e.brandt@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2016-08-03 16:01:43 +08:00
ACPI: EC: Rework flushing of EC work while suspended to idle The flushing of pending work in the EC driver uses drain_workqueue() to flush the event handling work that can requeue itself via advance_transaction(), but this is problematic, because that work may also be requeued from the query workqueue. Namely, if an EC transaction is carried out during the execution of a query handler, it involves calling advance_transaction() which may queue up the event handling work again. This causes the kernel to complain about attempts to add a work item to the EC event workqueue while it is being drained and worst-case it may cause a valid event to be skipped. To avoid this problem, introduce two new counters, events_in_progress and queries_in_progress, incremented when a work item is queued on the event workqueue or the query workqueue, respectively, and decremented at the end of the corresponding work function, and make acpi_ec_dispatch_gpe() the workqueues in a loop until the both of these counters are zero (or system wakeup is pending) instead of calling acpi_ec_flush_work(). At the same time, change __acpi_ec_flush_work() to call flush_workqueue() instead of drain_workqueue() to flush the event workqueue. While at it, use the observation that the work item queued in acpi_ec_query() cannot be pending at that time, because it is used only once, to simplify the code in there. Additionally, clean up a comment in acpi_ec_query() and adjust white space in acpi_ec_event_processor(). Fixes: f0ac20c3f613 ("ACPI: EC: Fix flushing of pending work") Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-11-23 19:36:51 +01:00
ACPI: EC: Rework flushing of EC work while suspended to idle The flushing of pending work in the EC driver uses drain_workqueue() to flush the event handling work that can requeue itself via advance_transaction(), but this is problematic, because that work may also be requeued from the query workqueue. Namely, if an EC transaction is carried out during the execution of a query handler, it involves calling advance_transaction() which may queue up the event handling work again. This causes the kernel to complain about attempts to add a work item to the EC event workqueue while it is being drained and worst-case it may cause a valid event to be skipped. To avoid this problem, introduce two new counters, events_in_progress and queries_in_progress, incremented when a work item is queued on the event workqueue or the query workqueue, respectively, and decremented at the end of the corresponding work function, and make acpi_ec_dispatch_gpe() the workqueues in a loop until the both of these counters are zero (or system wakeup is pending) instead of calling acpi_ec_flush_work(). At the same time, change __acpi_ec_flush_work() to call flush_workqueue() instead of drain_workqueue() to flush the event workqueue. While at it, use the observation that the work item queued in acpi_ec_query() cannot be pending at that time, because it is used only once, to simplify the code in there. Additionally, clean up a comment in acpi_ec_query() and adjust white space in acpi_ec_event_processor(). Fixes: f0ac20c3f613 ("ACPI: EC: Fix flushing of pending work") Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-11-23 19:36:51 +01:00
ACPI: EC: Rework flushing of EC work while suspended to idle The flushing of pending work in the EC driver uses drain_workqueue() to flush the event handling work that can requeue itself via advance_transaction(), but this is problematic, because that work may also be requeued from the query workqueue. Namely, if an EC transaction is carried out during the execution of a query handler, it involves calling advance_transaction() which may queue up the event handling work again. This causes the kernel to complain about attempts to add a work item to the EC event workqueue while it is being drained and worst-case it may cause a valid event to be skipped. To avoid this problem, introduce two new counters, events_in_progress and queries_in_progress, incremented when a work item is queued on the event workqueue or the query workqueue, respectively, and decremented at the end of the corresponding work function, and make acpi_ec_dispatch_gpe() the workqueues in a loop until the both of these counters are zero (or system wakeup is pending) instead of calling acpi_ec_flush_work(). At the same time, change __acpi_ec_flush_work() to call flush_workqueue() instead of drain_workqueue() to flush the event workqueue. While at it, use the observation that the work item queued in acpi_ec_query() cannot be pending at that time, because it is used only once, to simplify the code in there. Additionally, clean up a comment in acpi_ec_query() and adjust white space in acpi_ec_event_processor(). Fixes: f0ac20c3f613 ("ACPI: EC: Fix flushing of pending work") Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-11-23 19:36:51 +01:00
ACPI: EC: Rework flushing of EC work while suspended to idle The flushing of pending work in the EC driver uses drain_workqueue() to flush the event handling work that can requeue itself via advance_transaction(), but this is problematic, because that work may also be requeued from the query workqueue. Namely, if an EC transaction is carried out during the execution of a query handler, it involves calling advance_transaction() which may queue up the event handling work again. This causes the kernel to complain about attempts to add a work item to the EC event workqueue while it is being drained and worst-case it may cause a valid event to be skipped. To avoid this problem, introduce two new counters, events_in_progress and queries_in_progress, incremented when a work item is queued on the event workqueue or the query workqueue, respectively, and decremented at the end of the corresponding work function, and make acpi_ec_dispatch_gpe() the workqueues in a loop until the both of these counters are zero (or system wakeup is pending) instead of calling acpi_ec_flush_work(). At the same time, change __acpi_ec_flush_work() to call flush_workqueue() instead of drain_workqueue() to flush the event workqueue. While at it, use the observation that the work item queued in acpi_ec_query() cannot be pending at that time, because it is used only once, to simplify the code in there. Additionally, clean up a comment in acpi_ec_query() and adjust white space in acpi_ec_event_processor(). Fixes: f0ac20c3f613 ("ACPI: EC: Fix flushing of pending work") Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-11-23 19:36:51 +01:00
ACPI: EC: Rework flushing of EC work while suspended to idle The flushing of pending work in the EC driver uses drain_workqueue() to flush the event handling work that can requeue itself via advance_transaction(), but this is problematic, because that work may also be requeued from the query workqueue. Namely, if an EC transaction is carried out during the execution of a query handler, it involves calling advance_transaction() which may queue up the event handling work again. This causes the kernel to complain about attempts to add a work item to the EC event workqueue while it is being drained and worst-case it may cause a valid event to be skipped. To avoid this problem, introduce two new counters, events_in_progress and queries_in_progress, incremented when a work item is queued on the event workqueue or the query workqueue, respectively, and decremented at the end of the corresponding work function, and make acpi_ec_dispatch_gpe() the workqueues in a loop until the both of these counters are zero (or system wakeup is pending) instead of calling acpi_ec_flush_work(). At the same time, change __acpi_ec_flush_work() to call flush_workqueue() instead of drain_workqueue() to flush the event workqueue. While at it, use the observation that the work item queued in acpi_ec_query() cannot be pending at that time, because it is used only once, to simplify the code in there. Additionally, clean up a comment in acpi_ec_query() and adjust white space in acpi_ec_event_processor(). Fixes: f0ac20c3f613 ("ACPI: EC: Fix flushing of pending work") Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-11-23 19:36:51 +01:00
ACPI: EC: Rework flushing of EC work while suspended to idle The flushing of pending work in the EC driver uses drain_workqueue() to flush the event handling work that can requeue itself via advance_transaction(), but this is problematic, because that work may also be requeued from the query workqueue. Namely, if an EC transaction is carried out during the execution of a query handler, it involves calling advance_transaction() which may queue up the event handling work again. This causes the kernel to complain about attempts to add a work item to the EC event workqueue while it is being drained and worst-case it may cause a valid event to be skipped. To avoid this problem, introduce two new counters, events_in_progress and queries_in_progress, incremented when a work item is queued on the event workqueue or the query workqueue, respectively, and decremented at the end of the corresponding work function, and make acpi_ec_dispatch_gpe() the workqueues in a loop until the both of these counters are zero (or system wakeup is pending) instead of calling acpi_ec_flush_work(). At the same time, change __acpi_ec_flush_work() to call flush_workqueue() instead of drain_workqueue() to flush the event workqueue. While at it, use the observation that the work item queued in acpi_ec_query() cannot be pending at that time, because it is used only once, to simplify the code in there. Additionally, clean up a comment in acpi_ec_query() and adjust white space in acpi_ec_event_processor(). Fixes: f0ac20c3f613 ("ACPI: EC: Fix flushing of pending work") Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-11-23 19:36:51 +01:00
ACPI: EC: Rework flushing of EC work while suspended to idle The flushing of pending work in the EC driver uses drain_workqueue() to flush the event handling work that can requeue itself via advance_transaction(), but this is problematic, because that work may also be requeued from the query workqueue. Namely, if an EC transaction is carried out during the execution of a query handler, it involves calling advance_transaction() which may queue up the event handling work again. This causes the kernel to complain about attempts to add a work item to the EC event workqueue while it is being drained and worst-case it may cause a valid event to be skipped. To avoid this problem, introduce two new counters, events_in_progress and queries_in_progress, incremented when a work item is queued on the event workqueue or the query workqueue, respectively, and decremented at the end of the corresponding work function, and make acpi_ec_dispatch_gpe() the workqueues in a loop until the both of these counters are zero (or system wakeup is pending) instead of calling acpi_ec_flush_work(). At the same time, change __acpi_ec_flush_work() to call flush_workqueue() instead of drain_workqueue() to flush the event workqueue. While at it, use the observation that the work item queued in acpi_ec_query() cannot be pending at that time, because it is used only once, to simplify the code in there. Additionally, clean up a comment in acpi_ec_query() and adjust white space in acpi_ec_event_processor(). Fixes: f0ac20c3f613 ("ACPI: EC: Fix flushing of pending work") Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-11-23 19:36:51 +01:00
ACPI / EC: Process rather than discard events in acpi_ec_clear Address a regression caused by commit ad332c8a4533: (ACPI / EC: Clear stale EC events on Samsung systems) After the earlier patch, there was found to be a race condition on some earlier Samsung systems (N150/N210/N220). The function acpi_ec_clear was sometimes discarding a new EC event before its GPE was triggered by the system. In the case of these systems, this meant that the "lid open" event was not registered on resume if that was the cause of the wake, leading to problems when attempting to close the lid to suspend again. After testing on a number of Samsung systems, both those affected by the previous EC bug and those affected by the race condition, it seemed that the best course of action was to process rather than discard the events. On Samsung systems which accumulate stale EC events, there does not seem to be any adverse side-effects of running the associated _Q methods. This patch adds an argument to the static function acpi_ec_sync_query so that it may be used within the acpi_ec_clear loop in place of acpi_ec_query_unlocked which was used previously. With thanks to Stefan Biereigel for reporting the issue, and for all the people who helped test the new patch on affected systems. Fixes: ad332c8a4533 (ACPI / EC: Clear stale EC events on Samsung systems) References: https://lkml.kernel.org/r/532FE3B2.9060808@biereigel-wb.de References: https://bugzilla.kernel.org/show_bug.cgi?id=44161#c173 Reported-by: Stefan Biereigel <stefan@biereigel.de> Signed-off-by: Kieran Clancy <clancy.kieran@gmail.com> Tested-by: Stefan Biereigel <stefan@biereigel.de> Tested-by: Dennis Jansen <dennis.jansen@web.de> Tested-by: Nicolas Porcel <nicolasporcel06@gmail.com> Tested-by: Maurizio D'Addona <mauritiusdadd@gmail.com> Tested-by: Juan Manuel Cabo <juanmanuel.cabo@gmail.com> Tested-by: Giannis Koutsou <giannis.koutsou@gmail.com> Tested-by: Kieran Clancy <clancy.kieran@gmail.com> Cc: 3.14+ <stable@vger.kernel.org> # 3.14+ Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2014-04-30 00:21:20 +09:30
ACPI / EC: Process rather than discard events in acpi_ec_clear Address a regression caused by commit ad332c8a4533: (ACPI / EC: Clear stale EC events on Samsung systems) After the earlier patch, there was found to be a race condition on some earlier Samsung systems (N150/N210/N220). The function acpi_ec_clear was sometimes discarding a new EC event before its GPE was triggered by the system. In the case of these systems, this meant that the "lid open" event was not registered on resume if that was the cause of the wake, leading to problems when attempting to close the lid to suspend again. After testing on a number of Samsung systems, both those affected by the previous EC bug and those affected by the race condition, it seemed that the best course of action was to process rather than discard the events. On Samsung systems which accumulate stale EC events, there does not seem to be any adverse side-effects of running the associated _Q methods. This patch adds an argument to the static function acpi_ec_sync_query so that it may be used within the acpi_ec_clear loop in place of acpi_ec_query_unlocked which was used previously. With thanks to Stefan Biereigel for reporting the issue, and for all the people who helped test the new patch on affected systems. Fixes: ad332c8a4533 (ACPI / EC: Clear stale EC events on Samsung systems) References: https://lkml.kernel.org/r/532FE3B2.9060808@biereigel-wb.de References: https://bugzilla.kernel.org/show_bug.cgi?id=44161#c173 Reported-by: Stefan Biereigel <stefan@biereigel.de> Signed-off-by: Kieran Clancy <clancy.kieran@gmail.com> Tested-by: Stefan Biereigel <stefan@biereigel.de> Tested-by: Dennis Jansen <dennis.jansen@web.de> Tested-by: Nicolas Porcel <nicolasporcel06@gmail.com> Tested-by: Maurizio D'Addona <mauritiusdadd@gmail.com> Tested-by: Juan Manuel Cabo <juanmanuel.cabo@gmail.com> Tested-by: Giannis Koutsou <giannis.koutsou@gmail.com> Tested-by: Kieran Clancy <clancy.kieran@gmail.com> Cc: 3.14+ <stable@vger.kernel.org> # 3.14+ Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2014-04-30 00:21:20 +09:30
ACPI: EC: Rework flushing of EC work while suspended to idle The flushing of pending work in the EC driver uses drain_workqueue() to flush the event handling work that can requeue itself via advance_transaction(), but this is problematic, because that work may also be requeued from the query workqueue. Namely, if an EC transaction is carried out during the execution of a query handler, it involves calling advance_transaction() which may queue up the event handling work again. This causes the kernel to complain about attempts to add a work item to the EC event workqueue while it is being drained and worst-case it may cause a valid event to be skipped. To avoid this problem, introduce two new counters, events_in_progress and queries_in_progress, incremented when a work item is queued on the event workqueue or the query workqueue, respectively, and decremented at the end of the corresponding work function, and make acpi_ec_dispatch_gpe() the workqueues in a loop until the both of these counters are zero (or system wakeup is pending) instead of calling acpi_ec_flush_work(). At the same time, change __acpi_ec_flush_work() to call flush_workqueue() instead of drain_workqueue() to flush the event workqueue. While at it, use the observation that the work item queued in acpi_ec_query() cannot be pending at that time, because it is used only once, to simplify the code in there. Additionally, clean up a comment in acpi_ec_query() and adjust white space in acpi_ec_event_processor(). Fixes: f0ac20c3f613 ("ACPI: EC: Fix flushing of pending work") Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-11-23 19:36:51 +01:00
ACPI: EC: Rework flushing of EC work while suspended to idle The flushing of pending work in the EC driver uses drain_workqueue() to flush the event handling work that can requeue itself via advance_transaction(), but this is problematic, because that work may also be requeued from the query workqueue. Namely, if an EC transaction is carried out during the execution of a query handler, it involves calling advance_transaction() which may queue up the event handling work again. This causes the kernel to complain about attempts to add a work item to the EC event workqueue while it is being drained and worst-case it may cause a valid event to be skipped. To avoid this problem, introduce two new counters, events_in_progress and queries_in_progress, incremented when a work item is queued on the event workqueue or the query workqueue, respectively, and decremented at the end of the corresponding work function, and make acpi_ec_dispatch_gpe() the workqueues in a loop until the both of these counters are zero (or system wakeup is pending) instead of calling acpi_ec_flush_work(). At the same time, change __acpi_ec_flush_work() to call flush_workqueue() instead of drain_workqueue() to flush the event workqueue. While at it, use the observation that the work item queued in acpi_ec_query() cannot be pending at that time, because it is used only once, to simplify the code in there. Additionally, clean up a comment in acpi_ec_query() and adjust white space in acpi_ec_event_processor(). Fixes: f0ac20c3f613 ("ACPI: EC: Fix flushing of pending work") Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-11-23 19:36:51 +01:00
ACPI: EC: Rework flushing of EC work while suspended to idle The flushing of pending work in the EC driver uses drain_workqueue() to flush the event handling work that can requeue itself via advance_transaction(), but this is problematic, because that work may also be requeued from the query workqueue. Namely, if an EC transaction is carried out during the execution of a query handler, it involves calling advance_transaction() which may queue up the event handling work again. This causes the kernel to complain about attempts to add a work item to the EC event workqueue while it is being drained and worst-case it may cause a valid event to be skipped. To avoid this problem, introduce two new counters, events_in_progress and queries_in_progress, incremented when a work item is queued on the event workqueue or the query workqueue, respectively, and decremented at the end of the corresponding work function, and make acpi_ec_dispatch_gpe() the workqueues in a loop until the both of these counters are zero (or system wakeup is pending) instead of calling acpi_ec_flush_work(). At the same time, change __acpi_ec_flush_work() to call flush_workqueue() instead of drain_workqueue() to flush the event workqueue. While at it, use the observation that the work item queued in acpi_ec_query() cannot be pending at that time, because it is used only once, to simplify the code in there. Additionally, clean up a comment in acpi_ec_query() and adjust white space in acpi_ec_event_processor(). Fixes: f0ac20c3f613 ("ACPI: EC: Fix flushing of pending work") Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-11-23 19:36:51 +01:00
ACPI: EC: Rework flushing of EC work while suspended to idle The flushing of pending work in the EC driver uses drain_workqueue() to flush the event handling work that can requeue itself via advance_transaction(), but this is problematic, because that work may also be requeued from the query workqueue. Namely, if an EC transaction is carried out during the execution of a query handler, it involves calling advance_transaction() which may queue up the event handling work again. This causes the kernel to complain about attempts to add a work item to the EC event workqueue while it is being drained and worst-case it may cause a valid event to be skipped. To avoid this problem, introduce two new counters, events_in_progress and queries_in_progress, incremented when a work item is queued on the event workqueue or the query workqueue, respectively, and decremented at the end of the corresponding work function, and make acpi_ec_dispatch_gpe() the workqueues in a loop until the both of these counters are zero (or system wakeup is pending) instead of calling acpi_ec_flush_work(). At the same time, change __acpi_ec_flush_work() to call flush_workqueue() instead of drain_workqueue() to flush the event workqueue. While at it, use the observation that the work item queued in acpi_ec_query() cannot be pending at that time, because it is used only once, to simplify the code in there. Additionally, clean up a comment in acpi_ec_query() and adjust white space in acpi_ec_event_processor(). Fixes: f0ac20c3f613 ("ACPI: EC: Fix flushing of pending work") Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-11-23 19:36:51 +01:00
ACPI / EC: Fix issues related to the SCI_EVT handling This patch fixes 2 issues related to the draining behavior. But it doesn't implement the draining support, it only cleans up code so that further draining support is possible. The draining behavior is expected by some platforms (for example, Samsung) where SCI_EVT is set only once for a set of events and might be cleared for the very first QR_EC command issued after SCI_EVT is set. EC firmware on such platforms will return 0x00 to indicate "no outstanding event". Thus after seeing an SCI_EVT indication, EC driver need to fetch events until 0x00 returned (see acpi_ec_clear()). Issue 1 - acpi_ec_submit_query(): It's reported on Samsung laptops that SCI_EVT isn't checked when the transactions are advanced in ec_poll(), which leads to SCI_EVT triggering source lost: If no EC GPE IRQs are arrived after that, EC driver cannot detect this event and handle it. See comment 244/247 for kernel bugzilla 44161. This patch fixes this issue by moving SCI_EVT checks into advance_transaction(). So that SCI_EVT is checked each time we are going to handle the EC firmware indications. And this check will happen for both IRQ context and task context. Since after doing that, SCI_EVT is also checked after completing a transaction, ec_check_sci() and ec_check_sci_sync() can be removed. Issue 2 - acpi_ec_complete_query(): We expect to clear EC_FLAGS_QUERY_PENDING to allow queuing another draining QR_EC after writing a QR_EC command and before reading the event. After reading the event, SCI_EVT might be cleared by the firmware, thus it may not be possible to queue such a draining QR_EC at that time. But putting the EC_FLAGS_QUERY_PENDING clearing code after start_transaction() is wrong as there are chances that after start_transaction(), QR_EC can fail to be sent. If this happens, EC_FLAG_QUERY_PENDING will be cleared earlier. As a consequence, the draining QR_EC will also be queued earlier than expected. This patch also moves this code into advance_transaction() where QR_EC is just sent (ACPI_EC_COMMAND_POLL flagged) to fix this issue. Notes: 1. After introducing the 2 SCI_EVT related handlings into advance_transaction(), a next QR_EC can be queued right after writing the current QR_EC command and before reading the event. But this still hasn't implemented the draining behavior as the draining support requires: If a previous returned event value isn't 0x00, a draining QR_EC need to be issued even when SCI_EVT isn't set. 2. In this patch, acpi_os_execute() is also converted into a seperate work item to avoid invoking kmalloc() in the atomic context. We can do this because of the previous global lock fix. 3. Originally, EC_FLAGS_EVENT_PENDING is also used to avoid queuing up multiple work items (created by acpi_os_execute()), this can be covered by only using a single work item. But this patch still keeps this flag as there are different usages in the driver initialization steps relying on this flag. Link: https://bugzilla.kernel.org/show_bug.cgi?id=44161 Reported-by: Kieran Clancy <clancy.kieran@gmail.com> Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-01-14 19:28:47 +08:00
ACPI: EC: Make the event work state machine visible The EC driver uses a relatively simple state machine for the event work handling, but it is not really straightforward to figure out. The states are as follows: "Ready": The event handling work can be submitted. In this state, the EC_FLAGS_QUERY_PENDING flag is clear. "In progress": The event handling work is pending or is being processed. It cannot be submitted again. In ths state, the EC_FLAGS_QUERY_PENDING flag is set and both the events_to_process count is nonzero and the EC_FLAGS_QUERY_GUARDING flag is clear. "Complete": The event handling work has been completed, but it still cannot be submitted again. In ths state, the EC_FLAGS_QUERY_PENDING flag is set and the events_to_process count is zero or the EC_FLAGS_QUERY_GUARDING flag is set. The state changes from "Ready" to "In progress" when new event is detected by advance_transaction() and acpi_ec_submit_event() is called by it. Next, the state can change from "In progress" directly to "Ready" in the following situations: * ec_event_clearing is ACPI_EC_EVT_TIMING_STATUS and the state of an ACPI_EC_COMMAND_QUERY transaction becomes ACPI_EC_COMMAND_POLL. * ec_event_clearing is ACPI_EC_EVT_TIMING_QUERY and the state of an ACPI_EC_COMMAND_QUERY transaction becomes ACPI_EC_COMMAND_COMPLETE. * ec_event_clearing is either ACPI_EC_EVT_TIMING_STATUS or ACPI_EC_EVT_TIMING_QUERY and there are no more events to process (ie. ec->events_to_process becomes 0). If ec_event_clearing is ACPI_EC_EVT_TIMING_EVENT, however, the state must change from "In progress" to "Complete" before it can change to "Ready". The changes from "In progress" to "Complete" in that case occur in the following situations: * The state of an ACPI_EC_COMMAND_QUERY transaction becomes ACPI_EC_COMMAND_COMPLETE. * There are no more events to process (ie. ec->events_to_process becomes 0). Finally, the state changes from "Complete" to "Ready" when advance_transaction() is invoked when the state is "Complete" and the state of the current transaction is not ACPI_EC_COMMAND_POLL. To make this state machine visible in the code, add a new event_state field to struct acpi_ec and modify the code to use it istead the EC_FLAGS_QUERY_PENDING and EC_FLAGS_QUERY_GUARDING flags. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-11-23 19:44:46 +01:00
ACPI / EC: Add event clearing variation support. We've been suffering from the uncertainty of the SCI_EVT clearing timing. This patch implements 3 of 4 possible modes to handle SCI_EVT clearing variations. The old behavior is kept in this patch. Status: QR_EC is re-checked as early as possible after checking previous SCI_EVT. This always leads to 2 QR_EC transactions per SCI_EVT indication and the target may implement event queue which returns 0x00 indicating "no outstanding event". This is proven to be a conflict against Windows behavior, but is still kept in this patch to make the EC driver robust to the possible regressions that may occur on Samsung platforms. Query: QR_EC is re-checked after the target has handled the QR_EC query request command pushed by the host. Event: QR_EC is re-checked after the target has noticed the query event response data pulled by the host. This timing is not determined by any IRQs, so we may need to use a guard period in this mode, which may explain the existence of the ec_guard() code used by the old EC driver where the re-check timing is implemented in the similar way as this mode. Method: QR_EC is re-checked as late as possible after completing the _Qxx evaluation. The target may implement SCI_EVT like a level triggered interrupt. It is proven on kernel bugzilla 94411 that, Windows will have all _Qxx evaluations parallelized. Thus unless required by further evidences, we needn't implement this mode as it is a conflict of the _Qxx parallelism requirement. Note that, according to the reports, there are platforms that cannot be handled using the "Status" mode without enabling the EC_FLAGS_QUERY_HANDSHAKE quirk. But they can be handled with the other modes according to the tests (kernel bugzilla 97381). The following log entry can be used to confirm the differences of the 3 modes as it should appear at the different positions for the 3 modes: Command(QR_EC) unblocked Status: appearing after EC_SC(W) = 0x84 Query: appearing after EC_DATA(R) = 0xXX where XX is the event number used to determine _QXX Event: appearing after first EC_SC(R) = 0xX0 SCI_EVT=x BURST=0 CMD=0 IBF=0 OBF=0 that is next to the following log entry: Command(QR_EC) completed by hardware 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=98111 Reported-and-tested-by: Gabriele Mazzotta <gabriele.mzt@gmail.com> Reported-and-tested-by: Tigran Gabrielyan <tigrangab@gmail.com> Reported-and-tested-by: Adrien D <ghbdtn@openmailbox.org> Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-06-11 13:21:38 +08:00
ACPI: EC: Rework flushing of EC work while suspended to idle The flushing of pending work in the EC driver uses drain_workqueue() to flush the event handling work that can requeue itself via advance_transaction(), but this is problematic, because that work may also be requeued from the query workqueue. Namely, if an EC transaction is carried out during the execution of a query handler, it involves calling advance_transaction() which may queue up the event handling work again. This causes the kernel to complain about attempts to add a work item to the EC event workqueue while it is being drained and worst-case it may cause a valid event to be skipped. To avoid this problem, introduce two new counters, events_in_progress and queries_in_progress, incremented when a work item is queued on the event workqueue or the query workqueue, respectively, and decremented at the end of the corresponding work function, and make acpi_ec_dispatch_gpe() the workqueues in a loop until the both of these counters are zero (or system wakeup is pending) instead of calling acpi_ec_flush_work(). At the same time, change __acpi_ec_flush_work() to call flush_workqueue() instead of drain_workqueue() to flush the event workqueue. While at it, use the observation that the work item queued in acpi_ec_query() cannot be pending at that time, because it is used only once, to simplify the code in there. Additionally, clean up a comment in acpi_ec_query() and adjust white space in acpi_ec_event_processor(). Fixes: f0ac20c3f613 ("ACPI: EC: Fix flushing of pending work") Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-11-23 19:36:51 +01:00
ACPI / EC: Fix several GPE handling issues by deploying ACPI_GPE_DISPATCH_RAW_HANDLER mode. This patch switches EC driver into ACPI_GPE_DISPATCH_RAW_HANDLER mode where the GPE lock is not held for acpi_ec_gpe_handler() and the ACPICA internal GPE enabling/disabling/clearing operations are bypassed so that further improvements are possible with the GPE APIs. There are 2 strong reasons for deploying raw GPE handler mode in the EC driver: 1. Some hardware logics can control their interrupts via their own registers, so their interrupts can be disabled/enabled/acknowledged without using the super IRQ controller provided functions. While there is no mean (EC commands) for the EC driver to achieve this. 2. During suspending, the EC driver is still working for a while to complete the platform firmware provided functionailities using ec_poll() after all GPEs are disabled (see acpi_ec_block_transactions()), which means the EC driver will drive the EC GPE out of the GPE core's control. Without deploying the raw GPE handler mode, we can see many races between the EC driver and the GPE core due to the above restrictions: 1. There is a race condition due to ACPICA internal GPE disabling/clearing/enabling logics in acpi_ev_gpe_dispatch(): Orignally EC GPE is disabled (EN=0), cleared (STS=0) before invoking a GPE handler and re-enabled (EN=1) after invoking a GPE handler in acpi_ev_gpe_dispatch(). When re-enabling appears, GPE may be flagged (STS=1). ================================================================= (event pending A) ================================================================= acpi_ev_gpe_dispatch() ec_poll() EN=0 STS=0 acpi_ec_gpe_handler() ***************************************************************** (event handling A) Lock(EC) advance_transaction() EC_SC read ================================================================= (event pending B) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** ***************************************************************** (event handling B) Lock(EC) advance_transaction() EC_SC read ================================================================= (event pending C) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** EN=1 This race condition is the root cause of different issues on different silicon variations. A. Silicon variation A: On some platforms, GPE will be triggered due to "writing 1 to EN when STS=1". This is because both EN and STS lines are wired to the GPE trigger line. 1. Issue 1: We can see no-op acpi_ec_gpe_handler() invoked on such platforms. This is because: a. event pending B: An event can arrive after ACPICA's GPE clearing performed in acpi_ev_gpe_dispatch(), this event may fail to be detected by EC_SC read that is performed before its arrival; b. event handling B: The event can be handled in ec_poll() because EC lock is released after acpi_ec_gpe_handler() invocation; c. There is no code in ec_poll() to clear STS but the GPE can still be triggered by the EN=1 write performed in acpi_ev_finish_gpe(), this leads to a no-op EC GPE handler invocation; d. As no-op GPE handler invocations are counted by the EC driver to trigger the command storming conditions, the wrong no-op GPE handler invocations thus can easily trigger wrong command storming conditions. Note 1: If we removed GPE disabling/enabling code from acpi_ev_gpe_dispatch(), we could still see no-op GPE handlers triggered by the event arriving after the GPE clearing and before the GPE handling on both silicon variation A and B. This can only occur if the CPU is very slow (timing slice between STS=0 write and EC_SC read should be short enough before hardware sets another GPE indication). Thus this is very rare and is not what we need to fix. B. Silicon variation B: On other platforms, GPE may not be triggered due to "writing 1 to EN when STS=1". This is because only STS line is wired to the GPE trigger line. 2. Issue 2: We can see GPE loss on such platforms. This is because: a. event pending B vs. event handling A: An event can arrive after ACPICA's GPE handling performed in acpi_ev_gpe_dispatch(), or event pending C vs. event handling B: An event can arrive after Linux's GPE handling performed in ec_poll(), these events may fail to be detected by EC_SC read that is performed before their arrival; b. The GPE cannot be triggered by EN=1 write performed in acpi_ev_finish_gpe(); c. If no polling mechanism is implemented in the driver for the pending event (for example, SCI_EVT), this event is lost due to no GPE being triggered. Note 2: On most platforms, there might be another rule that GPE may not be triggered due to "writing 1 to STS when STS=1 and EN=1". Then on silicon variation B, an even worse case is if the issue 2 event loss happens, further events may never trigger GPE again on such platforms due to being blocked by the current STS=1. Unless someone clears STS, all events have to be polled. 2. There is a race condition due to lacking in GPE status checking in EC driver: Originally, GPE status is checked in ACPICA core but not checked in the GPE handler. Thus since the status checking and handling is not locked, it can be interrupted by another handling path. ================================================================= (event pending A) ================================================================= acpi_ev_gpe_detect() ec_poll() if (EN==1 && STS==1) ***************************************************************** (event handling A) Lock(EC) advance_transaction() EC_SC read EC_SC handled Unlock(EC) ***************************************************************** acpi_ev_gpe_dispatch() EN=0 STS=0 acpi_ec_gpe_handler() ***************************************************************** (event handling B) Lock(EC) advance_transaction() EC_SC read Unlock(EC) ***************************************************************** 3. Issue 3: We can see no-op acpi_ec_gpe_handler() invoked on both silicon variation A and B. This is because: a. event pending A: An event can arrive to trigger an EC GPE and ACPICA checks it and is about to invoke the EC GPE handler; b. event handling A: The event can be handled in ec_poll() because EC lock is not held after the GPE status checking; c. event handling B: Then when the EC GPE handler is invoked, it becomes a no-op GPE handler invocation. d. As no-op GPE handler invocations are counted by the EC driver to trigger the command storming conditions, the wrong no-op GPE handler invocations thus can easily trigger wrong command storming conditions. Note 3: This no-op GPE handler invocation is rare because the time between the IRQ arrival and the acpi_ec_gpe_handler() invocation is less than the timeout value waited in ec_poll(). So most of the no-op GPE handler invocations are caused by the reason described in issue 1. 3. There is a race condition due to ACPICA internal GPE clearing logic in acpi_enable_gpe(): During runtime, acpi_enable_gpe() can be invoked by the EC storming prevention code. When it is invoked, GPE may be flagged (STS=1). ================================================================= (event pending A) ================================================================= acpi_ev_gpe_dispatch() acpi_ec_transaction() EN=0 STS=0 acpi_ec_gpe_handler() ***************************************************************** (event handling A) Lock(EC) advance_transaction() EC_SC read EC_SC handled Unlock(EC) ***************************************************************** EN=1 ? Lock(EC) Unlock(EC) ================================================================= (event pending B) ================================================================= acpi_enable_gpe() STS=0 EN=1 4. Issue 4: We can see GPE loss on both silicon variation A and B platforms. This is because: a. event pending B: An event can arrive right before ACPICA's GPE clearing performed in acpi_enable_gpe(); b. If the GPE is cleared when GPE is disabled, then EN=1 write in acpi_enable_gpe() cannot trigger this GPE; c. If no polling mechanism is implemented in the driver for this event (for example, SCI_EVT), this event is lost due to no GPE being triggered. Note 4: Currently we don't have this issue, but after we switch the EC driver into ACPI_GPE_DISPATCH_RAW_HANDLER mode, we need to take care of handling this because the EN=1 write in acpi_ev_gpe_dispatch() will be abandoned. There might be more race issues for the current GPE handler usages. This is because the EC IRQ's enabling/disabling/checking/clearing/handling operations should be locked by a single lock that is under the EC driver's control to achieve the serialization. Which means we need to invoke GPE APIs with EC driver's lock held and all ACPICA internal GPE operations related to the GPE handler should be abandoned. Invoking GPE APIs inside of the EC driver lock and bypassing ACPICA internal GPE operations requires the ACPI_GPE_DISPATCH_RAW_HANDLER mode where the same lock used by the APIs are released prior than invoking the handlers. Otherwise, we can see dead locks due to circular locking dependencies (see Reference below). This patch then switches the EC driver into the ACPI_GPE_DISPATCH_RAW_HANDLER mode so that it can perform correct GPE operations using the GPE APIs: 1. Bypasses EN modifications performed in acpi_ev_gpe_dispatch() by using acpi_install_gpe_raw_handler() and invoking all GPE APIs with EC spin lock held. This can fix issue 1 as it makes a non frequent GPE enabling/disabling environment. 2. Bypasses STS clearing performed in acpi_enable_gpe() by replacing acpi_enable_gpe()/acpi_disable_gpe() with acpi_set_gpe(). This can fix issue 4. And this can also help to fix issue 1 as it makes a no sudden GPE clearing environment when GPE is frequently enabled/disabled. 3. Ensures STS acknowledged before handling by invoking acpi_clear_gpe() in advance_transaction(). This can finally fix issue 1 even in a frequent GPE enabling/disabling environment. And this can also finally fix issue 3 when issue 2 is fixed. Note 3: GPE clearing is edge triggered W1C, which means we can clear it right before handling it. Since all EC GPE indications are handled in advance_transaction() by previous commits, we can now move GPE clearing into it to implement the correct GPE clearing. Note 4: We can use acpi_set_gpe() which is not shared GPE safer instead of acpi_enable_gpe()/acpi_disable_gpe() because EC GPE is not shared by other hardware, which is mentioned in the ACPI specification 5.0, 12.6 Interrupt Model: "OSPM driver treats this as an edge event (the EC SCI cannot be shared)". So we can stop using shared GPE safer APIs acpi_enable_gpe()/acpi_disable_gpe() in the EC driver. Otherwise cleanups need to be made in acpi_ev_enable_gpe() to bypass the GPE clearing logic before keeping acpi_enable_gpe(). This patch also invokes advance_transaction() when GPE is re-enabled in the task context which: 1. Ensures EN=1 can trigger GPE by checking and handling EC status register right after EN=1 writes. This can fix issue 2. After applying this patch, without frequent GPE enablings considered: ================================================================= (event pending A) ================================================================= acpi_ec_gpe_handler() ec_poll() ***************************************************************** (event handling A) Lock(EC) advance_transaction() if STS==1 STS=0 EC_SC read ================================================================= (event pending B) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** ***************************************************************** (event handling B) Lock(EC) advance_transaction() if STS==1 STS=0 EC_SC read ================================================================= (event pending C) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** The event pending for issue 1 (event pending B) can arrive as a next GPE due to the previous IRQ context STS=0 write. And if it is handled by ec_poll() (event handling B), as it is also acknowledged by ec_poll(), the event pending for issue 2 (event pending C) can properly arrive as a next GPE after the task context STS=0 write. So no GPE will be lost and never triggered due to GPE clearing performed in the wrong position. And since all GPE handling is performed after a locked GPE status checking, we can hardly see no-op GPE handler invocations due to issue 1 and 3. We may still see no-op GPE handler invocations due to "Note 1", but as it is inevitable, it needn't be fixed. After applying this patch, with frequent GPE enablings considered: ================================================================= (event pending A) ================================================================= acpi_ec_gpe_handler() acpi_ec_transaction() ***************************************************************** (event handling A) Lock(EC) advance_transaction() if STS==1 STS=0 EC_SC read ================================================================= (event pending B) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** ***************************************************************** (event handling B) Lock(EC) EN=1 if STS==1 advance_transaction() if STS==1 STS=0 EC_SC read ================================================================= (event pending C) ================================================================= EC_SC handled Unlock(EC) ***************************************************************** The event pending for issue 2 can be manually handled by advance_transaction(). And after the STS=0 write performed in the manual triggered advance_transaction(), GPE can always arrive. So no GPE will be lost due to frequent GPE disabling/enabling performed in the driver like issue 4. Note 5: It's ideally when EN=1 write occurred, an IRQ thread should be woken up to handle the GPE when the GPE was raised. But this requires the IRQ thread to contain the poller code for all EC GPE indications, while currently some of the indications are handled in the user tasks. It then is very hard for the code to determine whether a user task should be invoked or the poller work item should be scheduled. So we have to invoke advance_transaction() directly now and it leaves us such a restriction for the GPE re-enabling: it must be performed in the task context to avoid starving the GPEs. As a conclusion: we can see the EC GPE is always handled in serial after deploying the raw GPE handler mode: Lock(EC) if (STS==1) STS=0 EC_SC read EC_SC handled Unlock(EC) The EC driver specific lock is responsible to make the EC GPE handling processes serialized so that EC can handle its GPE from both IRQ and task contexts and the next IRQ can be ensured to arrive after this process. Note 6: We have many EC_FLAGS_MSI qurik users in the current driver. They all seem to be suffering from unexpected GPE triggering source lost. And they are false root caused to a timing issue. Since EC communication protocol has already flow control defined, timing shouldn't be the root cause, while this fix might be fixing the root cause of the old bugs. Link: https://lkml.org/lkml/2014/11/4/974 Link: https://lkml.org/lkml/2014/11/18/316 Link: https://www.spinics.net/lists/linux-acpi/msg54340.html Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-02-05 16:27:22 +08:00
ACPI / EC: Fix and clean up register access guarding logics. In the polling mode, EC driver shouldn't access the EC registers too frequently. Though this statement is concluded from the non-root caused bugs (see links below), we've maintained the register access guarding logics in the current EC driver. The guarding logics can be found here and there, makes it hard to root cause real timing issues. This patch collects the guarding logics into one single function so that all hidden logics related to this can be seen clearly. The current guarding related code also has several issues: 1. Per-transaction timestamp prevents inter-transaction guarding from being implemented in the same place. We have an inter-transaction udelay() in acpi_ec_transaction_unblocked(), this logic can be merged into ec_poll() if we can use per-device timestamp. This patch completes such merge to form a new ec_guard() function and collects all guarding related hidden logics in it. One hidden logic is: there is no inter-transaction guarding performed for non MSI quirk (wait polling mode), this patch skips inter-transaction guarding before wait_event_timeout() for the wait polling mode to reveal the hidden logic. The other hidden logic is: there is msleep() inter-transaction guarding performed when the GPE storming is observed. As after merging this commit: Commit: e1d4d90fc0313d3d58cbd7912c90f8ef24df45ff Subject: ACPI / EC: Refine command storm prevention support EC_FLAGS_COMMAND_STORM is ensured to be cleared after invoking acpi_ec_transaction_unlocked(), the msleep() guard logic will never happen now. Since no one complains such change, this logic is likely added during the old times where the EC race issues are not fixed and the bugs are false root-caused to the timing issue. This patch simply removes the out-dated logic. We can restore it by stop skipping inter-transaction guarding for wait polling mode. Two different delay values are defined for msleep() and udelay() while they are merged in this patch to 550us. 2. time_after() causes additional delay in the polling mode (can only be observed in noirq suspend/resume processes where polling mode is always used) before advance_transaction() is invoked ("wait polling" log is added before wait_event_timeout()). We can see 2 wait_event_timeout() invocations. This is because time_after() ensures a ">" validation while we only need a ">=" validation here: [ 86.739909] ACPI: Waking up from system sleep state S3 [ 86.742857] ACPI : EC: 2: Increase command [ 86.742859] ACPI : EC: ***** Command(RD_EC) started ***** [ 86.742861] ACPI : EC: ===== TASK (0) ===== [ 86.742871] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 86.742873] ACPI : EC: EC_SC(W) = 0x80 [ 86.742876] ACPI : EC: ***** Event started ***** [ 86.742880] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.743972] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.747966] ACPI : EC: ===== TASK (0) ===== [ 86.747977] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 86.747978] ACPI : EC: EC_DATA(W) = 0x06 [ 86.747981] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.751971] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.755969] ACPI : EC: ===== TASK (0) ===== [ 86.755991] ACPI : EC: EC_SC(R) = 0x21 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=1 [ 86.755993] ACPI : EC: EC_DATA(R) = 0x03 [ 86.755994] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 86.755995] ACPI : EC: ***** Command(RD_EC) stopped ***** [ 86.755996] ACPI : EC: 1: Decrease command This patch corrects this by using time_before() instead in ec_guard(): [ 54.283146] ACPI: Waking up from system sleep state S3 [ 54.285414] ACPI : EC: 2: Increase command [ 54.285415] ACPI : EC: ***** Command(RD_EC) started ***** [ 54.285416] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.285417] ACPI : EC: ===== TASK (0) ===== [ 54.285424] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 54.285425] ACPI : EC: EC_SC(W) = 0x80 [ 54.285427] ACPI : EC: ***** Event started ***** [ 54.285429] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.287209] ACPI : EC: ===== TASK (0) ===== [ 54.287218] ACPI : EC: EC_SC(R) = 0x20 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=0 [ 54.287219] ACPI : EC: EC_DATA(W) = 0x06 [ 54.287222] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.291190] ACPI : EC: ===== TASK (0) ===== [ 54.291210] ACPI : EC: EC_SC(R) = 0x21 SCI_EVT=1 BURST=0 CMD=0 IBF=0 OBF=1 [ 54.291213] ACPI : EC: EC_DATA(R) = 0x03 [ 54.291214] ACPI : EC: ~~~~~ wait polling ~~~~~ [ 54.291215] ACPI : EC: ***** Command(RD_EC) stopped ***** [ 54.291216] ACPI : EC: 1: Decrease command After cleaning up all guarding logics, we have one single function ec_guard() collecting all old, non-root-caused, hidden logics. Then we can easily tune the logics in one place to respond to the bug reports. Except the time_before() change, all other changes do not change the behavior of the EC driver. Link: https://bugzilla.kernel.org/show_bug.cgi?id=12011 Link: https://bugzilla.kernel.org/show_bug.cgi?id=20242 Link: https://bugzilla.kernel.org/show_bug.cgi?id=77431 Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-05-15 14:16:42 +08:00
ACPI: EC: Drop the EC_FLAGS_IGNORE_DSDT_GPE quirk It seems that these quirks are no longer necessary since commit 69b957c26b32 ("ACPI: EC: Fix possible issues related to EC initialization order"), which has fixed this in a generic manner. There are 3 commits adding DMI entries with this quirk (adding multiple DMI entries per commit). 2/3 commits are from before the generic fix. Which leaves commit 6306f0431914 ("ACPI: EC: Make more Asus laptops use ECDT _GPE"), which was committed way after the generic fix. But this was just due to slow upstreaming of it. This commit stems from Endless from 15 Aug 2017 (committed upstream 20 May 2021): https://github.com/endlessm/linux/pull/288 The current code should work fine without this: 1. The EC_FLAGS_IGNORE_DSDT_GPE flag is only checked in ec_parse_device(), like this: if (boot_ec && boot_ec_is_ecdt && EC_FLAGS_IGNORE_DSDT_GPE) { ec->gpe = boot_ec->gpe; } else { /* parse GPE */ } 2. ec_parse_device() is only called from acpi_ec_add() and acpi_ec_dsdt_probe() 3. acpi_ec_dsdt_probe() starts with: if (boot_ec) return; so it only calls ec_parse_device() when boot_ec == NULL, meaning that the quirk never triggers for this call. So only the call in acpi_ec_add() matters. 4. acpi_ec_add() does the following after the ec_parse_device() call: if (boot_ec && ec->command_addr == boot_ec->command_addr && ec->data_addr == boot_ec->data_addr && !EC_FLAGS_TRUST_DSDT_GPE) { /* * Trust PNP0C09 namespace location rather than * ECDT ID. But trust ECDT GPE rather than _GPE * because of ASUS quirks, so do not change * boot_ec->gpe to ec->gpe. */ boot_ec->handle = ec->handle; acpi_handle_debug(ec->handle, "duplicated.\n"); acpi_ec_free(ec); ec = boot_ec; } The quirk only matters if boot_ec != NULL and EC_FLAGS_TRUST_DSDT_GPE is never set at the same time as EC_FLAGS_IGNORE_DSDT_GPE. That means that if the addresses match we always enter this if block and then only the ec->handle part of the data stored in ec by ec_parse_device() is used and the rest is thrown away, after which ec is made to point to boot_ec, at which point ec->gpe == boot_ec->gpe, so the same result as with the quirk set, independent of the value of the quirk. Also note the comment in this block which indicates that the gpe result from ec_parse_device() is deliberately not taken to deal with buggy Asus laptops and all DMI quirks setting EC_FLAGS_IGNORE_DSDT_GPE are for Asus laptops. Based on the above I believe that unless on some quirked laptops the ECDT and DSDT EC addresses do not match we can drop the quirk. I've checked dmesg output to ensure the ECDT and DSDT EC addresses match for quirked models using https://linux-hardware.org hw-probe reports. I've been able to confirm that the addresses match for the following models this way: GL702VMK, X505BA, X505BP, X550VXK, X580VD. Whereas for the following models I could find any dmesg output: FX502VD, FX502VE, X542BA, X542BP. Note the models without dmesg all were submitted in patches with a batch of models and other models from the same batch checkout ok. This, combined with that all the code adding the quirks was written before the generic fix makes me believe that it is safe to remove this quirk now. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Reviewed-by: Daniel Drake <drake@endlessos.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2022-06-20 11:25:44 +02:00
ACPI: EC: Avoid _REG disconnect on GPIO IRQ defer EC event delivery uses either a GPE or, on ACPI reduced hardware platforms, a GpioInt resource. The GPE path does not have a provider lookup that can defer, but acpi_dev_gpio_irq_get() can return -EPROBE_DEFER for the GpioInt path. ec_install_handlers() currently installs the EC address space handler and executes _REG before looking up the GPIO IRQ. If the GPIO lookup then defers, acpi_ec_setup() tears the handlers down again. Removing the EC address space handler causes ACPICA to execute _REG for disconnect, so firmware may observe an EC OpRegion connected -> disconnected transition during one failed probe attempt. This is observable when the namespace EC reuses a boot EC that has already installed the EC address space handler. A deferred namespace EC probe can disconnect the already usable boot EC OpRegion until a later reprobe connects it again. AML that gates EC field accesses on _REG state can then return fallback values to other drivers during that window. Prepare the GPIOInt IRQ before publishing EC OpRegion availability to AML. This leaves the GPE path unchanged, keeps non-deferred GPIO lookup errors non-fatal as before, and still lets the existing acpi_ec_setup() error path clean up real handler installation failures. Fixes: f6484cadbcaf ("ACPI: EC: clean up handlers on probe failure in acpi_ec_setup()") Signed-off-by: Zhu Ling <zhuling2709@phytium.com.cn> [ rjw: Added an empty code line after a conditional ] Link: https://patch.msgid.link/20260715012556.12043-1-zhuling2709@phytium.com.cn Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2026-07-15 09:25:19 +08:00
ACPI: EC: Fix ECDT probe ordering issues ACPI-2.0 says that the EC OpRegion handler must be available immediately (like the standard default OpRegion handlers): Quoting from the ACPI spec version 6.3: "6.5.4 _REG (Region) ... 2. OSPM must make Embedded Controller operation regions, accessed via the Embedded Controllers described in ECDT, available before executing any control method. These operation regions may become inaccessible after OSPM runs _REG(EmbeddedControl, 0)." So acpi_bus_init() calls acpi_ec_ecdt_probe(), which calls acpi_install_address_space_handler() to install the EC's OpRegion handler, early on. This not only installs the OpRegion handler, but also calls the EC's _REG method. The _REG method call is a problem because it may rely on initialization done by the _INI methods of one of the PCI / _SB root devs, see for example: https://bugzilla.kernel.org/show_bug.cgi?id=214899 . Generally speaking _REG methods are executed when the ACPI-device they are part of has a driver bound to it. Where as _INI methods must be executed at table load time (according to the spec). The problem here is that the early acpi_install_address_space_handler() call causes the _REG handler to run too early. To allow fixing this the ACPICA code now allows to split the OpRegion handler installation and the executing of _REG into 2 separate steps. This commit uses this ACPICA functionality to fix the EC probe ordering by delaying the executing of _REG for ECDT described ECs till the matching EC device in the DSDT gets parsed and acpi_ec_add() for it gets called. This moves the calling of _REG for the EC on devices with an ECDT to the same point in time where it is called on devices without an ECDT table. BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=214899 Reported-and-tested-by: Johannes Penßel <johannespenssel@posteo.net> Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2022-12-08 15:23:35 +01:00
ACPI: EC: Fix ECDT probe ordering issues ACPI-2.0 says that the EC OpRegion handler must be available immediately (like the standard default OpRegion handlers): Quoting from the ACPI spec version 6.3: "6.5.4 _REG (Region) ... 2. OSPM must make Embedded Controller operation regions, accessed via the Embedded Controllers described in ECDT, available before executing any control method. These operation regions may become inaccessible after OSPM runs _REG(EmbeddedControl, 0)." So acpi_bus_init() calls acpi_ec_ecdt_probe(), which calls acpi_install_address_space_handler() to install the EC's OpRegion handler, early on. This not only installs the OpRegion handler, but also calls the EC's _REG method. The _REG method call is a problem because it may rely on initialization done by the _INI methods of one of the PCI / _SB root devs, see for example: https://bugzilla.kernel.org/show_bug.cgi?id=214899 . Generally speaking _REG methods are executed when the ACPI-device they are part of has a driver bound to it. Where as _INI methods must be executed at table load time (according to the spec). The problem here is that the early acpi_install_address_space_handler() call causes the _REG handler to run too early. To allow fixing this the ACPICA code now allows to split the OpRegion handler installation and the executing of _REG into 2 separate steps. This commit uses this ACPICA functionality to fix the EC probe ordering by delaying the executing of _REG for ECDT described ECs till the matching EC device in the DSDT gets parsed and acpi_ec_add() for it gets called. This moves the calling of _REG for the EC on devices with an ECDT to the same point in time where it is called on devices without an ECDT table. BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=214899 Reported-and-tested-by: Johannes Penßel <johannespenssel@posteo.net> Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2022-12-08 15:23:35 +01:00
ACPI: EC: Evaluate _REG outside the EC scope more carefully Commit 60fa6ae6e6d0 ("ACPI: EC: Install address space handler at the namespace root") caused _REG methods for EC operation regions outside the EC device scope to be evaluated which on some systems leads to the evaluation of _REG methods in the scopes of device objects representing devices that are not present and not functional according to the _STA return values. Some of those device objects represent EC "alternatives" and if _REG is evaluated for their operation regions, the platform firmware may be confused and the platform may start to behave incorrectly. To avoid this problem, only evaluate _REG for EC operation regions located in the scopes of device objects representing known-to-be-present devices. For this purpose, partially revert commit 60fa6ae6e6d0 and trigger the evaluation of _REG for EC operation regions from acpi_bus_attach() for the known-valid devices. Fixes: 60fa6ae6e6d0 ("ACPI: EC: Install address space handler at the namespace root") Link: https://lore.kernel.org/linux-acpi/1f76b7e2-1928-4598-8037-28a1785c2d13@redhat.com Link: https://bugzilla.redhat.com/show_bug.cgi?id=2298938 Link: https://bugzilla.redhat.com/show_bug.cgi?id=2302253 Reported-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Reviewed-by: Hans de Goede <hdegoede@redhat.com> Cc: All applicable <stable@vger.kernel.org> Link: https://patch.msgid.link/23612351.6Emhk5qWAg@rjwysocki.net
2024-08-12 15:16:21 +02:00
ACPI: EC: Install address space handler at the namespace root It is reported that _DSM evaluation fails in ucsi_acpi_dsm() on Lenovo IdeaPad Pro 5 due to a missing address space handler for the EC address space: ACPI Error: No handler for Region [ECSI] (000000007b8176ee) [EmbeddedControl] (20230628/evregion-130) This happens because if there is no ECDT, the EC driver only registers the EC address space handler for operation regions defined in the EC device scope of the ACPI namespace while the operation region being accessed by the _DSM in question is located beyond that scope. To address this, modify the ACPI EC driver to install the EC address space handler at the root of the ACPI namespace for the first EC that can be found regardless of whether or not an ECDT is present. Note that this change is consistent with some examples in the ACPI specification in which EC operation regions located outside the EC device scope are used (for example, see Section 9.17.15 in ACPI 6.5), so the current behavior of the EC driver is arguably questionable. Reported-by: webcaptcha <webcapcha@gmail.com> Link: https://bugzilla.kernel.org/show_bug.cgi?id=218789 Link: https://uefi.org/specs/ACPI/6.5/09_ACPI_Defined_Devices_and_Device_Specific_Objects.html#example-asl-code Link: https://lore.kernel.org/linux-acpi/Zi+0whTvDbAdveHq@kuha.fi.intel.com Suggested-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Reviewed-by: Hans de Goede <hdegoede@redhat.com> Reviewed-by: Mario Limonciello <mario.limonciello@amd.com> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
2024-05-15 21:40:54 +02:00
ACPI: EC: Fix ECDT probe ordering issues ACPI-2.0 says that the EC OpRegion handler must be available immediately (like the standard default OpRegion handlers): Quoting from the ACPI spec version 6.3: "6.5.4 _REG (Region) ... 2. OSPM must make Embedded Controller operation regions, accessed via the Embedded Controllers described in ECDT, available before executing any control method. These operation regions may become inaccessible after OSPM runs _REG(EmbeddedControl, 0)." So acpi_bus_init() calls acpi_ec_ecdt_probe(), which calls acpi_install_address_space_handler() to install the EC's OpRegion handler, early on. This not only installs the OpRegion handler, but also calls the EC's _REG method. The _REG method call is a problem because it may rely on initialization done by the _INI methods of one of the PCI / _SB root devs, see for example: https://bugzilla.kernel.org/show_bug.cgi?id=214899 . Generally speaking _REG methods are executed when the ACPI-device they are part of has a driver bound to it. Where as _INI methods must be executed at table load time (according to the spec). The problem here is that the early acpi_install_address_space_handler() call causes the _REG handler to run too early. To allow fixing this the ACPICA code now allows to split the OpRegion handler installation and the executing of _REG into 2 separate steps. This commit uses this ACPICA functionality to fix the EC probe ordering by delaying the executing of _REG for ECDT described ECs till the matching EC device in the DSDT gets parsed and acpi_ec_add() for it gets called. This moves the calling of _REG for the EC on devices with an ECDT to the same point in time where it is called on devices without an ECDT table. BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=214899 Reported-and-tested-by: Johannes Penßel <johannespenssel@posteo.net> Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2022-12-08 15:23:35 +01:00
ACPI: EC: Fix ECDT probe ordering issues ACPI-2.0 says that the EC OpRegion handler must be available immediately (like the standard default OpRegion handlers): Quoting from the ACPI spec version 6.3: "6.5.4 _REG (Region) ... 2. OSPM must make Embedded Controller operation regions, accessed via the Embedded Controllers described in ECDT, available before executing any control method. These operation regions may become inaccessible after OSPM runs _REG(EmbeddedControl, 0)." So acpi_bus_init() calls acpi_ec_ecdt_probe(), which calls acpi_install_address_space_handler() to install the EC's OpRegion handler, early on. This not only installs the OpRegion handler, but also calls the EC's _REG method. The _REG method call is a problem because it may rely on initialization done by the _INI methods of one of the PCI / _SB root devs, see for example: https://bugzilla.kernel.org/show_bug.cgi?id=214899 . Generally speaking _REG methods are executed when the ACPI-device they are part of has a driver bound to it. Where as _INI methods must be executed at table load time (according to the spec). The problem here is that the early acpi_install_address_space_handler() call causes the _REG handler to run too early. To allow fixing this the ACPICA code now allows to split the OpRegion handler installation and the executing of _REG into 2 separate steps. This commit uses this ACPICA functionality to fix the EC probe ordering by delaying the executing of _REG for ECDT described ECs till the matching EC device in the DSDT gets parsed and acpi_ec_add() for it gets called. This moves the calling of _REG for the EC on devices with an ECDT to the same point in time where it is called on devices without an ECDT table. BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=214899 Reported-and-tested-by: Johannes Penßel <johannespenssel@posteo.net> Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2022-12-08 15:23:35 +01:00
ACPI: EC: Evaluate _REG outside the EC scope more carefully Commit 60fa6ae6e6d0 ("ACPI: EC: Install address space handler at the namespace root") caused _REG methods for EC operation regions outside the EC device scope to be evaluated which on some systems leads to the evaluation of _REG methods in the scopes of device objects representing devices that are not present and not functional according to the _STA return values. Some of those device objects represent EC "alternatives" and if _REG is evaluated for their operation regions, the platform firmware may be confused and the platform may start to behave incorrectly. To avoid this problem, only evaluate _REG for EC operation regions located in the scopes of device objects representing known-to-be-present devices. For this purpose, partially revert commit 60fa6ae6e6d0 and trigger the evaluation of _REG for EC operation regions from acpi_bus_attach() for the known-valid devices. Fixes: 60fa6ae6e6d0 ("ACPI: EC: Install address space handler at the namespace root") Link: https://lore.kernel.org/linux-acpi/1f76b7e2-1928-4598-8037-28a1785c2d13@redhat.com Link: https://bugzilla.redhat.com/show_bug.cgi?id=2298938 Link: https://bugzilla.redhat.com/show_bug.cgi?id=2302253 Reported-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Reviewed-by: Hans de Goede <hdegoede@redhat.com> Cc: All applicable <stable@vger.kernel.org> Link: https://patch.msgid.link/23612351.6Emhk5qWAg@rjwysocki.net
2024-08-12 15:16:21 +02:00
ACPI: EC: Fix ECDT probe ordering issues ACPI-2.0 says that the EC OpRegion handler must be available immediately (like the standard default OpRegion handlers): Quoting from the ACPI spec version 6.3: "6.5.4 _REG (Region) ... 2. OSPM must make Embedded Controller operation regions, accessed via the Embedded Controllers described in ECDT, available before executing any control method. These operation regions may become inaccessible after OSPM runs _REG(EmbeddedControl, 0)." So acpi_bus_init() calls acpi_ec_ecdt_probe(), which calls acpi_install_address_space_handler() to install the EC's OpRegion handler, early on. This not only installs the OpRegion handler, but also calls the EC's _REG method. The _REG method call is a problem because it may rely on initialization done by the _INI methods of one of the PCI / _SB root devs, see for example: https://bugzilla.kernel.org/show_bug.cgi?id=214899 . Generally speaking _REG methods are executed when the ACPI-device they are part of has a driver bound to it. Where as _INI methods must be executed at table load time (according to the spec). The problem here is that the early acpi_install_address_space_handler() call causes the _REG handler to run too early. To allow fixing this the ACPICA code now allows to split the OpRegion handler installation and the executing of _REG into 2 separate steps. This commit uses this ACPICA functionality to fix the EC probe ordering by delaying the executing of _REG for ECDT described ECs till the matching EC device in the DSDT gets parsed and acpi_ec_add() for it gets called. This moves the calling of _REG for the EC on devices with an ECDT to the same point in time where it is called on devices without an ECDT table. BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=214899 Reported-and-tested-by: Johannes Penßel <johannespenssel@posteo.net> Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2022-12-08 15:23:35 +01:00
ACPI / EC: Fix regression related to triggering source of EC event handling Originally the Samsung quirks removed by commit 4c237371 can be covered by commit e923e8e7 and ec_freeze_events=Y mode. But commit 9c40f956 changed ec_freeze_events=Y back to N, making this problem re-surface. Actually, if commit e923e8e7 is robust enough, we can freely change ec_freeze_events mode, so this patch fixes the issue by improving commit e923e8e7. Related commits listed in the merged order: Commit: e923e8e79e18fd6be9162f1be6b99a002e9df2cb Subject: ACPI / EC: Fix an issue that SCI_EVT cannot be detected after event is enabled Commit: 4c237371f290d1ed3b2071dd43554362137b1cce Subject: ACPI / EC: Remove old CLEAR_ON_RESUME quirk Commit: 9c40f956ce9b331493347d1b3cb7e384f7dc0581 Subject: Revert "ACPI / EC: Enable event freeze mode..." to fix a regression This patch not only fixes the reported post-resume EC event triggering source issue, but also fixes an unreported similar issue related to the driver bind by adding EC event triggering source in ec_install_handlers(). Fixes: e923e8e79e18 (ACPI / EC: Fix an issue that SCI_EVT cannot be detected after event is enabled) Fixes: 4c237371f290 (ACPI / EC: Remove old CLEAR_ON_RESUME quirk) Fixes: 9c40f956ce9b (Revert "ACPI / EC: Enable event freeze mode..." to fix a regression) Link: https://bugzilla.kernel.org/show_bug.cgi?id=196833 Signed-off-by: Lv Zheng <lv.zheng@intel.com> Reported-by: Alistair Hamilton <ahpatent@gmail.com> Tested-by: Alistair Hamilton <ahpatent@gmail.com> Cc: 4.11+ <stable@vger.kernel.org> # 4.11+ Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2017-09-26 16:54:03 +08:00
ACPI: EC: Install address space handler at the namespace root It is reported that _DSM evaluation fails in ucsi_acpi_dsm() on Lenovo IdeaPad Pro 5 due to a missing address space handler for the EC address space: ACPI Error: No handler for Region [ECSI] (000000007b8176ee) [EmbeddedControl] (20230628/evregion-130) This happens because if there is no ECDT, the EC driver only registers the EC address space handler for operation regions defined in the EC device scope of the ACPI namespace while the operation region being accessed by the _DSM in question is located beyond that scope. To address this, modify the ACPI EC driver to install the EC address space handler at the root of the ACPI namespace for the first EC that can be found regardless of whether or not an ECDT is present. Note that this change is consistent with some examples in the ACPI specification in which EC operation regions located outside the EC device scope are used (for example, see Section 9.17.15 in ACPI 6.5), so the current behavior of the EC driver is arguably questionable. Reported-by: webcaptcha <webcapcha@gmail.com> Link: https://bugzilla.kernel.org/show_bug.cgi?id=218789 Link: https://uefi.org/specs/ACPI/6.5/09_ACPI_Defined_Devices_and_Device_Specific_Objects.html#example-asl-code Link: https://lore.kernel.org/linux-acpi/Zi+0whTvDbAdveHq@kuha.fi.intel.com Suggested-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Reviewed-by: Hans de Goede <hdegoede@redhat.com> Reviewed-by: Mario Limonciello <mario.limonciello@amd.com> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
2024-05-15 21:40:54 +02:00
ACPI: EC: Install address space handler at the namespace root It is reported that _DSM evaluation fails in ucsi_acpi_dsm() on Lenovo IdeaPad Pro 5 due to a missing address space handler for the EC address space: ACPI Error: No handler for Region [ECSI] (000000007b8176ee) [EmbeddedControl] (20230628/evregion-130) This happens because if there is no ECDT, the EC driver only registers the EC address space handler for operation regions defined in the EC device scope of the ACPI namespace while the operation region being accessed by the _DSM in question is located beyond that scope. To address this, modify the ACPI EC driver to install the EC address space handler at the root of the ACPI namespace for the first EC that can be found regardless of whether or not an ECDT is present. Note that this change is consistent with some examples in the ACPI specification in which EC operation regions located outside the EC device scope are used (for example, see Section 9.17.15 in ACPI 6.5), so the current behavior of the EC driver is arguably questionable. Reported-by: webcaptcha <webcapcha@gmail.com> Link: https://bugzilla.kernel.org/show_bug.cgi?id=218789 Link: https://uefi.org/specs/ACPI/6.5/09_ACPI_Defined_Devices_and_Device_Specific_Objects.html#example-asl-code Link: https://lore.kernel.org/linux-acpi/Zi+0whTvDbAdveHq@kuha.fi.intel.com Suggested-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Reviewed-by: Hans de Goede <hdegoede@redhat.com> Reviewed-by: Mario Limonciello <mario.limonciello@amd.com> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
2024-05-15 21:40:54 +02:00
ACPI: EC: Fix ECDT probe ordering issues ACPI-2.0 says that the EC OpRegion handler must be available immediately (like the standard default OpRegion handlers): Quoting from the ACPI spec version 6.3: "6.5.4 _REG (Region) ... 2. OSPM must make Embedded Controller operation regions, accessed via the Embedded Controllers described in ECDT, available before executing any control method. These operation regions may become inaccessible after OSPM runs _REG(EmbeddedControl, 0)." So acpi_bus_init() calls acpi_ec_ecdt_probe(), which calls acpi_install_address_space_handler() to install the EC's OpRegion handler, early on. This not only installs the OpRegion handler, but also calls the EC's _REG method. The _REG method call is a problem because it may rely on initialization done by the _INI methods of one of the PCI / _SB root devs, see for example: https://bugzilla.kernel.org/show_bug.cgi?id=214899 . Generally speaking _REG methods are executed when the ACPI-device they are part of has a driver bound to it. Where as _INI methods must be executed at table load time (according to the spec). The problem here is that the early acpi_install_address_space_handler() call causes the _REG handler to run too early. To allow fixing this the ACPICA code now allows to split the OpRegion handler installation and the executing of _REG into 2 separate steps. This commit uses this ACPICA functionality to fix the EC probe ordering by delaying the executing of _REG for ECDT described ECs till the matching EC device in the DSDT gets parsed and acpi_ec_add() for it gets called. This moves the calling of _REG for the EC on devices with an ECDT to the same point in time where it is called on devices without an ECDT table. BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=214899 Reported-and-tested-by: Johannes Penßel <johannespenssel@posteo.net> Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2022-12-08 15:23:35 +01:00
ACPI: EC: Avoid _REG disconnect on GPIO IRQ defer EC event delivery uses either a GPE or, on ACPI reduced hardware platforms, a GpioInt resource. The GPE path does not have a provider lookup that can defer, but acpi_dev_gpio_irq_get() can return -EPROBE_DEFER for the GpioInt path. ec_install_handlers() currently installs the EC address space handler and executes _REG before looking up the GPIO IRQ. If the GPIO lookup then defers, acpi_ec_setup() tears the handlers down again. Removing the EC address space handler causes ACPICA to execute _REG for disconnect, so firmware may observe an EC OpRegion connected -> disconnected transition during one failed probe attempt. This is observable when the namespace EC reuses a boot EC that has already installed the EC address space handler. A deferred namespace EC probe can disconnect the already usable boot EC OpRegion until a later reprobe connects it again. AML that gates EC field accesses on _REG state can then return fallback values to other drivers during that window. Prepare the GPIOInt IRQ before publishing EC OpRegion availability to AML. This leaves the GPE path unchanged, keeps non-deferred GPIO lookup errors non-fatal as before, and still lets the existing acpi_ec_setup() error path clean up real handler installation failures. Fixes: f6484cadbcaf ("ACPI: EC: clean up handlers on probe failure in acpi_ec_setup()") Signed-off-by: Zhu Ling <zhuling2709@phytium.com.cn> [ rjw: Added an empty code line after a conditional ] Link: https://patch.msgid.link/20260715012556.12043-1-zhuling2709@phytium.com.cn Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2026-07-15 09:25:19 +08:00
ACPI: EC: Install address space handler at the namespace root It is reported that _DSM evaluation fails in ucsi_acpi_dsm() on Lenovo IdeaPad Pro 5 due to a missing address space handler for the EC address space: ACPI Error: No handler for Region [ECSI] (000000007b8176ee) [EmbeddedControl] (20230628/evregion-130) This happens because if there is no ECDT, the EC driver only registers the EC address space handler for operation regions defined in the EC device scope of the ACPI namespace while the operation region being accessed by the _DSM in question is located beyond that scope. To address this, modify the ACPI EC driver to install the EC address space handler at the root of the ACPI namespace for the first EC that can be found regardless of whether or not an ECDT is present. Note that this change is consistent with some examples in the ACPI specification in which EC operation regions located outside the EC device scope are used (for example, see Section 9.17.15 in ACPI 6.5), so the current behavior of the EC driver is arguably questionable. Reported-by: webcaptcha <webcapcha@gmail.com> Link: https://bugzilla.kernel.org/show_bug.cgi?id=218789 Link: https://uefi.org/specs/ACPI/6.5/09_ACPI_Defined_Devices_and_Device_Specific_Objects.html#example-asl-code Link: https://lore.kernel.org/linux-acpi/Zi+0whTvDbAdveHq@kuha.fi.intel.com Suggested-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Reviewed-by: Hans de Goede <hdegoede@redhat.com> Reviewed-by: Mario Limonciello <mario.limonciello@amd.com> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
2024-05-15 21:40:54 +02:00
ACPI: EC: clean up handlers on probe failure in acpi_ec_setup() When ec_install_handlers() returns -EPROBE_DEFER on reduced-hardware platforms, it has already started the EC and installed the address space handler with the struct acpi_ec pointer as handler context. However, acpi_ec_setup() propagates the error without any cleanup. The caller acpi_ec_add() then frees the struct acpi_ec for non-boot instances, leaving a dangling handler context in ACPICA. Any subsequent AML evaluation that accesses an EC OpRegion field dispatches into acpi_ec_space_handler() with the freed pointer, causing a use-after-free: BUG: KASAN: slab-use-after-free in mutex_lock (kernel/locking/mutex.c:289) Write of size 8 at addr ffff88800721de38 by task init/1 Call Trace: <TASK> mutex_lock (kernel/locking/mutex.c:289) acpi_ec_space_handler (drivers/acpi/ec.c:1362) acpi_ev_address_space_dispatch (drivers/acpi/acpica/evregion.c:293) acpi_ex_access_region (drivers/acpi/acpica/exfldio.c:246) acpi_ex_field_datum_io (drivers/acpi/acpica/exfldio.c:509) acpi_ex_extract_from_field (drivers/acpi/acpica/exfldio.c:700) acpi_ex_read_data_from_field (drivers/acpi/acpica/exfield.c:327) acpi_ex_resolve_node_to_value (drivers/acpi/acpica/exresolv.c:392) </TASK> Allocated by task 1: acpi_ec_alloc (drivers/acpi/ec.c:1424) acpi_ec_add (drivers/acpi/ec.c:1692) Freed by task 1: kfree (mm/slub.c:6876) acpi_ec_add (drivers/acpi/ec.c:1751) The bug triggers on reduced-hardware EC platforms (ec->gpe < 0) when the GPIO IRQ provider defers probing. Once the stale handler exists, any unprivileged sysfs read that causes AML to touch an EC OpRegion (battery, thermal, backlight) exercises the dangling pointer. Fix this by calling ec_remove_handlers() in the error path of acpi_ec_setup() before clearing first_ec. ec_remove_handlers() checks each EC_FLAGS_* bit before acting, so it is safe to call regardless of how far ec_install_handlers() progressed: -ENODEV (handler not installed): only calls acpi_ec_stop() -EPROBE_DEFER (handler installed): removes handler, stops EC Fixes: 03e9a0e05739 ("ACPI: EC: Consolidate event handler installation code") Reported-by: Xiang Mei <xmei5@asu.edu> Signed-off-by: Weiming Shi <bestswngs@gmail.com> Link: https://patch.msgid.link/20260324165458.1337233-2-bestswngs@gmail.com Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2026-03-25 00:54:59 +08:00
ACPI: EC: Install address space handler at the namespace root It is reported that _DSM evaluation fails in ucsi_acpi_dsm() on Lenovo IdeaPad Pro 5 due to a missing address space handler for the EC address space: ACPI Error: No handler for Region [ECSI] (000000007b8176ee) [EmbeddedControl] (20230628/evregion-130) This happens because if there is no ECDT, the EC driver only registers the EC address space handler for operation regions defined in the EC device scope of the ACPI namespace while the operation region being accessed by the _DSM in question is located beyond that scope. To address this, modify the ACPI EC driver to install the EC address space handler at the root of the ACPI namespace for the first EC that can be found regardless of whether or not an ECDT is present. Note that this change is consistent with some examples in the ACPI specification in which EC operation regions located outside the EC device scope are used (for example, see Section 9.17.15 in ACPI 6.5), so the current behavior of the EC driver is arguably questionable. Reported-by: webcaptcha <webcapcha@gmail.com> Link: https://bugzilla.kernel.org/show_bug.cgi?id=218789 Link: https://uefi.org/specs/ACPI/6.5/09_ACPI_Defined_Devices_and_Device_Specific_Objects.html#example-asl-code Link: https://lore.kernel.org/linux-acpi/Zi+0whTvDbAdveHq@kuha.fi.intel.com Suggested-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Reviewed-by: Hans de Goede <hdegoede@redhat.com> Reviewed-by: Mario Limonciello <mario.limonciello@amd.com> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
2024-05-15 21:40:54 +02:00
ACPI / EC: Fix regression related to PM ops support in ECDT device On platforms (ASUS X550ZE and possibly all ASUS X series) with valid ECDT EC but invalid DSDT EC, EC PM ops won't be invoked as ECDT EC is not an ACPI device. Thus the following commit actually removed post-resume acpi_ec_enable_event() invocation for such platforms, and triggered a regression on them that after being resumed, EC (actually should be ECDT) driver stops handling EC events: Commit: c2b46d679b30c5c0d7eb47a21085943242bdd8dc Subject: ACPI / EC: Add PM operations to improve event handling for resume process Notice that the root cause actually is "ECDT is not an ACPI device" rather than "the timing of acpi_ec_enable_event() invocation", this patch fixes this issue by enumerating ECDT EC as an ACPI device. Due to the existence of the noirq stage, the ability of tuning the timing of acpi_ec_enable_event() invocation is still meaningful. This patch is a little bit different from the posted fix by moving acpi_config_boot_ec() from acpi_ec_ecdt_start() to acpi_ec_add() to make sure that EC event handling won't be stopped as long as the ACPI EC driver is bound. Thus the following sequence shouldn't disable EC event handling: unbind,suspend,resume,bind. Fixes: c2b46d679b30 (ACPI / EC: Add PM operations to improve event handling for resume process) Link: https://bugzilla.kernel.org/show_bug.cgi?id=196847 Reported-by: Luya Tshimbalanga <luya@fedoraproject.org> Tested-by: Luya Tshimbalanga <luya@fedoraproject.org> Cc: 4.9+ <stable@vger.kernel.org> # 4.9+ Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2017-09-26 16:54:09 +08:00
ACPI / EC: Fix regression related to PM ops support in ECDT device On platforms (ASUS X550ZE and possibly all ASUS X series) with valid ECDT EC but invalid DSDT EC, EC PM ops won't be invoked as ECDT EC is not an ACPI device. Thus the following commit actually removed post-resume acpi_ec_enable_event() invocation for such platforms, and triggered a regression on them that after being resumed, EC (actually should be ECDT) driver stops handling EC events: Commit: c2b46d679b30c5c0d7eb47a21085943242bdd8dc Subject: ACPI / EC: Add PM operations to improve event handling for resume process Notice that the root cause actually is "ECDT is not an ACPI device" rather than "the timing of acpi_ec_enable_event() invocation", this patch fixes this issue by enumerating ECDT EC as an ACPI device. Due to the existence of the noirq stage, the ability of tuning the timing of acpi_ec_enable_event() invocation is still meaningful. This patch is a little bit different from the posted fix by moving acpi_config_boot_ec() from acpi_ec_ecdt_start() to acpi_ec_add() to make sure that EC event handling won't be stopped as long as the ACPI EC driver is bound. Thus the following sequence shouldn't disable EC event handling: unbind,suspend,resume,bind. Fixes: c2b46d679b30 (ACPI / EC: Add PM operations to improve event handling for resume process) Link: https://bugzilla.kernel.org/show_bug.cgi?id=196847 Reported-by: Luya Tshimbalanga <luya@fedoraproject.org> Tested-by: Luya Tshimbalanga <luya@fedoraproject.org> Cc: 4.9+ <stable@vger.kernel.org> # 4.9+ Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2017-09-26 16:54:09 +08:00
ACPI / EC: Fix regression related to PM ops support in ECDT device On platforms (ASUS X550ZE and possibly all ASUS X series) with valid ECDT EC but invalid DSDT EC, EC PM ops won't be invoked as ECDT EC is not an ACPI device. Thus the following commit actually removed post-resume acpi_ec_enable_event() invocation for such platforms, and triggered a regression on them that after being resumed, EC (actually should be ECDT) driver stops handling EC events: Commit: c2b46d679b30c5c0d7eb47a21085943242bdd8dc Subject: ACPI / EC: Add PM operations to improve event handling for resume process Notice that the root cause actually is "ECDT is not an ACPI device" rather than "the timing of acpi_ec_enable_event() invocation", this patch fixes this issue by enumerating ECDT EC as an ACPI device. Due to the existence of the noirq stage, the ability of tuning the timing of acpi_ec_enable_event() invocation is still meaningful. This patch is a little bit different from the posted fix by moving acpi_config_boot_ec() from acpi_ec_ecdt_start() to acpi_ec_add() to make sure that EC event handling won't be stopped as long as the ACPI EC driver is bound. Thus the following sequence shouldn't disable EC event handling: unbind,suspend,resume,bind. Fixes: c2b46d679b30 (ACPI / EC: Add PM operations to improve event handling for resume process) Link: https://bugzilla.kernel.org/show_bug.cgi?id=196847 Reported-by: Luya Tshimbalanga <luya@fedoraproject.org> Tested-by: Luya Tshimbalanga <luya@fedoraproject.org> Cc: 4.9+ <stable@vger.kernel.org> # 4.9+ Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2017-09-26 16:54:09 +08:00
ACPI / EC: Fix regression related to PM ops support in ECDT device On platforms (ASUS X550ZE and possibly all ASUS X series) with valid ECDT EC but invalid DSDT EC, EC PM ops won't be invoked as ECDT EC is not an ACPI device. Thus the following commit actually removed post-resume acpi_ec_enable_event() invocation for such platforms, and triggered a regression on them that after being resumed, EC (actually should be ECDT) driver stops handling EC events: Commit: c2b46d679b30c5c0d7eb47a21085943242bdd8dc Subject: ACPI / EC: Add PM operations to improve event handling for resume process Notice that the root cause actually is "ECDT is not an ACPI device" rather than "the timing of acpi_ec_enable_event() invocation", this patch fixes this issue by enumerating ECDT EC as an ACPI device. Due to the existence of the noirq stage, the ability of tuning the timing of acpi_ec_enable_event() invocation is still meaningful. This patch is a little bit different from the posted fix by moving acpi_config_boot_ec() from acpi_ec_ecdt_start() to acpi_ec_add() to make sure that EC event handling won't be stopped as long as the ACPI EC driver is bound. Thus the following sequence shouldn't disable EC event handling: unbind,suspend,resume,bind. Fixes: c2b46d679b30 (ACPI / EC: Add PM operations to improve event handling for resume process) Link: https://bugzilla.kernel.org/show_bug.cgi?id=196847 Reported-by: Luya Tshimbalanga <luya@fedoraproject.org> Tested-by: Luya Tshimbalanga <luya@fedoraproject.org> Cc: 4.9+ <stable@vger.kernel.org> # 4.9+ Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2017-09-26 16:54:09 +08:00
ACPI / EC: Fix regression related to PM ops support in ECDT device On platforms (ASUS X550ZE and possibly all ASUS X series) with valid ECDT EC but invalid DSDT EC, EC PM ops won't be invoked as ECDT EC is not an ACPI device. Thus the following commit actually removed post-resume acpi_ec_enable_event() invocation for such platforms, and triggered a regression on them that after being resumed, EC (actually should be ECDT) driver stops handling EC events: Commit: c2b46d679b30c5c0d7eb47a21085943242bdd8dc Subject: ACPI / EC: Add PM operations to improve event handling for resume process Notice that the root cause actually is "ECDT is not an ACPI device" rather than "the timing of acpi_ec_enable_event() invocation", this patch fixes this issue by enumerating ECDT EC as an ACPI device. Due to the existence of the noirq stage, the ability of tuning the timing of acpi_ec_enable_event() invocation is still meaningful. This patch is a little bit different from the posted fix by moving acpi_config_boot_ec() from acpi_ec_ecdt_start() to acpi_ec_add() to make sure that EC event handling won't be stopped as long as the ACPI EC driver is bound. Thus the following sequence shouldn't disable EC event handling: unbind,suspend,resume,bind. Fixes: c2b46d679b30 (ACPI / EC: Add PM operations to improve event handling for resume process) Link: https://bugzilla.kernel.org/show_bug.cgi?id=196847 Reported-by: Luya Tshimbalanga <luya@fedoraproject.org> Tested-by: Luya Tshimbalanga <luya@fedoraproject.org> Cc: 4.9+ <stable@vger.kernel.org> # 4.9+ Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2017-09-26 16:54:09 +08:00
ACPI / EC: Fix regression related to PM ops support in ECDT device On platforms (ASUS X550ZE and possibly all ASUS X series) with valid ECDT EC but invalid DSDT EC, EC PM ops won't be invoked as ECDT EC is not an ACPI device. Thus the following commit actually removed post-resume acpi_ec_enable_event() invocation for such platforms, and triggered a regression on them that after being resumed, EC (actually should be ECDT) driver stops handling EC events: Commit: c2b46d679b30c5c0d7eb47a21085943242bdd8dc Subject: ACPI / EC: Add PM operations to improve event handling for resume process Notice that the root cause actually is "ECDT is not an ACPI device" rather than "the timing of acpi_ec_enable_event() invocation", this patch fixes this issue by enumerating ECDT EC as an ACPI device. Due to the existence of the noirq stage, the ability of tuning the timing of acpi_ec_enable_event() invocation is still meaningful. This patch is a little bit different from the posted fix by moving acpi_config_boot_ec() from acpi_ec_ecdt_start() to acpi_ec_add() to make sure that EC event handling won't be stopped as long as the ACPI EC driver is bound. Thus the following sequence shouldn't disable EC event handling: unbind,suspend,resume,bind. Fixes: c2b46d679b30 (ACPI / EC: Add PM operations to improve event handling for resume process) Link: https://bugzilla.kernel.org/show_bug.cgi?id=196847 Reported-by: Luya Tshimbalanga <luya@fedoraproject.org> Tested-by: Luya Tshimbalanga <luya@fedoraproject.org> Cc: 4.9+ <stable@vger.kernel.org> # 4.9+ Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2017-09-26 16:54:09 +08:00
ACPI / EC: Fix regression related to PM ops support in ECDT device On platforms (ASUS X550ZE and possibly all ASUS X series) with valid ECDT EC but invalid DSDT EC, EC PM ops won't be invoked as ECDT EC is not an ACPI device. Thus the following commit actually removed post-resume acpi_ec_enable_event() invocation for such platforms, and triggered a regression on them that after being resumed, EC (actually should be ECDT) driver stops handling EC events: Commit: c2b46d679b30c5c0d7eb47a21085943242bdd8dc Subject: ACPI / EC: Add PM operations to improve event handling for resume process Notice that the root cause actually is "ECDT is not an ACPI device" rather than "the timing of acpi_ec_enable_event() invocation", this patch fixes this issue by enumerating ECDT EC as an ACPI device. Due to the existence of the noirq stage, the ability of tuning the timing of acpi_ec_enable_event() invocation is still meaningful. This patch is a little bit different from the posted fix by moving acpi_config_boot_ec() from acpi_ec_ecdt_start() to acpi_ec_add() to make sure that EC event handling won't be stopped as long as the ACPI EC driver is bound. Thus the following sequence shouldn't disable EC event handling: unbind,suspend,resume,bind. Fixes: c2b46d679b30 (ACPI / EC: Add PM operations to improve event handling for resume process) Link: https://bugzilla.kernel.org/show_bug.cgi?id=196847 Reported-by: Luya Tshimbalanga <luya@fedoraproject.org> Tested-by: Luya Tshimbalanga <luya@fedoraproject.org> Cc: 4.9+ <stable@vger.kernel.org> # 4.9+ Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2017-09-26 16:54:09 +08:00
ACPI: EC: Fix ECDT probe ordering issues ACPI-2.0 says that the EC OpRegion handler must be available immediately (like the standard default OpRegion handlers): Quoting from the ACPI spec version 6.3: "6.5.4 _REG (Region) ... 2. OSPM must make Embedded Controller operation regions, accessed via the Embedded Controllers described in ECDT, available before executing any control method. These operation regions may become inaccessible after OSPM runs _REG(EmbeddedControl, 0)." So acpi_bus_init() calls acpi_ec_ecdt_probe(), which calls acpi_install_address_space_handler() to install the EC's OpRegion handler, early on. This not only installs the OpRegion handler, but also calls the EC's _REG method. The _REG method call is a problem because it may rely on initialization done by the _INI methods of one of the PCI / _SB root devs, see for example: https://bugzilla.kernel.org/show_bug.cgi?id=214899 . Generally speaking _REG methods are executed when the ACPI-device they are part of has a driver bound to it. Where as _INI methods must be executed at table load time (according to the spec). The problem here is that the early acpi_install_address_space_handler() call causes the _REG handler to run too early. To allow fixing this the ACPICA code now allows to split the OpRegion handler installation and the executing of _REG into 2 separate steps. This commit uses this ACPICA functionality to fix the EC probe ordering by delaying the executing of _REG for ECDT described ECs till the matching EC device in the DSDT gets parsed and acpi_ec_add() for it gets called. This moves the calling of _REG for the EC on devices with an ECDT to the same point in time where it is called on devices without an ECDT table. BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=214899 Reported-and-tested-by: Johannes Penßel <johannespenssel@posteo.net> Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2022-12-08 15:23:35 +01:00
ACPI: EC: Evaluate _REG outside the EC scope more carefully Commit 60fa6ae6e6d0 ("ACPI: EC: Install address space handler at the namespace root") caused _REG methods for EC operation regions outside the EC device scope to be evaluated which on some systems leads to the evaluation of _REG methods in the scopes of device objects representing devices that are not present and not functional according to the _STA return values. Some of those device objects represent EC "alternatives" and if _REG is evaluated for their operation regions, the platform firmware may be confused and the platform may start to behave incorrectly. To avoid this problem, only evaluate _REG for EC operation regions located in the scopes of device objects representing known-to-be-present devices. For this purpose, partially revert commit 60fa6ae6e6d0 and trigger the evaluation of _REG for EC operation regions from acpi_bus_attach() for the known-valid devices. Fixes: 60fa6ae6e6d0 ("ACPI: EC: Install address space handler at the namespace root") Link: https://lore.kernel.org/linux-acpi/1f76b7e2-1928-4598-8037-28a1785c2d13@redhat.com Link: https://bugzilla.redhat.com/show_bug.cgi?id=2298938 Link: https://bugzilla.redhat.com/show_bug.cgi?id=2302253 Reported-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Reviewed-by: Hans de Goede <hdegoede@redhat.com> Cc: All applicable <stable@vger.kernel.org> Link: https://patch.msgid.link/23612351.6Emhk5qWAg@rjwysocki.net
2024-08-12 15:16:21 +02:00
ACPI / EC: Fix regression related to PM ops support in ECDT device On platforms (ASUS X550ZE and possibly all ASUS X series) with valid ECDT EC but invalid DSDT EC, EC PM ops won't be invoked as ECDT EC is not an ACPI device. Thus the following commit actually removed post-resume acpi_ec_enable_event() invocation for such platforms, and triggered a regression on them that after being resumed, EC (actually should be ECDT) driver stops handling EC events: Commit: c2b46d679b30c5c0d7eb47a21085943242bdd8dc Subject: ACPI / EC: Add PM operations to improve event handling for resume process Notice that the root cause actually is "ECDT is not an ACPI device" rather than "the timing of acpi_ec_enable_event() invocation", this patch fixes this issue by enumerating ECDT EC as an ACPI device. Due to the existence of the noirq stage, the ability of tuning the timing of acpi_ec_enable_event() invocation is still meaningful. This patch is a little bit different from the posted fix by moving acpi_config_boot_ec() from acpi_ec_ecdt_start() to acpi_ec_add() to make sure that EC event handling won't be stopped as long as the ACPI EC driver is bound. Thus the following sequence shouldn't disable EC event handling: unbind,suspend,resume,bind. Fixes: c2b46d679b30 (ACPI / EC: Add PM operations to improve event handling for resume process) Link: https://bugzilla.kernel.org/show_bug.cgi?id=196847 Reported-by: Luya Tshimbalanga <luya@fedoraproject.org> Tested-by: Luya Tshimbalanga <luya@fedoraproject.org> Cc: 4.9+ <stable@vger.kernel.org> # 4.9+ Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2017-09-26 16:54:09 +08:00
ACPI / EC: Add support to skip boot stage DSDT probe We prepared _INI/_STA methods for \_SB, \_SB.PCI0, \_SB.LID0 and \_SB.EC, _HID(PNP0C09)/_CRS/_GPE for \_SB.EC to poke Windows behavior with qemu, we got the following execution sequence: \_SB._INI \_SB.PCI0._STA \_SB.LID0._STA \_SB.EC._STA \_SB.PCI0._INI \_SB.LID0._INI \_SB.EC._INI There is no extra DSDT EC device enumeration process occurring before the main ACPI device enumeration process. That means acpi_ec_dsdt_probe() is not Windows-compatible. Tracking back, it was added by the following commit: Commit: c5279dee26c0e8d7c4200993bfc4b540d2469598 Subject: ACPI: EC: Add some basic check for ECDT data but that commit was misguided. Why we shouldn't enumerate DSDT EC before the main ACPI device enumeration? The only way to know if the DSDT EC is valid would be to evaluate its _STA control method, but it's not safe to evaluate this control method that early and out of the ACPI enumeration process, because _STA may refer to entities (such as resources or ACPI device objects) that may not have been initialized before OSPM starts to enumerate them via the main ACPI device enumeration. But after we had reverted back to the expected behavior, a regression was reported. On that platform, there is no ECDT, but the platform control methods access EC operation region earlier than Linux expects causing some ACPI method execution errors. For this reason, we just go back to old behavior to still probe DSDT EC as the boot EC. However, that turns out to lead to yet another functional breakage and in order to work around all of the problems, we skip boot stage DSDT probe when the ECDT exists so that a later quirk can always use correct ECDT GPE setting. Link: http://bugzilla.kernel.org/show_bug.cgi?id=11880 Link: http://bugzilla.kernel.org/show_bug.cgi?id=119261 Link: http://bugzilla.kernel.org/show_bug.cgi?id=195651 Tested-by: Daniel Drake <drake@endlessm.com> Signed-off-by: Lv Zheng <lv.zheng@intel.com> [ rjw: Changelog & comments massage ] Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2017-06-15 09:41:41 +08:00
ACPI / EC: Add support to skip boot stage DSDT probe We prepared _INI/_STA methods for \_SB, \_SB.PCI0, \_SB.LID0 and \_SB.EC, _HID(PNP0C09)/_CRS/_GPE for \_SB.EC to poke Windows behavior with qemu, we got the following execution sequence: \_SB._INI \_SB.PCI0._STA \_SB.LID0._STA \_SB.EC._STA \_SB.PCI0._INI \_SB.LID0._INI \_SB.EC._INI There is no extra DSDT EC device enumeration process occurring before the main ACPI device enumeration process. That means acpi_ec_dsdt_probe() is not Windows-compatible. Tracking back, it was added by the following commit: Commit: c5279dee26c0e8d7c4200993bfc4b540d2469598 Subject: ACPI: EC: Add some basic check for ECDT data but that commit was misguided. Why we shouldn't enumerate DSDT EC before the main ACPI device enumeration? The only way to know if the DSDT EC is valid would be to evaluate its _STA control method, but it's not safe to evaluate this control method that early and out of the ACPI enumeration process, because _STA may refer to entities (such as resources or ACPI device objects) that may not have been initialized before OSPM starts to enumerate them via the main ACPI device enumeration. But after we had reverted back to the expected behavior, a regression was reported. On that platform, there is no ECDT, but the platform control methods access EC operation region earlier than Linux expects causing some ACPI method execution errors. For this reason, we just go back to old behavior to still probe DSDT EC as the boot EC. However, that turns out to lead to yet another functional breakage and in order to work around all of the problems, we skip boot stage DSDT probe when the ECDT exists so that a later quirk can always use correct ECDT GPE setting. Link: http://bugzilla.kernel.org/show_bug.cgi?id=11880 Link: http://bugzilla.kernel.org/show_bug.cgi?id=119261 Link: http://bugzilla.kernel.org/show_bug.cgi?id=195651 Tested-by: Daniel Drake <drake@endlessm.com> Signed-off-by: Lv Zheng <lv.zheng@intel.com> [ rjw: Changelog & comments massage ] Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2017-06-15 09:41:41 +08:00
ACPI / EC: Add support to skip boot stage DSDT probe We prepared _INI/_STA methods for \_SB, \_SB.PCI0, \_SB.LID0 and \_SB.EC, _HID(PNP0C09)/_CRS/_GPE for \_SB.EC to poke Windows behavior with qemu, we got the following execution sequence: \_SB._INI \_SB.PCI0._STA \_SB.LID0._STA \_SB.EC._STA \_SB.PCI0._INI \_SB.LID0._INI \_SB.EC._INI There is no extra DSDT EC device enumeration process occurring before the main ACPI device enumeration process. That means acpi_ec_dsdt_probe() is not Windows-compatible. Tracking back, it was added by the following commit: Commit: c5279dee26c0e8d7c4200993bfc4b540d2469598 Subject: ACPI: EC: Add some basic check for ECDT data but that commit was misguided. Why we shouldn't enumerate DSDT EC before the main ACPI device enumeration? The only way to know if the DSDT EC is valid would be to evaluate its _STA control method, but it's not safe to evaluate this control method that early and out of the ACPI enumeration process, because _STA may refer to entities (such as resources or ACPI device objects) that may not have been initialized before OSPM starts to enumerate them via the main ACPI device enumeration. But after we had reverted back to the expected behavior, a regression was reported. On that platform, there is no ECDT, but the platform control methods access EC operation region earlier than Linux expects causing some ACPI method execution errors. For this reason, we just go back to old behavior to still probe DSDT EC as the boot EC. However, that turns out to lead to yet another functional breakage and in order to work around all of the problems, we skip boot stage DSDT probe when the ECDT exists so that a later quirk can always use correct ECDT GPE setting. Link: http://bugzilla.kernel.org/show_bug.cgi?id=11880 Link: http://bugzilla.kernel.org/show_bug.cgi?id=119261 Link: http://bugzilla.kernel.org/show_bug.cgi?id=195651 Tested-by: Daniel Drake <drake@endlessm.com> Signed-off-by: Lv Zheng <lv.zheng@intel.com> [ rjw: Changelog & comments massage ] Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2017-06-15 09:41:41 +08:00
ACPI: EC: Fix ECDT probe ordering issues ACPI-2.0 says that the EC OpRegion handler must be available immediately (like the standard default OpRegion handlers): Quoting from the ACPI spec version 6.3: "6.5.4 _REG (Region) ... 2. OSPM must make Embedded Controller operation regions, accessed via the Embedded Controllers described in ECDT, available before executing any control method. These operation regions may become inaccessible after OSPM runs _REG(EmbeddedControl, 0)." So acpi_bus_init() calls acpi_ec_ecdt_probe(), which calls acpi_install_address_space_handler() to install the EC's OpRegion handler, early on. This not only installs the OpRegion handler, but also calls the EC's _REG method. The _REG method call is a problem because it may rely on initialization done by the _INI methods of one of the PCI / _SB root devs, see for example: https://bugzilla.kernel.org/show_bug.cgi?id=214899 . Generally speaking _REG methods are executed when the ACPI-device they are part of has a driver bound to it. Where as _INI methods must be executed at table load time (according to the spec). The problem here is that the early acpi_install_address_space_handler() call causes the _REG handler to run too early. To allow fixing this the ACPICA code now allows to split the OpRegion handler installation and the executing of _REG into 2 separate steps. This commit uses this ACPICA functionality to fix the EC probe ordering by delaying the executing of _REG for ECDT described ECs till the matching EC device in the DSDT gets parsed and acpi_ec_add() for it gets called. This moves the calling of _REG for the EC on devices with an ECDT to the same point in time where it is called on devices without an ECDT table. BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=214899 Reported-and-tested-by: Johannes Penßel <johannespenssel@posteo.net> Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2022-12-08 15:23:35 +01:00
ACPI / EC: Fix regression related to PM ops support in ECDT device On platforms (ASUS X550ZE and possibly all ASUS X series) with valid ECDT EC but invalid DSDT EC, EC PM ops won't be invoked as ECDT EC is not an ACPI device. Thus the following commit actually removed post-resume acpi_ec_enable_event() invocation for such platforms, and triggered a regression on them that after being resumed, EC (actually should be ECDT) driver stops handling EC events: Commit: c2b46d679b30c5c0d7eb47a21085943242bdd8dc Subject: ACPI / EC: Add PM operations to improve event handling for resume process Notice that the root cause actually is "ECDT is not an ACPI device" rather than "the timing of acpi_ec_enable_event() invocation", this patch fixes this issue by enumerating ECDT EC as an ACPI device. Due to the existence of the noirq stage, the ability of tuning the timing of acpi_ec_enable_event() invocation is still meaningful. This patch is a little bit different from the posted fix by moving acpi_config_boot_ec() from acpi_ec_ecdt_start() to acpi_ec_add() to make sure that EC event handling won't be stopped as long as the ACPI EC driver is bound. Thus the following sequence shouldn't disable EC event handling: unbind,suspend,resume,bind. Fixes: c2b46d679b30 (ACPI / EC: Add PM operations to improve event handling for resume process) Link: https://bugzilla.kernel.org/show_bug.cgi?id=196847 Reported-by: Luya Tshimbalanga <luya@fedoraproject.org> Tested-by: Luya Tshimbalanga <luya@fedoraproject.org> Cc: 4.9+ <stable@vger.kernel.org> # 4.9+ Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2017-09-26 16:54:09 +08:00
ACPI 2.0 / ECDT: Remove early namespace reference from EC All operation region accesses are allowed by AML interpreter when AML is executed, so actually BIOSen are responsible to avoid the operation region accesses in AML before OSPM has prepared an operation region driver. This is done via _REG control method. So AML code normally sets a global named object REGC to 1 when _REG(3, 1) is evaluated. Then what is ECDT? Quoting from ACPI spec 6.0, 5.2.15 Embedded Controller Boot Resources Table (ECDT): "The presence of this table allows OSPM to provide Embedded Controller operation region space access before the namespace has been evaluated." Spec also suggests a compatible mean to indicate the early EC access availability: Device (EC) { Name (REGC, Ones) Method (_REG, 2) { If (LEqual (Arg0, 3)) { Store (Arg1, REGC) } } Method (ECAV) { If (LEqual (REGC, Ones)) { If (LGreaterEqual (_REV, 2)) { Return (One) } Else { Return (Zero) } } Else { Return (REGC) } } } In this way, it allows EC accesses to happen before EC._REG(3, 1) is invoked. But ECAV is not the only way practical BIOSen using to indicate the early EC access availibility, the known variations include: 1. Setting REGC to One in \_SB._INI when _REV >= 2. Since \_SB._INI is the first control method evaluated by OSPM during the enumeration, this allows EC accesses to happen for the entire enumeration process before the namespace EC is enumerated. 2. Initialize REGC to One by default, this even allows EC accesses to happen during the table loading. Linux is now broken around ECDT support during the long term bug fixing work because it has merged many wrong ECDT bug fixes (see details below). Linux currently uses namespace EC's settings instead of ECDT settings when ECDT is detected. This apparently will result in namespace walk and _CRS/_GPE/_REG evaluations. Such stuffs could only happen after namespace is ready, while ECDT is purposely to be used before namespace is ready. The wrong bug fixing story is: 1. Link 1: At Linux ACPI early stages, "no _Lxx/_Exx/_Qxx evaluation can happen before the namespace is ready" are not ensured by ACPICA core and Linux. This is currently ensured by deferred enabling of GPE and defered registering of EC query methods (acpi_ec_register_query_methods). 2. Link 2: Reporters reported buggy ECDTs, expecting quirks for the platform. Originally, the quirk is simple, only doing things with ECDT. Bug 9399 and 12461 are platforms (Asus L4R, Asus M6R, MSI MS-171F) reported to have wrong ECDT IO port addresses, the port addresses are reversed. Bug 11880 is a platform (Asus X50GL) reported to have 0 valued port addresses, we can see that all EC accesses are protected by ECAV on this platform, so actually no early EC accesses is required by this platform. 3. Link 3: But when the bug fixing developer was requested to provide a handy and non-quirk bug fix, he tried to use correct EC settings from namespace and broke the spec purpose. We can even see that the developer was suffered from many regrssions. One interesting one is 14086, where the actual root cause obviously should be: _REG is evaluated too early. But unfortunately, the bug is fixed in a totally wrong way. So everything goes wrong from these commits: Commit: c6cb0e878446c79f42e7833d7bb69ed6bfbb381f Subject: ACPI: EC: Don't trust ECDT tables from ASUS Commit: a5032bfdd9c80e0231a6324661e123818eb46ecd Subject: ACPI: EC: Always parse EC device This patch reverts Linux behavior to simple ECDT quirk support in order to stop early _CRS/_GPE/_REG evaluations. For Bug 9399, 12461, since it is reported that the platforms require early EC accesses, this patch restores the simple ECDT quirks for them. For Bug 11880, since it is not reported that the platform requires early EC accesses and its ACPI tables contain correct ECAV, we choose an ECDT enumeration failure for this platform. Link 1: https://bugzilla.kernel.org/show_bug.cgi?id=9916 http://bugzilla.kernel.org/show_bug.cgi?id=10100 https://lkml.org/lkml/2008/2/25/282 Link 2: https://bugzilla.kernel.org/show_bug.cgi?id=9399 https://bugzilla.kernel.org/show_bug.cgi?id=12461 https://bugzilla.kernel.org/show_bug.cgi?id=11880 Link 3: https://bugzilla.kernel.org/show_bug.cgi?id=11884 https://bugzilla.kernel.org/show_bug.cgi?id=14081 https://bugzilla.kernel.org/show_bug.cgi?id=14086 https://bugzilla.kernel.org/show_bug.cgi?id=14446 Link 4: https://bugzilla.kernel.org/show_bug.cgi?id=112911 Signed-off-by: Lv Zheng <lv.zheng@intel.com> Tested-by: Chris Bainbridge <chris.bainbridge@gmail.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2016-03-24 10:42:53 +08:00
ACPI 2.0 / ECDT: Remove early namespace reference from EC All operation region accesses are allowed by AML interpreter when AML is executed, so actually BIOSen are responsible to avoid the operation region accesses in AML before OSPM has prepared an operation region driver. This is done via _REG control method. So AML code normally sets a global named object REGC to 1 when _REG(3, 1) is evaluated. Then what is ECDT? Quoting from ACPI spec 6.0, 5.2.15 Embedded Controller Boot Resources Table (ECDT): "The presence of this table allows OSPM to provide Embedded Controller operation region space access before the namespace has been evaluated." Spec also suggests a compatible mean to indicate the early EC access availability: Device (EC) { Name (REGC, Ones) Method (_REG, 2) { If (LEqual (Arg0, 3)) { Store (Arg1, REGC) } } Method (ECAV) { If (LEqual (REGC, Ones)) { If (LGreaterEqual (_REV, 2)) { Return (One) } Else { Return (Zero) } } Else { Return (REGC) } } } In this way, it allows EC accesses to happen before EC._REG(3, 1) is invoked. But ECAV is not the only way practical BIOSen using to indicate the early EC access availibility, the known variations include: 1. Setting REGC to One in \_SB._INI when _REV >= 2. Since \_SB._INI is the first control method evaluated by OSPM during the enumeration, this allows EC accesses to happen for the entire enumeration process before the namespace EC is enumerated. 2. Initialize REGC to One by default, this even allows EC accesses to happen during the table loading. Linux is now broken around ECDT support during the long term bug fixing work because it has merged many wrong ECDT bug fixes (see details below). Linux currently uses namespace EC's settings instead of ECDT settings when ECDT is detected. This apparently will result in namespace walk and _CRS/_GPE/_REG evaluations. Such stuffs could only happen after namespace is ready, while ECDT is purposely to be used before namespace is ready. The wrong bug fixing story is: 1. Link 1: At Linux ACPI early stages, "no _Lxx/_Exx/_Qxx evaluation can happen before the namespace is ready" are not ensured by ACPICA core and Linux. This is currently ensured by deferred enabling of GPE and defered registering of EC query methods (acpi_ec_register_query_methods). 2. Link 2: Reporters reported buggy ECDTs, expecting quirks for the platform. Originally, the quirk is simple, only doing things with ECDT. Bug 9399 and 12461 are platforms (Asus L4R, Asus M6R, MSI MS-171F) reported to have wrong ECDT IO port addresses, the port addresses are reversed. Bug 11880 is a platform (Asus X50GL) reported to have 0 valued port addresses, we can see that all EC accesses are protected by ECAV on this platform, so actually no early EC accesses is required by this platform. 3. Link 3: But when the bug fixing developer was requested to provide a handy and non-quirk bug fix, he tried to use correct EC settings from namespace and broke the spec purpose. We can even see that the developer was suffered from many regrssions. One interesting one is 14086, where the actual root cause obviously should be: _REG is evaluated too early. But unfortunately, the bug is fixed in a totally wrong way. So everything goes wrong from these commits: Commit: c6cb0e878446c79f42e7833d7bb69ed6bfbb381f Subject: ACPI: EC: Don't trust ECDT tables from ASUS Commit: a5032bfdd9c80e0231a6324661e123818eb46ecd Subject: ACPI: EC: Always parse EC device This patch reverts Linux behavior to simple ECDT quirk support in order to stop early _CRS/_GPE/_REG evaluations. For Bug 9399, 12461, since it is reported that the platforms require early EC accesses, this patch restores the simple ECDT quirks for them. For Bug 11880, since it is not reported that the platform requires early EC accesses and its ACPI tables contain correct ECAV, we choose an ECDT enumeration failure for this platform. Link 1: https://bugzilla.kernel.org/show_bug.cgi?id=9916 http://bugzilla.kernel.org/show_bug.cgi?id=10100 https://lkml.org/lkml/2008/2/25/282 Link 2: https://bugzilla.kernel.org/show_bug.cgi?id=9399 https://bugzilla.kernel.org/show_bug.cgi?id=12461 https://bugzilla.kernel.org/show_bug.cgi?id=11880 Link 3: https://bugzilla.kernel.org/show_bug.cgi?id=11884 https://bugzilla.kernel.org/show_bug.cgi?id=14081 https://bugzilla.kernel.org/show_bug.cgi?id=14086 https://bugzilla.kernel.org/show_bug.cgi?id=14446 Link 4: https://bugzilla.kernel.org/show_bug.cgi?id=112911 Signed-off-by: Lv Zheng <lv.zheng@intel.com> Tested-by: Chris Bainbridge <chris.bainbridge@gmail.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2016-03-24 10:42:53 +08:00
ACPI 2.0 / ECDT: Remove early namespace reference from EC All operation region accesses are allowed by AML interpreter when AML is executed, so actually BIOSen are responsible to avoid the operation region accesses in AML before OSPM has prepared an operation region driver. This is done via _REG control method. So AML code normally sets a global named object REGC to 1 when _REG(3, 1) is evaluated. Then what is ECDT? Quoting from ACPI spec 6.0, 5.2.15 Embedded Controller Boot Resources Table (ECDT): "The presence of this table allows OSPM to provide Embedded Controller operation region space access before the namespace has been evaluated." Spec also suggests a compatible mean to indicate the early EC access availability: Device (EC) { Name (REGC, Ones) Method (_REG, 2) { If (LEqual (Arg0, 3)) { Store (Arg1, REGC) } } Method (ECAV) { If (LEqual (REGC, Ones)) { If (LGreaterEqual (_REV, 2)) { Return (One) } Else { Return (Zero) } } Else { Return (REGC) } } } In this way, it allows EC accesses to happen before EC._REG(3, 1) is invoked. But ECAV is not the only way practical BIOSen using to indicate the early EC access availibility, the known variations include: 1. Setting REGC to One in \_SB._INI when _REV >= 2. Since \_SB._INI is the first control method evaluated by OSPM during the enumeration, this allows EC accesses to happen for the entire enumeration process before the namespace EC is enumerated. 2. Initialize REGC to One by default, this even allows EC accesses to happen during the table loading. Linux is now broken around ECDT support during the long term bug fixing work because it has merged many wrong ECDT bug fixes (see details below). Linux currently uses namespace EC's settings instead of ECDT settings when ECDT is detected. This apparently will result in namespace walk and _CRS/_GPE/_REG evaluations. Such stuffs could only happen after namespace is ready, while ECDT is purposely to be used before namespace is ready. The wrong bug fixing story is: 1. Link 1: At Linux ACPI early stages, "no _Lxx/_Exx/_Qxx evaluation can happen before the namespace is ready" are not ensured by ACPICA core and Linux. This is currently ensured by deferred enabling of GPE and defered registering of EC query methods (acpi_ec_register_query_methods). 2. Link 2: Reporters reported buggy ECDTs, expecting quirks for the platform. Originally, the quirk is simple, only doing things with ECDT. Bug 9399 and 12461 are platforms (Asus L4R, Asus M6R, MSI MS-171F) reported to have wrong ECDT IO port addresses, the port addresses are reversed. Bug 11880 is a platform (Asus X50GL) reported to have 0 valued port addresses, we can see that all EC accesses are protected by ECAV on this platform, so actually no early EC accesses is required by this platform. 3. Link 3: But when the bug fixing developer was requested to provide a handy and non-quirk bug fix, he tried to use correct EC settings from namespace and broke the spec purpose. We can even see that the developer was suffered from many regrssions. One interesting one is 14086, where the actual root cause obviously should be: _REG is evaluated too early. But unfortunately, the bug is fixed in a totally wrong way. So everything goes wrong from these commits: Commit: c6cb0e878446c79f42e7833d7bb69ed6bfbb381f Subject: ACPI: EC: Don't trust ECDT tables from ASUS Commit: a5032bfdd9c80e0231a6324661e123818eb46ecd Subject: ACPI: EC: Always parse EC device This patch reverts Linux behavior to simple ECDT quirk support in order to stop early _CRS/_GPE/_REG evaluations. For Bug 9399, 12461, since it is reported that the platforms require early EC accesses, this patch restores the simple ECDT quirks for them. For Bug 11880, since it is not reported that the platform requires early EC accesses and its ACPI tables contain correct ECAV, we choose an ECDT enumeration failure for this platform. Link 1: https://bugzilla.kernel.org/show_bug.cgi?id=9916 http://bugzilla.kernel.org/show_bug.cgi?id=10100 https://lkml.org/lkml/2008/2/25/282 Link 2: https://bugzilla.kernel.org/show_bug.cgi?id=9399 https://bugzilla.kernel.org/show_bug.cgi?id=12461 https://bugzilla.kernel.org/show_bug.cgi?id=11880 Link 3: https://bugzilla.kernel.org/show_bug.cgi?id=11884 https://bugzilla.kernel.org/show_bug.cgi?id=14081 https://bugzilla.kernel.org/show_bug.cgi?id=14086 https://bugzilla.kernel.org/show_bug.cgi?id=14446 Link 4: https://bugzilla.kernel.org/show_bug.cgi?id=112911 Signed-off-by: Lv Zheng <lv.zheng@intel.com> Tested-by: Chris Bainbridge <chris.bainbridge@gmail.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2016-03-24 10:42:53 +08:00
ACPI 2.0 / ECDT: Remove early namespace reference from EC All operation region accesses are allowed by AML interpreter when AML is executed, so actually BIOSen are responsible to avoid the operation region accesses in AML before OSPM has prepared an operation region driver. This is done via _REG control method. So AML code normally sets a global named object REGC to 1 when _REG(3, 1) is evaluated. Then what is ECDT? Quoting from ACPI spec 6.0, 5.2.15 Embedded Controller Boot Resources Table (ECDT): "The presence of this table allows OSPM to provide Embedded Controller operation region space access before the namespace has been evaluated." Spec also suggests a compatible mean to indicate the early EC access availability: Device (EC) { Name (REGC, Ones) Method (_REG, 2) { If (LEqual (Arg0, 3)) { Store (Arg1, REGC) } } Method (ECAV) { If (LEqual (REGC, Ones)) { If (LGreaterEqual (_REV, 2)) { Return (One) } Else { Return (Zero) } } Else { Return (REGC) } } } In this way, it allows EC accesses to happen before EC._REG(3, 1) is invoked. But ECAV is not the only way practical BIOSen using to indicate the early EC access availibility, the known variations include: 1. Setting REGC to One in \_SB._INI when _REV >= 2. Since \_SB._INI is the first control method evaluated by OSPM during the enumeration, this allows EC accesses to happen for the entire enumeration process before the namespace EC is enumerated. 2. Initialize REGC to One by default, this even allows EC accesses to happen during the table loading. Linux is now broken around ECDT support during the long term bug fixing work because it has merged many wrong ECDT bug fixes (see details below). Linux currently uses namespace EC's settings instead of ECDT settings when ECDT is detected. This apparently will result in namespace walk and _CRS/_GPE/_REG evaluations. Such stuffs could only happen after namespace is ready, while ECDT is purposely to be used before namespace is ready. The wrong bug fixing story is: 1. Link 1: At Linux ACPI early stages, "no _Lxx/_Exx/_Qxx evaluation can happen before the namespace is ready" are not ensured by ACPICA core and Linux. This is currently ensured by deferred enabling of GPE and defered registering of EC query methods (acpi_ec_register_query_methods). 2. Link 2: Reporters reported buggy ECDTs, expecting quirks for the platform. Originally, the quirk is simple, only doing things with ECDT. Bug 9399 and 12461 are platforms (Asus L4R, Asus M6R, MSI MS-171F) reported to have wrong ECDT IO port addresses, the port addresses are reversed. Bug 11880 is a platform (Asus X50GL) reported to have 0 valued port addresses, we can see that all EC accesses are protected by ECAV on this platform, so actually no early EC accesses is required by this platform. 3. Link 3: But when the bug fixing developer was requested to provide a handy and non-quirk bug fix, he tried to use correct EC settings from namespace and broke the spec purpose. We can even see that the developer was suffered from many regrssions. One interesting one is 14086, where the actual root cause obviously should be: _REG is evaluated too early. But unfortunately, the bug is fixed in a totally wrong way. So everything goes wrong from these commits: Commit: c6cb0e878446c79f42e7833d7bb69ed6bfbb381f Subject: ACPI: EC: Don't trust ECDT tables from ASUS Commit: a5032bfdd9c80e0231a6324661e123818eb46ecd Subject: ACPI: EC: Always parse EC device This patch reverts Linux behavior to simple ECDT quirk support in order to stop early _CRS/_GPE/_REG evaluations. For Bug 9399, 12461, since it is reported that the platforms require early EC accesses, this patch restores the simple ECDT quirks for them. For Bug 11880, since it is not reported that the platform requires early EC accesses and its ACPI tables contain correct ECAV, we choose an ECDT enumeration failure for this platform. Link 1: https://bugzilla.kernel.org/show_bug.cgi?id=9916 http://bugzilla.kernel.org/show_bug.cgi?id=10100 https://lkml.org/lkml/2008/2/25/282 Link 2: https://bugzilla.kernel.org/show_bug.cgi?id=9399 https://bugzilla.kernel.org/show_bug.cgi?id=12461 https://bugzilla.kernel.org/show_bug.cgi?id=11880 Link 3: https://bugzilla.kernel.org/show_bug.cgi?id=11884 https://bugzilla.kernel.org/show_bug.cgi?id=14081 https://bugzilla.kernel.org/show_bug.cgi?id=14086 https://bugzilla.kernel.org/show_bug.cgi?id=14446 Link 4: https://bugzilla.kernel.org/show_bug.cgi?id=112911 Signed-off-by: Lv Zheng <lv.zheng@intel.com> Tested-by: Chris Bainbridge <chris.bainbridge@gmail.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2016-03-24 10:42:53 +08:00
ACPI 2.0 / ECDT: Remove early namespace reference from EC All operation region accesses are allowed by AML interpreter when AML is executed, so actually BIOSen are responsible to avoid the operation region accesses in AML before OSPM has prepared an operation region driver. This is done via _REG control method. So AML code normally sets a global named object REGC to 1 when _REG(3, 1) is evaluated. Then what is ECDT? Quoting from ACPI spec 6.0, 5.2.15 Embedded Controller Boot Resources Table (ECDT): "The presence of this table allows OSPM to provide Embedded Controller operation region space access before the namespace has been evaluated." Spec also suggests a compatible mean to indicate the early EC access availability: Device (EC) { Name (REGC, Ones) Method (_REG, 2) { If (LEqual (Arg0, 3)) { Store (Arg1, REGC) } } Method (ECAV) { If (LEqual (REGC, Ones)) { If (LGreaterEqual (_REV, 2)) { Return (One) } Else { Return (Zero) } } Else { Return (REGC) } } } In this way, it allows EC accesses to happen before EC._REG(3, 1) is invoked. But ECAV is not the only way practical BIOSen using to indicate the early EC access availibility, the known variations include: 1. Setting REGC to One in \_SB._INI when _REV >= 2. Since \_SB._INI is the first control method evaluated by OSPM during the enumeration, this allows EC accesses to happen for the entire enumeration process before the namespace EC is enumerated. 2. Initialize REGC to One by default, this even allows EC accesses to happen during the table loading. Linux is now broken around ECDT support during the long term bug fixing work because it has merged many wrong ECDT bug fixes (see details below). Linux currently uses namespace EC's settings instead of ECDT settings when ECDT is detected. This apparently will result in namespace walk and _CRS/_GPE/_REG evaluations. Such stuffs could only happen after namespace is ready, while ECDT is purposely to be used before namespace is ready. The wrong bug fixing story is: 1. Link 1: At Linux ACPI early stages, "no _Lxx/_Exx/_Qxx evaluation can happen before the namespace is ready" are not ensured by ACPICA core and Linux. This is currently ensured by deferred enabling of GPE and defered registering of EC query methods (acpi_ec_register_query_methods). 2. Link 2: Reporters reported buggy ECDTs, expecting quirks for the platform. Originally, the quirk is simple, only doing things with ECDT. Bug 9399 and 12461 are platforms (Asus L4R, Asus M6R, MSI MS-171F) reported to have wrong ECDT IO port addresses, the port addresses are reversed. Bug 11880 is a platform (Asus X50GL) reported to have 0 valued port addresses, we can see that all EC accesses are protected by ECAV on this platform, so actually no early EC accesses is required by this platform. 3. Link 3: But when the bug fixing developer was requested to provide a handy and non-quirk bug fix, he tried to use correct EC settings from namespace and broke the spec purpose. We can even see that the developer was suffered from many regrssions. One interesting one is 14086, where the actual root cause obviously should be: _REG is evaluated too early. But unfortunately, the bug is fixed in a totally wrong way. So everything goes wrong from these commits: Commit: c6cb0e878446c79f42e7833d7bb69ed6bfbb381f Subject: ACPI: EC: Don't trust ECDT tables from ASUS Commit: a5032bfdd9c80e0231a6324661e123818eb46ecd Subject: ACPI: EC: Always parse EC device This patch reverts Linux behavior to simple ECDT quirk support in order to stop early _CRS/_GPE/_REG evaluations. For Bug 9399, 12461, since it is reported that the platforms require early EC accesses, this patch restores the simple ECDT quirks for them. For Bug 11880, since it is not reported that the platform requires early EC accesses and its ACPI tables contain correct ECAV, we choose an ECDT enumeration failure for this platform. Link 1: https://bugzilla.kernel.org/show_bug.cgi?id=9916 http://bugzilla.kernel.org/show_bug.cgi?id=10100 https://lkml.org/lkml/2008/2/25/282 Link 2: https://bugzilla.kernel.org/show_bug.cgi?id=9399 https://bugzilla.kernel.org/show_bug.cgi?id=12461 https://bugzilla.kernel.org/show_bug.cgi?id=11880 Link 3: https://bugzilla.kernel.org/show_bug.cgi?id=11884 https://bugzilla.kernel.org/show_bug.cgi?id=14081 https://bugzilla.kernel.org/show_bug.cgi?id=14086 https://bugzilla.kernel.org/show_bug.cgi?id=14446 Link 4: https://bugzilla.kernel.org/show_bug.cgi?id=112911 Signed-off-by: Lv Zheng <lv.zheng@intel.com> Tested-by: Chris Bainbridge <chris.bainbridge@gmail.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2016-03-24 10:42:53 +08:00
ACPI 2.0 / ECDT: Remove early namespace reference from EC All operation region accesses are allowed by AML interpreter when AML is executed, so actually BIOSen are responsible to avoid the operation region accesses in AML before OSPM has prepared an operation region driver. This is done via _REG control method. So AML code normally sets a global named object REGC to 1 when _REG(3, 1) is evaluated. Then what is ECDT? Quoting from ACPI spec 6.0, 5.2.15 Embedded Controller Boot Resources Table (ECDT): "The presence of this table allows OSPM to provide Embedded Controller operation region space access before the namespace has been evaluated." Spec also suggests a compatible mean to indicate the early EC access availability: Device (EC) { Name (REGC, Ones) Method (_REG, 2) { If (LEqual (Arg0, 3)) { Store (Arg1, REGC) } } Method (ECAV) { If (LEqual (REGC, Ones)) { If (LGreaterEqual (_REV, 2)) { Return (One) } Else { Return (Zero) } } Else { Return (REGC) } } } In this way, it allows EC accesses to happen before EC._REG(3, 1) is invoked. But ECAV is not the only way practical BIOSen using to indicate the early EC access availibility, the known variations include: 1. Setting REGC to One in \_SB._INI when _REV >= 2. Since \_SB._INI is the first control method evaluated by OSPM during the enumeration, this allows EC accesses to happen for the entire enumeration process before the namespace EC is enumerated. 2. Initialize REGC to One by default, this even allows EC accesses to happen during the table loading. Linux is now broken around ECDT support during the long term bug fixing work because it has merged many wrong ECDT bug fixes (see details below). Linux currently uses namespace EC's settings instead of ECDT settings when ECDT is detected. This apparently will result in namespace walk and _CRS/_GPE/_REG evaluations. Such stuffs could only happen after namespace is ready, while ECDT is purposely to be used before namespace is ready. The wrong bug fixing story is: 1. Link 1: At Linux ACPI early stages, "no _Lxx/_Exx/_Qxx evaluation can happen before the namespace is ready" are not ensured by ACPICA core and Linux. This is currently ensured by deferred enabling of GPE and defered registering of EC query methods (acpi_ec_register_query_methods). 2. Link 2: Reporters reported buggy ECDTs, expecting quirks for the platform. Originally, the quirk is simple, only doing things with ECDT. Bug 9399 and 12461 are platforms (Asus L4R, Asus M6R, MSI MS-171F) reported to have wrong ECDT IO port addresses, the port addresses are reversed. Bug 11880 is a platform (Asus X50GL) reported to have 0 valued port addresses, we can see that all EC accesses are protected by ECAV on this platform, so actually no early EC accesses is required by this platform. 3. Link 3: But when the bug fixing developer was requested to provide a handy and non-quirk bug fix, he tried to use correct EC settings from namespace and broke the spec purpose. We can even see that the developer was suffered from many regrssions. One interesting one is 14086, where the actual root cause obviously should be: _REG is evaluated too early. But unfortunately, the bug is fixed in a totally wrong way. So everything goes wrong from these commits: Commit: c6cb0e878446c79f42e7833d7bb69ed6bfbb381f Subject: ACPI: EC: Don't trust ECDT tables from ASUS Commit: a5032bfdd9c80e0231a6324661e123818eb46ecd Subject: ACPI: EC: Always parse EC device This patch reverts Linux behavior to simple ECDT quirk support in order to stop early _CRS/_GPE/_REG evaluations. For Bug 9399, 12461, since it is reported that the platforms require early EC accesses, this patch restores the simple ECDT quirks for them. For Bug 11880, since it is not reported that the platform requires early EC accesses and its ACPI tables contain correct ECAV, we choose an ECDT enumeration failure for this platform. Link 1: https://bugzilla.kernel.org/show_bug.cgi?id=9916 http://bugzilla.kernel.org/show_bug.cgi?id=10100 https://lkml.org/lkml/2008/2/25/282 Link 2: https://bugzilla.kernel.org/show_bug.cgi?id=9399 https://bugzilla.kernel.org/show_bug.cgi?id=12461 https://bugzilla.kernel.org/show_bug.cgi?id=11880 Link 3: https://bugzilla.kernel.org/show_bug.cgi?id=11884 https://bugzilla.kernel.org/show_bug.cgi?id=14081 https://bugzilla.kernel.org/show_bug.cgi?id=14086 https://bugzilla.kernel.org/show_bug.cgi?id=14446 Link 4: https://bugzilla.kernel.org/show_bug.cgi?id=112911 Signed-off-by: Lv Zheng <lv.zheng@intel.com> Tested-by: Chris Bainbridge <chris.bainbridge@gmail.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2016-03-24 10:42:53 +08:00
ACPI: EC: Fix ECDT probe ordering issues ACPI-2.0 says that the EC OpRegion handler must be available immediately (like the standard default OpRegion handlers): Quoting from the ACPI spec version 6.3: "6.5.4 _REG (Region) ... 2. OSPM must make Embedded Controller operation regions, accessed via the Embedded Controllers described in ECDT, available before executing any control method. These operation regions may become inaccessible after OSPM runs _REG(EmbeddedControl, 0)." So acpi_bus_init() calls acpi_ec_ecdt_probe(), which calls acpi_install_address_space_handler() to install the EC's OpRegion handler, early on. This not only installs the OpRegion handler, but also calls the EC's _REG method. The _REG method call is a problem because it may rely on initialization done by the _INI methods of one of the PCI / _SB root devs, see for example: https://bugzilla.kernel.org/show_bug.cgi?id=214899 . Generally speaking _REG methods are executed when the ACPI-device they are part of has a driver bound to it. Where as _INI methods must be executed at table load time (according to the spec). The problem here is that the early acpi_install_address_space_handler() call causes the _REG handler to run too early. To allow fixing this the ACPICA code now allows to split the OpRegion handler installation and the executing of _REG into 2 separate steps. This commit uses this ACPICA functionality to fix the EC probe ordering by delaying the executing of _REG for ECDT described ECs till the matching EC device in the DSDT gets parsed and acpi_ec_add() for it gets called. This moves the calling of _REG for the EC on devices with an ECDT to the same point in time where it is called on devices without an ECDT table. BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=214899 Reported-and-tested-by: Johannes Penßel <johannespenssel@posteo.net> Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2022-12-08 15:23:35 +01:00
ACPI / EC: Add PM operations to improve event handling for suspend process In the original EC driver, though the event handling is not explicitly stopped, the EC driver is actually not able to handle events during the noirq stage as the EC driver is not prepared to handle the EC events in the polling mode. So if there is no advance_transaction() triggered, the EC driver couldn't notice the EC events. However, do we actually need to handle EC events during suspend/resume stage? EC events are mostly useless for the suspend/resume period (key strokes and battery/thermal updates, etc.,), and the useful ones (lid close, power/sleep button press) should have already been delivered to the OSPM to trigger the power saving operations. Thus this patch implements acpi_ec_disable_event() to be a reverse call of acpi_ec_enable_event(), with which, the EC driver is able to stop handling the EC events in a position before entering the noirq stage. Since there are actually 2 choices for us: 1. implement event handling in polling mode; 2. stop event handling before entering noirq stage. And this patch only implements the second choice using .suspend() callback. Thus this is experimental (first choice is better? or different hook position is better?). This patch finally keeps the old behavior by default and prepares a boot parameter to enable this feature. The differences of the event handling availability between the old behavior (this patch is not applied) and the new behavior (this patch is applied) are as follows: !FreezeEvents FreezeEvents before suspend Y Y suspend before EC Y Y suspend after EC Y N suspend_late Y N suspend_noirq Y (actually N) N resume_noirq Y (actually N) N resume_late Y (actually N) N resume before EC Y (actually N) N resume after EC Y Y after resume Y Y Where "actually N" means if there is no EC transactions, the EC driver is actually not able to notice the pending events. We can see that FreezeEvents is the only approach now can actually flush the EC event handling with both query commands and _Qxx evaluations flushed, other modes can only flush the EC event handling with only query commands flushed, _Qxx evaluations occurred after stopping the EC driver may end up failure due to the failure of the EC transaction carried out in the _Qxx control methods. We also can see that this feature should be able to trigger some platform notifications later than resuming other drivers. Signed-off-by: Lv Zheng <lv.zheng@intel.com> Tested-by: Todd E Brandt <todd.e.brandt@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2016-08-03 16:01:43 +08:00
ACPI / EC: Add PM operations to improve event handling for suspend process In the original EC driver, though the event handling is not explicitly stopped, the EC driver is actually not able to handle events during the noirq stage as the EC driver is not prepared to handle the EC events in the polling mode. So if there is no advance_transaction() triggered, the EC driver couldn't notice the EC events. However, do we actually need to handle EC events during suspend/resume stage? EC events are mostly useless for the suspend/resume period (key strokes and battery/thermal updates, etc.,), and the useful ones (lid close, power/sleep button press) should have already been delivered to the OSPM to trigger the power saving operations. Thus this patch implements acpi_ec_disable_event() to be a reverse call of acpi_ec_enable_event(), with which, the EC driver is able to stop handling the EC events in a position before entering the noirq stage. Since there are actually 2 choices for us: 1. implement event handling in polling mode; 2. stop event handling before entering noirq stage. And this patch only implements the second choice using .suspend() callback. Thus this is experimental (first choice is better? or different hook position is better?). This patch finally keeps the old behavior by default and prepares a boot parameter to enable this feature. The differences of the event handling availability between the old behavior (this patch is not applied) and the new behavior (this patch is applied) are as follows: !FreezeEvents FreezeEvents before suspend Y Y suspend before EC Y Y suspend after EC Y N suspend_late Y N suspend_noirq Y (actually N) N resume_noirq Y (actually N) N resume_late Y (actually N) N resume before EC Y (actually N) N resume after EC Y Y after resume Y Y Where "actually N" means if there is no EC transactions, the EC driver is actually not able to notice the pending events. We can see that FreezeEvents is the only approach now can actually flush the EC event handling with both query commands and _Qxx evaluations flushed, other modes can only flush the EC event handling with only query commands flushed, _Qxx evaluations occurred after stopping the EC driver may end up failure due to the failure of the EC transaction carried out in the _Qxx control methods. We also can see that this feature should be able to trigger some platform notifications later than resuming other drivers. Signed-off-by: Lv Zheng <lv.zheng@intel.com> Tested-by: Todd E Brandt <todd.e.brandt@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2016-08-03 16:01:43 +08:00
ACPI / EC: Add PM operations to improve event handling for suspend process In the original EC driver, though the event handling is not explicitly stopped, the EC driver is actually not able to handle events during the noirq stage as the EC driver is not prepared to handle the EC events in the polling mode. So if there is no advance_transaction() triggered, the EC driver couldn't notice the EC events. However, do we actually need to handle EC events during suspend/resume stage? EC events are mostly useless for the suspend/resume period (key strokes and battery/thermal updates, etc.,), and the useful ones (lid close, power/sleep button press) should have already been delivered to the OSPM to trigger the power saving operations. Thus this patch implements acpi_ec_disable_event() to be a reverse call of acpi_ec_enable_event(), with which, the EC driver is able to stop handling the EC events in a position before entering the noirq stage. Since there are actually 2 choices for us: 1. implement event handling in polling mode; 2. stop event handling before entering noirq stage. And this patch only implements the second choice using .suspend() callback. Thus this is experimental (first choice is better? or different hook position is better?). This patch finally keeps the old behavior by default and prepares a boot parameter to enable this feature. The differences of the event handling availability between the old behavior (this patch is not applied) and the new behavior (this patch is applied) are as follows: !FreezeEvents FreezeEvents before suspend Y Y suspend before EC Y Y suspend after EC Y N suspend_late Y N suspend_noirq Y (actually N) N resume_noirq Y (actually N) N resume_late Y (actually N) N resume before EC Y (actually N) N resume after EC Y Y after resume Y Y Where "actually N" means if there is no EC transactions, the EC driver is actually not able to notice the pending events. We can see that FreezeEvents is the only approach now can actually flush the EC event handling with both query commands and _Qxx evaluations flushed, other modes can only flush the EC event handling with only query commands flushed, _Qxx evaluations occurred after stopping the EC driver may end up failure due to the failure of the EC transaction carried out in the _Qxx control methods. We also can see that this feature should be able to trigger some platform notifications later than resuming other drivers. Signed-off-by: Lv Zheng <lv.zheng@intel.com> Tested-by: Todd E Brandt <todd.e.brandt@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2016-08-03 16:01:43 +08:00
ACPI / EC: Add PM operations to improve event handling for resume process This patch makes 2 changes: 1. Restore old behavior Originally, EC driver stops handling both events and transactions in acpi_ec_block_transactions(), and restarts to handle transactions in acpi_ec_unblock_transactions_early(), restarts to handle both events and transactions in acpi_ec_unblock_transactions(). While currently, EC driver still stops handling both events and transactions in acpi_ec_block_transactions(), but restarts to handle both events and transactions in acpi_ec_unblock_transactions_early(). This patch tries to restore the old behavior by dropping __acpi_ec_enable_event() from acpi_unblock_transactions_early(). 2. Improve old behavior However this still cannot fix the real issue as both of the acpi_ec_unblock_xxx() functions are invoked in the noirq stage. Since the EC driver actually doesn't implement the event handling in the polling mode, re-enabling the event handling too early in the noirq stage could result in the problem that if there is no triggering source causing advance_transaction() to be invoked, pending SCI_EVT cannot be detected by the EC driver and _Qxx cannot be triggered. It actually makes sense to restart the event handling in any point during resuming after the noirq stage. Just like the boot stage where the event handling is enabled in .add(), this patch further moves acpi_ec_enable_event() to .resume(). After doing that, the following 2 functions can be combined: acpi_ec_unblock_transactions_early()/acpi_ec_unblock_transactions(). The differences of the event handling availability between the old behavior (this patch isn't applied) and the new behavior (this patch is applied) are as follows: !Applied Applied before suspend Y Y suspend before EC Y Y suspend after EC Y Y suspend_late Y Y suspend_noirq Y (actually N) Y (actually N) resume_noirq Y (actually N) Y (actually N) resume_late Y (actually N) Y (actually N) resume before EC Y (actually N) Y (actually N) resume after EC Y (actually N) Y after resume Y (actually N) Y Where "actually N" means if there is no triggering source, the EC driver is actually not able to notice the pending SCI_EVT occurred in the noirq stage. So we can clearly see that this patch has improved the situation. Signed-off-by: Lv Zheng <lv.zheng@intel.com> Tested-by: Todd E Brandt <todd.e.brandt@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2016-08-03 16:01:36 +08:00
ACPI / EC: Add PM operations to improve event handling for resume process This patch makes 2 changes: 1. Restore old behavior Originally, EC driver stops handling both events and transactions in acpi_ec_block_transactions(), and restarts to handle transactions in acpi_ec_unblock_transactions_early(), restarts to handle both events and transactions in acpi_ec_unblock_transactions(). While currently, EC driver still stops handling both events and transactions in acpi_ec_block_transactions(), but restarts to handle both events and transactions in acpi_ec_unblock_transactions_early(). This patch tries to restore the old behavior by dropping __acpi_ec_enable_event() from acpi_unblock_transactions_early(). 2. Improve old behavior However this still cannot fix the real issue as both of the acpi_ec_unblock_xxx() functions are invoked in the noirq stage. Since the EC driver actually doesn't implement the event handling in the polling mode, re-enabling the event handling too early in the noirq stage could result in the problem that if there is no triggering source causing advance_transaction() to be invoked, pending SCI_EVT cannot be detected by the EC driver and _Qxx cannot be triggered. It actually makes sense to restart the event handling in any point during resuming after the noirq stage. Just like the boot stage where the event handling is enabled in .add(), this patch further moves acpi_ec_enable_event() to .resume(). After doing that, the following 2 functions can be combined: acpi_ec_unblock_transactions_early()/acpi_ec_unblock_transactions(). The differences of the event handling availability between the old behavior (this patch isn't applied) and the new behavior (this patch is applied) are as follows: !Applied Applied before suspend Y Y suspend before EC Y Y suspend after EC Y Y suspend_late Y Y suspend_noirq Y (actually N) Y (actually N) resume_noirq Y (actually N) Y (actually N) resume_late Y (actually N) Y (actually N) resume before EC Y (actually N) Y (actually N) resume after EC Y (actually N) Y after resume Y (actually N) Y Where "actually N" means if there is no triggering source, the EC driver is actually not able to notice the pending SCI_EVT occurred in the noirq stage. So we can clearly see that this patch has improved the situation. Signed-off-by: Lv Zheng <lv.zheng@intel.com> Tested-by: Todd E Brandt <todd.e.brandt@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2016-08-03 16:01:36 +08:00
ACPI: EC: PM: Avoid premature returns from acpi_s2idle_wake() If the EC GPE status is not set after checking all of the other GPEs, acpi_s2idle_wake() returns 'false', to indicate that the SCI event that has just triggered is not a system wakeup one, but it does that without canceling the pending wakeup and re-arming the SCI for system wakeup which is a mistake, because it may cause s2idle_loop() to busy spin until the next valid wakeup event. [If that happens, the first spurious wakeup is still pending after acpi_s2idle_wake() has returned, so s2idle_enter() does nothing, acpi_s2idle_wake() is called again and it sees that the SCI has triggered, but no GPEs are active, so 'false' is returned again, and so on.] Fix that by moving all of the GPE checking logic from acpi_s2idle_wake() to acpi_ec_dispatch_gpe() and making the latter return 'true' only if a non-EC GPE has triggered and 'false' otherwise, which will cause acpi_s2idle_wake() to cancel the pending SCI wakeup and re-arm the SCI for system wakeup regardless of the EC GPE status. This also addresses a lockup observed on an Elitegroup EF20EA laptop after attempting to wake it up from suspend-to-idle by a key press. Fixes: d5406284ff80 ("ACPI: PM: s2idle: Refine active GPEs check") Link: https://bugzilla.kernel.org/show_bug.cgi?id=207603 Reported-by: Todd Brandt <todd.e.brandt@linux.intel.com> Fixes: fdde0ff8590b ("ACPI: PM: s2idle: Prevent spurious SCIs from waking up the system") Link: https://lore.kernel.org/linux-acpi/CAB4CAwdqo7=MvyG_PE+PGVfeA17AHF5i5JucgaKqqMX6mjArbQ@mail.gmail.com/ Reported-by: Chris Chiu <chiu@endlessm.com> Tested-by: Chris Chiu <chiu@endlessm.com> Cc: 5.4+ <stable@vger.kernel.org> # 5.4+ Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2020-05-09 10:44:41 +02:00
ACPI: EC: PM: Avoid premature returns from acpi_s2idle_wake() If the EC GPE status is not set after checking all of the other GPEs, acpi_s2idle_wake() returns 'false', to indicate that the SCI event that has just triggered is not a system wakeup one, but it does that without canceling the pending wakeup and re-arming the SCI for system wakeup which is a mistake, because it may cause s2idle_loop() to busy spin until the next valid wakeup event. [If that happens, the first spurious wakeup is still pending after acpi_s2idle_wake() has returned, so s2idle_enter() does nothing, acpi_s2idle_wake() is called again and it sees that the SCI has triggered, but no GPEs are active, so 'false' is returned again, and so on.] Fix that by moving all of the GPE checking logic from acpi_s2idle_wake() to acpi_ec_dispatch_gpe() and making the latter return 'true' only if a non-EC GPE has triggered and 'false' otherwise, which will cause acpi_s2idle_wake() to cancel the pending SCI wakeup and re-arm the SCI for system wakeup regardless of the EC GPE status. This also addresses a lockup observed on an Elitegroup EF20EA laptop after attempting to wake it up from suspend-to-idle by a key press. Fixes: d5406284ff80 ("ACPI: PM: s2idle: Refine active GPEs check") Link: https://bugzilla.kernel.org/show_bug.cgi?id=207603 Reported-by: Todd Brandt <todd.e.brandt@linux.intel.com> Fixes: fdde0ff8590b ("ACPI: PM: s2idle: Prevent spurious SCIs from waking up the system") Link: https://lore.kernel.org/linux-acpi/CAB4CAwdqo7=MvyG_PE+PGVfeA17AHF5i5JucgaKqqMX6mjArbQ@mail.gmail.com/ Reported-by: Chris Chiu <chiu@endlessm.com> Tested-by: Chris Chiu <chiu@endlessm.com> Cc: 5.4+ <stable@vger.kernel.org> # 5.4+ Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2020-05-09 10:44:41 +02:00
ACPI: EC: PM: Avoid premature returns from acpi_s2idle_wake() If the EC GPE status is not set after checking all of the other GPEs, acpi_s2idle_wake() returns 'false', to indicate that the SCI event that has just triggered is not a system wakeup one, but it does that without canceling the pending wakeup and re-arming the SCI for system wakeup which is a mistake, because it may cause s2idle_loop() to busy spin until the next valid wakeup event. [If that happens, the first spurious wakeup is still pending after acpi_s2idle_wake() has returned, so s2idle_enter() does nothing, acpi_s2idle_wake() is called again and it sees that the SCI has triggered, but no GPEs are active, so 'false' is returned again, and so on.] Fix that by moving all of the GPE checking logic from acpi_s2idle_wake() to acpi_ec_dispatch_gpe() and making the latter return 'true' only if a non-EC GPE has triggered and 'false' otherwise, which will cause acpi_s2idle_wake() to cancel the pending SCI wakeup and re-arm the SCI for system wakeup regardless of the EC GPE status. This also addresses a lockup observed on an Elitegroup EF20EA laptop after attempting to wake it up from suspend-to-idle by a key press. Fixes: d5406284ff80 ("ACPI: PM: s2idle: Refine active GPEs check") Link: https://bugzilla.kernel.org/show_bug.cgi?id=207603 Reported-by: Todd Brandt <todd.e.brandt@linux.intel.com> Fixes: fdde0ff8590b ("ACPI: PM: s2idle: Prevent spurious SCIs from waking up the system") Link: https://lore.kernel.org/linux-acpi/CAB4CAwdqo7=MvyG_PE+PGVfeA17AHF5i5JucgaKqqMX6mjArbQ@mail.gmail.com/ Reported-by: Chris Chiu <chiu@endlessm.com> Tested-by: Chris Chiu <chiu@endlessm.com> Cc: 5.4+ <stable@vger.kernel.org> # 5.4+ Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2020-05-09 10:44:41 +02:00
ACPI: EC: Rework flushing of EC work while suspended to idle The flushing of pending work in the EC driver uses drain_workqueue() to flush the event handling work that can requeue itself via advance_transaction(), but this is problematic, because that work may also be requeued from the query workqueue. Namely, if an EC transaction is carried out during the execution of a query handler, it involves calling advance_transaction() which may queue up the event handling work again. This causes the kernel to complain about attempts to add a work item to the EC event workqueue while it is being drained and worst-case it may cause a valid event to be skipped. To avoid this problem, introduce two new counters, events_in_progress and queries_in_progress, incremented when a work item is queued on the event workqueue or the query workqueue, respectively, and decremented at the end of the corresponding work function, and make acpi_ec_dispatch_gpe() the workqueues in a loop until the both of these counters are zero (or system wakeup is pending) instead of calling acpi_ec_flush_work(). At the same time, change __acpi_ec_flush_work() to call flush_workqueue() instead of drain_workqueue() to flush the event workqueue. While at it, use the observation that the work item queued in acpi_ec_query() cannot be pending at that time, because it is used only once, to simplify the code in there. Additionally, clean up a comment in acpi_ec_query() and adjust white space in acpi_ec_event_processor(). Fixes: f0ac20c3f613 ("ACPI: EC: Fix flushing of pending work") Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-11-23 19:36:51 +01:00
ACPI: EC: Rework flushing of EC work while suspended to idle The flushing of pending work in the EC driver uses drain_workqueue() to flush the event handling work that can requeue itself via advance_transaction(), but this is problematic, because that work may also be requeued from the query workqueue. Namely, if an EC transaction is carried out during the execution of a query handler, it involves calling advance_transaction() which may queue up the event handling work again. This causes the kernel to complain about attempts to add a work item to the EC event workqueue while it is being drained and worst-case it may cause a valid event to be skipped. To avoid this problem, introduce two new counters, events_in_progress and queries_in_progress, incremented when a work item is queued on the event workqueue or the query workqueue, respectively, and decremented at the end of the corresponding work function, and make acpi_ec_dispatch_gpe() the workqueues in a loop until the both of these counters are zero (or system wakeup is pending) instead of calling acpi_ec_flush_work(). At the same time, change __acpi_ec_flush_work() to call flush_workqueue() instead of drain_workqueue() to flush the event workqueue. While at it, use the observation that the work item queued in acpi_ec_query() cannot be pending at that time, because it is used only once, to simplify the code in there. Additionally, clean up a comment in acpi_ec_query() and adjust white space in acpi_ec_event_processor(). Fixes: f0ac20c3f613 ("ACPI: EC: Fix flushing of pending work") Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-11-23 19:36:51 +01:00
ACPI: EC: Rework flushing of EC work while suspended to idle The flushing of pending work in the EC driver uses drain_workqueue() to flush the event handling work that can requeue itself via advance_transaction(), but this is problematic, because that work may also be requeued from the query workqueue. Namely, if an EC transaction is carried out during the execution of a query handler, it involves calling advance_transaction() which may queue up the event handling work again. This causes the kernel to complain about attempts to add a work item to the EC event workqueue while it is being drained and worst-case it may cause a valid event to be skipped. To avoid this problem, introduce two new counters, events_in_progress and queries_in_progress, incremented when a work item is queued on the event workqueue or the query workqueue, respectively, and decremented at the end of the corresponding work function, and make acpi_ec_dispatch_gpe() the workqueues in a loop until the both of these counters are zero (or system wakeup is pending) instead of calling acpi_ec_flush_work(). At the same time, change __acpi_ec_flush_work() to call flush_workqueue() instead of drain_workqueue() to flush the event workqueue. While at it, use the observation that the work item queued in acpi_ec_query() cannot be pending at that time, because it is used only once, to simplify the code in there. Additionally, clean up a comment in acpi_ec_query() and adjust white space in acpi_ec_event_processor(). Fixes: f0ac20c3f613 ("ACPI: EC: Fix flushing of pending work") Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-11-23 19:36:51 +01:00
ACPI: EC: Rework flushing of EC work while suspended to idle The flushing of pending work in the EC driver uses drain_workqueue() to flush the event handling work that can requeue itself via advance_transaction(), but this is problematic, because that work may also be requeued from the query workqueue. Namely, if an EC transaction is carried out during the execution of a query handler, it involves calling advance_transaction() which may queue up the event handling work again. This causes the kernel to complain about attempts to add a work item to the EC event workqueue while it is being drained and worst-case it may cause a valid event to be skipped. To avoid this problem, introduce two new counters, events_in_progress and queries_in_progress, incremented when a work item is queued on the event workqueue or the query workqueue, respectively, and decremented at the end of the corresponding work function, and make acpi_ec_dispatch_gpe() the workqueues in a loop until the both of these counters are zero (or system wakeup is pending) instead of calling acpi_ec_flush_work(). At the same time, change __acpi_ec_flush_work() to call flush_workqueue() instead of drain_workqueue() to flush the event workqueue. While at it, use the observation that the work item queued in acpi_ec_query() cannot be pending at that time, because it is used only once, to simplify the code in there. Additionally, clean up a comment in acpi_ec_query() and adjust white space in acpi_ec_event_processor(). Fixes: f0ac20c3f613 ("ACPI: EC: Fix flushing of pending work") Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-11-23 19:36:51 +01:00
ACPI / EC: Add PM operations to improve event handling for suspend process In the original EC driver, though the event handling is not explicitly stopped, the EC driver is actually not able to handle events during the noirq stage as the EC driver is not prepared to handle the EC events in the polling mode. So if there is no advance_transaction() triggered, the EC driver couldn't notice the EC events. However, do we actually need to handle EC events during suspend/resume stage? EC events are mostly useless for the suspend/resume period (key strokes and battery/thermal updates, etc.,), and the useful ones (lid close, power/sleep button press) should have already been delivered to the OSPM to trigger the power saving operations. Thus this patch implements acpi_ec_disable_event() to be a reverse call of acpi_ec_enable_event(), with which, the EC driver is able to stop handling the EC events in a position before entering the noirq stage. Since there are actually 2 choices for us: 1. implement event handling in polling mode; 2. stop event handling before entering noirq stage. And this patch only implements the second choice using .suspend() callback. Thus this is experimental (first choice is better? or different hook position is better?). This patch finally keeps the old behavior by default and prepares a boot parameter to enable this feature. The differences of the event handling availability between the old behavior (this patch is not applied) and the new behavior (this patch is applied) are as follows: !FreezeEvents FreezeEvents before suspend Y Y suspend before EC Y Y suspend after EC Y N suspend_late Y N suspend_noirq Y (actually N) N resume_noirq Y (actually N) N resume_late Y (actually N) N resume before EC Y (actually N) N resume after EC Y Y after resume Y Y Where "actually N" means if there is no EC transactions, the EC driver is actually not able to notice the pending events. We can see that FreezeEvents is the only approach now can actually flush the EC event handling with both query commands and _Qxx evaluations flushed, other modes can only flush the EC event handling with only query commands flushed, _Qxx evaluations occurred after stopping the EC driver may end up failure due to the failure of the EC transaction carried out in the _Qxx control methods. We also can see that this feature should be able to trigger some platform notifications later than resuming other drivers. Signed-off-by: Lv Zheng <lv.zheng@intel.com> Tested-by: Todd E Brandt <todd.e.brandt@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2016-08-03 16:01:43 +08:00
ACPI / EC: Add event clearing variation support. We've been suffering from the uncertainty of the SCI_EVT clearing timing. This patch implements 3 of 4 possible modes to handle SCI_EVT clearing variations. The old behavior is kept in this patch. Status: QR_EC is re-checked as early as possible after checking previous SCI_EVT. This always leads to 2 QR_EC transactions per SCI_EVT indication and the target may implement event queue which returns 0x00 indicating "no outstanding event". This is proven to be a conflict against Windows behavior, but is still kept in this patch to make the EC driver robust to the possible regressions that may occur on Samsung platforms. Query: QR_EC is re-checked after the target has handled the QR_EC query request command pushed by the host. Event: QR_EC is re-checked after the target has noticed the query event response data pulled by the host. This timing is not determined by any IRQs, so we may need to use a guard period in this mode, which may explain the existence of the ec_guard() code used by the old EC driver where the re-check timing is implemented in the similar way as this mode. Method: QR_EC is re-checked as late as possible after completing the _Qxx evaluation. The target may implement SCI_EVT like a level triggered interrupt. It is proven on kernel bugzilla 94411 that, Windows will have all _Qxx evaluations parallelized. Thus unless required by further evidences, we needn't implement this mode as it is a conflict of the _Qxx parallelism requirement. Note that, according to the reports, there are platforms that cannot be handled using the "Status" mode without enabling the EC_FLAGS_QUERY_HANDSHAKE quirk. But they can be handled with the other modes according to the tests (kernel bugzilla 97381). The following log entry can be used to confirm the differences of the 3 modes as it should appear at the different positions for the 3 modes: Command(QR_EC) unblocked Status: appearing after EC_SC(W) = 0x84 Query: appearing after EC_DATA(R) = 0xXX where XX is the event number used to determine _QXX Event: appearing after first EC_SC(R) = 0xX0 SCI_EVT=x BURST=0 CMD=0 IBF=0 OBF=0 that is next to the following log entry: Command(QR_EC) completed by hardware 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=98111 Reported-and-tested-by: Gabriele Mazzotta <gabriele.mzt@gmail.com> Reported-and-tested-by: Tigran Gabrielyan <tigrangab@gmail.com> Reported-and-tested-by: Adrien D <ghbdtn@openmailbox.org> Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-06-11 13:21:38 +08:00
ACPI / EC: Add event clearing variation support. We've been suffering from the uncertainty of the SCI_EVT clearing timing. This patch implements 3 of 4 possible modes to handle SCI_EVT clearing variations. The old behavior is kept in this patch. Status: QR_EC is re-checked as early as possible after checking previous SCI_EVT. This always leads to 2 QR_EC transactions per SCI_EVT indication and the target may implement event queue which returns 0x00 indicating "no outstanding event". This is proven to be a conflict against Windows behavior, but is still kept in this patch to make the EC driver robust to the possible regressions that may occur on Samsung platforms. Query: QR_EC is re-checked after the target has handled the QR_EC query request command pushed by the host. Event: QR_EC is re-checked after the target has noticed the query event response data pulled by the host. This timing is not determined by any IRQs, so we may need to use a guard period in this mode, which may explain the existence of the ec_guard() code used by the old EC driver where the re-check timing is implemented in the similar way as this mode. Method: QR_EC is re-checked as late as possible after completing the _Qxx evaluation. The target may implement SCI_EVT like a level triggered interrupt. It is proven on kernel bugzilla 94411 that, Windows will have all _Qxx evaluations parallelized. Thus unless required by further evidences, we needn't implement this mode as it is a conflict of the _Qxx parallelism requirement. Note that, according to the reports, there are platforms that cannot be handled using the "Status" mode without enabling the EC_FLAGS_QUERY_HANDSHAKE quirk. But they can be handled with the other modes according to the tests (kernel bugzilla 97381). The following log entry can be used to confirm the differences of the 3 modes as it should appear at the different positions for the 3 modes: Command(QR_EC) unblocked Status: appearing after EC_SC(W) = 0x84 Query: appearing after EC_DATA(R) = 0xXX where XX is the event number used to determine _QXX Event: appearing after first EC_SC(R) = 0xX0 SCI_EVT=x BURST=0 CMD=0 IBF=0 OBF=0 that is next to the following log entry: Command(QR_EC) completed by hardware 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=98111 Reported-and-tested-by: Gabriele Mazzotta <gabriele.mzt@gmail.com> Reported-and-tested-by: Tigran Gabrielyan <tigrangab@gmail.com> Reported-and-tested-by: Adrien D <ghbdtn@openmailbox.org> Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-06-11 13:21:38 +08:00
ACPI / EC: Add event clearing variation support. We've been suffering from the uncertainty of the SCI_EVT clearing timing. This patch implements 3 of 4 possible modes to handle SCI_EVT clearing variations. The old behavior is kept in this patch. Status: QR_EC is re-checked as early as possible after checking previous SCI_EVT. This always leads to 2 QR_EC transactions per SCI_EVT indication and the target may implement event queue which returns 0x00 indicating "no outstanding event". This is proven to be a conflict against Windows behavior, but is still kept in this patch to make the EC driver robust to the possible regressions that may occur on Samsung platforms. Query: QR_EC is re-checked after the target has handled the QR_EC query request command pushed by the host. Event: QR_EC is re-checked after the target has noticed the query event response data pulled by the host. This timing is not determined by any IRQs, so we may need to use a guard period in this mode, which may explain the existence of the ec_guard() code used by the old EC driver where the re-check timing is implemented in the similar way as this mode. Method: QR_EC is re-checked as late as possible after completing the _Qxx evaluation. The target may implement SCI_EVT like a level triggered interrupt. It is proven on kernel bugzilla 94411 that, Windows will have all _Qxx evaluations parallelized. Thus unless required by further evidences, we needn't implement this mode as it is a conflict of the _Qxx parallelism requirement. Note that, according to the reports, there are platforms that cannot be handled using the "Status" mode without enabling the EC_FLAGS_QUERY_HANDSHAKE quirk. But they can be handled with the other modes according to the tests (kernel bugzilla 97381). The following log entry can be used to confirm the differences of the 3 modes as it should appear at the different positions for the 3 modes: Command(QR_EC) unblocked Status: appearing after EC_SC(W) = 0x84 Query: appearing after EC_DATA(R) = 0xXX where XX is the event number used to determine _QXX Event: appearing after first EC_SC(R) = 0xX0 SCI_EVT=x BURST=0 CMD=0 IBF=0 OBF=0 that is next to the following log entry: Command(QR_EC) completed by hardware 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=98111 Reported-and-tested-by: Gabriele Mazzotta <gabriele.mzt@gmail.com> Reported-and-tested-by: Tigran Gabrielyan <tigrangab@gmail.com> Reported-and-tested-by: Adrien D <ghbdtn@openmailbox.org> Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-06-11 13:21:38 +08:00
ACPI / EC: Add event clearing variation support. We've been suffering from the uncertainty of the SCI_EVT clearing timing. This patch implements 3 of 4 possible modes to handle SCI_EVT clearing variations. The old behavior is kept in this patch. Status: QR_EC is re-checked as early as possible after checking previous SCI_EVT. This always leads to 2 QR_EC transactions per SCI_EVT indication and the target may implement event queue which returns 0x00 indicating "no outstanding event". This is proven to be a conflict against Windows behavior, but is still kept in this patch to make the EC driver robust to the possible regressions that may occur on Samsung platforms. Query: QR_EC is re-checked after the target has handled the QR_EC query request command pushed by the host. Event: QR_EC is re-checked after the target has noticed the query event response data pulled by the host. This timing is not determined by any IRQs, so we may need to use a guard period in this mode, which may explain the existence of the ec_guard() code used by the old EC driver where the re-check timing is implemented in the similar way as this mode. Method: QR_EC is re-checked as late as possible after completing the _Qxx evaluation. The target may implement SCI_EVT like a level triggered interrupt. It is proven on kernel bugzilla 94411 that, Windows will have all _Qxx evaluations parallelized. Thus unless required by further evidences, we needn't implement this mode as it is a conflict of the _Qxx parallelism requirement. Note that, according to the reports, there are platforms that cannot be handled using the "Status" mode without enabling the EC_FLAGS_QUERY_HANDSHAKE quirk. But they can be handled with the other modes according to the tests (kernel bugzilla 97381). The following log entry can be used to confirm the differences of the 3 modes as it should appear at the different positions for the 3 modes: Command(QR_EC) unblocked Status: appearing after EC_SC(W) = 0x84 Query: appearing after EC_DATA(R) = 0xXX where XX is the event number used to determine _QXX Event: appearing after first EC_SC(R) = 0xX0 SCI_EVT=x BURST=0 CMD=0 IBF=0 OBF=0 that is next to the following log entry: Command(QR_EC) completed by hardware 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=98111 Reported-and-tested-by: Gabriele Mazzotta <gabriele.mzt@gmail.com> Reported-and-tested-by: Tigran Gabrielyan <tigrangab@gmail.com> Reported-and-tested-by: Adrien D <ghbdtn@openmailbox.org> Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-06-11 13:21:38 +08:00
ACPI / EC: Add event clearing variation support. We've been suffering from the uncertainty of the SCI_EVT clearing timing. This patch implements 3 of 4 possible modes to handle SCI_EVT clearing variations. The old behavior is kept in this patch. Status: QR_EC is re-checked as early as possible after checking previous SCI_EVT. This always leads to 2 QR_EC transactions per SCI_EVT indication and the target may implement event queue which returns 0x00 indicating "no outstanding event". This is proven to be a conflict against Windows behavior, but is still kept in this patch to make the EC driver robust to the possible regressions that may occur on Samsung platforms. Query: QR_EC is re-checked after the target has handled the QR_EC query request command pushed by the host. Event: QR_EC is re-checked after the target has noticed the query event response data pulled by the host. This timing is not determined by any IRQs, so we may need to use a guard period in this mode, which may explain the existence of the ec_guard() code used by the old EC driver where the re-check timing is implemented in the similar way as this mode. Method: QR_EC is re-checked as late as possible after completing the _Qxx evaluation. The target may implement SCI_EVT like a level triggered interrupt. It is proven on kernel bugzilla 94411 that, Windows will have all _Qxx evaluations parallelized. Thus unless required by further evidences, we needn't implement this mode as it is a conflict of the _Qxx parallelism requirement. Note that, according to the reports, there are platforms that cannot be handled using the "Status" mode without enabling the EC_FLAGS_QUERY_HANDSHAKE quirk. But they can be handled with the other modes according to the tests (kernel bugzilla 97381). The following log entry can be used to confirm the differences of the 3 modes as it should appear at the different positions for the 3 modes: Command(QR_EC) unblocked Status: appearing after EC_SC(W) = 0x84 Query: appearing after EC_DATA(R) = 0xXX where XX is the event number used to determine _QXX Event: appearing after first EC_SC(R) = 0xX0 SCI_EVT=x BURST=0 CMD=0 IBF=0 OBF=0 that is next to the following log entry: Command(QR_EC) completed by hardware 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=98111 Reported-and-tested-by: Gabriele Mazzotta <gabriele.mzt@gmail.com> Reported-and-tested-by: Tigran Gabrielyan <tigrangab@gmail.com> Reported-and-tested-by: Adrien D <ghbdtn@openmailbox.org> Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-06-11 13:21:38 +08:00
ACPI / EC: Add event clearing variation support. We've been suffering from the uncertainty of the SCI_EVT clearing timing. This patch implements 3 of 4 possible modes to handle SCI_EVT clearing variations. The old behavior is kept in this patch. Status: QR_EC is re-checked as early as possible after checking previous SCI_EVT. This always leads to 2 QR_EC transactions per SCI_EVT indication and the target may implement event queue which returns 0x00 indicating "no outstanding event". This is proven to be a conflict against Windows behavior, but is still kept in this patch to make the EC driver robust to the possible regressions that may occur on Samsung platforms. Query: QR_EC is re-checked after the target has handled the QR_EC query request command pushed by the host. Event: QR_EC is re-checked after the target has noticed the query event response data pulled by the host. This timing is not determined by any IRQs, so we may need to use a guard period in this mode, which may explain the existence of the ec_guard() code used by the old EC driver where the re-check timing is implemented in the similar way as this mode. Method: QR_EC is re-checked as late as possible after completing the _Qxx evaluation. The target may implement SCI_EVT like a level triggered interrupt. It is proven on kernel bugzilla 94411 that, Windows will have all _Qxx evaluations parallelized. Thus unless required by further evidences, we needn't implement this mode as it is a conflict of the _Qxx parallelism requirement. Note that, according to the reports, there are platforms that cannot be handled using the "Status" mode without enabling the EC_FLAGS_QUERY_HANDSHAKE quirk. But they can be handled with the other modes according to the tests (kernel bugzilla 97381). The following log entry can be used to confirm the differences of the 3 modes as it should appear at the different positions for the 3 modes: Command(QR_EC) unblocked Status: appearing after EC_SC(W) = 0x84 Query: appearing after EC_DATA(R) = 0xXX where XX is the event number used to determine _QXX Event: appearing after first EC_SC(R) = 0xX0 SCI_EVT=x BURST=0 CMD=0 IBF=0 OBF=0 that is next to the following log entry: Command(QR_EC) completed by hardware 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=98111 Reported-and-tested-by: Gabriele Mazzotta <gabriele.mzt@gmail.com> Reported-and-tested-by: Tigran Gabrielyan <tigrangab@gmail.com> Reported-and-tested-by: Adrien D <ghbdtn@openmailbox.org> Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-06-11 13:21:38 +08:00
ACPI: EC: Fix flushing of pending work Commit 016b87ca5c8c ("ACPI: EC: Rework flushing of pending work") introduced a subtle bug into the flushing of pending EC work while suspended to idle, which may cause the EC driver to fail to re-enable the EC GPE after handling a non-wakeup event (like a battery status change event, for example). The problem is that the work item flushed by flush_scheduled_work() in __acpi_ec_flush_work() may disable the EC GPE and schedule another work item expected to re-enable it, but that new work item is not flushed, so __acpi_ec_flush_work() returns with the EC GPE disabled and the CPU running it goes into an idle state subsequently. If all of the other CPUs are in idle states at that point, the EC GPE won't be re-enabled until at least one CPU is woken up by another interrupt source, so system wakeup events that would normally come from the EC then don't work. This is reproducible on a Dell XPS13 9360 in my office which sometimes stops reacting to power button and lid events (triggered by the EC on that machine) after switching from AC power to battery power or vice versa while suspended to idle (each of those switches causes the EC GPE to trigger for several times in a row, but they are not system wakeup events). To avoid this problem, it is necessary to drain the workqueue entirely in __acpi_ec_flush_work(), but that cannot be done with respect to system_wq, because work items may be added to it from other places while __acpi_ec_flush_work() is running. For this reason, make the EC driver use a dedicated workqueue for EC events processing (let that workqueue be ordered so that EC events are processed sequentially) and use drain_workqueue() on it in __acpi_ec_flush_work(). Fixes: 016b87ca5c8c ("ACPI: EC: Rework flushing of pending work") Cc: 5.4+ <stable@vger.kernel.org> # 5.4+ Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2020-02-11 10:07:43 +01:00
ACPI: EC: Fix flushing of pending work Commit 016b87ca5c8c ("ACPI: EC: Rework flushing of pending work") introduced a subtle bug into the flushing of pending EC work while suspended to idle, which may cause the EC driver to fail to re-enable the EC GPE after handling a non-wakeup event (like a battery status change event, for example). The problem is that the work item flushed by flush_scheduled_work() in __acpi_ec_flush_work() may disable the EC GPE and schedule another work item expected to re-enable it, but that new work item is not flushed, so __acpi_ec_flush_work() returns with the EC GPE disabled and the CPU running it goes into an idle state subsequently. If all of the other CPUs are in idle states at that point, the EC GPE won't be re-enabled until at least one CPU is woken up by another interrupt source, so system wakeup events that would normally come from the EC then don't work. This is reproducible on a Dell XPS13 9360 in my office which sometimes stops reacting to power button and lid events (triggered by the EC on that machine) after switching from AC power to battery power or vice versa while suspended to idle (each of those switches causes the EC GPE to trigger for several times in a row, but they are not system wakeup events). To avoid this problem, it is necessary to drain the workqueue entirely in __acpi_ec_flush_work(), but that cannot be done with respect to system_wq, because work items may be added to it from other places while __acpi_ec_flush_work() is running. For this reason, make the EC driver use a dedicated workqueue for EC events processing (let that workqueue be ordered so that EC events are processed sequentially) and use drain_workqueue() on it in __acpi_ec_flush_work(). Fixes: 016b87ca5c8c ("ACPI: EC: Rework flushing of pending work") Cc: 5.4+ <stable@vger.kernel.org> # 5.4+ Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2020-02-11 10:07:43 +01:00
ACPI: EC: Fix flushing of pending work Commit 016b87ca5c8c ("ACPI: EC: Rework flushing of pending work") introduced a subtle bug into the flushing of pending EC work while suspended to idle, which may cause the EC driver to fail to re-enable the EC GPE after handling a non-wakeup event (like a battery status change event, for example). The problem is that the work item flushed by flush_scheduled_work() in __acpi_ec_flush_work() may disable the EC GPE and schedule another work item expected to re-enable it, but that new work item is not flushed, so __acpi_ec_flush_work() returns with the EC GPE disabled and the CPU running it goes into an idle state subsequently. If all of the other CPUs are in idle states at that point, the EC GPE won't be re-enabled until at least one CPU is woken up by another interrupt source, so system wakeup events that would normally come from the EC then don't work. This is reproducible on a Dell XPS13 9360 in my office which sometimes stops reacting to power button and lid events (triggered by the EC on that machine) after switching from AC power to battery power or vice versa while suspended to idle (each of those switches causes the EC GPE to trigger for several times in a row, but they are not system wakeup events). To avoid this problem, it is necessary to drain the workqueue entirely in __acpi_ec_flush_work(), but that cannot be done with respect to system_wq, because work items may be added to it from other places while __acpi_ec_flush_work() is running. For this reason, make the EC driver use a dedicated workqueue for EC events processing (let that workqueue be ordered so that EC events are processed sequentially) and use drain_workqueue() on it in __acpi_ec_flush_work(). Fixes: 016b87ca5c8c ("ACPI: EC: Rework flushing of pending work") Cc: 5.4+ <stable@vger.kernel.org> # 5.4+ Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2020-02-11 10:07:43 +01:00
ACPI: EC: Fix flushing of pending work Commit 016b87ca5c8c ("ACPI: EC: Rework flushing of pending work") introduced a subtle bug into the flushing of pending EC work while suspended to idle, which may cause the EC driver to fail to re-enable the EC GPE after handling a non-wakeup event (like a battery status change event, for example). The problem is that the work item flushed by flush_scheduled_work() in __acpi_ec_flush_work() may disable the EC GPE and schedule another work item expected to re-enable it, but that new work item is not flushed, so __acpi_ec_flush_work() returns with the EC GPE disabled and the CPU running it goes into an idle state subsequently. If all of the other CPUs are in idle states at that point, the EC GPE won't be re-enabled until at least one CPU is woken up by another interrupt source, so system wakeup events that would normally come from the EC then don't work. This is reproducible on a Dell XPS13 9360 in my office which sometimes stops reacting to power button and lid events (triggered by the EC on that machine) after switching from AC power to battery power or vice versa while suspended to idle (each of those switches causes the EC GPE to trigger for several times in a row, but they are not system wakeup events). To avoid this problem, it is necessary to drain the workqueue entirely in __acpi_ec_flush_work(), but that cannot be done with respect to system_wq, because work items may be added to it from other places while __acpi_ec_flush_work() is running. For this reason, make the EC driver use a dedicated workqueue for EC events processing (let that workqueue be ordered so that EC events are processed sequentially) and use drain_workqueue() on it in __acpi_ec_flush_work(). Fixes: 016b87ca5c8c ("ACPI: EC: Rework flushing of pending work") Cc: 5.4+ <stable@vger.kernel.org> # 5.4+ Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2020-02-11 10:07:43 +01:00
ACPI: EC: Fix flushing of pending work Commit 016b87ca5c8c ("ACPI: EC: Rework flushing of pending work") introduced a subtle bug into the flushing of pending EC work while suspended to idle, which may cause the EC driver to fail to re-enable the EC GPE after handling a non-wakeup event (like a battery status change event, for example). The problem is that the work item flushed by flush_scheduled_work() in __acpi_ec_flush_work() may disable the EC GPE and schedule another work item expected to re-enable it, but that new work item is not flushed, so __acpi_ec_flush_work() returns with the EC GPE disabled and the CPU running it goes into an idle state subsequently. If all of the other CPUs are in idle states at that point, the EC GPE won't be re-enabled until at least one CPU is woken up by another interrupt source, so system wakeup events that would normally come from the EC then don't work. This is reproducible on a Dell XPS13 9360 in my office which sometimes stops reacting to power button and lid events (triggered by the EC on that machine) after switching from AC power to battery power or vice versa while suspended to idle (each of those switches causes the EC GPE to trigger for several times in a row, but they are not system wakeup events). To avoid this problem, it is necessary to drain the workqueue entirely in __acpi_ec_flush_work(), but that cannot be done with respect to system_wq, because work items may be added to it from other places while __acpi_ec_flush_work() is running. For this reason, make the EC driver use a dedicated workqueue for EC events processing (let that workqueue be ordered so that EC events are processed sequentially) and use drain_workqueue() on it in __acpi_ec_flush_work(). Fixes: 016b87ca5c8c ("ACPI: EC: Rework flushing of pending work") Cc: 5.4+ <stable@vger.kernel.org> # 5.4+ Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2020-02-11 10:07:43 +01:00