diff options
author | Dave Airlie <airlied@redhat.com> | 2014-01-28 18:37:47 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2014-01-28 18:37:47 -0500 |
commit | dee13f12f6ab0c0927adf9168dfc84da93fc9f13 (patch) | |
tree | 593748d4054a7d623ca04be3b93cd9ae7126f961 /drivers | |
parent | 5a0abe30bebae3e73bf7808f55b2cd0309fa101d (diff) | |
parent | 3d232346c5656b300028b6c920ddc10b229b5264 (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.c | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/omapdrm/omap_dmm_tiler.c | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/omapdrm/omap_drv.c | 84 | ||||
-rw-r--r-- | drivers/gpu/drm/omapdrm/omap_drv.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/omapdrm/omap_encoder.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/omapdrm/omap_irq.c | 22 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dispc.c | 1 |
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 | ||
417 | static void omap_crtc_apply_irq(struct omap_drm_irq *irq, uint32_t irqstatus) | 417 | static 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 | ||
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_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) | ||
973 | static const struct of_device_id dmm_of_match[] = { | ||
974 | { .compatible = "ti,omap4-dmm", }, | ||
975 | { .compatible = "ti,omap5-dmm", }, | ||
976 | {}, | ||
977 | }; | ||
978 | #endif | ||
979 | |||
972 | struct platform_driver omap_dmm_driver = { | 980 | struct 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 | } |
89 | static 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 | |||
97 | static 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 | |||
121 | cleanup: | ||
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 | ||
90 | static int omap_modeset_init(struct drm_device *dev) | 131 | static 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 | ||
656 | static int pdev_probe(struct platform_device *device) | 676 | static 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); | |||
145 | void omap_irq_preinstall(struct drm_device *dev); | 145 | void omap_irq_preinstall(struct drm_device *dev); |
146 | int omap_irq_postinstall(struct drm_device *dev); | 146 | int omap_irq_postinstall(struct drm_device *dev); |
147 | void omap_irq_uninstall(struct drm_device *dev); | 147 | void omap_irq_uninstall(struct drm_device *dev); |
148 | void __omap_irq_register(struct drm_device *dev, struct omap_drm_irq *irq); | ||
149 | void __omap_irq_unregister(struct drm_device *dev, struct omap_drm_irq *irq); | ||
148 | void omap_irq_register(struct drm_device *dev, struct omap_drm_irq *irq); | 150 | void omap_irq_register(struct drm_device *dev, struct omap_drm_irq *irq); |
149 | void omap_irq_unregister(struct drm_device *dev, struct omap_drm_irq *irq); | 151 | void omap_irq_unregister(struct drm_device *dev, struct omap_drm_irq *irq); |
150 | int omap_drm_irq_uninstall(struct drm_device *dev); | 152 | int omap_drm_irq_uninstall(struct drm_device *dev); |
@@ -158,6 +160,7 @@ enum omap_channel omap_crtc_channel(struct drm_crtc *crtc); | |||
158 | int omap_crtc_apply(struct drm_crtc *crtc, | 160 | int omap_crtc_apply(struct drm_crtc *crtc, |
159 | struct omap_drm_apply *apply); | 161 | struct omap_drm_apply *apply); |
160 | void omap_crtc_pre_init(void); | 162 | void omap_crtc_pre_init(void); |
163 | void omap_crtc_pre_uninit(void); | ||
161 | struct drm_crtc *omap_crtc_init(struct drm_device *dev, | 164 | struct 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) | |||
51 | static void omap_encoder_destroy(struct drm_encoder *encoder) | 51 | static 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 | ||
48 | void omap_irq_register(struct drm_device *dev, struct omap_drm_irq *irq) | 48 | void __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 | |||
64 | void 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 | ||
66 | void omap_irq_unregister(struct drm_device *dev, struct omap_drm_irq *irq) | 73 | void __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 | |||
88 | void 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) |