]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
drm/tegra: gr2d: Properly clean up resources
authorThierry Reding <treding@nvidia.com>
Fri, 4 May 2018 12:58:26 +0000 (14:58 +0200)
committerThierry Reding <treding@nvidia.com>
Fri, 4 May 2018 15:07:22 +0000 (17:07 +0200)
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>
drivers/gpu/drm/tegra/gr2d.c

index 8eb530a85dd05e27ea98c1b94a0f3554947783fc..0b42e99da8adedb18d9c8bedaaafe367a49f7ddb 100644 (file)
@@ -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)