return r;
        }
 
-       dst->src = dssdev;
-       dssdev->dst = dst;
-
        ddata->in = in;
        return 0;
 }
        struct panel_drv_data *ddata = to_panel_data(dssdev);
        struct omap_dss_device *in = ddata->in;
 
-       WARN_ON(dst != dssdev->dst);
-       if (dst != dssdev->dst)
-               return;
-
-       dst->src = NULL;
-       dssdev->dst = NULL;
-
        omapdss_device_disconnect(in, &ddata->dssdev);
 
        omap_dss_put_device(in);
 
                return r;
        }
 
-       dst->src = dssdev;
-       dssdev->dst = dst;
-
        ddata->in = in;
        return 0;
 }
        struct panel_drv_data *ddata = to_panel_data(dssdev);
        struct omap_dss_device *in = ddata->in;
 
-       WARN_ON(dst != dssdev->dst);
-       if (dst != dssdev->dst)
-               return;
-
-       dst->src = NULL;
-       dssdev->dst = NULL;
-
        omapdss_device_disconnect(in, &ddata->dssdev);
 
        omap_dss_put_device(in);
 
                return r;
        }
 
-       dst->src = dssdev;
-       dssdev->dst = dst;
-
        gpiod_set_value_cansleep(ddata->ct_cp_hpd_gpio, 1);
        gpiod_set_value_cansleep(ddata->ls_oe_gpio, 1);
 
        struct panel_drv_data *ddata = to_panel_data(dssdev);
        struct omap_dss_device *in = ddata->in;
 
-       WARN_ON(dst != dssdev->dst);
-
-       if (dst != dssdev->dst)
-               return;
-
        gpiod_set_value_cansleep(ddata->ct_cp_hpd_gpio, 0);
        gpiod_set_value_cansleep(ddata->ls_oe_gpio, 0);
 
-       dst->src = NULL;
-       dssdev->dst = NULL;
-
        omapdss_device_disconnect(in, &ddata->dssdev);
 
        omap_dss_put_device(in);
 
 int omapdss_device_connect(struct omap_dss_device *src,
                           struct omap_dss_device *dst)
 {
+       int ret;
+
        dev_dbg(src->dev, "connect\n");
 
        if (omapdss_device_is_connected(src))
                return -EBUSY;
 
        if (src->driver)
-               return src->driver->connect(src);
+               ret = src->driver->connect(src);
        else
-               return src->ops->connect(src, dst);
+               ret = src->ops->connect(src, dst);
+
+       if (ret < 0)
+               return ret;
+
+       if (dst) {
+               dst->src = src;
+               src->dst = dst;
+       }
+
+       return 0;
 }
 EXPORT_SYMBOL_GPL(omapdss_device_connect);
 
                return;
        }
 
+       if (dst) {
+               if (WARN_ON(dst != src->dst))
+                       return;
+
+               dst->src = NULL;
+               src->dst = NULL;
+       }
+
        if (src->driver)
                src->driver->disconnect(src);
        else
 
 {
        struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
 
-       WARN_ON(dst != dssdev->dst);
-
-       if (dst != dssdev->dst)
-               return;
-
        omapdss_output_unset_device(dssdev);
 
        dss_mgr_disconnect(&dpi->output, dssdev);
 
 {
        struct dsi_data *dsi = to_dsi_data(dssdev);
 
-       WARN_ON(dst != dssdev->dst);
-
-       if (dst != dssdev->dst)
-               return;
-
        omapdss_output_unset_device(dssdev);
 
        dss_mgr_disconnect(&dsi->output, dssdev);
 
 {
        struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
 
-       WARN_ON(dst != dssdev->dst);
-
-       if (dst != dssdev->dst)
-               return;
-
        omapdss_output_unset_device(dssdev);
 
        dss_mgr_disconnect(&hdmi->output, dssdev);
 
 {
        struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
 
-       WARN_ON(dst != dssdev->dst);
-
-       if (dst != dssdev->dst)
-               return;
-
        omapdss_output_unset_device(dssdev);
 
        dss_mgr_disconnect(&hdmi->output, dssdev);
 
 
        struct module *owner;
 
+       struct omap_dss_device *src;
+       struct omap_dss_device *dst;
+
        struct list_head list;
        struct list_head panel_list;
 
 
        enum omap_display_caps caps;
 
-       struct omap_dss_device *src;
-
        enum omap_dss_display_state state;
 
        /* OMAP DSS output specific fields */
 
        /* the port number in the DT node */
        int port_num;
-
-       /* dynamic fields */
-       struct omap_dss_device *dst;
 };
 
 struct omap_dss_driver {
 
                goto err;
        }
 
-       out->dst = dssdev;
-       dssdev->src = out;
-
        mutex_unlock(&output_lock);
 
        return 0;
                goto err;
        }
 
-       out->dst->src = NULL;
-       out->dst = NULL;
-
        mutex_unlock(&output_lock);
 
        return 0;
 
 {
        struct sdi_device *sdi = dssdev_to_sdi(dssdev);
 
-       WARN_ON(dst != dssdev->dst);
-
-       if (dst != dssdev->dst)
-               return;
-
        omapdss_output_unset_device(dssdev);
 
        dss_mgr_disconnect(&sdi->output, dssdev);
 
 {
        struct venc_device *venc = dssdev_to_venc(dssdev);
 
-       WARN_ON(dst != dssdev->dst);
-
-       if (dst != dssdev->dst)
-               return;
-
        omapdss_output_unset_device(dssdev);
 
        dss_mgr_disconnect(&venc->output, dssdev);