diff options
-rw-r--r-- | drivers/gpu/drm/omapdrm/omap_crtc.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/omapdrm/omap_drv.c | 70 | ||||
-rw-r--r-- | drivers/gpu/drm/omapdrm/omap_drv.h | 1 |
3 files changed, 54 insertions, 22 deletions
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c index e6241c2b8b26..4313bb0a49a6 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.c +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c | |||
@@ -623,6 +623,11 @@ void omap_crtc_pre_init(void) | |||
623 | dss_install_mgr_ops(&mgr_ops); | 623 | dss_install_mgr_ops(&mgr_ops); |
624 | } | 624 | } |
625 | 625 | ||
626 | void omap_crtc_pre_uninit(void) | ||
627 | { | ||
628 | dss_uninstall_mgr_ops(); | ||
629 | } | ||
630 | |||
626 | /* initialize crtc */ | 631 | /* initialize crtc */ |
627 | struct drm_crtc *omap_crtc_init(struct drm_device *dev, | 632 | struct drm_crtc *omap_crtc_init(struct drm_device *dev, |
628 | struct drm_plane *plane, enum omap_channel channel, int id) | 633 | struct drm_plane *plane, enum omap_channel channel, int id) |
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 | ||
90 | static 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 | |||
114 | cleanup: | ||
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 | |||
90 | static int omap_modeset_init(struct drm_device *dev) | 127 | static 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 | ||
656 | static int pdev_probe(struct platform_device *device) | 672 | static 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 | } |
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h index e835c27c5ad4..26dfd2129943 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.h +++ b/drivers/gpu/drm/omapdrm/omap_drv.h | |||
@@ -160,6 +160,7 @@ enum omap_channel omap_crtc_channel(struct drm_crtc *crtc); | |||
160 | int omap_crtc_apply(struct drm_crtc *crtc, | 160 | int omap_crtc_apply(struct drm_crtc *crtc, |
161 | struct omap_drm_apply *apply); | 161 | struct omap_drm_apply *apply); |
162 | void omap_crtc_pre_init(void); | 162 | void omap_crtc_pre_init(void); |
163 | void omap_crtc_pre_uninit(void); | ||
163 | struct drm_crtc *omap_crtc_init(struct drm_device *dev, | 164 | struct drm_crtc *omap_crtc_init(struct drm_device *dev, |
164 | struct drm_plane *plane, enum omap_channel channel, int id); | 165 | struct drm_plane *plane, enum omap_channel channel, int id); |
165 | 166 | ||