Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

+99 -34
+8 -3
drivers/gpu/drm/omapdrm/omap_crtc.c
··· 411 411 struct drm_crtc *crtc = &omap_crtc->base; 412 412 DRM_ERROR("%s: errors: %08x\n", omap_crtc->name, irqstatus); 413 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 417 static void omap_crtc_apply_irq(struct omap_drm_irq *irq, uint32_t irqstatus) ··· 421 421 struct drm_crtc *crtc = &omap_crtc->base; 422 422 423 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 426 if (!dispc_mgr_go_busy(omap_crtc->channel)) { 427 427 struct omap_drm_private *priv = 428 428 crtc->dev->dev_private; 429 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 431 queue_work(priv->wq, &omap_crtc->apply_work); 432 432 } 433 433 } ··· 621 621 void omap_crtc_pre_init(void) 622 622 { 623 623 dss_install_mgr_ops(&mgr_ops); 624 + } 625 + 626 + void omap_crtc_pre_uninit(void) 627 + { 628 + dss_uninstall_mgr_ops(); 624 629 } 625 630 626 631 /* initialize crtc */
+9
drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
··· 969 969 }; 970 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 980 struct platform_driver omap_dmm_driver = { 973 981 .probe = omap_dmm_probe, 974 982 .remove = omap_dmm_remove, 975 983 .driver = { 976 984 .owner = THIS_MODULE, 977 985 .name = DMM_DRIVER_NAME, 986 + .of_match_table = of_match_ptr(dmm_of_match), 978 987 #ifdef CONFIG_PM 979 988 .pm = &omap_dmm_pm_ops, 980 989 #endif
+58 -26
drivers/gpu/drm/omapdrm/omap_drv.c
··· 86 86 87 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 131 static int omap_modeset_init(struct drm_device *dev) 91 132 { ··· 136 95 int num_mgrs = dss_feat_get_num_mgrs(); 137 96 int num_crtcs; 138 97 int i, id = 0; 139 - int r; 140 - 141 - omap_crtc_pre_init(); 142 98 143 99 drm_mode_config_init(dev); 144 100 ··· 157 119 enum omap_channel channel; 158 120 struct omap_overlay_manager *mgr; 159 121 160 - if (!dssdev->driver) { 161 - dev_warn(dev->dev, "%s has no driver.. skipping it\n", 162 - dssdev->name); 122 + if (!omapdss_device_is_connected(dssdev)) 163 123 continue; 164 - } 165 - 166 - if (!(dssdev->driver->get_timings || 167 - dssdev->driver->read_edid)) { 168 - dev_warn(dev->dev, "%s driver does not support " 169 - "get_timings or read_edid.. skipping it!\n", 170 - dssdev->name); 171 - continue; 172 - } 173 - 174 - r = dssdev->driver->connect(dssdev); 175 - if (r) { 176 - dev_err(dev->dev, "could not connect display: %s\n", 177 - dssdev->name); 178 - continue; 179 - } 180 124 181 125 encoder = omap_encoder_init(dev, dssdev); 182 126 ··· 517 497 DBG("unload: dev=%p", dev); 518 498 519 499 drm_kms_helper_poll_fini(dev); 520 - drm_vblank_cleanup(dev); 521 - omap_drm_irq_uninstall(dev); 522 500 523 501 omap_fbdev_free(dev); 524 502 omap_modeset_free(dev); 525 503 omap_gem_deinit(dev); 526 504 527 - flush_workqueue(priv->wq); 528 505 destroy_workqueue(priv->wq); 506 + 507 + drm_vblank_cleanup(dev); 508 + omap_drm_irq_uninstall(dev); 529 509 530 510 kfree(dev->dev_private); 531 511 dev->dev_private = NULL; ··· 675 655 676 656 static int pdev_probe(struct platform_device *device) 677 657 { 658 + int r; 659 + 678 660 if (omapdss_is_initialized() == false) 679 661 return -EPROBE_DEFER; 662 + 663 + omap_crtc_pre_init(); 664 + 665 + r = omap_connect_dssdevs(); 666 + if (r) { 667 + omap_crtc_pre_uninit(); 668 + return r; 669 + } 680 670 681 671 DBG("%s", device->name); 682 672 return drm_platform_init(&omap_drm_driver, device); ··· 696 666 { 697 667 DBG(""); 698 668 699 - drm_put_dev(platform_get_drvdata(device)); 669 + omap_disconnect_dssdevs(); 670 + omap_crtc_pre_uninit(); 700 671 672 + drm_put_dev(platform_get_drvdata(device)); 701 673 return 0; 702 674 } 703 675
+3
drivers/gpu/drm/omapdrm/omap_drv.h
··· 145 145 void omap_irq_preinstall(struct drm_device *dev); 146 146 int omap_irq_postinstall(struct drm_device *dev); 147 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 150 void omap_irq_register(struct drm_device *dev, struct omap_drm_irq *irq); 149 151 void omap_irq_unregister(struct drm_device *dev, struct omap_drm_irq *irq); 150 152 int omap_drm_irq_uninstall(struct drm_device *dev); ··· 160 158 int omap_crtc_apply(struct drm_crtc *crtc, 161 159 struct omap_drm_apply *apply); 162 160 void omap_crtc_pre_init(void); 161 + void omap_crtc_pre_uninit(void); 163 162 struct drm_crtc *omap_crtc_init(struct drm_device *dev, 164 163 struct drm_plane *plane, enum omap_channel channel, int id); 165 164
+3
drivers/gpu/drm/omapdrm/omap_encoder.c
··· 51 51 static void omap_encoder_destroy(struct drm_encoder *encoder) 52 52 { 53 53 struct omap_encoder *omap_encoder = to_omap_encoder(encoder); 54 + 55 + omap_encoder_set_enabled(encoder, false); 56 + 54 57 drm_encoder_cleanup(encoder); 55 58 kfree(omap_encoder); 56 59 }
+18 -4
drivers/gpu/drm/omapdrm/omap_irq.c
··· 45 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 50 struct omap_drm_private *priv = dev->dev_private; 51 51 unsigned long flags; 52 52 53 - dispc_runtime_get(); 54 53 spin_lock_irqsave(&list_lock, flags); 55 54 56 55 if (!WARN_ON(irq->registered)) { ··· 59 60 } 60 61 61 62 spin_unlock_irqrestore(&list_lock, flags); 63 + } 64 + 65 + void omap_irq_register(struct drm_device *dev, struct omap_drm_irq *irq) 66 + { 67 + dispc_runtime_get(); 68 + 69 + __omap_irq_register(dev, irq); 70 + 62 71 dispc_runtime_put(); 63 72 } 64 73 65 - void omap_irq_unregister(struct drm_device *dev, struct omap_drm_irq *irq) 74 + void __omap_irq_unregister(struct drm_device *dev, struct omap_drm_irq *irq) 66 75 { 67 76 unsigned long flags; 68 77 69 - dispc_runtime_get(); 70 78 spin_lock_irqsave(&list_lock, flags); 71 79 72 80 if (!WARN_ON(!irq->registered)) { ··· 83 77 } 84 78 85 79 spin_unlock_irqrestore(&list_lock, flags); 80 + } 81 + 82 + void omap_irq_unregister(struct drm_device *dev, struct omap_drm_irq *irq) 83 + { 84 + dispc_runtime_get(); 85 + 86 + __omap_irq_unregister(dev, irq); 87 + 86 88 dispc_runtime_put(); 87 89 } 88 90
-1
drivers/video/omap2/dss/dispc.c
··· 3691 3691 } 3692 3692 3693 3693 pm_runtime_enable(&pdev->dev); 3694 - pm_runtime_irq_safe(&pdev->dev); 3695 3694 3696 3695 r = dispc_runtime_get(); 3697 3696 if (r)