drm/tegra: dc: Request/free syncpoint at init/exit

syncpoints are resources provided by host1x and their lifetime is tied
to the host1x device. They are not properly reference counted either, so
removing the host1x device before any of its clients causes a use-after-
free error. Adding proper reference counting would be a major enterprise
so work around it for now by requesting and freeing the syncpoint at
init and exit time, respectively. The host1x device is guaranteed to be
around at this point.

Signed-off-by: Thierry Reding <treding@nvidia.com>
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index ddefb85..b463fd9 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -1696,6 +1696,7 @@
 static int tegra_dc_init(struct host1x_client *client)
 {
 	struct drm_device *drm = dev_get_drvdata(client->parent);
+	unsigned long flags = HOST1X_SYNCPT_CLIENT_MANAGED;
 	struct tegra_dc *dc = host1x_client_to_dc(client);
 	struct tegra_drm *tegra = drm->dev_private;
 	struct drm_plane *primary = NULL;
@@ -1703,6 +1704,10 @@
 	u32 value;
 	int err;
 
+	dc->syncpt = host1x_syncpt_request(dc->dev, flags);
+	if (!dc->syncpt)
+		dev_warn(dc->dev, "failed to allocate syncpoint\n");
+
 	if (tegra->domain) {
 		err = iommu_attach_device(tegra->domain, dc->dev);
 		if (err < 0) {
@@ -1849,6 +1854,8 @@
 		dc->domain = NULL;
 	}
 
+	host1x_syncpt_free(dc->syncpt);
+
 	return 0;
 }
 
@@ -1961,7 +1968,6 @@
 
 static int tegra_dc_probe(struct platform_device *pdev)
 {
-	unsigned long flags = HOST1X_SYNCPT_CLIENT_MANAGED;
 	const struct of_device_id *id;
 	struct resource *regs;
 	struct tegra_dc *dc;
@@ -2036,10 +2042,6 @@
 		return -ENXIO;
 	}
 
-	dc->syncpt = host1x_syncpt_request(&pdev->dev, flags);
-	if (!dc->syncpt)
-		dev_warn(&pdev->dev, "failed to allocate syncpoint\n");
-
 	INIT_LIST_HEAD(&dc->client.list);
 	dc->client.ops = &dc_client_ops;
 	dc->client.dev = &pdev->dev;
@@ -2067,8 +2069,6 @@
 	struct tegra_dc *dc = platform_get_drvdata(pdev);
 	int err;
 
-	host1x_syncpt_free(dc->syncpt);
-
 	err = host1x_client_unregister(&dc->client);
 	if (err < 0) {
 		dev_err(&pdev->dev, "failed to unregister host1x client: %d\n",