]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
HID: intel-ish-hid: Send clock sync message immediately after reset
authorZhang Lixu <lixu.zhang@intel.com>
Wed, 22 Jan 2025 01:29:01 +0000 (09:29 +0800)
committerJiri Kosina <jkosina@suse.com>
Mon, 3 Feb 2025 09:53:12 +0000 (10:53 +0100)
The ISH driver performs a clock sync with the firmware once at system
startup and then every 20 seconds. If a firmware reset occurs right
after a clock sync, the driver would wait 20 seconds before performing
another clock sync with the firmware. This is particularly problematic
with the introduction of the "load firmware from host" feature, where
the driver performs a clock sync with the bootloader and then has to
wait 20 seconds before syncing with the main firmware.

This patch clears prev_sync immediately upon receiving an IPC reset,
so that the main firmware and driver will perform a clock sync
immediately after completing the IPC handshake.

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/ipc/ipc.c
drivers/hid/intel-ish-hid/ishtp/ishtp-dev.h

index cb956a8c386cbba7f12b16fdd7f67689268505e3..4c861119e97aa0dae16b0dae3e23be6bec0e46ef 100644 (file)
@@ -517,6 +517,10 @@ static int ish_fw_reset_handler(struct ishtp_device *dev)
        /* ISH FW is dead */
        if (!ish_is_input_ready(dev))
                return  -EPIPE;
+
+       /* Send clock sync at once after reset */
+       ishtp_dev->prev_sync = 0;
+
        /*
         * Set HOST2ISH.ILUP. Apparently we need this BEFORE sending
         * RESET_NOTIFY_ACK - FW will be checking for it
@@ -577,13 +581,12 @@ static void fw_reset_work_fn(struct work_struct *work)
  */
 static void _ish_sync_fw_clock(struct ishtp_device *dev)
 {
-       static unsigned long    prev_sync;
        struct ipc_time_update_msg time = {};
 
-       if (prev_sync && time_before(jiffies, prev_sync + 20 * HZ))
+       if (dev->prev_sync && time_before(jiffies, dev->prev_sync + 20 * HZ))
                return;
 
-       prev_sync = jiffies;
+       dev->prev_sync = jiffies;
        /* The fields of time would be updated while sending message */
        ipc_send_mng_msg(dev, MNG_SYNC_FW_CLOCK, &time, sizeof(time));
 }
index 44eddc411e97cb18c23757472d6c1e5e0e163983..ec9f6e87aaf2339c1a0c642d3452fe3723e6e4ea 100644 (file)
@@ -253,6 +253,8 @@ struct ishtp_device {
        unsigned int    ipc_tx_cnt;
        unsigned long long      ipc_tx_bytes_cnt;
 
+       /* Time of the last clock sync */
+       unsigned long prev_sync;
        const struct ishtp_hw_ops *ops;
        size_t  mtu;
        uint32_t        ishtp_msg_hdr;