Skip to content

Commit b42dc06

Browse files
ausyskingregkh
authored andcommitted
mei: always use domain runtime pm callbacks.
This patch fixes a regression caused by the new changes in the "run wake" handlers. The mei devices that support D0i3 are no longer receiving an interrupt after entering runtime suspend state and will stall. pci_dev_run_wake function now returns "true" for some devices (including mei) for which it used to return "false", arguably incorrectly as "run wake" used to mean that wakeup signals can be generated for a device in the working state of the system, so it could not be enabled or disabled before too. MEI maps runtime suspend/resume to its own defined power gating (PG) states, (D0i3 or other depending on generation), hence we need to go around the native PCI runtime service which eventually brings the device into D3cold/hot state, but the mei devices cannot wake up from D3 unlike from D0i3/PG state, which keeps irq running. To get around PCI device native runtime pm, MEI uses runtime pm domain handlers which take precedence. Cc: <[email protected]> #4.13+ Signed-off-by: Alexander Usyskin <[email protected]> Signed-off-by: Tomas Winkler <[email protected]> Acked-by: Rafael J. Wysocki <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent d81fa66 commit b42dc06

File tree

2 files changed

+22
-29
lines changed

2 files changed

+22
-29
lines changed

drivers/misc/mei/pci-me.c

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -226,12 +226,15 @@ static int mei_me_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
226226
pdev->dev_flags |= PCI_DEV_FLAGS_NEEDS_RESUME;
227227

228228
/*
229-
* For not wake-able HW runtime pm framework
230-
* can't be used on pci device level.
231-
* Use domain runtime pm callbacks instead.
232-
*/
233-
if (!pci_dev_run_wake(pdev))
234-
mei_me_set_pm_domain(dev);
229+
* ME maps runtime suspend/resume to D0i states,
230+
* hence we need to go around native PCI runtime service which
231+
* eventually brings the device into D3cold/hot state,
232+
* but the mei device cannot wake up from D3 unlike from D0i3.
233+
* To get around the PCI device native runtime pm,
234+
* ME uses runtime pm domain handlers which take precedence
235+
* over the driver's pm handlers.
236+
*/
237+
mei_me_set_pm_domain(dev);
235238

236239
if (mei_pg_is_enabled(dev))
237240
pm_runtime_put_noidle(&pdev->dev);
@@ -271,8 +274,7 @@ static void mei_me_shutdown(struct pci_dev *pdev)
271274
dev_dbg(&pdev->dev, "shutdown\n");
272275
mei_stop(dev);
273276

274-
if (!pci_dev_run_wake(pdev))
275-
mei_me_unset_pm_domain(dev);
277+
mei_me_unset_pm_domain(dev);
276278

277279
mei_disable_interrupts(dev);
278280
free_irq(pdev->irq, dev);
@@ -300,8 +302,7 @@ static void mei_me_remove(struct pci_dev *pdev)
300302
dev_dbg(&pdev->dev, "stop\n");
301303
mei_stop(dev);
302304

303-
if (!pci_dev_run_wake(pdev))
304-
mei_me_unset_pm_domain(dev);
305+
mei_me_unset_pm_domain(dev);
305306

306307
mei_disable_interrupts(dev);
307308

drivers/misc/mei/pci-txe.c

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -144,12 +144,14 @@ static int mei_txe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
144144
pdev->dev_flags |= PCI_DEV_FLAGS_NEEDS_RESUME;
145145

146146
/*
147-
* For not wake-able HW runtime pm framework
148-
* can't be used on pci device level.
149-
* Use domain runtime pm callbacks instead.
150-
*/
151-
if (!pci_dev_run_wake(pdev))
152-
mei_txe_set_pm_domain(dev);
147+
* TXE maps runtime suspend/resume to own power gating states,
148+
* hence we need to go around native PCI runtime service which
149+
* eventually brings the device into D3cold/hot state.
150+
* But the TXE device cannot wake up from D3 unlike from own
151+
* power gating. To get around PCI device native runtime pm,
152+
* TXE uses runtime pm domain handlers which take precedence.
153+
*/
154+
mei_txe_set_pm_domain(dev);
153155

154156
pm_runtime_put_noidle(&pdev->dev);
155157

@@ -186,8 +188,7 @@ static void mei_txe_shutdown(struct pci_dev *pdev)
186188
dev_dbg(&pdev->dev, "shutdown\n");
187189
mei_stop(dev);
188190

189-
if (!pci_dev_run_wake(pdev))
190-
mei_txe_unset_pm_domain(dev);
191+
mei_txe_unset_pm_domain(dev);
191192

192193
mei_disable_interrupts(dev);
193194
free_irq(pdev->irq, dev);
@@ -215,8 +216,7 @@ static void mei_txe_remove(struct pci_dev *pdev)
215216

216217
mei_stop(dev);
217218

218-
if (!pci_dev_run_wake(pdev))
219-
mei_txe_unset_pm_domain(dev);
219+
mei_txe_unset_pm_domain(dev);
220220

221221
mei_disable_interrupts(dev);
222222
free_irq(pdev->irq, dev);
@@ -318,15 +318,7 @@ static int mei_txe_pm_runtime_suspend(struct device *device)
318318
else
319319
ret = -EAGAIN;
320320

321-
/*
322-
* If everything is okay we're about to enter PCI low
323-
* power state (D3) therefor we need to disable the
324-
* interrupts towards host.
325-
* However if device is not wakeable we do not enter
326-
* D-low state and we need to keep the interrupt kicking
327-
*/
328-
if (!ret && pci_dev_run_wake(pdev))
329-
mei_disable_interrupts(dev);
321+
/* keep irq on we are staying in D0 */
330322

331323
dev_dbg(&pdev->dev, "rpm: txe: runtime suspend ret=%d\n", ret);
332324

0 commit comments

Comments
 (0)