diff options
Diffstat (limited to 'drivers/misc/mei/pci-txe.c')
-rw-r--r-- | drivers/misc/mei/pci-txe.c | 49 |
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 | }; |
42 | MODULE_DEVICE_TABLE(pci, mei_txe_pci_tbl); | 42 | MODULE_DEVICE_TABLE(pci, mei_txe_pci_tbl); |
43 | 43 | ||
44 | #ifdef CONFIG_PM_RUNTIME | ||
45 | static inline void mei_txe_set_pm_domain(struct mei_device *dev); | ||
46 | static inline void mei_txe_unset_pm_domain(struct mei_device *dev); | ||
47 | #else | ||
48 | static inline void mei_txe_set_pm_domain(struct mei_device *dev) {} | ||
49 | static inline void mei_txe_unset_pm_domain(struct mei_device *dev) {} | ||
50 | #endif /* CONFIG_PM_RUNTIME */ | ||
44 | 51 | ||
45 | static void mei_txe_pci_iounmap(struct pci_dev *pdev, struct mei_txe_hw *hw) | 52 | static 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 | */ | ||
377 | static 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 | */ | ||
397 | static 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 |