Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mei: txe: use runtime PG pm domain for non wakeable devices

For non wakeable devices we can't use pci runtime framework
as we are not able to wakeup from D3 states.
Instead we create new pg runtime domain that only drives TXE power
gating protocol to reduce the power consumption.

Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Alexander Usyskin and committed by
Greg Kroah-Hartman
d2d56fae e13fa90c

+49
+49
drivers/misc/mei/pci-txe.c
··· 41 41 }; 42 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 52 static void mei_txe_pci_iounmap(struct pci_dev *pdev, struct mei_txe_hw *hw) 46 53 { ··· 154 147 155 148 pci_set_drvdata(pdev, dev); 156 149 150 + /* 151 + * For not wake-able HW runtime pm framework 152 + * can't be used on pci device level. 153 + * Use domain runtime pm callbacks instead. 154 + */ 155 + if (!pci_dev_run_wake(pdev)) 156 + mei_txe_set_pm_domain(dev); 157 + 157 158 pm_runtime_put_noidle(&pdev->dev); 158 159 159 160 return 0; ··· 213 198 hw = to_txe_hw(dev); 214 199 215 200 mei_stop(dev); 201 + 202 + if (!pci_dev_run_wake(pdev)) 203 + mei_txe_unset_pm_domain(dev); 216 204 217 205 /* disable interrupts */ 218 206 mei_disable_interrupts(dev); ··· 367 349 dev_dbg(&pdev->dev, "rpm: txe: runtime resume ret = %d\n", ret); 368 350 369 351 return ret; 352 + } 353 + 354 + /** 355 + * mei_txe_set_pm_domain - fill and set pm domian stucture for device 356 + * 357 + * @dev: mei_device 358 + */ 359 + static inline void mei_txe_set_pm_domain(struct mei_device *dev) 360 + { 361 + struct pci_dev *pdev = dev->pdev; 362 + 363 + if (pdev->dev.bus && pdev->dev.bus->pm) { 364 + dev->pg_domain.ops = *pdev->dev.bus->pm; 365 + 366 + dev->pg_domain.ops.runtime_suspend = mei_txe_pm_runtime_suspend; 367 + dev->pg_domain.ops.runtime_resume = mei_txe_pm_runtime_resume; 368 + dev->pg_domain.ops.runtime_idle = mei_txe_pm_runtime_idle; 369 + 370 + pdev->dev.pm_domain = &dev->pg_domain; 371 + } 372 + } 373 + 374 + /** 375 + * mei_txe_unset_pm_domain - clean pm domian stucture for device 376 + * 377 + * @dev: mei_device 378 + */ 379 + static inline void mei_txe_unset_pm_domain(struct mei_device *dev) 380 + { 381 + /* stop using pm callbacks if any */ 382 + dev->pdev->dev.pm_domain = NULL; 370 383 } 371 384 #endif /* CONFIG_PM_RUNTIME */ 372 385