diff options
author | Zhang Lixu <lixu.zhang@intel.com> | 2019-08-08 18:21:12 +0800 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2019-08-19 14:01:50 +0200 |
commit | 2db8edaa88c1208f7346c65041120081e2434d2a (patch) | |
tree | 92498be4620a98973a9f02997d922ff51a997927 /drivers/hid/intel-ish-hid | |
parent | c1ca58f6982bb815c27a4a75f0f430f87b624f66 (diff) |
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>
Diffstat (limited to 'drivers/hid/intel-ish-hid')
-rw-r--r-- | drivers/hid/intel-ish-hid/ipc/pci-ish.c | 52 |
1 files changed, 31 insertions, 21 deletions
diff --git a/drivers/hid/intel-ish-hid/ipc/pci-ish.c b/drivers/hid/intel-ish-hid/ipc/pci-ish.c index 89b14d2edd0b..35081f2cf781 100644 --- a/drivers/hid/intel-ish-hid/ipc/pci-ish.c +++ b/drivers/hid/intel-ish-hid/ipc/pci-ish.c @@ -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; |