aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/mei/pci-txe.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/mei/pci-txe.c')
-rw-r--r--drivers/misc/mei/pci-txe.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/drivers/misc/mei/pci-txe.c b/drivers/misc/mei/pci-txe.c
index 31d86e76fb7f..2c3f5625a04e 100644
--- a/drivers/misc/mei/pci-txe.c
+++ b/drivers/misc/mei/pci-txe.c
@@ -41,6 +41,13 @@ static const struct pci_device_id mei_txe_pci_tbl[] = {
41}; 41};
42MODULE_DEVICE_TABLE(pci, mei_txe_pci_tbl); 42MODULE_DEVICE_TABLE(pci, mei_txe_pci_tbl);
43 43
44#ifdef CONFIG_PM_RUNTIME
45static inline void mei_txe_set_pm_domain(struct mei_device *dev);
46static inline void mei_txe_unset_pm_domain(struct mei_device *dev);
47#else
48static inline void mei_txe_set_pm_domain(struct mei_device *dev) {}
49static inline void mei_txe_unset_pm_domain(struct mei_device *dev) {}
50#endif /* CONFIG_PM_RUNTIME */
44 51
45static void mei_txe_pci_iounmap(struct pci_dev *pdev, struct mei_txe_hw *hw) 52static void mei_txe_pci_iounmap(struct pci_dev *pdev, struct mei_txe_hw *hw)
46{ 53{
@@ -147,6 +154,14 @@ static int mei_txe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
147 154
148 pci_set_drvdata(pdev, dev); 155 pci_set_drvdata(pdev, dev);
149 156
157 /*
158 * For not wake-able HW runtime pm framework
159 * can't be used on pci device level.
160 * Use domain runtime pm callbacks instead.
161 */
162 if (!pci_dev_run_wake(pdev))
163 mei_txe_set_pm_domain(dev);
164
150 pm_runtime_put_noidle(&pdev->dev); 165 pm_runtime_put_noidle(&pdev->dev);
151 166
152 return 0; 167 return 0;
@@ -199,6 +214,9 @@ static void mei_txe_remove(struct pci_dev *pdev)
199 214
200 mei_stop(dev); 215 mei_stop(dev);
201 216
217 if (!pci_dev_run_wake(pdev))
218 mei_txe_unset_pm_domain(dev);
219
202 /* disable interrupts */ 220 /* disable interrupts */
203 mei_disable_interrupts(dev); 221 mei_disable_interrupts(dev);
204 free_irq(pdev->irq, dev); 222 free_irq(pdev->irq, dev);
@@ -350,6 +368,37 @@ static int mei_txe_pm_runtime_resume(struct device *device)
350 368
351 return ret; 369 return ret;
352} 370}
371
372/**
373 * mei_txe_set_pm_domain - fill and set pm domian stucture for device
374 *
375 * @dev: mei_device
376 */
377static inline void mei_txe_set_pm_domain(struct mei_device *dev)
378{
379 struct pci_dev *pdev = dev->pdev;
380
381 if (pdev->dev.bus && pdev->dev.bus->pm) {
382 dev->pg_domain.ops = *pdev->dev.bus->pm;
383
384 dev->pg_domain.ops.runtime_suspend = mei_txe_pm_runtime_suspend;
385 dev->pg_domain.ops.runtime_resume = mei_txe_pm_runtime_resume;
386 dev->pg_domain.ops.runtime_idle = mei_txe_pm_runtime_idle;
387
388 pdev->dev.pm_domain = &dev->pg_domain;
389 }
390}
391
392/**
393 * mei_txe_unset_pm_domain - clean pm domian stucture for device
394 *
395 * @dev: mei_device
396 */
397static inline void mei_txe_unset_pm_domain(struct mei_device *dev)
398{
399 /* stop using pm callbacks if any */
400 dev->pdev->dev.pm_domain = NULL;
401}
353#endif /* CONFIG_PM_RUNTIME */ 402#endif /* CONFIG_PM_RUNTIME */
354 403
355#ifdef CONFIG_PM 404#ifdef CONFIG_PM