Skip to content

Commit 507561b

Browse files
lixuzhaJiri Kosina
authored andcommitted
HID: intel-ish-hid: Use IPC RESET instead of void message in ish_wakeup()
On ISH power-up, the bootloader enters sleep after preparing to load the main firmware, waiting for the driver to be ready. When the driver is ready, it sends a void message to wake up the bootloader and load the main firmware. The main firmware then sends MNG_RESET_NOTIFY to the driver for handshake. This void message-based IPC handshake only works if the main firmware has not been loaded. During hibernation resume, if the restore kernel has the ISH driver, the driver wakes up the bootloader to load the main firmware and perform IPC handshake. However, when switching to the image kernel, since the main firmware is already loaded, sending a void message in the .restore() callback does not trigger IPC handshake. By sending MNG_RESET_NOTIFY (IPC RESET message) in ish_wakeup() instead of a void message, we can explicitly wake up the bootloader and perform IPC handshake, regardless of the firmware state. Additionally, since ish_ipc_reset() already waits for recvd_hw_ready, the redundant wait for recvd_hw_ready in ish_hw_start() is removed. The timeout for waiting for HW ready is set to 10 seconds, matching the original timeout value used in ish_wakeup(), to ensure reliable wakeup on hardware that requires more time, such as the Lenovo ThinkPad X1 Titanium Gen 1. 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>
1 parent 9e097dc commit 507561b

1 file changed

Lines changed: 16 additions & 23 deletions

File tree

  • drivers/hid/intel-ish-hid/ipc

drivers/hid/intel-ish-hid/ipc/ipc.c

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -728,22 +728,28 @@ int ish_disable_dma(struct ishtp_device *dev)
728728
* ish_wakeup() - wakeup ishfw from waiting-for-host state
729729
* @dev: ishtp device pointer
730730
*
731-
* Set the dma enable bit and send a void message to FW,
731+
* Set the dma enable bit and send a IPC RESET message to FW,
732732
* it wil wakeup FW from waiting-for-host state.
733+
*
734+
* Return: 0 for success else error code.
733735
*/
734-
static void ish_wakeup(struct ishtp_device *dev)
736+
static int ish_wakeup(struct ishtp_device *dev)
735737
{
738+
int ret;
739+
736740
/* Set dma enable bit */
737741
ish_reg_write(dev, IPC_REG_ISH_RMP2, IPC_RMP2_DMA_ENABLED);
738742

739743
/*
740-
* Send 0 IPC message so that ISH FW wakes up if it was already
744+
* Send IPC RESET message so that ISH FW wakes up if it was already
741745
* asleep.
742746
*/
743-
ish_reg_write(dev, IPC_REG_HOST2ISH_DRBL, IPC_DRBL_BUSY_BIT);
747+
ret = ish_ipc_reset(dev);
744748

745749
/* Flush writes to doorbell and REMAP2 */
746750
ish_reg_read(dev, IPC_REG_ISH_HOST_FWSTS);
751+
752+
return ret;
747753
}
748754

749755
/**
@@ -792,11 +798,11 @@ static int _ish_hw_reset(struct ishtp_device *dev)
792798
pci_write_config_word(pdev, pdev->pm_cap + PCI_PM_CTRL, csr);
793799

794800
/* Now we can enable ISH DMA operation and wakeup ISHFW */
795-
ish_wakeup(dev);
796-
797-
return 0;
801+
return ish_wakeup(dev);
798802
}
799803

804+
#define RECVD_HW_READY_TIMEOUT (10 * HZ)
805+
800806
/**
801807
* _ish_ipc_reset() - IPC reset
802808
* @dev: ishtp device pointer
@@ -831,7 +837,8 @@ static int _ish_ipc_reset(struct ishtp_device *dev)
831837
}
832838

833839
wait_event_interruptible_timeout(dev->wait_hw_ready,
834-
dev->recvd_hw_ready, 2 * HZ);
840+
dev->recvd_hw_ready,
841+
RECVD_HW_READY_TIMEOUT);
835842
if (!dev->recvd_hw_ready) {
836843
dev_err(dev->devc, "Timed out waiting for HW ready\n");
837844
rv = -ENODEV;
@@ -855,21 +862,7 @@ int ish_hw_start(struct ishtp_device *dev)
855862
set_host_ready(dev);
856863

857864
/* After that we can enable ISH DMA operation and wakeup ISHFW */
858-
ish_wakeup(dev);
859-
860-
/* wait for FW-initiated reset flow */
861-
if (!dev->recvd_hw_ready)
862-
wait_event_interruptible_timeout(dev->wait_hw_ready,
863-
dev->recvd_hw_ready,
864-
10 * HZ);
865-
866-
if (!dev->recvd_hw_ready) {
867-
dev_err(dev->devc,
868-
"[ishtp-ish]: Timed out waiting for FW-initiated reset\n");
869-
return -ENODEV;
870-
}
871-
872-
return 0;
865+
return ish_wakeup(dev);
873866
}
874867

875868
/**

0 commit comments

Comments
 (0)