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.c84
1 files changed, 58 insertions, 26 deletions
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
index 13f294aeaefd..bf39fcc49e0f 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -86,6 +86,47 @@ static bool channel_used(struct drm_device *dev, enum omap_channel channel)
86 86
87 return false; 87 return false;
88} 88}
89static void omap_disconnect_dssdevs(void)
90{
91 struct omap_dss_device *dssdev = NULL;
92
93 for_each_dss_dev(dssdev)
94 dssdev->driver->disconnect(dssdev);
95}
96
97static int omap_connect_dssdevs(void)
98{
99 int r;
100 struct omap_dss_device *dssdev = NULL;
101 bool no_displays = true;
102
103 for_each_dss_dev(dssdev) {
104 r = dssdev->driver->connect(dssdev);
105 if (r == -EPROBE_DEFER) {
106 omap_dss_put_device(dssdev);
107 goto cleanup;
108 } else if (r) {
109 dev_warn(dssdev->dev, "could not connect display: %s\n",
110 dssdev->name);
111 } else {
112 no_displays = false;
113 }
114 }
115
116 if (no_displays)
117 return -EPROBE_DEFER;
118
119 return 0;
120
121cleanup:
122 /*
123 * if we are deferring probe, we disconnect the devices we previously
124 * connected
125 */
126 omap_disconnect_dssdevs();
127
128 return r;
129}
89 130
90static int omap_modeset_init(struct drm_device *dev) 131static int omap_modeset_init(struct drm_device *dev)
91{ 132{
@@ -95,9 +136,6 @@ static int omap_modeset_init(struct drm_device *dev)
95 int num_mgrs = dss_feat_get_num_mgrs(); 136 int num_mgrs = dss_feat_get_num_mgrs();
96 int num_crtcs; 137 int num_crtcs;
97 int i, id = 0; 138 int i, id = 0;
98 int r;
99
100 omap_crtc_pre_init();
101 139
102 drm_mode_config_init(dev); 140 drm_mode_config_init(dev);
103 141
@@ -119,26 +157,8 @@ static int omap_modeset_init(struct drm_device *dev)
119 enum omap_channel channel; 157 enum omap_channel channel;
120 struct omap_overlay_manager *mgr; 158 struct omap_overlay_manager *mgr;
121 159
122 if (!dssdev->driver) { 160 if (!omapdss_device_is_connected(dssdev))
123 dev_warn(dev->dev, "%s has no driver.. skipping it\n",
124 dssdev->name);
125 continue; 161 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;
141 }
142 162
143 encoder = omap_encoder_init(dev, dssdev); 163 encoder = omap_encoder_init(dev, dssdev);
144 164
@@ -497,16 +517,16 @@ static int dev_unload(struct drm_device *dev)
497 DBG("unload: dev=%p", dev); 517 DBG("unload: dev=%p", dev);
498 518
499 drm_kms_helper_poll_fini(dev); 519 drm_kms_helper_poll_fini(dev);
500 drm_vblank_cleanup(dev);
501 omap_drm_irq_uninstall(dev);
502 520
503 omap_fbdev_free(dev); 521 omap_fbdev_free(dev);
504 omap_modeset_free(dev); 522 omap_modeset_free(dev);
505 omap_gem_deinit(dev); 523 omap_gem_deinit(dev);
506 524
507 flush_workqueue(priv->wq);
508 destroy_workqueue(priv->wq); 525 destroy_workqueue(priv->wq);
509 526
527 drm_vblank_cleanup(dev);
528 omap_drm_irq_uninstall(dev);
529
510 kfree(dev->dev_private); 530 kfree(dev->dev_private);
511 dev->dev_private = NULL; 531 dev->dev_private = NULL;
512 532
@@ -655,9 +675,19 @@ static void pdev_shutdown(struct platform_device *device)
655 675
656static int pdev_probe(struct platform_device *device) 676static int pdev_probe(struct platform_device *device)
657{ 677{
678 int r;
679
658 if (omapdss_is_initialized() == false) 680 if (omapdss_is_initialized() == false)
659 return -EPROBE_DEFER; 681 return -EPROBE_DEFER;
660 682
683 omap_crtc_pre_init();
684
685 r = omap_connect_dssdevs();
686 if (r) {
687 omap_crtc_pre_uninit();
688 return r;
689 }
690
661 DBG("%s", device->name); 691 DBG("%s", device->name);
662 return drm_platform_init(&omap_drm_driver, device); 692 return drm_platform_init(&omap_drm_driver, device);
663} 693}
@@ -666,8 +696,10 @@ static int pdev_remove(struct platform_device *device)
666{ 696{
667 DBG(""); 697 DBG("");
668 698
669 drm_put_dev(platform_get_drvdata(device)); 699 omap_disconnect_dssdevs();
700 omap_crtc_pre_uninit();
670 701
702 drm_put_dev(platform_get_drvdata(device));
671 return 0; 703 return 0;
672} 704}
673 705