diff options
Diffstat (limited to 'drivers/gpu/nvgpu/os/linux/pci.c')
-rw-r--r-- | drivers/gpu/nvgpu/os/linux/pci.c | 39 |
1 files changed, 34 insertions, 5 deletions
diff --git a/drivers/gpu/nvgpu/os/linux/pci.c b/drivers/gpu/nvgpu/os/linux/pci.c index dba8a5df..3493b105 100644 --- a/drivers/gpu/nvgpu/os/linux/pci.c +++ b/drivers/gpu/nvgpu/os/linux/pci.c | |||
@@ -590,11 +590,21 @@ static int nvgpu_pci_pm_runtime_suspend(struct device *dev) | |||
590 | return 0; | 590 | return 0; |
591 | } | 591 | } |
592 | 592 | ||
593 | static int nvgpu_pci_pm_resume(struct device *dev) | ||
594 | { | ||
595 | return gk20a_pm_finalize_poweron(dev); | ||
596 | } | ||
597 | |||
598 | static int nvgpu_pci_pm_suspend(struct device *dev) | ||
599 | { | ||
600 | return 0; | ||
601 | } | ||
602 | |||
593 | static const struct dev_pm_ops nvgpu_pci_pm_ops = { | 603 | static const struct dev_pm_ops nvgpu_pci_pm_ops = { |
594 | .runtime_resume = nvgpu_pci_pm_runtime_resume, | 604 | .runtime_resume = nvgpu_pci_pm_runtime_resume, |
595 | .runtime_suspend = nvgpu_pci_pm_runtime_suspend, | 605 | .runtime_suspend = nvgpu_pci_pm_runtime_suspend, |
596 | .resume = nvgpu_pci_pm_runtime_resume, | 606 | .resume = nvgpu_pci_pm_resume, |
597 | .suspend = nvgpu_pci_pm_runtime_suspend, | 607 | .suspend = nvgpu_pci_pm_suspend, |
598 | }; | 608 | }; |
599 | #endif | 609 | #endif |
600 | 610 | ||
@@ -611,10 +621,15 @@ static int nvgpu_pci_pm_init(struct device *dev) | |||
611 | g->railgate_delay); | 621 | g->railgate_delay); |
612 | 622 | ||
613 | /* | 623 | /* |
614 | * Runtime PM for PCI devices is disabled by default, | 624 | * set gpu dev's use_autosuspend flag to allow |
615 | * so we need to enable it first | 625 | * runtime power management of GPU |
616 | */ | 626 | */ |
617 | pm_runtime_use_autosuspend(dev); | 627 | pm_runtime_use_autosuspend(dev); |
628 | |||
629 | /* | ||
630 | * runtime PM for PCI devices is forbidden | ||
631 | * by default, so unblock RTPM of GPU | ||
632 | */ | ||
618 | pm_runtime_put_noidle(dev); | 633 | pm_runtime_put_noidle(dev); |
619 | pm_runtime_allow(dev); | 634 | pm_runtime_allow(dev); |
620 | } | 635 | } |
@@ -622,6 +637,19 @@ static int nvgpu_pci_pm_init(struct device *dev) | |||
622 | return 0; | 637 | return 0; |
623 | } | 638 | } |
624 | 639 | ||
640 | static int nvgpu_pci_pm_deinit(struct device *dev) | ||
641 | { | ||
642 | #ifdef CONFIG_PM | ||
643 | struct gk20a *g = get_gk20a(dev); | ||
644 | |||
645 | if (!nvgpu_is_enabled(g, NVGPU_CAN_RAILGATE)) | ||
646 | pm_runtime_enable(dev); | ||
647 | else | ||
648 | pm_runtime_forbid(dev); | ||
649 | #endif | ||
650 | return 0; | ||
651 | } | ||
652 | |||
625 | static int nvgpu_pci_probe(struct pci_dev *pdev, | 653 | static int nvgpu_pci_probe(struct pci_dev *pdev, |
626 | const struct pci_device_id *pent) | 654 | const struct pci_device_id *pent) |
627 | { | 655 | { |
@@ -826,11 +854,12 @@ static void nvgpu_pci_remove(struct pci_dev *pdev) | |||
826 | enable_irq(g->irq_stall); | 854 | enable_irq(g->irq_stall); |
827 | } | 855 | } |
828 | #endif | 856 | #endif |
857 | nvgpu_pci_pm_deinit(&pdev->dev); | ||
829 | 858 | ||
830 | /* free allocated platform data space */ | 859 | /* free allocated platform data space */ |
860 | gk20a_get_platform(&pdev->dev)->g = NULL; | ||
831 | nvgpu_kfree(g, gk20a_get_platform(&pdev->dev)); | 861 | nvgpu_kfree(g, gk20a_get_platform(&pdev->dev)); |
832 | 862 | ||
833 | gk20a_get_platform(&pdev->dev)->g = NULL; | ||
834 | gk20a_put(g); | 863 | gk20a_put(g); |
835 | } | 864 | } |
836 | 865 | ||