mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 17:25:35 +03:00
drm/tegra: Enable runtime PM during probe for internal engines
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. Bug 3982357 Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com> Change-Id: I9a10e1dff580affebe05d9cc9ab3e24d1d3ca547 Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2859476 Reviewed-by: Santosh BS <santoshb@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com>
This commit is contained in:
committed by
Laxman Dewangan
parent
63901a1066
commit
5ad064a2bb
@@ -100,13 +100,9 @@ static int nvenc_init(struct host1x_client *client)
|
|||||||
goto free_channel;
|
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);
|
err = tegra_drm_register_client(tegra, drm);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto disable_rpm;
|
goto free_syncpt;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Inherit the DMA parameters (such as maximum segment size) from the
|
* Inherit the DMA parameters (such as maximum segment size) from the
|
||||||
@@ -116,9 +112,7 @@ static int nvenc_init(struct host1x_client *client)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
disable_rpm:
|
free_syncpt:
|
||||||
pm_runtime_dont_use_autosuspend(client->dev);
|
|
||||||
pm_runtime_force_suspend(client->dev);
|
|
||||||
host1x_syncpt_put(client->syncpts[0]);
|
host1x_syncpt_put(client->syncpts[0]);
|
||||||
free_channel:
|
free_channel:
|
||||||
host1x_channel_put(nvenc->channel);
|
host1x_channel_put(nvenc->channel);
|
||||||
@@ -435,6 +429,10 @@ static int nvenc_probe(struct platform_device *pdev)
|
|||||||
goto exit_falcon;
|
goto exit_falcon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pm_runtime_enable(dev);
|
||||||
|
pm_runtime_use_autosuspend(dev);
|
||||||
|
pm_runtime_set_autosuspend_delay(dev, 500);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
exit_falcon:
|
exit_falcon:
|
||||||
@@ -448,6 +446,8 @@ static int nvenc_remove(struct platform_device *pdev)
|
|||||||
struct nvenc *nvenc = platform_get_drvdata(pdev);
|
struct nvenc *nvenc = platform_get_drvdata(pdev);
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
pm_runtime_disable(&pdev->dev);
|
||||||
|
|
||||||
err = host1x_client_unregister(&nvenc->client.base);
|
err = host1x_client_unregister(&nvenc->client.base);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
dev_err(&pdev->dev, "failed to unregister host1x client: %d\n",
|
dev_err(&pdev->dev, "failed to unregister host1x client: %d\n",
|
||||||
|
|||||||
@@ -100,13 +100,9 @@ static int nvjpg_init(struct host1x_client *client)
|
|||||||
goto free_channel;
|
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);
|
err = tegra_drm_register_client(tegra, drm);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto disable_rpm;
|
goto free_syncpt;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Inherit the DMA parameters (such as maximum segment size) from the
|
* Inherit the DMA parameters (such as maximum segment size) from the
|
||||||
@@ -116,9 +112,7 @@ static int nvjpg_init(struct host1x_client *client)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
disable_rpm:
|
free_syncpt:
|
||||||
pm_runtime_dont_use_autosuspend(client->dev);
|
|
||||||
pm_runtime_force_suspend(client->dev);
|
|
||||||
host1x_syncpt_put(client->syncpts[0]);
|
host1x_syncpt_put(client->syncpts[0]);
|
||||||
free_channel:
|
free_channel:
|
||||||
host1x_channel_put(nvjpg->channel);
|
host1x_channel_put(nvjpg->channel);
|
||||||
@@ -435,6 +429,10 @@ static int nvjpg_probe(struct platform_device *pdev)
|
|||||||
goto exit_falcon;
|
goto exit_falcon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pm_runtime_enable(dev);
|
||||||
|
pm_runtime_use_autosuspend(dev);
|
||||||
|
pm_runtime_set_autosuspend_delay(dev, 500);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
exit_falcon:
|
exit_falcon:
|
||||||
@@ -448,6 +446,8 @@ static int nvjpg_remove(struct platform_device *pdev)
|
|||||||
struct nvjpg *nvjpg = platform_get_drvdata(pdev);
|
struct nvjpg *nvjpg = platform_get_drvdata(pdev);
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
pm_runtime_disable(&pdev->dev);
|
||||||
|
|
||||||
err = host1x_client_unregister(&nvjpg->client.base);
|
err = host1x_client_unregister(&nvjpg->client.base);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
dev_err(&pdev->dev, "failed to unregister host1x client: %d\n",
|
dev_err(&pdev->dev, "failed to unregister host1x client: %d\n",
|
||||||
|
|||||||
@@ -103,13 +103,9 @@ static int ofa_init(struct host1x_client *client)
|
|||||||
goto free_channel;
|
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);
|
err = tegra_drm_register_client(tegra, drm);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto disable_rpm;
|
goto free_syncpt;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Inherit the DMA parameters (such as maximum segment size) from the
|
* Inherit the DMA parameters (such as maximum segment size) from the
|
||||||
@@ -119,9 +115,7 @@ static int ofa_init(struct host1x_client *client)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
disable_rpm:
|
free_syncpt:
|
||||||
pm_runtime_dont_use_autosuspend(client->dev);
|
|
||||||
pm_runtime_force_suspend(client->dev);
|
|
||||||
host1x_syncpt_put(client->syncpts[0]);
|
host1x_syncpt_put(client->syncpts[0]);
|
||||||
free_channel:
|
free_channel:
|
||||||
host1x_channel_put(ofa->channel);
|
host1x_channel_put(ofa->channel);
|
||||||
@@ -366,6 +360,10 @@ static int ofa_probe(struct platform_device *pdev)
|
|||||||
goto exit_falcon;
|
goto exit_falcon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pm_runtime_enable(dev);
|
||||||
|
pm_runtime_use_autosuspend(dev);
|
||||||
|
pm_runtime_set_autosuspend_delay(dev, 500);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
exit_falcon:
|
exit_falcon:
|
||||||
@@ -379,6 +377,8 @@ static int ofa_remove(struct platform_device *pdev)
|
|||||||
struct ofa *ofa = platform_get_drvdata(pdev);
|
struct ofa *ofa = platform_get_drvdata(pdev);
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
pm_runtime_disable(&pdev->dev);
|
||||||
|
|
||||||
err = host1x_client_unregister(&ofa->client.base);
|
err = host1x_client_unregister(&ofa->client.base);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
dev_err(&pdev->dev, "failed to unregister host1x client: %d\n",
|
dev_err(&pdev->dev, "failed to unregister host1x client: %d\n",
|
||||||
|
|||||||
Reference in New Issue
Block a user