summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/tegra
diff options
context:
space:
mode:
authorThierry Reding <treding@nvidia.com>2018-05-04 15:58:26 +0300
committerThierry Reding <treding@nvidia.com>2018-05-04 18:07:22 +0300
commitdd99b4b48833a55817d78a48034b606664b1fff8 (patch)
treee0ecab4a6311c16bfd92d3c33aef849babc6bd96 /drivers/gpu/drm/tegra
parentfd5ec0dc34dafa6c5bb46770ca283ae90a4db3c7 (diff)
downloadlinux-dd99b4b48833a55817d78a48034b606664b1fff8.tar.xz
drm/tegra: gr2d: Properly clean up resources
Failure to register the Tegra DRM client would leak the resources. Move cleanup code to error unwinding gotos to fix that and share the cleanup code with the other error paths. Reviewed-by: Dmitry Osipenko <digetx@gmail.com> Signed-off-by: Thierry Reding <treding@nvidia.com>
Diffstat (limited to 'drivers/gpu/drm/tegra')
-rw-r--r--drivers/gpu/drm/tegra/gr2d.c28
1 files changed, 22 insertions, 6 deletions
diff --git a/drivers/gpu/drm/tegra/gr2d.c b/drivers/gpu/drm/tegra/gr2d.c
index 8eb530a85dd0..0b42e99da8ad 100644
--- a/drivers/gpu/drm/tegra/gr2d.c
+++ b/drivers/gpu/drm/tegra/gr2d.c
@@ -42,8 +42,9 @@ static int gr2d_init(struct host1x_client *client)
client->syncpts[0] = host1x_syncpt_request(client, flags);
if (!client->syncpts[0]) {
- host1x_channel_put(gr2d->channel);
- return -ENOMEM;
+ err = -ENOMEM;
+ dev_err(client->dev, "failed to request syncpoint: %d\n", err);
+ goto put;
}
if (tegra->domain) {
@@ -55,15 +56,30 @@ static int gr2d_init(struct host1x_client *client)
dev_err(client->dev,
"failed to attach to domain: %d\n",
err);
- host1x_syncpt_free(client->syncpts[0]);
- host1x_channel_put(gr2d->channel);
iommu_group_put(gr2d->group);
- return err;
+ goto free;
}
}
}
- return tegra_drm_register_client(tegra, drm);
+ err = tegra_drm_register_client(tegra, drm);
+ if (err < 0) {
+ dev_err(client->dev, "failed to register client: %d\n", err);
+ goto detach;
+ }
+
+ return 0;
+
+detach:
+ if (gr2d->group) {
+ iommu_detach_group(tegra->domain, gr2d->group);
+ iommu_group_put(gr2d->group);
+ }
+free:
+ host1x_syncpt_free(client->syncpts[0]);
+put:
+ host1x_channel_put(gr2d->channel);
+ return err;
}
static int gr2d_exit(struct host1x_client *client)