]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - drivers/video/omap2/dss/manager-sysfs.c
OMAPDSS: Implement display (dis)connect support
[mirror_ubuntu-bionic-kernel.git] / drivers / video / omap2 / dss / manager-sysfs.c
index 9a2fb59b6f897695cf961cc73342c2da1b70f277..de7e7b5b1b7c05d7b3371edd8d9e1205abfdeec5 100644 (file)
@@ -50,6 +50,7 @@ static ssize_t manager_display_store(struct omap_overlay_manager *mgr,
        int r = 0;
        size_t len = size;
        struct omap_dss_device *dssdev = NULL;
+       struct omap_dss_device *old_dssdev;
 
        int match(struct omap_dss_device *dssdev, void *data)
        {
@@ -66,32 +67,44 @@ static ssize_t manager_display_store(struct omap_overlay_manager *mgr,
        if (len > 0 && dssdev == NULL)
                return -EINVAL;
 
-       if (dssdev)
+       if (dssdev) {
                DSSDBG("display %s found\n", dssdev->name);
 
-       if (mgr->output) {
-               r = mgr->unset_output(mgr);
-               if (r) {
-                       DSSERR("failed to unset current output\n");
+               if (omapdss_device_is_connected(dssdev)) {
+                       DSSERR("new display is already connected\n");
+                       r = -EINVAL;
+                       goto put_device;
+               }
+
+               if (omapdss_device_is_enabled(dssdev)) {
+                       DSSERR("new display is not disabled\n");
+                       r = -EINVAL;
                        goto put_device;
                }
        }
 
-       if (dssdev) {
-               struct omap_dss_output *out = dssdev->output;
-
-               /*
-                * a registered device should have an output connected to it
-                * already
-                */
-               if (!out) {
-                       DSSERR("device has no output connected to it\n");
+       old_dssdev = mgr->get_device(mgr);
+       if (old_dssdev) {
+               if (omapdss_device_is_enabled(old_dssdev)) {
+                       DSSERR("old display is not disabled\n");
+                       r = -EINVAL;
                        goto put_device;
                }
 
-               r = mgr->set_output(mgr, out);
+               old_dssdev->driver->disconnect(old_dssdev);
+       }
+
+       if (dssdev) {
+               r = dssdev->driver->connect(dssdev);
                if (r) {
-                       DSSERR("failed to set manager output\n");
+                       DSSERR("failed to connect new device\n");
+                       goto put_device;
+               }
+
+               old_dssdev = mgr->get_device(mgr);
+               if (old_dssdev != dssdev) {
+                       DSSERR("failed to connect device to this manager\n");
+                       dssdev->driver->disconnect(dssdev);
                        goto put_device;
                }
 
@@ -509,4 +522,6 @@ void dss_manager_kobj_uninit(struct omap_overlay_manager *mgr)
 {
        kobject_del(&mgr->kobj);
        kobject_put(&mgr->kobj);
+
+       memset(&mgr->kobj, 0, sizeof(mgr->kobj));
 }