]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
HID: intel-ishtp-hid: Clear suspended flag only after connected on resume
authorZhang Lixu <lixu.zhang@intel.com>
Fri, 17 Oct 2025 02:22:14 +0000 (10:22 +0800)
committerJiri Kosina <jkosina@suse.com>
Fri, 17 Oct 2025 15:47:53 +0000 (17:47 +0200)
When resuming from suspend-to-RAM or hibernate, the ISH firmware is powered
on from D3, causing all previous client connections between the firmware
and driver to be lost. Although the underlying ishtp bus driver initiates a
client reconnection flow, this process is asynchronous. As a result, when
hid_ishtp_cl_resume_handler() is executed, the connection may not have been
re-established yet. Clearing the suspended flag prematurely in this
scenario can lead to a timeout when the upper-layer HID sensor driver set
feature during resume.

To prevent such timeouts, only clear the suspended flag after confirming
that the connection state is ISHTP_CL_CONNECTED.

Signed-off-by: Zhang Lixu <lixu.zhang@intel.com>
Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
drivers/hid/intel-ish-hid/ishtp-hid-client.c

index f61add862b6b3fb60678b85d016f3b5c35ced6f6..f37b3bc2bb7d1c9b0ea6acb3f9dbdd07423dd29e 100644 (file)
@@ -757,8 +757,15 @@ static void hid_ishtp_cl_resume_handler(struct work_struct *work)
        struct ishtp_cl *hid_ishtp_cl = client_data->hid_ishtp_cl;
 
        if (ishtp_wait_resume(ishtp_get_ishtp_device(hid_ishtp_cl))) {
-               client_data->suspended = false;
-               wake_up_interruptible(&client_data->ishtp_resume_wait);
+               /*
+                * Clear the suspended flag only when the connection is established.
+                * If the connection is not established, the suspended flag will be cleared after
+                * the connection is made.
+                */
+               if (ishtp_get_connection_state(hid_ishtp_cl) == ISHTP_CL_CONNECTED) {
+                       client_data->suspended = false;
+                       wake_up_interruptible(&client_data->ishtp_resume_wait);
+               }
        } else {
                hid_ishtp_trace(client_data, "hid client: wait for resume timed out");
                dev_err(cl_data_to_dev(client_data), "wait for resume timed out");