summaryrefslogtreecommitdiff
path: root/drivers/acpi/ec.c
AgeCommit message (Collapse)Author
2021-12-01ACPI: EC: Relocate acpi_ec_create_query() and drop acpi_ec_delete_query()Rafael J. Wysocki
Move acpi_ec_create_query() after acpi_ec_event_processor(), drop the no longer needed forward declaration of the latter, and eliminate acpi_ec_delete_query() which isn't really necessary. No intentional functional impact. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-12-01ACPI: EC: Make the event work state machine visibleRafael J. Wysocki
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-12-01ACPI: EC: Avoid queuing unnecessary work in acpi_ec_submit_event()Rafael J. Wysocki
Notice that it is not necessary to queue up the event work again if the while () loop in acpi_ec_event_handler() is still running which is the case if nr_pending_queries is greater than 0 at the beginning of acpi_ec_submit_event() and modify the code to avoid doing that. While at it, rename nr_pending_queries in struct acpi_ec to events_to_process which actually matches the role of that field and change its data type to unsigned int which is sufficient. No expected functional impact. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-12-01ACPI: EC: Rename three functionsRafael J. Wysocki
Rename acpi_ec_submit_query() to acpi_ec_submit_event(), acpi_ec_query() to acpi_ec_submit_query(), and acpi_ec_complete_query() to acpi_ec_close_event() to make the names reflect what the functions do. No expected functional impact. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-12-01ACPI: EC: Simplify locking in acpi_ec_event_handler()Rafael J. Wysocki
Because acpi_ec_event_handler() is a work function, it always runs in process context with interrupts enabled, so it can use spin_lock_irq() and spin_unlock_irq() for the locking. Make it do so and adjust white space around those calls. No expected functional impact. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-12-01ACPI: EC: Rearrange the loop in acpi_ec_event_handler()Rafael J. Wysocki
It is not necessary to check ec->nr_pending_queries against 0 in the while () loop in acpi_ec_event_handler(), because that loop terminates when ec->nr_pending_queries is 0 and the code depending on that can be run after the loop has ended. Modify the code accordingly and while at it rewrite the comment regarding that code to make it clearer. No intentional functional impact. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-12-01ACPI: EC: Fold acpi_ec_check_event() into acpi_ec_event_handler()Rafael J. Wysocki
Because acpi_ec_event_handler() is the only caller of acpi_ec_check_event() and the separation of these two functions makes it harder to follow the code flow, fold the latter into the former (and simplify that code while at it). No expected functional impact. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-12-01ACPI: EC: Pass one argument to acpi_ec_query()Rafael J. Wysocki
Notice that the second argument to acpi_ec_query() is redundant, because in the only case when it is not NULL, the value passed through it is only checked against 0 and it can only be 0 when acpi_ec_query() returns an error code, but its return value is checked along with the value passed through its second argument. Accordingly, modify acpi_ec_query() to take only one argument and while at it, change its handling of the case when acpi_ec_transaction() returns an error so as to return that error value to the caller right away. No expected functional impact. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-12-01ACPI: EC: Call advance_transaction() from acpi_ec_dispatch_gpe()Rafael J. Wysocki
Calling acpi_dispatch_gpe() from acpi_ec_dispatch_gpe() is generally problematic, because it may cause the spurious interrupt handling in advance_transaction() to trigger in theory. However, instead of calling acpi_dispatch_gpe() to dispatch the EC GPE, acpi_ec_dispatch_gpe() can call advance_transaction() directly on first_ec and it can pass 'false' as its second argument to indicate calling it from process context. Moreover, if advance_transaction() is modified to return a bool value indicating whether or not the EC work needs to be flushed, it can be used to avoid unnecessary EC work flushing in acpi_ec_dispatch_gpe(), so change the code accordingly. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-12-01ACPI: EC: Rework flushing of EC work while suspended to idleRafael J. Wysocki
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-03ACPI: EC: Remove initialization of static variables to falsewangzhitong
Remove the initialization of two static variables to false which is pointless. Signed-off-by: wangzhitong <wangzhitong@uniontech.com> [ rjw: Subject and changelog ] Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-11-03ACPI: EC: Use ec_no_wakeup on HP ZHAN 66 ProBinbin Zhou
EC interrupts constantly wake up system from s2idle, so set ec_no_wakeup by default to keep the system in s2idle and reduce energy consumption. Signed-off-by: Binbin Zhou <zhoubinbin@uniontech.com> [ rjw: Changelog and subject edits ] Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-06-29Merge branches 'acpi-ec', 'acpi-apei', 'acpi-soc' and 'acpi-misc'Rafael J. Wysocki
* acpi-ec: ACPI: EC: trust DSDT GPE for certain HP laptop ACPI: EC: Make more Asus laptops use ECDT _GPE * acpi-apei: ACPI: APEI: fix synchronous external aborts in user-mode ACPI: APEI: Don't warn if ACPI is disabled * acpi-soc: ACPI: LPSS: Use kstrtol() instead of simple_strtol() * acpi-misc: ACPI: NVS: fix doc warnings in nvs.c ACPI: NUMA: fix typo in a comment ACPI: OSL: Use DEFINE_RES_IO_NAMED() to simplify code ACPI: bus: Call kobject_put() in acpi_init() error path ACPI: bus: Remove unneeded assignment ACPI: configfs: Replace ACPI_INFO() with pr_debug() ACPI: ipmi: Remove address space handler in error path ACPI: event: Remove redundant initialization of local variable ACPI: sbshc: Fix fall-through warning for Clang
2021-06-21ACPI: EC: trust DSDT GPE for certain HP laptopZhang Rui
On HP Pavilion Gaming Laptop 15-cx0xxx, the ECDT EC and DSDT EC share the same port addresses but different GPEs. And the DSDT GPE is the right one to use. The current code duplicates DSDT EC with ECDT EC if the port addresses are the same, and uses ECDT GPE as a result, which breaks this machine. Introduce a new quirk for the HP laptop to trust the DSDT GPE, and avoid duplicating even if the port addresses are the same. Link: https://bugzilla.kernel.org/show_bug.cgi?id=209989 Reported-and-tested-by: Shao Fu, Chen <leo881003@gmail.com> Signed-off-by: Zhang Rui <rui.zhang@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-06-07ACPI: scan: Extend acpi_walk_dep_device_list()Daniel Scally
The acpi_walk_dep_device_list() function is not as generic as its name implies, serving only to decrement the dependency count for each dependent device of the input. Extend it to accept a callback which can be applied to all the dependencies in acpi_dep_list. Replace all existing calls to the function with calls to a wrapper, passing a callback that applies the same dependency reduction. Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Acked-by: Maximilian Luz <luzmaximilian@gmail.com> # for platform/surface parts Signed-off-by: Daniel Scally <djrscally@gmail.com> [ rjw: Changelog edits ] Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-05-21ACPI: EC: Make more Asus laptops use ECDT _GPEChris Chiu
More ASUS laptops have the _GPE define in the DSDT table with a different value than the _GPE number in the ECDT. This is causing media keys not working on ASUS X505BA/BP, X542BA/BP Add model info to the quirks list. Signed-off-by: Chris Chiu <chris.chiu@canonical.com> Signed-off-by: Jian-Hong Pan <jhp@endlessos.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2020-11-23ACPI: EC: Clean up status flags checks in advance_transaction()Rafael J. Wysocki
Eliminate comparisons from the status flags checks in advance_transaction() (especially from the one that is only correct, because the value of the flag checked in there is 1) and rearrange the code for more clarity while at it. No intentional functional impact. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2020-11-23ACPI: EC: Untangle error handling in advance_transaction()Rafael J. Wysocki
Introduce acpi_ec_spurious_interrupt() for recording spurious interrupts and use it for error handling in advance_transaction(), drop the (now redundant) original error handling block from there along with a frew goto statements that are not necessary any more. No intentional functional impact. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2020-11-23ACPI: EC: Simplify error handling in advance_transaction()Rafael J. Wysocki
Notice that the value of t in advance_transaction() does not change after its initialization and: - Initialize t upfront (and rearrange the definitions of local variables while at it). - Check it against NULL in a block executed when it is NULL. - Skip error handling for t == NULL, because a valid pointer value of t is required for the error handling. - Drop the (now redundant) check of t against NULL from the error handling block and reduce the indentation level in there. No intentional functional impact. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2020-11-23ACPI: EC: Rename acpi_ec_is_gpe_raised()Rafael J. Wysocki
Rename acpi_ec_is_gpe_raised() into acpi_ec_gpe_status_set(), update its callers accordingly and drop the ternary operator (which isn't really necessary in there) from it. No intentional functional impact. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2020-11-23ACPI: EC: Fold acpi_ec_clear_gpe() into its callerRafael J. Wysocki
Fold acpi_ec_clear_gpe() which is only used in one place into its caller and clean up comments related to that function while at it. No intentional functional impact. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2020-11-23ACPI: EC: Eliminate in_interrupt() usageSebastian Andrzej Siewior
advance_transaction() is using in_interrupt() to distinguish between an invocation from the interrupt handler and an invocation from another part of the stack. This looks misleading because chains like acpi_update_all_gpes() -> acpi_ev_gpe_detect() -> acpi_ev_detect_gpe() -> acpi_ec_gpe_handler() should probably also behave as if they were called from an interrupt handler. Replace in_interrupt() usage with a function parameter. Set this parameter to `true' if invoked from an interrupt handler (acpi_ec_gpe_handler() and acpi_ec_irq_handler()) and `false' otherwise. Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> [ rjw: Subject edits ] Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2020-10-06ACPI: EC: PM: Drop ec_no_wakeup check from acpi_ec_dispatch_gpe()Rafael J. Wysocki
It turns out that in some cases there are EC events to flush in acpi_ec_dispatch_gpe() even though the ec_no_wakeup kernel parameter is set and the EC GPE is disabled while sleeping, so drop the ec_no_wakeup check that prevents those events from being processed from acpi_ec_dispatch_gpe(). Reported-by: Todd Brandt <todd.e.brandt@linux.intel.com> Cc: 5.4+ <stable@vger.kernel.org> # 5.4+ Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2020-10-06ACPI: EC: PM: Flush EC work unconditionally after wakeupRafael J. Wysocki
Commit 607b9df63057 ("ACPI: EC: PM: Avoid flushing EC work when EC GPE is inactive") has been reported to cause some power button wakeup events to be missed on some systems, so modify acpi_ec_dispatch_gpe() to call acpi_ec_flush_work() unconditionally to effectively reverse the changes made by that commit. Also note that the problem which prompted commit 607b9df63057 is not reproducible any more on the affected machine. Fixes: 607b9df63057 ("ACPI: EC: PM: Avoid flushing EC work when EC GPE is inactive") Reported-by: Raymond Tan <raymond.tan@intel.com> Cc: 5.4+ <stable@vger.kernel.org> # 5.4+ Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2020-06-22ACPI: EC: add newline when printing 'ec_event_clearing' module parameterXiongfeng Wang
When I cat acpi module parameter '/sys/module/acpi/parameters/ec_event_clearing', it displays as follows. It is better to add a newline for easy reading. [root@hulk-202 ~]# cat /sys/module/acpi/parameters/ec_event_clearing query[root@hulk-202 ~]# Signed-off-by: Xiongfeng Wang <wangxiongfeng2@huawei.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2020-06-02Merge tag 'acpi-5.8-rc1' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm Pull ACPI updates from Rafael Wysocki: "These update the ACPICA code in the kernel to upstream revision 20200430, fix several reference counting errors related to ACPI tables, add _Exx / _Lxx support to the GED driver, add a new acpi_evaluate_reg() helper, add new DPTF battery participant driver and extend the DPFT power participant driver, improve the handling of memory failures in the APEI code, add a blacklist entry to the backlight driver, update the PMIC driver and the processor idle driver, fix two kobject reference count leaks, and make a few janitory changes. Specifics: - Update the ACPICA code in the kernel to upstream revision 20200430: - Move acpi_gbl_next_cmd_num definition (Erik Kaneda). - Ignore AE_ALREADY_EXISTS status in the disassembler when parsing create operators (Erik Kaneda). - Add status checks to the dispatcher (Erik Kaneda). - Fix required parameters for _NIG and _NIH (Erik Kaneda). - Make acpi_protocol_lengths static (Yue Haibing). - Fix ACPI table reference counting errors in several places, mostly in error code paths (Hanjun Guo). - Extend the Generic Event Device (GED) driver to support _Exx and _Lxx handler methods (Ard Biesheuvel). - Add new acpi_evaluate_reg() helper and modify the ACPI PCI hotplug code to use it (Hans de Goede). - Add new DPTF battery participant driver and make the DPFT power participant driver create more sysfs device attributes (Srinivas Pandruvada). - Improve the handling of memory failures in APEI (James Morse). - Add new blacklist entry for Acer TravelMate 5735Z to the backlight driver (Paul Menzel). - Add i2c address for thermal control to the PMIC driver (Mauro Carvalho Chehab). - Allow the ACPI processor idle driver to work on platforms with only one ACPI C-state present (Zhang Rui). - Fix kobject reference count leaks in error code paths in two places (Qiushi Wu). - Delete unused proc filename macros and make some symbols static (Pascal Terjan, Zheng Zengkai, Zou Wei)" * tag 'acpi-5.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (32 commits) ACPI: CPPC: Fix reference count leak in acpi_cppc_processor_probe() ACPI: sysfs: Fix reference count leak in acpi_sysfs_add_hotplug_profile() ACPI: GED: use correct trigger type field in _Exx / _Lxx handling ACPI: DPTF: Add battery participant driver ACPI: DPTF: Additional sysfs attributes for power participant driver ACPI: video: Use native backlight on Acer TravelMate 5735Z arm64: acpi: Make apei_claim_sea() synchronise with APEI's irq work ACPI: APEI: Kick the memory_failure() queue for synchronous errors mm/memory-failure: Add memory_failure_queue_kick() ACPI / PMIC: Add i2c address for thermal control ACPI: GED: add support for _Exx / _Lxx handler methods ACPI: Delete unused proc filename macros ACPI: hotplug: PCI: Use the new acpi_evaluate_reg() helper ACPI: utils: Add acpi_evaluate_reg() helper ACPI: debug: Make two functions static ACPI: sleep: Put the FACS table after using it ACPI: scan: Put SPCR and STAO table after using it ACPI: EC: Put the ACPI table after using it ACPI: APEI: Put the HEST table for error path ACPI: APEI: Put the error record serialization table for error path ...
2020-06-01Merge branches 'acpi-processor', 'acpi-cppc', 'acpi-dbg', 'acpi-misc' and ↵Rafael J. Wysocki
'acpi-pci' * acpi-processor: ACPI: processor: idle: Allow probing on platforms with one ACPI C-state * acpi-cppc: ACPI: CPPC: Fix reference count leak in acpi_cppc_processor_probe() ACPI: CPPC: Make some symbols static * acpi-dbg: ACPI: debug: Make two functions static * acpi-misc: ACPI: GED: use correct trigger type field in _Exx / _Lxx handling ACPI: GED: add support for _Exx / _Lxx handler methods ACPI: Delete unused proc filename macros * acpi-pci: ACPI: hotplug: PCI: Use the new acpi_evaluate_reg() helper ACPI: utils: Add acpi_evaluate_reg() helper
2020-06-01Merge branches 'acpica' and 'acpi-tables'Rafael J. Wysocki
* acpica: ACPICA: Update version to 20200430 ACPICA: Fix required parameters for _NIG and _NIH ACPICA: Dispatcher: add status checks ACPICA: Disassembler: ignore AE_ALREADY_EXISTS status when parsing create operators ACPICA: Move acpi_gbl_next_cmd_num definition to acglobal.h ACPICA: Make acpi_protocol_lengths static * acpi-tables: ACPI: sleep: Put the FACS table after using it ACPI: scan: Put SPCR and STAO table after using it ACPI: EC: Put the ACPI table after using it ACPI: APEI: Put the HEST table for error path ACPI: APEI: Put the error record serialization table for error path ACPI: APEI: Put the error injection table for error path and module exit ACPI: APEI: Put the boot error record table after parsing ACPI: watchdog: Put the watchdog action table after parsing ACPI: LPIT: Put the low power idle table after using it
2020-05-25ACPI: EC: PM: s2idle: Extend GPE dispatching debug messageRafael J. Wysocki
Add the "ACPI" string to the "EC GPE dispatched" message as it is ACPI-related. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2020-05-18ACPI: EC: PM: Avoid flushing EC work when EC GPE is inactiveRafael J. Wysocki
Flushing the EC work while suspended to idle when the EC GPE status is not set causes some EC wakeup events (notably power button and lid ones) to be missed after a series of spurious wakeups on the Dell XPS13 9360 in my office. If that happens, the machine cannot be woken up from suspend-to-idle by the power button or lid status change and it needs to be woken up in some other way (eg. by a key press). Flushing the EC work only after successful dispatching the EC GPE, which means that its status has been set, avoids the issue, so change the code in question accordingly. Fixes: 7b301750f7f8 ("ACPI: EC: PM: Avoid premature returns from acpi_s2idle_wake()") Cc: 5.4+ <stable@vger.kernel.org> # 5.4+ Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Tested-by: Chris Chiu <chiu@endlessm.com>
2020-05-14ACPI: Delete unused proc filename macrosPascal Terjan
Those were used to create files in /proc/acpi long ago and were missed when that code was deleted. Signed-off-by: Pascal Terjan <pterjan@google.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2020-05-11ACPI: EC: PM: Avoid premature returns from acpi_s2idle_wake()Rafael J. Wysocki
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-09ACPI: EC: Put the ACPI table after using itHanjun Guo
The embedded controller boot resources table needs to be released after using it. Signed-off-by: Hanjun Guo <guohanjun@huawei.com> [ rjw: avoid adding a label in acpi_ec_ecdt_start() ] Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2020-04-06ACPI: EC: Fix up fast path check in acpi_ec_add()Rafael J. Wysocki
The fast path check in acpi_ec_add() is not incorrect, because in fact acpi_device_hid(device) can be equal to ACPI_ECDT_HID only if boot_ec is not NULL, but it may confuse static checkers, so change it to explicitly check boot_ec upfront and use the slow path if that pointer is NULL. Link: https://lore.kernel.org/linux-acpi/20200406144217.GA68494@mwanda/ Fixes: 3d9b8dd8320d ("ACPI: EC: Use fast path in acpi_ec_add() for DSDT boot EC") Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2020-03-30Merge tag 'acpi-5.7-rc1' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm Pull ACPI updates from Rafael Wysocki: - Update the ACPICA code in the kernel to the 20200214 upstream release including: * Fix to re-enable the sleep button after wakeup (Anchal Agarwal). * Fixes for mistakes in comments and typos (Bob Moore). * ASL-ASL+ converter updates (Erik Kaneda). * Type casting cleanups (Sven Barth). - Clean up the intialization of the EC driver and eliminate some dead code from it (Rafael Wysocki). - Clean up the quirk tables in the AC and battery drivers (Hans de Goede). - Fix the global lock handling on x86 to ignore unspecified bit positions in the global lock field (Jan Engelhardt). - Add a new "tiny" driver for ACPI button devices exposed by VMs to guest kernels to send signals directly to init (Josh Triplett). - Add a kernel parameter to disable ACPI BGRT on x86 (Alex Hung). - Make the ACPI PCI host bridge and fan drivers use scnprintf() to avoid potential buffer overflows (Takashi Iwai). - Clean up assorted pieces of code: * Reorder "asmlinkage" to make g++ happy (Alexey Dobriyan). * Drop unneeded variable initialization (Colin Ian King). * Add missing __acquires/__releases annotations (Jules Irenge). * Replace list_for_each_safe() with list_for_each_entry_safe() (chenqiwu)" * tag 'acpi-5.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (31 commits) ACPICA: Update version to 20200214 ACPI: PCI: Use scnprintf() for avoiding potential buffer overflow ACPI: fan: Use scnprintf() for avoiding potential buffer overflow ACPI: EC: Eliminate EC_FLAGS_QUERY_HANDSHAKE ACPI: EC: Do not clear boot_ec_is_ecdt in acpi_ec_add() ACPI: EC: Simplify acpi_ec_ecdt_start() and acpi_ec_init() ACPI: EC: Consolidate event handler installation code acpi/x86: ignore unspecified bit positions in the ACPI global lock field acpi/x86: add a kernel parameter to disable ACPI BGRT x86/acpi: make "asmlinkage" part first thing in the function definition ACPI: list_for_each_safe() -> list_for_each_entry_safe() ACPI: video: remove redundant assignments to variable result ACPI: OSL: Add missing __acquires/__releases annotations ACPI / battery: Cleanup Lenovo Ideapad Miix 320 DMI table entry ACPI / AC: Cleanup DMI quirk table ACPI: EC: Use fast path in acpi_ec_add() for DSDT boot EC ACPI: EC: Simplify acpi_ec_add() ACPI: EC: Drop AE_NOT_FOUND special case from ec_install_handlers() ACPI: EC: Avoid passing redundant argument to functions ACPI: EC: Avoid printing confusing messages in acpi_ec_setup() ...
2020-03-25ACPI: PM: s2idle: Refine active GPEs checkRafael J. Wysocki
The check for any active GPEs added by commit fdde0ff8590b ("ACPI: PM: s2idle: Prevent spurious SCIs from waking up the system") turns out to be insufficiently precise to prevent some systems from resuming prematurely due to a spurious EC wakeup, so refine it by first checking if any GPEs other than the EC GPE are active and skipping all of the SCIs coming from the EC that do not produce any genuine wakeup events after processing. Link: https://bugzilla.kernel.org/show_bug.cgi?id=206629 Fixes: fdde0ff8590b ("ACPI: PM: s2idle: Prevent spurious SCIs from waking up the system") Reported-by: Ondřej Caletka <ondrej@caletka.cz> Tested-by: Ondřej Caletka <ondrej@caletka.cz> Cc: 5.4+ <stable@vger.kernel.org> # 5.4+ Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2020-03-14ACPI: EC: Eliminate EC_FLAGS_QUERY_HANDSHAKERafael J. Wysocki
The EC_FLAGS_QUERY_HANDSHAKE switch is never set in the current code (the only function setting it is defined under #if 0) and has no effect whatever, so eliminate it and drop the code depending on it. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2020-03-14ACPI: EC: Do not clear boot_ec_is_ecdt in acpi_ec_add()Rafael J. Wysocki
The reason for clearing boot_ec_is_ecdt in acpi_ec_add() (if a PNP0C09 device object matching the ECDT boot EC had been found in the namespace) was to cause acpi_ec_ecdt_start() to return early, but since the latter does not look at boot_ec_is_ecdt any more, acpi_ec_add() need not clear it. Moreover, doing that may be confusing as it may cause "DSDT" to be printed instead of "ECDT" in the EC initialization completion message, so stop doing it. While at it, split the EC initialization completion message into two messages, one regarding the boot EC and another one printed regardless of whether or not the EC at hand is the boot one. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2020-03-14ACPI: EC: Simplify acpi_ec_ecdt_start() and acpi_ec_init()Rafael J. Wysocki
Notice that the return value of acpi_ec_init() is discarded anyway, so it can be void and it doesn't need to check the return values of acpi_bus_register_driver() and acpi_ec_ecdt_start() called by it. Thus the latter can be void too and it really has nothing to do if acpi_ec_add() has already found an EC matching the boot one in the namespace. Also, acpi_ec_ecdt_get_handle() can be folded into it. Modify the code accordingly and while at it create a propoer kerneldoc comment to document acpi_ec_ecdt_start() and move the remark regarding ASUS X550ZE along with the related bug URL from acpi_ec_init() into that comment. Additionally, fix up a stale comment in acpi_ec_init(). Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2020-03-14ACPI: EC: Consolidate event handler installation codeRafael J. Wysocki
Commit 406857f773b0 ("ACPI: EC: add support for hardware-reduced systems") made ec_install_handlers() return an error on failures to configure a GPIO IRQ for the EC, but that is inconsistent with the handling of the GPE event handler installation failures even though it is exactly the same issue and the driver can respond to it in the same way in both cases (the EC can be actively polled for events through its registers if the event handler installation fails). Moreover, it requires acpi_ec_add() to take that special case into account and disagrees with the ec_install_handlers() header comment. For this reason, rework the event handler installation code in ec_install_handlers() to explicitly take deferred probing (that may be needed in the GPIO IRQ case) into account and to avoid failing the EC initialization in any other case. Among other things, reduce code duplication between install_gpe_event_handler() and install_gpio_irq_event_handler() by moving some code from there into ec_install_handlers() itself and simplify the error code path in acpi_ec_add(). While at it, turn the ec_install_handlers() header comment into a proper kerneldoc one and add some general control flow information to it. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Tested-by: Jian-Hong Pan <jian-hong@endlessm.com>
2020-03-02ACPI: EC: Use fast path in acpi_ec_add() for DSDT boot ECRafael J. Wysocki
If the boot EC comes from the DSDT, its ACPI handle is equal to the handle of a device object with the PNP0C09 device ID. If that device object is passed to acpi_ec_add(), it is not necessary to allocate a new EC structure for it and parse it, because that has been done already, so change the function to use the fast path in that case. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2020-03-02ACPI: EC: Simplify acpi_ec_add()Rafael J. Wysocki
First, notice that if the device ID in acpi_ec_add() is equal to ACPI_ECDT_HID, boot_ec_is_ecdt must be set, because this means that the device object passed to acpi_ec_add() comes from acpi_ec_ecdt_start() which fails if boot_ec_is_ecdt is unset. Accordingly, boot_ec_is_ecdt need not be set again in that case, so drop that redundant update of it from the code. Next, ec->handle must be a valid ACPI handle right before returning 0 from acpi_ec_add(), because it either is the handle of the device object passed to that function, or it is the boot EC handle coming from acpi_ec_ecdt_start() which fails if it cannot find a valid handle for the boot EC. Moreover, the object with that handle is regarded as a valid representation of the EC in all cases, so there is no reason to avoid the _DEP list update walk if that handle is the boot EC handle. Accordingly, drop the dep_update local variable from acpi_ec_add() and call acpi_walk_dep_device_list() for ec->handle unconditionally before returning 0 from it. Finally, the ec local variable in acpi_ec_add() need not be initialized to NULL and the status local variable declaration can be moved to the block in which it is used, so change the code in accordance with these observations. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2020-02-27ACPI: EC: Drop AE_NOT_FOUND special case from ec_install_handlers()Rafael J. Wysocki
If the status value returned by acpi_install_address_space_handler() in ec_install_handlers() is AE_NOT_FOUND, it is treated in a special way, apparently because it might mean a _REG method evaluation failure (at least that is the case according to the comment in there), but acpi_install_address_space_handler() does not take _REG evaluation errors into account at all, so the AE_NOT_FOUND special handling is confusing at best. For this reason, change ec_install_handlers() to stop the EC and return -ENODEV on all acpi_install_address_space_handler() errors. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2020-02-27ACPI: EC: Avoid passing redundant argument to functionsRafael J. Wysocki
After commit 406857f773b0 ("ACPI: EC: add support for hardware-reduced systems") the handle_events argument passed to ec_install_handlers() and acpi_ec_setup() is redundant, because it is always 'false' when the device argument passed to them in NULL and it is always 'true' otherwise, so the device argument can be tested against NULL instead of testing the handle_events one. Accordingly, modify ec_install_handlers() and acpi_ec_setup() to take two arguments and reduce the number of checks in the former. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2020-02-27ACPI: EC: Avoid printing confusing messages in acpi_ec_setup()Rafael J. Wysocki
It doesn't really make sense to pass ec->handle of the ECDT EC to acpi_handle_info(), because it is set to ACPI_ROOT_OBJECT in acpi_ec_ecdt_probe(), so rework acpi_ec_setup() to avoid using acpi_handle_info() for printing messages. First, notice that the "Used as first EC" message is not really useful, because it is immediately followed by a more meaningful one from either acpi_ec_ecdt_probe() or acpi_ec_dsdt_probe() (the latter also includes the EC object path), so drop it altogether. Second, use pr_info() for printing the EC configuration information. While at it, make the code in question avoid printing invalid GPE or IRQ numbers and make it print the GPE/IRQ information only when the driver is ready to handle events. Fixes: 72c77b7ea9ce ("ACPI / EC: Cleanup first_ec/boot_ec code") Fixes: 406857f773b0 ("ACPI: EC: add support for hardware-reduced systems") Cc: 5.5+ <stable@vger.kernel.org> # 5.5+ Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2020-02-11ACPI: EC: Fix flushing of pending workRafael J. Wysocki
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>
2019-12-27ACPI: EC: Reference count query handlers under lockRafael J. Wysocki
There is a race condition in acpi_ec_get_query_handler() theoretically allowing query handlers to go away before refernce counting them. In order to avoid it, call kref_get() on query handlers under ec->mutex. Also simplify the code a bit while at it. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2019-12-04Merge branches 'pm-sleep', 'pm-cpuidle', 'pm-cpufreq', 'pm-devfreq' and 'pm-avs'Rafael J. Wysocki
* pm-sleep: ACPI: PM: s2idle: Rework ACPI events synchronization ACPI: EC: Rework flushing of pending work * pm-cpuidle: cpuidle: minor Kconfig help text fixes cpuidle: Drop disabled field from struct cpuidle_state cpuidle: Fix Kconfig indentation * pm-cpufreq: cpufreq: Fix Kconfig indentation * pm-devfreq: PM / devfreq: Add missing locking while setting suspend_freq * pm-avs: power: avs: Fix Kconfig indentation
2019-12-02ACPI: EC: Rework flushing of pending workRafael J. Wysocki
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-10-28ACPI: EC: add support for hardware-reduced systemsDaniel Drake
As defined in the ACPI spec section 12.11, ACPI hardware-reduced platforms define the EC SCI interrupt as a GpioInt in the _CRS object. This replaces the previous way of using a GPE for this interrupt; GPE blocks are not available on reduced hardware platforms. Add support for handling this interrupt as an EC event source, and avoid GPE usage on reduced hardware platforms. This enables the use of several media keys (e.g. screen brightness up/down) on Asus UX434DA. Signed-off-by: Daniel Drake <drake@endlessm.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>