summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/tegra/vic.c
diff options
context:
space:
mode:
authorMikko Perttunen <mperttunen@nvidia.com>2023-06-13 12:52:14 +0300
committerThierry Reding <treding@nvidia.com>2023-07-27 19:41:59 +0300
commit62fa0a985e2c99f716688e6bfbc37338a283a301 (patch)
treea5524368d0b32e0b2df19f35563c2795962ac8f7 /drivers/gpu/drm/tegra/vic.c
parent3c5a5df9c39bd0e408fdf60966b2c8dc2bb9a411 (diff)
downloadlinux-62fa0a985e2c99f716688e6bfbc37338a283a301.tar.xz
drm/tegra: Enable runtime PM during probe
Currently, engine drivers only enable runtime PM during the host1x init callback. This can happen slightly later than the probe, which can cause the power domain to intermittently not be turned off after probe. My hypothesis is that there is a race condition between the post-probe power domain poweroff that is done from a queued work, and the pm_runtime_enable call happening in the host1x init callback. If the pm_runtime_enable call happens first, everything is OK and the power off work can disable the power domain as PM runtime is enabled and the device is runtime suspended. If power off work runs first, PM runtime is still disabled for the device and the domain must be kept powered. Resolve the issue by moving the runtime PM enablement to the probe function. Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com> Signed-off-by: Thierry Reding <treding@nvidia.com> Link: https://patchwork.freedesktop.org/patch/msgid/20230613095215.2497004-1-cyndis@kapsi.fi
Diffstat (limited to 'drivers/gpu/drm/tegra/vic.c')
-rw-r--r--drivers/gpu/drm/tegra/vic.c17
1 files changed, 7 insertions, 10 deletions
diff --git a/drivers/gpu/drm/tegra/vic.c b/drivers/gpu/drm/tegra/vic.c
index 5da989ac700e..73c356f1c901 100644
--- a/drivers/gpu/drm/tegra/vic.c
+++ b/drivers/gpu/drm/tegra/vic.c
@@ -141,13 +141,9 @@ static int vic_init(struct host1x_client *client)
goto free_channel;
}
- pm_runtime_enable(client->dev);
- pm_runtime_use_autosuspend(client->dev);
- pm_runtime_set_autosuspend_delay(client->dev, 500);
-
err = tegra_drm_register_client(tegra, drm);
if (err < 0)
- goto disable_rpm;
+ goto free_syncpt;
/*
* Inherit the DMA parameters (such as maximum segment size) from the
@@ -157,10 +153,7 @@ static int vic_init(struct host1x_client *client)
return 0;
-disable_rpm:
- pm_runtime_dont_use_autosuspend(client->dev);
- pm_runtime_force_suspend(client->dev);
-
+free_syncpt:
host1x_syncpt_put(client->syncpts[0]);
free_channel:
host1x_channel_put(vic->channel);
@@ -527,6 +520,10 @@ static int vic_probe(struct platform_device *pdev)
goto exit_falcon;
}
+ pm_runtime_enable(dev);
+ pm_runtime_use_autosuspend(dev);
+ pm_runtime_set_autosuspend_delay(dev, 500);
+
return 0;
exit_falcon:
@@ -539,8 +536,8 @@ static void vic_remove(struct platform_device *pdev)
{
struct vic *vic = platform_get_drvdata(pdev);
+ pm_runtime_disable(&pdev->dev);
host1x_client_unregister(&vic->client.base);
-
falcon_exit(&vic->falcon);
}