aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/omapdrm/omap_drv.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/omapdrm/omap_drv.c')
-rw-r--r--drivers/gpu/drm/omapdrm/omap_drv.c70
1 files changed, 48 insertions, 22 deletions
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
index e7fa3cd96743..651f9022308f 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -87,6 +87,43 @@ static bool channel_used(struct drm_device *dev, enum omap_channel channel)
87 return false; 87 return false;
88} 88}
89 89
90static int omap_connect_dssdevs(void)
91{
92 int r;
93 struct omap_dss_device *dssdev = NULL;
94 bool no_displays = true;
95
96 for_each_dss_dev(dssdev) {
97 r = dssdev->driver->connect(dssdev);
98 if (r == -EPROBE_DEFER) {
99 omap_dss_put_device(dssdev);
100 goto cleanup;
101 } else if (r) {
102 dev_warn(dssdev->dev, "could not connect display: %s\n",
103 dssdev->name);
104 } else {
105 no_displays = false;
106 }
107 }
108
109 if (no_displays)
110 return -EPROBE_DEFER;
111
112 return 0;
113
114cleanup:
115 /*
116 * if we are deferring probe, we disconnect the devices we previously
117 * connected
118 */
119 dssdev = NULL;
120
121 for_each_dss_dev(dssdev)
122 dssdev->driver->disconnect(dssdev);
123
124 return r;
125}
126
90static int omap_modeset_init(struct drm_device *dev) 127static int omap_modeset_init(struct drm_device *dev)
91{ 128{
92 struct omap_drm_private *priv = dev->dev_private; 129 struct omap_drm_private *priv = dev->dev_private;
@@ -95,9 +132,6 @@ static int omap_modeset_init(struct drm_device *dev)
95 int num_mgrs = dss_feat_get_num_mgrs(); 132 int num_mgrs = dss_feat_get_num_mgrs();
96 int num_crtcs; 133 int num_crtcs;
97 int i, id = 0; 134 int i, id = 0;
98 int r;
99
100 omap_crtc_pre_init();
101 135
102 drm_mode_config_init(dev); 136 drm_mode_config_init(dev);
103 137
@@ -119,26 +153,8 @@ static int omap_modeset_init(struct drm_device *dev)
119 enum omap_channel channel; 153 enum omap_channel channel;
120 struct omap_overlay_manager *mgr; 154 struct omap_overlay_manager *mgr;
121 155
122 if (!dssdev->driver) { 156 if (!omapdss_device_is_connected(dssdev))
123 dev_warn(dev->dev, "%s has no driver.. skipping it\n",
124 dssdev->name);
125 continue;
126 }
127
128 if (!(dssdev->driver->get_timings ||
129 dssdev->driver->read_edid)) {
130 dev_warn(dev->dev, "%s driver does not support "
131 "get_timings or read_edid.. skipping it!\n",
132 dssdev->name);
133 continue;
134 }
135
136 r = dssdev->driver->connect(dssdev);
137 if (r) {
138 dev_err(dev->dev, "could not connect display: %s\n",
139 dssdev->name);
140 continue; 157 continue;
141 }
142 158
143 encoder = omap_encoder_init(dev, dssdev); 159 encoder = omap_encoder_init(dev, dssdev);
144 160
@@ -655,9 +671,19 @@ static void pdev_shutdown(struct platform_device *device)
655 671
656static int pdev_probe(struct platform_device *device) 672static int pdev_probe(struct platform_device *device)
657{ 673{
674 int r;
675
658 if (omapdss_is_initialized() == false) 676 if (omapdss_is_initialized() == false)
659 return -EPROBE_DEFER; 677 return -EPROBE_DEFER;
660 678
679 omap_crtc_pre_init();
680
681 r = omap_connect_dssdevs();
682 if (r) {
683 omap_crtc_pre_uninit();
684 return r;
685 }
686
661 DBG("%s", device->name); 687 DBG("%s", device->name);
662 return drm_platform_init(&omap_drm_driver, device); 688 return drm_platform_init(&omap_drm_driver, device);
663} 689}