Commit 16b06b15 authored by Song Hongyan's avatar Song Hongyan Committed by Greg Kroah-Hartman

HID: intel-ish: ipc: handle PIMR before ish_wakeup also clear PISR busy_clear bit

[ Upstream commit 2edefc05 ]

Host driver should handle interrupt mask register earlier than wake up ish FW
else there will be conditions when FW interrupt comes, host PIMR register still
not set ready, so move the interrupt mask setting before ish_wakeup.

Clear PISR busy_clear bit in ish_irq_handler. If not clear, there will be
conditions host driver received a busy_clear interrupt (before the busy_clear
mask bit is ready), it will return IRQ_NONE after check_generated_interrupt,
the interrupt will never be cleared, causing the DEVICE not sending following
IRQ.

Since PISR clear should not be called for the CHV device we do this change.
After the change, both ISH2HOST interrupt and busy_clear interrupt will be
considered as interrupt from ISH, busy_clear interrupt will return IRQ_HANDLED
from IPC_IS_BUSY check.
Signed-off-by: default avatarSong Hongyan <hongyan.song@intel.com>
Acked-by: default avatarSrinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 67c2be16
...@@ -91,7 +91,10 @@ static bool check_generated_interrupt(struct ishtp_device *dev) ...@@ -91,7 +91,10 @@ static bool check_generated_interrupt(struct ishtp_device *dev)
IPC_INT_FROM_ISH_TO_HOST_CHV_AB(pisr_val); IPC_INT_FROM_ISH_TO_HOST_CHV_AB(pisr_val);
} else { } else {
pisr_val = ish_reg_read(dev, IPC_REG_PISR_BXT); pisr_val = ish_reg_read(dev, IPC_REG_PISR_BXT);
interrupt_generated = IPC_INT_FROM_ISH_TO_HOST_BXT(pisr_val); interrupt_generated = !!pisr_val;
/* only busy-clear bit is RW, others are RO */
if (pisr_val)
ish_reg_write(dev, IPC_REG_PISR_BXT, pisr_val);
} }
return interrupt_generated; return interrupt_generated;
...@@ -843,11 +846,11 @@ int ish_hw_start(struct ishtp_device *dev) ...@@ -843,11 +846,11 @@ int ish_hw_start(struct ishtp_device *dev)
{ {
ish_set_host_rdy(dev); ish_set_host_rdy(dev);
set_host_ready(dev);
/* After that we can enable ISH DMA operation and wakeup ISHFW */ /* After that we can enable ISH DMA operation and wakeup ISHFW */
ish_wakeup(dev); ish_wakeup(dev);
set_host_ready(dev);
/* wait for FW-initiated reset flow */ /* wait for FW-initiated reset flow */
if (!dev->recvd_hw_ready) if (!dev->recvd_hw_ready)
wait_event_interruptible_timeout(dev->wait_hw_ready, wait_event_interruptible_timeout(dev->wait_hw_ready,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment