OMAPDSS: cleanup dss_recheck_connections further

Cleanup dss_recheck_connections, move and rename it to a static
dss_init_connections function inside display.c. Improve the function to
return errors, and implement a matching dss_uninit_connections that can
be used to free the mgr->dssdev link.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
index f719010..db83ae8 100644
--- a/drivers/video/omap2/dss/display.c
+++ b/drivers/video/omap2/dss/display.c
@@ -320,11 +320,66 @@
 }
 EXPORT_SYMBOL(omapdss_default_get_timings);
 
+/*
+ * Connect dssdev to a manager if the manager is free or if force is specified.
+ * Connect all overlays to that manager if they are free or if force is
+ * specified.
+ */
+static int dss_init_connections(struct omap_dss_device *dssdev, bool force)
+{
+	struct omap_overlay_manager *mgr;
+	int i, r;
+
+	WARN_ON(dssdev->manager);
+
+	mgr = omap_dss_get_overlay_manager(dssdev->channel);
+
+	if (mgr->device && !force)
+		return 0;
+
+	if (mgr->device)
+		mgr->unset_device(mgr);
+
+	r = mgr->set_device(mgr, dssdev);
+	if (r) {
+		DSSERR("failed to set initial manager\n");
+		return r;
+	}
+
+	for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
+		struct omap_overlay *ovl = omap_dss_get_overlay(i);
+
+		if (!ovl->manager || force) {
+			if (ovl->manager)
+				ovl->unset_manager(ovl);
+
+			r = ovl->set_manager(ovl, mgr);
+			if (r) {
+				DSSERR("failed to set initial overlay\n");
+				return r;
+			}
+		}
+	}
+
+	return 0;
+}
+
+static void dss_uninit_connections(struct omap_dss_device *dssdev)
+{
+	if (dssdev->manager)
+		dssdev->manager->unset_device(dssdev->manager);
+}
+
 int dss_init_device(struct platform_device *pdev,
 		struct omap_dss_device *dssdev)
 {
 	struct device_attribute *attr;
 	int i, r;
+	const char *def_disp_name = dss_get_default_display_name();
+	bool force;
+
+	force = def_disp_name && strcmp(def_disp_name, dssdev->name) == 0;
+	dss_init_connections(dssdev, force);
 
 	/* create device sysfs files */
 	i = 0;
@@ -336,6 +391,8 @@
 				device_remove_file(&dssdev->dev, attr);
 			}
 
+			dss_uninit_connections(dssdev);
+
 			DSSERR("failed to create sysfs file\n");
 			return r;
 		}
@@ -348,6 +405,8 @@
 		while ((attr = display_sysfs_attrs[i++]) != NULL)
 			device_remove_file(&dssdev->dev, attr);
 
+		dss_uninit_connections(dssdev);
+
 		DSSERR("failed to create sysfs display link\n");
 		return r;
 	}
@@ -366,8 +425,7 @@
 	while ((attr = display_sysfs_attrs[i++]) != NULL)
 		device_remove_file(&dssdev->dev, attr);
 
-	if (dssdev->manager)
-		dssdev->manager->unset_device(dssdev->manager);
+	dss_uninit_connections(dssdev);
 }
 
 static int dss_suspend_device(struct device *dev, void *data)