aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c27
-rw-r--r--drivers/gpu/drm/omapdrm/displays/connector-dvi.c27
-rw-r--r--drivers/gpu/drm/omapdrm/displays/connector-hdmi.c27
-rw-r--r--drivers/gpu/drm/omapdrm/displays/encoder-opa362.c34
-rw-r--r--drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c34
-rw-r--r--drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c32
-rw-r--r--drivers/gpu/drm/omapdrm/displays/panel-dpi.c27
-rw-r--r--drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c42
-rw-r--r--drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c28
-rw-r--r--drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c27
-rw-r--r--drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c27
-rw-r--r--drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c27
-rw-r--r--drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c27
-rw-r--r--drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c27
-rw-r--r--drivers/gpu/drm/omapdrm/dss/base.c32
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dpi.c32
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dsi.c32
-rw-r--r--drivers/gpu/drm/omapdrm/dss/hdmi4.c30
-rw-r--r--drivers/gpu/drm/omapdrm/dss/hdmi5.c30
-rw-r--r--drivers/gpu/drm/omapdrm/dss/omapdss.h6
-rw-r--r--drivers/gpu/drm/omapdrm/dss/sdi.c30
-rw-r--r--drivers/gpu/drm/omapdrm/dss/venc.c30
-rw-r--r--drivers/gpu/drm/omapdrm/omap_drv.c35
-rw-r--r--drivers/gpu/drm/omapdrm/omap_drv.h1
24 files changed, 239 insertions, 432 deletions
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c b/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
index cda6c312ad05..d59b4f2e22dc 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
@@ -41,33 +41,15 @@ static const struct videomode tvc_pal_vm = {
41 41
42#define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev) 42#define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev)
43 43
44static int tvc_connect(struct omap_dss_device *dssdev) 44static int tvc_connect(struct omap_dss_device *src,
45 struct omap_dss_device *dst)
45{ 46{
46 struct omap_dss_device *src;
47 int r;
48
49 src = omapdss_of_find_connected_device(dssdev->dev->of_node, 0);
50 if (IS_ERR_OR_NULL(src)) {
51 dev_err(dssdev->dev, "failed to find video source\n");
52 return src ? PTR_ERR(src) : -EINVAL;
53 }
54
55 r = omapdss_device_connect(dssdev->dss, src, dssdev);
56 if (r) {
57 omapdss_device_put(src);
58 return r;
59 }
60
61 return 0; 47 return 0;
62} 48}
63 49
64static void tvc_disconnect(struct omap_dss_device *dssdev) 50static void tvc_disconnect(struct omap_dss_device *src,
51 struct omap_dss_device *dst)
65{ 52{
66 struct omap_dss_device *src = dssdev->src;
67
68 omapdss_device_disconnect(src, dssdev);
69
70 omapdss_device_put(src);
71} 53}
72 54
73static int tvc_enable(struct omap_dss_device *dssdev) 55static int tvc_enable(struct omap_dss_device *dssdev)
@@ -184,7 +166,6 @@ static int __exit tvc_remove(struct platform_device *pdev)
184 omapdss_device_unregister(&ddata->dssdev); 166 omapdss_device_unregister(&ddata->dssdev);
185 167
186 tvc_disable(dssdev); 168 tvc_disable(dssdev);
187 omapdss_device_disconnect(dssdev, NULL);
188 169
189 return 0; 170 return 0;
190} 171}
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
index f8510cd7b166..39e7d0be887f 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
@@ -56,33 +56,15 @@ struct panel_drv_data {
56 56
57#define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev) 57#define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev)
58 58
59static int dvic_connect(struct omap_dss_device *dssdev) 59static int dvic_connect(struct omap_dss_device *src,
60 struct omap_dss_device *dst)
60{ 61{
61 struct omap_dss_device *src;
62 int r;
63
64 src = omapdss_of_find_connected_device(dssdev->dev->of_node, 0);
65 if (IS_ERR_OR_NULL(src)) {
66 dev_err(dssdev->dev, "failed to find video source\n");
67 return src ? PTR_ERR(src) : -EINVAL;
68 }
69
70 r = omapdss_device_connect(dssdev->dss, src, dssdev);
71 if (r) {
72 omapdss_device_put(src);
73 return r;
74 }
75
76 return 0; 62 return 0;
77} 63}
78 64
79static void dvic_disconnect(struct omap_dss_device *dssdev) 65static void dvic_disconnect(struct omap_dss_device *src,
66 struct omap_dss_device *dst)
80{ 67{
81 struct omap_dss_device *src = dssdev->src;
82
83 omapdss_device_disconnect(src, dssdev);
84
85 omapdss_device_put(src);
86} 68}
87 69
88static int dvic_enable(struct omap_dss_device *dssdev) 70static int dvic_enable(struct omap_dss_device *dssdev)
@@ -405,7 +387,6 @@ static int __exit dvic_remove(struct platform_device *pdev)
405 omapdss_device_unregister(&ddata->dssdev); 387 omapdss_device_unregister(&ddata->dssdev);
406 388
407 dvic_disable(dssdev); 389 dvic_disable(dssdev);
408 omapdss_device_disconnect(dssdev, NULL);
409 390
410 i2c_put_adapter(ddata->i2c_adapter); 391 i2c_put_adapter(ddata->i2c_adapter);
411 392
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
index 6eb4c24d6aa7..e9878da5bfdb 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
@@ -51,33 +51,15 @@ struct panel_drv_data {
51 51
52#define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev) 52#define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev)
53 53
54static int hdmic_connect(struct omap_dss_device *dssdev) 54static int hdmic_connect(struct omap_dss_device *src,
55 struct omap_dss_device *dst)
55{ 56{
56 struct omap_dss_device *src;
57 int r;
58
59 src = omapdss_of_find_connected_device(dssdev->dev->of_node, 0);
60 if (IS_ERR_OR_NULL(src)) {
61 dev_err(dssdev->dev, "failed to find video source\n");
62 return src ? PTR_ERR(src) : -EINVAL;
63 }
64
65 r = omapdss_device_connect(dssdev->dss, src, dssdev);
66 if (r) {
67 omapdss_device_put(src);
68 return r;
69 }
70
71 return 0; 57 return 0;
72} 58}
73 59
74static void hdmic_disconnect(struct omap_dss_device *dssdev) 60static void hdmic_disconnect(struct omap_dss_device *src,
61 struct omap_dss_device *dst)
75{ 62{
76 struct omap_dss_device *src = dssdev->src;
77
78 omapdss_device_disconnect(src, dssdev);
79
80 omapdss_device_put(src);
81} 63}
82 64
83static int hdmic_enable(struct omap_dss_device *dssdev) 65static int hdmic_enable(struct omap_dss_device *dssdev)
@@ -364,7 +346,6 @@ static int __exit hdmic_remove(struct platform_device *pdev)
364 omapdss_device_unregister(&ddata->dssdev); 346 omapdss_device_unregister(&ddata->dssdev);
365 347
366 hdmic_disable(dssdev); 348 hdmic_disable(dssdev);
367 omapdss_device_disconnect(dssdev, NULL);
368 349
369 return 0; 350 return 0;
370} 351}
diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c b/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c
index f661ba8f3fa0..3243e5f9bd06 100644
--- a/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c
+++ b/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c
@@ -31,36 +31,16 @@ struct panel_drv_data {
31 31
32#define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev) 32#define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev)
33 33
34static int opa362_connect(struct omap_dss_device *dssdev, 34static int opa362_connect(struct omap_dss_device *src,
35 struct omap_dss_device *dst) 35 struct omap_dss_device *dst)
36{ 36{
37 struct omap_dss_device *src; 37 return omapdss_device_connect(dst->dss, dst, dst->next);
38 int r;
39
40 src = omapdss_of_find_connected_device(dssdev->dev->of_node, 0);
41 if (IS_ERR(src)) {
42 dev_err(dssdev->dev, "failed to find video source\n");
43 return PTR_ERR(src);
44 }
45
46 r = omapdss_device_connect(dssdev->dss, src, dssdev);
47 if (r) {
48 omapdss_device_put(src);
49 return r;
50 }
51
52 return 0;
53} 38}
54 39
55static void opa362_disconnect(struct omap_dss_device *dssdev, 40static void opa362_disconnect(struct omap_dss_device *src,
56 struct omap_dss_device *dst) 41 struct omap_dss_device *dst)
57{ 42{
58 struct panel_drv_data *ddata = to_panel_data(dssdev); 43 omapdss_device_disconnect(dst, dst->next);
59 struct omap_dss_device *src = dssdev->src;
60
61 omapdss_device_disconnect(src, &ddata->dssdev);
62
63 omapdss_device_put(src);
64} 44}
65 45
66static int opa362_enable(struct omap_dss_device *dssdev) 46static int opa362_enable(struct omap_dss_device *dssdev)
@@ -196,7 +176,7 @@ static int __exit opa362_remove(struct platform_device *pdev)
196 176
197 WARN_ON(omapdss_device_is_connected(dssdev)); 177 WARN_ON(omapdss_device_is_connected(dssdev));
198 if (omapdss_device_is_connected(dssdev)) 178 if (omapdss_device_is_connected(dssdev))
199 omapdss_device_disconnect(dssdev, dssdev->dst); 179 omapdss_device_disconnect(NULL, dssdev);
200 180
201 return 0; 181 return 0;
202} 182}
diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c b/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c
index 3be35ba564da..7114ea672e69 100644
--- a/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c
+++ b/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c
@@ -27,36 +27,16 @@ struct panel_drv_data {
27 27
28#define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev) 28#define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev)
29 29
30static int tfp410_connect(struct omap_dss_device *dssdev, 30static int tfp410_connect(struct omap_dss_device *src,
31 struct omap_dss_device *dst) 31 struct omap_dss_device *dst)
32{ 32{
33 struct omap_dss_device *src; 33 return omapdss_device_connect(dst->dss, dst, dst->next);
34 int r;
35
36 src = omapdss_of_find_connected_device(dssdev->dev->of_node, 0);
37 if (IS_ERR(src)) {
38 dev_err(dssdev->dev, "failed to find video source\n");
39 return PTR_ERR(src);
40 }
41
42 r = omapdss_device_connect(dssdev->dss, src, dssdev);
43 if (r) {
44 omapdss_device_put(src);
45 return r;
46 }
47
48 return 0;
49} 34}
50 35
51static void tfp410_disconnect(struct omap_dss_device *dssdev, 36static void tfp410_disconnect(struct omap_dss_device *src,
52 struct omap_dss_device *dst) 37 struct omap_dss_device *dst)
53{ 38{
54 struct panel_drv_data *ddata = to_panel_data(dssdev); 39 omapdss_device_disconnect(dst, dst->next);
55 struct omap_dss_device *src = dssdev->src;
56
57 omapdss_device_disconnect(src, &ddata->dssdev);
58
59 omapdss_device_put(src);
60} 40}
61 41
62static int tfp410_enable(struct omap_dss_device *dssdev) 42static int tfp410_enable(struct omap_dss_device *dssdev)
@@ -219,7 +199,7 @@ static int __exit tfp410_remove(struct platform_device *pdev)
219 199
220 WARN_ON(omapdss_device_is_connected(dssdev)); 200 WARN_ON(omapdss_device_is_connected(dssdev));
221 if (omapdss_device_is_connected(dssdev)) 201 if (omapdss_device_is_connected(dssdev))
222 omapdss_device_disconnect(dssdev, dssdev->dst); 202 omapdss_device_disconnect(NULL, dssdev);
223 203
224 return 0; 204 return 0;
225} 205}
diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
index cee53346f6fc..c99e55487d38 100644
--- a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
+++ b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
@@ -35,24 +35,15 @@ struct panel_drv_data {
35 35
36#define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev) 36#define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev)
37 37
38static int tpd_connect(struct omap_dss_device *dssdev, 38static int tpd_connect(struct omap_dss_device *src,
39 struct omap_dss_device *dst) 39 struct omap_dss_device *dst)
40{ 40{
41 struct panel_drv_data *ddata = to_panel_data(dssdev); 41 struct panel_drv_data *ddata = to_panel_data(dst);
42 struct omap_dss_device *src;
43 int r; 42 int r;
44 43
45 src = omapdss_of_find_connected_device(dssdev->dev->of_node, 0); 44 r = omapdss_device_connect(dst->dss, dst, dst->next);
46 if (IS_ERR(src)) { 45 if (r)
47 dev_err(dssdev->dev, "failed to find video source\n");
48 return PTR_ERR(src);
49 }
50
51 r = omapdss_device_connect(dssdev->dss, src, dssdev);
52 if (r) {
53 omapdss_device_put(src);
54 return r; 46 return r;
55 }
56 47
57 gpiod_set_value_cansleep(ddata->ct_cp_hpd_gpio, 1); 48 gpiod_set_value_cansleep(ddata->ct_cp_hpd_gpio, 1);
58 gpiod_set_value_cansleep(ddata->ls_oe_gpio, 1); 49 gpiod_set_value_cansleep(ddata->ls_oe_gpio, 1);
@@ -63,18 +54,15 @@ static int tpd_connect(struct omap_dss_device *dssdev,
63 return 0; 54 return 0;
64} 55}
65 56
66static void tpd_disconnect(struct omap_dss_device *dssdev, 57static void tpd_disconnect(struct omap_dss_device *src,
67 struct omap_dss_device *dst) 58 struct omap_dss_device *dst)
68{ 59{
69 struct panel_drv_data *ddata = to_panel_data(dssdev); 60 struct panel_drv_data *ddata = to_panel_data(dst);
70 struct omap_dss_device *src = dssdev->src;
71 61
72 gpiod_set_value_cansleep(ddata->ct_cp_hpd_gpio, 0); 62 gpiod_set_value_cansleep(ddata->ct_cp_hpd_gpio, 0);
73 gpiod_set_value_cansleep(ddata->ls_oe_gpio, 0); 63 gpiod_set_value_cansleep(ddata->ls_oe_gpio, 0);
74 64
75 omapdss_device_disconnect(src, &ddata->dssdev); 65 omapdss_device_disconnect(dst, dst->next);
76
77 omapdss_device_put(src);
78} 66}
79 67
80static int tpd_enable(struct omap_dss_device *dssdev) 68static int tpd_enable(struct omap_dss_device *dssdev)
@@ -328,7 +316,7 @@ static int __exit tpd_remove(struct platform_device *pdev)
328 316
329 WARN_ON(omapdss_device_is_connected(dssdev)); 317 WARN_ON(omapdss_device_is_connected(dssdev));
330 if (omapdss_device_is_connected(dssdev)) 318 if (omapdss_device_is_connected(dssdev))
331 omapdss_device_disconnect(dssdev, dssdev->dst); 319 omapdss_device_disconnect(NULL, dssdev);
332 320
333 return 0; 321 return 0;
334} 322}
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dpi.c b/drivers/gpu/drm/omapdrm/displays/panel-dpi.c
index 8c17ad4ddf84..91f99c95c4c4 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-dpi.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dpi.c
@@ -34,33 +34,15 @@ struct panel_drv_data {
34 34
35#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev) 35#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)
36 36
37static int panel_dpi_connect(struct omap_dss_device *dssdev) 37static int panel_dpi_connect(struct omap_dss_device *src,
38 struct omap_dss_device *dst)
38{ 39{
39 struct omap_dss_device *src;
40 int r;
41
42 src = omapdss_of_find_connected_device(dssdev->dev->of_node, 0);
43 if (IS_ERR_OR_NULL(src)) {
44 dev_err(dssdev->dev, "failed to find video source\n");
45 return src ? PTR_ERR(src) : -EINVAL;
46 }
47
48 r = omapdss_device_connect(dssdev->dss, src, dssdev);
49 if (r) {
50 omapdss_device_put(src);
51 return r;
52 }
53
54 return 0; 40 return 0;
55} 41}
56 42
57static void panel_dpi_disconnect(struct omap_dss_device *dssdev) 43static void panel_dpi_disconnect(struct omap_dss_device *src,
44 struct omap_dss_device *dst)
58{ 45{
59 struct omap_dss_device *src = dssdev->src;
60
61 omapdss_device_disconnect(src, dssdev);
62
63 omapdss_device_put(src);
64} 46}
65 47
66static int panel_dpi_enable(struct omap_dss_device *dssdev) 48static int panel_dpi_enable(struct omap_dss_device *dssdev)
@@ -233,7 +215,6 @@ static int __exit panel_dpi_remove(struct platform_device *pdev)
233 omapdss_device_unregister(dssdev); 215 omapdss_device_unregister(dssdev);
234 216
235 panel_dpi_disable(dssdev); 217 panel_dpi_disable(dssdev);
236 omapdss_device_disconnect(dssdev, NULL);
237 218
238 return 0; 219 return 0;
239} 220}
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
index 501c47f95130..e30f0ab315f5 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
@@ -756,57 +756,35 @@ static int dsicm_panel_reset(struct panel_drv_data *ddata)
756 return dsicm_power_on(ddata); 756 return dsicm_power_on(ddata);
757} 757}
758 758
759static int dsicm_connect(struct omap_dss_device *dssdev) 759static int dsicm_connect(struct omap_dss_device *src,
760 struct omap_dss_device *dst)
760{ 761{
761 struct panel_drv_data *ddata = to_panel_data(dssdev); 762 struct panel_drv_data *ddata = to_panel_data(dst);
762 struct device *dev = &ddata->pdev->dev; 763 struct device *dev = &ddata->pdev->dev;
763 struct omap_dss_device *src;
764 int r; 764 int r;
765 765
766 src = omapdss_of_find_connected_device(dssdev->dev->of_node, 0);
767 if (IS_ERR_OR_NULL(src)) {
768 dev_err(dssdev->dev, "failed to find video source\n");
769 return src ? PTR_ERR(src) : -EINVAL;
770 }
771
772 r = omapdss_device_connect(dssdev->dss, src, dssdev);
773 if (r) {
774 dev_err(dev, "Failed to connect to video source\n");
775 goto err_connect;
776 }
777
778 r = src->ops->dsi.request_vc(src, &ddata->channel); 766 r = src->ops->dsi.request_vc(src, &ddata->channel);
779 if (r) { 767 if (r) {
780 dev_err(dev, "failed to get virtual channel\n"); 768 dev_err(dev, "failed to get virtual channel\n");
781 goto err_req_vc; 769 return r;
782 } 770 }
783 771
784 r = src->ops->dsi.set_vc_id(src, ddata->channel, TCH); 772 r = src->ops->dsi.set_vc_id(src, ddata->channel, TCH);
785 if (r) { 773 if (r) {
786 dev_err(dev, "failed to set VC_ID\n"); 774 dev_err(dev, "failed to set VC_ID\n");
787 goto err_vc_id; 775 src->ops->dsi.release_vc(src, ddata->channel);
776 return r;
788 } 777 }
789 778
790 return 0; 779 return 0;
791
792err_vc_id:
793 src->ops->dsi.release_vc(src, ddata->channel);
794err_req_vc:
795 omapdss_device_disconnect(src, dssdev);
796err_connect:
797 omapdss_device_put(src);
798 return r;
799} 780}
800 781
801static void dsicm_disconnect(struct omap_dss_device *dssdev) 782static void dsicm_disconnect(struct omap_dss_device *src,
783 struct omap_dss_device *dst)
802{ 784{
803 struct panel_drv_data *ddata = to_panel_data(dssdev); 785 struct panel_drv_data *ddata = to_panel_data(dst);
804 struct omap_dss_device *src = dssdev->src;
805 786
806 src->ops->dsi.release_vc(src, ddata->channel); 787 src->ops->dsi.release_vc(src, ddata->channel);
807 omapdss_device_disconnect(src, dssdev);
808
809 omapdss_device_put(src);
810} 788}
811 789
812static int dsicm_enable(struct omap_dss_device *dssdev) 790static int dsicm_enable(struct omap_dss_device *dssdev)
@@ -1404,7 +1382,7 @@ static int __exit dsicm_remove(struct platform_device *pdev)
1404 omapdss_device_unregister(dssdev); 1382 omapdss_device_unregister(dssdev);
1405 1383
1406 dsicm_disable(dssdev); 1384 dsicm_disable(dssdev);
1407 omapdss_device_disconnect(dssdev, NULL); 1385 omapdss_device_disconnect(dssdev->src, dssdev);
1408 1386
1409 sysfs_remove_group(&pdev->dev.kobj, &dsicm_attr_group); 1387 sysfs_remove_group(&pdev->dev.kobj, &dsicm_attr_group);
1410 1388
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c b/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c
index 73416b1c7386..66763a12fc3d 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c
@@ -115,36 +115,19 @@ static void init_lb035q02_panel(struct spi_device *spi)
115 lb035q02_write_reg(spi, 0x3b, 0x0806); 115 lb035q02_write_reg(spi, 0x3b, 0x0806);
116} 116}
117 117
118static int lb035q02_connect(struct omap_dss_device *dssdev) 118static int lb035q02_connect(struct omap_dss_device *src,
119 struct omap_dss_device *dst)
119{ 120{
120 struct panel_drv_data *ddata = to_panel_data(dssdev); 121 struct panel_drv_data *ddata = to_panel_data(dst);
121 struct omap_dss_device *src;
122 int r;
123
124 src = omapdss_of_find_connected_device(dssdev->dev->of_node, 0);
125 if (IS_ERR_OR_NULL(src)) {
126 dev_err(dssdev->dev, "failed to find video source\n");
127 return src ? PTR_ERR(src) : -EINVAL;
128 }
129
130 r = omapdss_device_connect(dssdev->dss, src, dssdev);
131 if (r) {
132 omapdss_device_put(src);
133 return r;
134 }
135 122
136 init_lb035q02_panel(ddata->spi); 123 init_lb035q02_panel(ddata->spi);
137 124
138 return 0; 125 return 0;
139} 126}
140 127
141static void lb035q02_disconnect(struct omap_dss_device *dssdev) 128static void lb035q02_disconnect(struct omap_dss_device *src,
129 struct omap_dss_device *dst)
142{ 130{
143 struct omap_dss_device *src = dssdev->src;
144
145 omapdss_device_disconnect(src, dssdev);
146
147 omapdss_device_put(src);
148} 131}
149 132
150static int lb035q02_enable(struct omap_dss_device *dssdev) 133static int lb035q02_enable(struct omap_dss_device *dssdev)
@@ -285,7 +268,6 @@ static int lb035q02_panel_spi_remove(struct spi_device *spi)
285 omapdss_device_unregister(dssdev); 268 omapdss_device_unregister(dssdev);
286 269
287 lb035q02_disable(dssdev); 270 lb035q02_disable(dssdev);
288 omapdss_device_disconnect(dssdev, NULL);
289 271
290 return 0; 272 return 0;
291} 273}
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c b/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c
index cf5d9e1522a8..b4dba55b678b 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c
@@ -111,33 +111,15 @@ static int init_nec_8048_wvga_lcd(struct spi_device *spi)
111 return 0; 111 return 0;
112} 112}
113 113
114static int nec_8048_connect(struct omap_dss_device *dssdev) 114static int nec_8048_connect(struct omap_dss_device *src,
115 struct omap_dss_device *dst)
115{ 116{
116 struct omap_dss_device *src;
117 int r;
118
119 src = omapdss_of_find_connected_device(dssdev->dev->of_node, 0);
120 if (IS_ERR_OR_NULL(src)) {
121 dev_err(dssdev->dev, "failed to find video source\n");
122 return src ? PTR_ERR(src) : -EINVAL;
123 }
124
125 r = omapdss_device_connect(dssdev->dss, src, dssdev);
126 if (r) {
127 omapdss_device_put(src);
128 return r;
129 }
130
131 return 0; 117 return 0;
132} 118}
133 119
134static void nec_8048_disconnect(struct omap_dss_device *dssdev) 120static void nec_8048_disconnect(struct omap_dss_device *src,
121 struct omap_dss_device *dst)
135{ 122{
136 struct omap_dss_device *src = dssdev->src;
137
138 omapdss_device_disconnect(src, dssdev);
139
140 omapdss_device_put(src);
141} 123}
142 124
143static int nec_8048_enable(struct omap_dss_device *dssdev) 125static int nec_8048_enable(struct omap_dss_device *dssdev)
@@ -310,7 +292,6 @@ static int nec_8048_remove(struct spi_device *spi)
310 omapdss_device_unregister(dssdev); 292 omapdss_device_unregister(dssdev);
311 293
312 nec_8048_disable(dssdev); 294 nec_8048_disable(dssdev);
313 omapdss_device_disconnect(dssdev, NULL);
314 295
315 return 0; 296 return 0;
316} 297}
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c b/drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c
index 1c3180495dfd..7fbdf3ec0113 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c
@@ -57,33 +57,15 @@ static const struct videomode sharp_ls_vm = {
57 57
58#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev) 58#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)
59 59
60static int sharp_ls_connect(struct omap_dss_device *dssdev) 60static int sharp_ls_connect(struct omap_dss_device *src,
61 struct omap_dss_device *dst)
61{ 62{
62 struct omap_dss_device *src;
63 int r;
64
65 src = omapdss_of_find_connected_device(dssdev->dev->of_node, 0);
66 if (IS_ERR_OR_NULL(src)) {
67 dev_err(dssdev->dev, "failed to find video source\n");
68 return src ? PTR_ERR(src) : -EINVAL;
69 }
70
71 r = omapdss_device_connect(dssdev->dss, src, dssdev);
72 if (r) {
73 omapdss_device_put(src);
74 return r;
75 }
76
77 return 0; 63 return 0;
78} 64}
79 65
80static void sharp_ls_disconnect(struct omap_dss_device *dssdev) 66static void sharp_ls_disconnect(struct omap_dss_device *src,
67 struct omap_dss_device *dst)
81{ 68{
82 struct omap_dss_device *src = dssdev->src;
83
84 omapdss_device_disconnect(src, dssdev);
85
86 omapdss_device_put(src);
87} 69}
88 70
89static int sharp_ls_enable(struct omap_dss_device *dssdev) 71static int sharp_ls_enable(struct omap_dss_device *dssdev)
@@ -284,7 +266,6 @@ static int __exit sharp_ls_remove(struct platform_device *pdev)
284 omapdss_device_unregister(dssdev); 266 omapdss_device_unregister(dssdev);
285 267
286 sharp_ls_disable(dssdev); 268 sharp_ls_disable(dssdev);
287 omapdss_device_disconnect(dssdev, NULL);
288 269
289 return 0; 270 return 0;
290} 271}
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c b/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c
index d91ab8dab4d9..036fd8e57074 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c
@@ -506,33 +506,15 @@ static const struct attribute_group bldev_attr_group = {
506 .attrs = bldev_attrs, 506 .attrs = bldev_attrs,
507}; 507};
508 508
509static int acx565akm_connect(struct omap_dss_device *dssdev) 509static int acx565akm_connect(struct omap_dss_device *src,
510 struct omap_dss_device *dst)
510{ 511{
511 struct omap_dss_device *src;
512 int r;
513
514 src = omapdss_of_find_connected_device(dssdev->dev->of_node, 0);
515 if (IS_ERR_OR_NULL(src)) {
516 dev_err(dssdev->dev, "failed to find video source\n");
517 return src ? PTR_ERR(src) : -EINVAL;
518 }
519
520 r = omapdss_device_connect(dssdev->dss, src, dssdev);
521 if (r) {
522 omapdss_device_put(src);
523 return r;
524 }
525
526 return 0; 512 return 0;
527} 513}
528 514
529static void acx565akm_disconnect(struct omap_dss_device *dssdev) 515static void acx565akm_disconnect(struct omap_dss_device *src,
516 struct omap_dss_device *dst)
530{ 517{
531 struct omap_dss_device *src = dssdev->src;
532
533 omapdss_device_disconnect(src, dssdev);
534
535 omapdss_device_put(src);
536} 518}
537 519
538static int acx565akm_panel_power_on(struct omap_dss_device *dssdev) 520static int acx565akm_panel_power_on(struct omap_dss_device *dssdev)
@@ -822,7 +804,6 @@ static int acx565akm_remove(struct spi_device *spi)
822 omapdss_device_unregister(dssdev); 804 omapdss_device_unregister(dssdev);
823 805
824 acx565akm_disable(dssdev); 806 acx565akm_disable(dssdev);
825 omapdss_device_disconnect(dssdev, NULL);
826 807
827 return 0; 808 return 0;
828} 809}
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c
index a57daf44d421..fc08f71b95a0 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c
@@ -165,33 +165,15 @@ enum jbt_register {
165 165
166#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev) 166#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)
167 167
168static int td028ttec1_panel_connect(struct omap_dss_device *dssdev) 168static int td028ttec1_panel_connect(struct omap_dss_device *src,
169 struct omap_dss_device *dst)
169{ 170{
170 struct omap_dss_device *src;
171 int r;
172
173 src = omapdss_of_find_connected_device(dssdev->dev->of_node, 0);
174 if (IS_ERR_OR_NULL(src)) {
175 dev_err(dssdev->dev, "failed to find video source\n");
176 return src ? PTR_ERR(src) : -EINVAL;
177 }
178
179 r = omapdss_device_connect(dssdev->dss, src, dssdev);
180 if (r) {
181 omapdss_device_put(src);
182 return r;
183 }
184
185 return 0; 171 return 0;
186} 172}
187 173
188static void td028ttec1_panel_disconnect(struct omap_dss_device *dssdev) 174static void td028ttec1_panel_disconnect(struct omap_dss_device *src,
175 struct omap_dss_device *dst)
189{ 176{
190 struct omap_dss_device *src = dssdev->src;
191
192 omapdss_device_disconnect(src, dssdev);
193
194 omapdss_device_put(src);
195} 177}
196 178
197static int td028ttec1_panel_enable(struct omap_dss_device *dssdev) 179static int td028ttec1_panel_enable(struct omap_dss_device *dssdev)
@@ -411,7 +393,6 @@ static int td028ttec1_panel_remove(struct spi_device *spi)
411 omapdss_device_unregister(dssdev); 393 omapdss_device_unregister(dssdev);
412 394
413 td028ttec1_panel_disable(dssdev); 395 td028ttec1_panel_disable(dssdev);
414 omapdss_device_disconnect(dssdev, NULL);
415 396
416 return 0; 397 return 0;
417} 398}
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c
index 719c298d3996..cb6f19f8a0da 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c
@@ -336,33 +336,15 @@ static void tpo_td043_power_off(struct panel_drv_data *ddata)
336 ddata->powered_on = 0; 336 ddata->powered_on = 0;
337} 337}
338 338
339static int tpo_td043_connect(struct omap_dss_device *dssdev) 339static int tpo_td043_connect(struct omap_dss_device *src,
340 struct omap_dss_device *dst)
340{ 341{
341 struct omap_dss_device *src;
342 int r;
343
344 src = omapdss_of_find_connected_device(dssdev->dev->of_node, 0);
345 if (IS_ERR_OR_NULL(src)) {
346 dev_err(dssdev->dev, "failed to find video source\n");
347 return src ? PTR_ERR(src) : -EINVAL;
348 }
349
350 r = omapdss_device_connect(dssdev->dss, src, dssdev);
351 if (r) {
352 omapdss_device_put(src);
353 return r;
354 }
355
356 return 0; 342 return 0;
357} 343}
358 344
359static void tpo_td043_disconnect(struct omap_dss_device *dssdev) 345static void tpo_td043_disconnect(struct omap_dss_device *src,
346 struct omap_dss_device *dst)
360{ 347{
361 struct omap_dss_device *src = dssdev->src;
362
363 omapdss_device_disconnect(src, dssdev);
364
365 omapdss_device_put(src);
366} 348}
367 349
368static int tpo_td043_enable(struct omap_dss_device *dssdev) 350static int tpo_td043_enable(struct omap_dss_device *dssdev)
@@ -553,7 +535,6 @@ static int tpo_td043_remove(struct spi_device *spi)
553 omapdss_device_unregister(dssdev); 535 omapdss_device_unregister(dssdev);
554 536
555 tpo_td043_disable(dssdev); 537 tpo_td043_disable(dssdev);
556 omapdss_device_disconnect(dssdev, NULL);
557 538
558 sysfs_remove_group(&spi->dev.kobj, &tpo_td043_attr_group); 539 sysfs_remove_group(&spi->dev.kobj, &tpo_td043_attr_group);
559 540
diff --git a/drivers/gpu/drm/omapdrm/dss/base.c b/drivers/gpu/drm/omapdrm/dss/base.c
index 1dbd08e6e029..c3e451440d4b 100644
--- a/drivers/gpu/drm/omapdrm/dss/base.c
+++ b/drivers/gpu/drm/omapdrm/dss/base.c
@@ -190,24 +190,24 @@ int omapdss_device_connect(struct dss_device *dss,
190{ 190{
191 int ret; 191 int ret;
192 192
193 dev_dbg(src->dev, "connect\n"); 193 dev_dbg(dst->dev, "connect\n");
194 194
195 if (omapdss_device_is_connected(src)) 195 if (omapdss_device_is_connected(dst))
196 return -EBUSY; 196 return -EBUSY;
197 197
198 src->dss = dss; 198 dst->dss = dss;
199 199
200 if (src->driver) 200 if (dst->driver)
201 ret = src->driver->connect(src); 201 ret = dst->driver->connect(src, dst);
202 else 202 else
203 ret = src->ops->connect(src, dst); 203 ret = dst->ops->connect(src, dst);
204 204
205 if (ret < 0) { 205 if (ret < 0) {
206 src->dss = NULL; 206 dst->dss = NULL;
207 return ret; 207 return ret;
208 } 208 }
209 209
210 if (dst) { 210 if (src) {
211 dst->src = src; 211 dst->src = src;
212 src->dst = dst; 212 src->dst = dst;
213 } 213 }
@@ -219,14 +219,14 @@ EXPORT_SYMBOL_GPL(omapdss_device_connect);
219void omapdss_device_disconnect(struct omap_dss_device *src, 219void omapdss_device_disconnect(struct omap_dss_device *src,
220 struct omap_dss_device *dst) 220 struct omap_dss_device *dst)
221{ 221{
222 dev_dbg(src->dev, "disconnect\n"); 222 dev_dbg(dst->dev, "disconnect\n");
223 223
224 if (!src->id && !omapdss_device_is_connected(src)) { 224 if (!dst->id && !omapdss_device_is_connected(dst)) {
225 WARN_ON(!src->driver); 225 WARN_ON(!dst->driver);
226 return; 226 return;
227 } 227 }
228 228
229 if (dst) { 229 if (src) {
230 if (WARN_ON(dst != src->dst)) 230 if (WARN_ON(dst != src->dst))
231 return; 231 return;
232 232
@@ -234,12 +234,12 @@ void omapdss_device_disconnect(struct omap_dss_device *src,
234 src->dst = NULL; 234 src->dst = NULL;
235 } 235 }
236 236
237 if (src->driver) 237 if (dst->driver)
238 src->driver->disconnect(src); 238 dst->driver->disconnect(src, dst);
239 else 239 else
240 src->ops->disconnect(src, dst); 240 dst->ops->disconnect(src, dst);
241 241
242 src->dss = NULL; 242 dst->dss = NULL;
243} 243}
244EXPORT_SYMBOL_GPL(omapdss_device_disconnect); 244EXPORT_SYMBOL_GPL(omapdss_device_disconnect);
245 245
diff --git a/drivers/gpu/drm/omapdrm/dss/dpi.c b/drivers/gpu/drm/omapdrm/dss/dpi.c
index 35d63c686393..6bd0fd12883e 100644
--- a/drivers/gpu/drm/omapdrm/dss/dpi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dpi.c
@@ -608,35 +608,45 @@ static enum omap_channel dpi_get_channel(struct dpi_data *dpi)
608 } 608 }
609} 609}
610 610
611static int dpi_connect(struct omap_dss_device *dssdev, 611static int dpi_connect(struct omap_dss_device *src,
612 struct omap_dss_device *dst) 612 struct omap_dss_device *dst)
613{ 613{
614 struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev); 614 struct dpi_data *dpi = dpi_get_data_from_dssdev(dst);
615 int r; 615 int r;
616 616
617 dpi_init_pll(dpi); 617 dpi_init_pll(dpi);
618 618
619 r = dss_mgr_connect(dssdev); 619 r = dss_mgr_connect(dst);
620 if (r) 620 if (r)
621 return r; 621 return r;
622 622
623 r = omapdss_output_set_device(dssdev, dst); 623 r = omapdss_output_set_device(dst, dst->next);
624 if (r) { 624 if (r) {
625 DSSERR("failed to connect output to new device: %s\n", 625 DSSERR("failed to connect output to new device: %s\n",
626 dst->name); 626 dst->name);
627 dss_mgr_disconnect(dssdev); 627 goto err_mgr_disconnect;
628 return r;
629 } 628 }
630 629
630 r = omapdss_device_connect(dst->dss, dst, dst->next);
631 if (r)
632 goto err_output_unset;
633
631 return 0; 634 return 0;
635
636err_output_unset:
637 omapdss_output_unset_device(dst);
638err_mgr_disconnect:
639 dss_mgr_disconnect(dst);
640 return r;
632} 641}
633 642
634static void dpi_disconnect(struct omap_dss_device *dssdev, 643static void dpi_disconnect(struct omap_dss_device *src,
635 struct omap_dss_device *dst) 644 struct omap_dss_device *dst)
636{ 645{
637 omapdss_output_unset_device(dssdev); 646 omapdss_device_disconnect(dst, dst->next);
647 omapdss_output_unset_device(dst);
638 648
639 dss_mgr_disconnect(dssdev); 649 dss_mgr_disconnect(dst);
640} 650}
641 651
642static const struct omap_dss_device_ops dpi_ops = { 652static const struct omap_dss_device_ops dpi_ops = {
diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index 41a98021d5bf..0e88ae1178f7 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -4881,32 +4881,42 @@ static int dsi_get_clocks(struct dsi_data *dsi)
4881 return 0; 4881 return 0;
4882} 4882}
4883 4883
4884static int dsi_connect(struct omap_dss_device *dssdev, 4884static int dsi_connect(struct omap_dss_device *src,
4885 struct omap_dss_device *dst) 4885 struct omap_dss_device *dst)
4886{ 4886{
4887 int r; 4887 int r;
4888 4888
4889 r = dss_mgr_connect(dssdev); 4889 r = dss_mgr_connect(dst);
4890 if (r) 4890 if (r)
4891 return r; 4891 return r;
4892 4892
4893 r = omapdss_output_set_device(dssdev, dst); 4893 r = omapdss_output_set_device(dst, dst->next);
4894 if (r) { 4894 if (r) {
4895 DSSERR("failed to connect output to new device: %s\n", 4895 DSSERR("failed to connect output to new device: %s\n",
4896 dssdev->name); 4896 dst->name);
4897 dss_mgr_disconnect(dssdev); 4897 goto err_mgr_disconnect;
4898 return r;
4899 } 4898 }
4900 4899
4900 r = omapdss_device_connect(dst->dss, dst, dst->next);
4901 if (r)
4902 goto err_output_unset;
4903
4901 return 0; 4904 return 0;
4905
4906err_output_unset:
4907 omapdss_output_unset_device(dst);
4908err_mgr_disconnect:
4909 dss_mgr_disconnect(dst);
4910 return r;
4902} 4911}
4903 4912
4904static void dsi_disconnect(struct omap_dss_device *dssdev, 4913static void dsi_disconnect(struct omap_dss_device *src,
4905 struct omap_dss_device *dst) 4914 struct omap_dss_device *dst)
4906{ 4915{
4907 omapdss_output_unset_device(dssdev); 4916 omapdss_device_disconnect(dst, dst->next);
4917 omapdss_output_unset_device(dst);
4908 4918
4909 dss_mgr_disconnect(dssdev); 4919 dss_mgr_disconnect(dst);
4910} 4920}
4911 4921
4912static const struct omap_dss_device_ops dsi_ops = { 4922static const struct omap_dss_device_ops dsi_ops = {
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
index 6edb85898a7d..9f883669e71b 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
@@ -428,32 +428,42 @@ void hdmi4_core_disable(struct hdmi_core_data *core)
428 mutex_unlock(&hdmi->lock); 428 mutex_unlock(&hdmi->lock);
429} 429}
430 430
431static int hdmi_connect(struct omap_dss_device *dssdev, 431static int hdmi_connect(struct omap_dss_device *src,
432 struct omap_dss_device *dst) 432 struct omap_dss_device *dst)
433{ 433{
434 int r; 434 int r;
435 435
436 r = dss_mgr_connect(dssdev); 436 r = dss_mgr_connect(dst);
437 if (r) 437 if (r)
438 return r; 438 return r;
439 439
440 r = omapdss_output_set_device(dssdev, dst); 440 r = omapdss_output_set_device(dst, dst->next);
441 if (r) { 441 if (r) {
442 DSSERR("failed to connect output to new device: %s\n", 442 DSSERR("failed to connect output to new device: %s\n",
443 dst->name); 443 dst->name);
444 dss_mgr_disconnect(dssdev); 444 goto err_mgr_disconnect;
445 return r;
446 } 445 }
447 446
447 r = omapdss_device_connect(dst->dss, dst, dst->next);
448 if (r)
449 goto err_output_unset;
450
448 return 0; 451 return 0;
452
453err_output_unset:
454 omapdss_output_unset_device(dst);
455err_mgr_disconnect:
456 dss_mgr_disconnect(dst);
457 return r;
449} 458}
450 459
451static void hdmi_disconnect(struct omap_dss_device *dssdev, 460static void hdmi_disconnect(struct omap_dss_device *src,
452 struct omap_dss_device *dst) 461 struct omap_dss_device *dst)
453{ 462{
454 omapdss_output_unset_device(dssdev); 463 omapdss_device_disconnect(dst, dst->next);
464 omapdss_output_unset_device(dst);
455 465
456 dss_mgr_disconnect(dssdev); 466 dss_mgr_disconnect(dst);
457} 467}
458 468
459static int hdmi_read_edid(struct omap_dss_device *dssdev, 469static int hdmi_read_edid(struct omap_dss_device *dssdev,
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi5.c b/drivers/gpu/drm/omapdrm/dss/hdmi5.c
index db20a578091b..beb70b1fab94 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi5.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi5.c
@@ -433,32 +433,42 @@ static void hdmi_core_disable(struct omap_hdmi *hdmi)
433 mutex_unlock(&hdmi->lock); 433 mutex_unlock(&hdmi->lock);
434} 434}
435 435
436static int hdmi_connect(struct omap_dss_device *dssdev, 436static int hdmi_connect(struct omap_dss_device *src,
437 struct omap_dss_device *dst) 437 struct omap_dss_device *dst)
438{ 438{
439 int r; 439 int r;
440 440
441 r = dss_mgr_connect(dssdev); 441 r = dss_mgr_connect(dst);
442 if (r) 442 if (r)
443 return r; 443 return r;
444 444
445 r = omapdss_output_set_device(dssdev, dst); 445 r = omapdss_output_set_device(dst, dst->next);
446 if (r) { 446 if (r) {
447 DSSERR("failed to connect output to new device: %s\n", 447 DSSERR("failed to connect output to new device: %s\n",
448 dst->name); 448 dst->name);
449 dss_mgr_disconnect(dssdev); 449 goto err_mgr_disconnect;
450 return r;
451 } 450 }
452 451
452 r = omapdss_device_connect(dst->dss, dst, dst->next);
453 if (r)
454 goto err_output_unset;
455
453 return 0; 456 return 0;
457
458err_output_unset:
459 omapdss_output_unset_device(dst);
460err_mgr_disconnect:
461 dss_mgr_disconnect(dst);
462 return r;
454} 463}
455 464
456static void hdmi_disconnect(struct omap_dss_device *dssdev, 465static void hdmi_disconnect(struct omap_dss_device *src,
457 struct omap_dss_device *dst) 466 struct omap_dss_device *dst)
458{ 467{
459 omapdss_output_unset_device(dssdev); 468 omapdss_device_disconnect(dst, dst->next);
469 omapdss_output_unset_device(dst);
460 470
461 dss_mgr_disconnect(dssdev); 471 dss_mgr_disconnect(dst);
462} 472}
463 473
464static int hdmi_read_edid(struct omap_dss_device *dssdev, 474static int hdmi_read_edid(struct omap_dss_device *dssdev,
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index 5d03e9066a33..80c4c2ae306a 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -437,8 +437,10 @@ struct omap_dss_driver {
437 int (*probe)(struct omap_dss_device *); 437 int (*probe)(struct omap_dss_device *);
438 void (*remove)(struct omap_dss_device *); 438 void (*remove)(struct omap_dss_device *);
439 439
440 int (*connect)(struct omap_dss_device *dssdev); 440 int (*connect)(struct omap_dss_device *src,
441 void (*disconnect)(struct omap_dss_device *dssdev); 441 struct omap_dss_device *dst);
442 void (*disconnect)(struct omap_dss_device *src,
443 struct omap_dss_device *dst);
442 444
443 int (*enable)(struct omap_dss_device *display); 445 int (*enable)(struct omap_dss_device *display);
444 void (*disable)(struct omap_dss_device *display); 446 void (*disable)(struct omap_dss_device *display);
diff --git a/drivers/gpu/drm/omapdrm/dss/sdi.c b/drivers/gpu/drm/omapdrm/dss/sdi.c
index 1fb25e2c5f87..c32e8ed2a96f 100644
--- a/drivers/gpu/drm/omapdrm/dss/sdi.c
+++ b/drivers/gpu/drm/omapdrm/dss/sdi.c
@@ -252,32 +252,42 @@ static int sdi_check_timings(struct omap_dss_device *dssdev,
252 return 0; 252 return 0;
253} 253}
254 254
255static int sdi_connect(struct omap_dss_device *dssdev, 255static int sdi_connect(struct omap_dss_device *src,
256 struct omap_dss_device *dst) 256 struct omap_dss_device *dst)
257{ 257{
258 int r; 258 int r;
259 259
260 r = dss_mgr_connect(dssdev); 260 r = dss_mgr_connect(dst);
261 if (r) 261 if (r)
262 return r; 262 return r;
263 263
264 r = omapdss_output_set_device(dssdev, dst); 264 r = omapdss_output_set_device(dst, dst);
265 if (r) { 265 if (r) {
266 DSSERR("failed to connect output to new device: %s\n", 266 DSSERR("failed to connect output to new device: %s\n",
267 dst->name); 267 dst->name);
268 dss_mgr_disconnect(dssdev); 268 goto err_mgr_disconnect;
269 return r;
270 } 269 }
271 270
271 r = omapdss_device_connect(dst->dss, dst, dst->next);
272 if (r)
273 goto err_output_unset;
274
272 return 0; 275 return 0;
276
277err_output_unset:
278 omapdss_output_unset_device(dst);
279err_mgr_disconnect:
280 dss_mgr_disconnect(dst);
281 return r;
273} 282}
274 283
275static void sdi_disconnect(struct omap_dss_device *dssdev, 284static void sdi_disconnect(struct omap_dss_device *src,
276 struct omap_dss_device *dst) 285 struct omap_dss_device *dst)
277{ 286{
278 omapdss_output_unset_device(dssdev); 287 omapdss_device_disconnect(dst, dst->next);
288 omapdss_output_unset_device(dst);
279 289
280 dss_mgr_disconnect(dssdev); 290 dss_mgr_disconnect(dst);
281} 291}
282 292
283static const struct omap_dss_device_ops sdi_ops = { 293static const struct omap_dss_device_ops sdi_ops = {
diff --git a/drivers/gpu/drm/omapdrm/dss/venc.c b/drivers/gpu/drm/omapdrm/dss/venc.c
index 7aa06b796481..db0aa8f1ff7c 100644
--- a/drivers/gpu/drm/omapdrm/dss/venc.c
+++ b/drivers/gpu/drm/omapdrm/dss/venc.c
@@ -691,32 +691,42 @@ static int venc_get_clocks(struct venc_device *venc)
691 return 0; 691 return 0;
692} 692}
693 693
694static int venc_connect(struct omap_dss_device *dssdev, 694static int venc_connect(struct omap_dss_device *src,
695 struct omap_dss_device *dst) 695 struct omap_dss_device *dst)
696{ 696{
697 int r; 697 int r;
698 698
699 r = dss_mgr_connect(dssdev); 699 r = dss_mgr_connect(dst);
700 if (r) 700 if (r)
701 return r; 701 return r;
702 702
703 r = omapdss_output_set_device(dssdev, dst); 703 r = omapdss_output_set_device(dst, dst->next);
704 if (r) { 704 if (r) {
705 DSSERR("failed to connect output to new device: %s\n", 705 DSSERR("failed to connect output to new device: %s\n",
706 dst->name); 706 dst->name);
707 dss_mgr_disconnect(dssdev); 707 goto err_mgr_disconnect;
708 return r;
709 } 708 }
710 709
710 r = omapdss_device_connect(dst->dss, dst, dst->next);
711 if (r)
712 goto err_output_unset;
713
711 return 0; 714 return 0;
715
716err_output_unset:
717 omapdss_output_unset_device(dst);
718err_mgr_disconnect:
719 dss_mgr_disconnect(dst);
720 return r;
712} 721}
713 722
714static void venc_disconnect(struct omap_dss_device *dssdev, 723static void venc_disconnect(struct omap_dss_device *src,
715 struct omap_dss_device *dst) 724 struct omap_dss_device *dst)
716{ 725{
717 omapdss_output_unset_device(dssdev); 726 omapdss_device_disconnect(dst, dst->next);
727 omapdss_output_unset_device(dst);
718 728
719 dss_mgr_disconnect(dssdev); 729 dss_mgr_disconnect(dst);
720} 730}
721 731
722static const struct omap_dss_device_ops venc_ops = { 732static const struct omap_dss_device_ops venc_ops = {
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
index f10e5053580b..0052f151bf7a 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -157,11 +157,14 @@ static void omap_disconnect_pipelines(struct drm_device *ddev)
157 unsigned int i; 157 unsigned int i;
158 158
159 for (i = 0; i < priv->num_pipes; i++) { 159 for (i = 0; i < priv->num_pipes; i++) {
160 struct omap_dss_device *display = priv->pipes[i].display; 160 struct omap_drm_pipeline *pipe = &priv->pipes[i];
161
162 omapdss_device_disconnect(NULL, pipe->output);
161 163
162 omapdss_device_disconnect(display, NULL); 164 omapdss_device_put(pipe->output);
163 priv->pipes[i].display = NULL; 165 omapdss_device_put(pipe->display);
164 omapdss_device_put(display); 166 pipe->output = NULL;
167 pipe->display = NULL;
165 } 168 }
166 169
167 priv->num_pipes = 0; 170 priv->num_pipes = 0;
@@ -182,26 +185,30 @@ static int omap_compare_pipes(const void *a, const void *b)
182static int omap_connect_pipelines(struct drm_device *ddev) 185static int omap_connect_pipelines(struct drm_device *ddev)
183{ 186{
184 struct omap_drm_private *priv = ddev->dev_private; 187 struct omap_drm_private *priv = ddev->dev_private;
185 struct omap_dss_device *display = NULL; 188 struct omap_dss_device *output = NULL;
186 int r; 189 int r;
187 190
188 if (!omapdss_stack_is_ready()) 191 if (!omapdss_stack_is_ready())
189 return -EPROBE_DEFER; 192 return -EPROBE_DEFER;
190 193
191 for_each_dss_display(display) { 194 for_each_dss_output(output) {
192 r = omapdss_device_connect(priv->dss, display, NULL); 195 r = omapdss_device_connect(priv->dss, NULL, output);
193 if (r == -EPROBE_DEFER) { 196 if (r == -EPROBE_DEFER) {
194 omapdss_device_put(display); 197 omapdss_device_put(output);
195 goto cleanup; 198 goto cleanup;
196 } else if (r) { 199 } else if (r) {
197 dev_warn(display->dev, "could not connect display: %s\n", 200 dev_warn(output->dev, "could not connect output %s\n",
198 display->name); 201 output->name);
199 } else { 202 } else {
200 omapdss_device_get(display); 203 struct omap_drm_pipeline *pipe;
201 priv->pipes[priv->num_pipes++].display = display; 204
205 pipe = &priv->pipes[priv->num_pipes++];
206 pipe->output = omapdss_device_get(output);
207 pipe->display = omapdss_display_get(output);
208
202 if (priv->num_pipes == ARRAY_SIZE(priv->pipes)) { 209 if (priv->num_pipes == ARRAY_SIZE(priv->pipes)) {
203 /* To balance the 'for_each_dss_display' loop */ 210 /* To balance the 'for_each_dss_output' loop */
204 omapdss_device_put(display); 211 omapdss_device_put(output);
205 break; 212 break;
206 } 213 }
207 } 214 }
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h
index bc9b954fcc31..a38d07d4d6ea 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
@@ -49,6 +49,7 @@ struct omap_drm_pipeline {
49 struct drm_crtc *crtc; 49 struct drm_crtc *crtc;
50 struct drm_encoder *encoder; 50 struct drm_encoder *encoder;
51 struct drm_connector *connector; 51 struct drm_connector *connector;
52 struct omap_dss_device *output;
52 struct omap_dss_device *display; 53 struct omap_dss_device *display;
53}; 54};
54 55