gpu: nvgpu: add pm_rumtime fixes

Runtime PM is enabled only for iGPU and not for dGPU. For dGPU,
the .probe() of driver pm_runtime_disable()s, if rail-gating is
not enabled. With nvgpu kernel module load/unload, .probe() is
called multiple times for same struct device *. This results
in an overflow of disable_depth (3 bit refcount) and enables
runtime PM on 8th iteration and calls RTPM routines even if it's
disabled.

To effectively manage pm_runtime_disable(), move it from common
nvgpu_remove() to iGPU/dGPU specific routines.

Also, add restore pm_runtime state of device on driver .remove().

Bug 1987855

Change-Id: I781278da546ef9c9ef7d7da7dbea0757df32716f
Signed-off-by: Nitin Kumbhar <nkumbhar@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1770804
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
Nitin Kumbhar
2018-07-04 22:59:36 +05:30
committed by mobile promotions
parent 0b7fbc1ff4
commit 97c6a10928
2 changed files with 44 additions and 8 deletions

View File

@@ -590,11 +590,21 @@ static int nvgpu_pci_pm_runtime_suspend(struct device *dev)
return 0;
}
static int nvgpu_pci_pm_resume(struct device *dev)
{
return gk20a_pm_finalize_poweron(dev);
}
static int nvgpu_pci_pm_suspend(struct device *dev)
{
return 0;
}
static const struct dev_pm_ops nvgpu_pci_pm_ops = {
.runtime_resume = nvgpu_pci_pm_runtime_resume,
.runtime_suspend = nvgpu_pci_pm_runtime_suspend,
.resume = nvgpu_pci_pm_runtime_resume,
.suspend = nvgpu_pci_pm_runtime_suspend,
.resume = nvgpu_pci_pm_resume,
.suspend = nvgpu_pci_pm_suspend,
};
#endif
@@ -611,10 +621,15 @@ static int nvgpu_pci_pm_init(struct device *dev)
g->railgate_delay);
/*
* Runtime PM for PCI devices is disabled by default,
* so we need to enable it first
* set gpu dev's use_autosuspend flag to allow
* runtime power management of GPU
*/
pm_runtime_use_autosuspend(dev);
/*
* runtime PM for PCI devices is forbidden
* by default, so unblock RTPM of GPU
*/
pm_runtime_put_noidle(dev);
pm_runtime_allow(dev);
}
@@ -622,6 +637,19 @@ static int nvgpu_pci_pm_init(struct device *dev)
return 0;
}
static int nvgpu_pci_pm_deinit(struct device *dev)
{
#ifdef CONFIG_PM
struct gk20a *g = get_gk20a(dev);
if (!nvgpu_is_enabled(g, NVGPU_CAN_RAILGATE))
pm_runtime_enable(dev);
else
pm_runtime_forbid(dev);
#endif
return 0;
}
static int nvgpu_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *pent)
{
@@ -826,11 +854,12 @@ static void nvgpu_pci_remove(struct pci_dev *pdev)
enable_irq(g->irq_stall);
}
#endif
nvgpu_pci_pm_deinit(&pdev->dev);
/* free allocated platform data space */
gk20a_get_platform(&pdev->dev)->g = NULL;
nvgpu_kfree(g, gk20a_get_platform(&pdev->dev));
gk20a_get_platform(&pdev->dev)->g = NULL;
gk20a_put(g);
}