aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2014-01-28 18:37:47 -0500
committerDave Airlie <airlied@redhat.com>2014-01-28 18:37:47 -0500
commitdee13f12f6ab0c0927adf9168dfc84da93fc9f13 (patch)
tree593748d4054a7d623ca04be3b93cd9ae7126f961 /drivers
parent5a0abe30bebae3e73bf7808f55b2cd0309fa101d (diff)
parent3d232346c5656b300028b6c920ddc10b229b5264 (diff)
Merge tag 'omapdrm-3.14' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux into drm-next
omapdrm patches for 3.14 * tag 'omapdrm-3.14' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux: drm/omap: Enable DT support for DMM drm/omap: fix: change dev_unload order drm/omap: fix: disable encoder before destroying it drm/omap: fix: disconnect devices when omapdrm module is removed drm/omap: fix: Defer probe if an omapdss device requests for it at connect drm/omap: fix (un)registering irqs inside an irq handler Conflicts: drivers/gpu/drm/omapdrm/omap_drv.c
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/omapdrm/omap_crtc.c11
-rw-r--r--drivers/gpu/drm/omapdrm/omap_dmm_tiler.c9
-rw-r--r--drivers/gpu/drm/omapdrm/omap_drv.c84
-rw-r--r--drivers/gpu/drm/omapdrm/omap_drv.h3
-rw-r--r--drivers/gpu/drm/omapdrm/omap_encoder.c3
-rw-r--r--drivers/gpu/drm/omapdrm/omap_irq.c22
-rw-r--r--drivers/video/omap2/dss/dispc.c1
7 files changed, 99 insertions, 34 deletions
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 0fd2eb139f6e..4313bb0a49a6 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -411,7 +411,7 @@ static void omap_crtc_error_irq(struct omap_drm_irq *irq, uint32_t irqstatus)
411 struct drm_crtc *crtc = &omap_crtc->base; 411 struct drm_crtc *crtc = &omap_crtc->base;
412 DRM_ERROR("%s: errors: %08x\n", omap_crtc->name, irqstatus); 412 DRM_ERROR("%s: errors: %08x\n", omap_crtc->name, irqstatus);
413 /* avoid getting in a flood, unregister the irq until next vblank */ 413 /* avoid getting in a flood, unregister the irq until next vblank */
414 omap_irq_unregister(crtc->dev, &omap_crtc->error_irq); 414 __omap_irq_unregister(crtc->dev, &omap_crtc->error_irq);
415} 415}
416 416
417static void omap_crtc_apply_irq(struct omap_drm_irq *irq, uint32_t irqstatus) 417static void omap_crtc_apply_irq(struct omap_drm_irq *irq, uint32_t irqstatus)
@@ -421,13 +421,13 @@ static void omap_crtc_apply_irq(struct omap_drm_irq *irq, uint32_t irqstatus)
421 struct drm_crtc *crtc = &omap_crtc->base; 421 struct drm_crtc *crtc = &omap_crtc->base;
422 422
423 if (!omap_crtc->error_irq.registered) 423 if (!omap_crtc->error_irq.registered)
424 omap_irq_register(crtc->dev, &omap_crtc->error_irq); 424 __omap_irq_register(crtc->dev, &omap_crtc->error_irq);
425 425
426 if (!dispc_mgr_go_busy(omap_crtc->channel)) { 426 if (!dispc_mgr_go_busy(omap_crtc->channel)) {
427 struct omap_drm_private *priv = 427 struct omap_drm_private *priv =
428 crtc->dev->dev_private; 428 crtc->dev->dev_private;
429 DBG("%s: apply done", omap_crtc->name); 429 DBG("%s: apply done", omap_crtc->name);
430 omap_irq_unregister(crtc->dev, &omap_crtc->apply_irq); 430 __omap_irq_unregister(crtc->dev, &omap_crtc->apply_irq);
431 queue_work(priv->wq, &omap_crtc->apply_work); 431 queue_work(priv->wq, &omap_crtc->apply_work);
432 } 432 }
433} 433}
@@ -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
626void omap_crtc_pre_uninit(void)
627{
628 dss_uninstall_mgr_ops();
629}
630
626/* initialize crtc */ 631/* initialize crtc */
627struct drm_crtc *omap_crtc_init(struct drm_device *dev, 632struct 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_dmm_tiler.c b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
index 701c4c10e08b..f926b4caf449 100644
--- a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
+++ b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
@@ -969,12 +969,21 @@ static const struct dev_pm_ops omap_dmm_pm_ops = {
969}; 969};
970#endif 970#endif
971 971
972#if defined(CONFIG_OF)
973static const struct of_device_id dmm_of_match[] = {
974 { .compatible = "ti,omap4-dmm", },
975 { .compatible = "ti,omap5-dmm", },
976 {},
977};
978#endif
979
972struct platform_driver omap_dmm_driver = { 980struct platform_driver omap_dmm_driver = {
973 .probe = omap_dmm_probe, 981 .probe = omap_dmm_probe,
974 .remove = omap_dmm_remove, 982 .remove = omap_dmm_remove,
975 .driver = { 983 .driver = {
976 .owner = THIS_MODULE, 984 .owner = THIS_MODULE,
977 .name = DMM_DRIVER_NAME, 985 .name = DMM_DRIVER_NAME,
986 .of_match_table = of_match_ptr(dmm_of_match),
978#ifdef CONFIG_PM 987#ifdef CONFIG_PM
979 .pm = &omap_dmm_pm_ops, 988 .pm = &omap_dmm_pm_ops,
980#endif 989#endif
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
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h
index c88fea32dbf6..428b2981fd68 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
@@ -145,6 +145,8 @@ irqreturn_t omap_irq_handler(int irq, void *arg);
145void omap_irq_preinstall(struct drm_device *dev); 145void omap_irq_preinstall(struct drm_device *dev);
146int omap_irq_postinstall(struct drm_device *dev); 146int omap_irq_postinstall(struct drm_device *dev);
147void omap_irq_uninstall(struct drm_device *dev); 147void omap_irq_uninstall(struct drm_device *dev);
148void __omap_irq_register(struct drm_device *dev, struct omap_drm_irq *irq);
149void __omap_irq_unregister(struct drm_device *dev, struct omap_drm_irq *irq);
148void omap_irq_register(struct drm_device *dev, struct omap_drm_irq *irq); 150void omap_irq_register(struct drm_device *dev, struct omap_drm_irq *irq);
149void omap_irq_unregister(struct drm_device *dev, struct omap_drm_irq *irq); 151void omap_irq_unregister(struct drm_device *dev, struct omap_drm_irq *irq);
150int omap_drm_irq_uninstall(struct drm_device *dev); 152int omap_drm_irq_uninstall(struct drm_device *dev);
@@ -158,6 +160,7 @@ enum omap_channel omap_crtc_channel(struct drm_crtc *crtc);
158int omap_crtc_apply(struct drm_crtc *crtc, 160int omap_crtc_apply(struct drm_crtc *crtc,
159 struct omap_drm_apply *apply); 161 struct omap_drm_apply *apply);
160void omap_crtc_pre_init(void); 162void omap_crtc_pre_init(void);
163void omap_crtc_pre_uninit(void);
161struct drm_crtc *omap_crtc_init(struct drm_device *dev, 164struct drm_crtc *omap_crtc_init(struct drm_device *dev,
162 struct drm_plane *plane, enum omap_channel channel, int id); 165 struct drm_plane *plane, enum omap_channel channel, int id);
163 166
diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.c b/drivers/gpu/drm/omapdrm/omap_encoder.c
index 6a12e899235b..5290a88c681d 100644
--- a/drivers/gpu/drm/omapdrm/omap_encoder.c
+++ b/drivers/gpu/drm/omapdrm/omap_encoder.c
@@ -51,6 +51,9 @@ struct omap_dss_device *omap_encoder_get_dssdev(struct drm_encoder *encoder)
51static void omap_encoder_destroy(struct drm_encoder *encoder) 51static void omap_encoder_destroy(struct drm_encoder *encoder)
52{ 52{
53 struct omap_encoder *omap_encoder = to_omap_encoder(encoder); 53 struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
54
55 omap_encoder_set_enabled(encoder, false);
56
54 drm_encoder_cleanup(encoder); 57 drm_encoder_cleanup(encoder);
55 kfree(omap_encoder); 58 kfree(omap_encoder);
56} 59}
diff --git a/drivers/gpu/drm/omapdrm/omap_irq.c b/drivers/gpu/drm/omapdrm/omap_irq.c
index 0e5336e5a791..f035d2bceae7 100644
--- a/drivers/gpu/drm/omapdrm/omap_irq.c
+++ b/drivers/gpu/drm/omapdrm/omap_irq.c
@@ -45,12 +45,11 @@ static void omap_irq_update(struct drm_device *dev)
45 dispc_read_irqenable(); /* flush posted write */ 45 dispc_read_irqenable(); /* flush posted write */
46} 46}
47 47
48void omap_irq_register(struct drm_device *dev, struct omap_drm_irq *irq) 48void __omap_irq_register(struct drm_device *dev, struct omap_drm_irq *irq)
49{ 49{
50 struct omap_drm_private *priv = dev->dev_private; 50 struct omap_drm_private *priv = dev->dev_private;
51 unsigned long flags; 51 unsigned long flags;
52 52
53 dispc_runtime_get();
54 spin_lock_irqsave(&list_lock, flags); 53 spin_lock_irqsave(&list_lock, flags);
55 54
56 if (!WARN_ON(irq->registered)) { 55 if (!WARN_ON(irq->registered)) {
@@ -60,14 +59,21 @@ void omap_irq_register(struct drm_device *dev, struct omap_drm_irq *irq)
60 } 59 }
61 60
62 spin_unlock_irqrestore(&list_lock, flags); 61 spin_unlock_irqrestore(&list_lock, flags);
62}
63
64void omap_irq_register(struct drm_device *dev, struct omap_drm_irq *irq)
65{
66 dispc_runtime_get();
67
68 __omap_irq_register(dev, irq);
69
63 dispc_runtime_put(); 70 dispc_runtime_put();
64} 71}
65 72
66void omap_irq_unregister(struct drm_device *dev, struct omap_drm_irq *irq) 73void __omap_irq_unregister(struct drm_device *dev, struct omap_drm_irq *irq)
67{ 74{
68 unsigned long flags; 75 unsigned long flags;
69 76
70 dispc_runtime_get();
71 spin_lock_irqsave(&list_lock, flags); 77 spin_lock_irqsave(&list_lock, flags);
72 78
73 if (!WARN_ON(!irq->registered)) { 79 if (!WARN_ON(!irq->registered)) {
@@ -77,6 +83,14 @@ void omap_irq_unregister(struct drm_device *dev, struct omap_drm_irq *irq)
77 } 83 }
78 84
79 spin_unlock_irqrestore(&list_lock, flags); 85 spin_unlock_irqrestore(&list_lock, flags);
86}
87
88void omap_irq_unregister(struct drm_device *dev, struct omap_drm_irq *irq)
89{
90 dispc_runtime_get();
91
92 __omap_irq_unregister(dev, irq);
93
80 dispc_runtime_put(); 94 dispc_runtime_put();
81} 95}
82 96
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 4ec59ca72e5d..91c687fd002e 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -3691,7 +3691,6 @@ static int __init omap_dispchw_probe(struct platform_device *pdev)
3691 } 3691 }
3692 3692
3693 pm_runtime_enable(&pdev->dev); 3693 pm_runtime_enable(&pdev->dev);
3694 pm_runtime_irq_safe(&pdev->dev);
3695 3694
3696 r = dispc_runtime_get(); 3695 r = dispc_runtime_get();
3697 if (r) 3696 if (r)