1
0
Fork 0

HID: intel-ish-hid: ipc: make ish suspend paths clear

For suspend-to-idle, send suspend message and set N0_D3 flag to put
the ISH into D0i3 state.
For suspend-to-mem, disable the DMA bit before ISH entering D3, and
NO_D3 flag is cleared by default, then the ISH would enter D3.

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.cz>
alistair/sunxi64-5.4-dsi
Zhang Lixu 2019-08-08 18:21:12 +08:00 committed by Jiri Kosina
parent c1ca58f698
commit 2db8edaa88
1 changed files with 31 additions and 21 deletions

View File

@ -223,6 +223,8 @@ static void __maybe_unused ish_resume_handler(struct work_struct *work)
* it means ISH isn't powered off, in this case, send a resume message.
*/
if (fwsts >= FWSTS_SENSOR_APP_LOADED) {
disable_irq_wake(pdev->irq);
ishtp_send_resume(dev);
/* Waiting to get resume response */
@ -255,27 +257,36 @@ static int __maybe_unused ish_suspend(struct device *device)
struct pci_dev *pdev = to_pci_dev(device);
struct ishtp_device *dev = pci_get_drvdata(pdev);
enable_irq_wake(pdev->irq);
/*
* If previous suspend hasn't been asnwered then ISH is likely dead,
* don't attempt nested notification
*/
if (dev->suspend_flag)
return 0;
dev->resume_flag = 0;
dev->suspend_flag = 1;
ishtp_send_suspend(dev);
/* 25 ms should be enough for live ISH to flush all IPC buf */
if (dev->suspend_flag)
wait_event_interruptible_timeout(dev->suspend_wait,
!dev->suspend_flag,
msecs_to_jiffies(25));
if (ish_should_enter_d0i3(pdev)) {
/* Set the NO_D3 flag, the ISH would enter D0i3 */
pdev->dev_flags |= PCI_DEV_FLAGS_NO_D3;
/*
* If previous suspend hasn't been asnwered then ISH is likely
* dead, don't attempt nested notification
*/
if (dev->suspend_flag)
return 0;
dev->resume_flag = 0;
dev->suspend_flag = 1;
ishtp_send_suspend(dev);
/* 25 ms should be enough for live ISH to flush all IPC buf */
if (dev->suspend_flag)
wait_event_interruptible_timeout(dev->suspend_wait,
!dev->suspend_flag,
msecs_to_jiffies(25));
if (dev->suspend_flag) {
/*
* It looks like FW halt, clear the DMA bit, and put
* ISH into D3, and FW would reset on resume.
*/
ish_disable_dma(dev);
} else {
/* Set the NO_D3 flag, the ISH would enter D0i3 */
pdev->dev_flags |= PCI_DEV_FLAGS_NO_D3;
enable_irq_wake(pdev->irq);
}
} else {
/*
* Clear the DMA bit before putting ISH into D3,
@ -304,7 +315,6 @@ static int __maybe_unused ish_resume(struct device *device)
ish_resume_device = device;
dev->resume_flag = 1;
disable_irq_wake(pdev->irq);
schedule_work(&resume_work);
return 0;