This pull-request includes some bug fixes and code cleanups. Especially, this fixes the bind failure issue occurred when it tries to re-bind Exynos drm driver after unbound, and the modetest failure issue incurred by not having a pair to vblank on and off requests. * 'exynos-drm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos: drm/exynos: correct connector->dpms field before resuming drm/exynos: enable vblank after DPMS on drm/exynos: init kms poll at the end of initialization drm/exynos: propagate plane initialization errors drm/exynos: vidi: fix build warning drm/exynos: remove explicit encoder/connector de-initialization drm/exynos: init vblank with real number of crtcs
Unified · Split
| @@ -1355,13 +1355,8 @@ static void exynos_dp_unbind(struct device *dev, struct device *master, · 1354 unmodified lines | |||
| 1355 | void *data) | 1355 | void *data) |
| 1356 | { | 1356 | { |
| 1357 | struct exynos_drm_display *display = dev_get_drvdata(dev); | 1357 | struct exynos_drm_display *display = dev_get_drvdata(dev); |
| 1358 | struct exynos_dp_device *dp = display->ctx; | ||
| 1359 | struct drm_encoder *encoder = dp->encoder; | ||
| 1360 | 1358 | ||
| 1361 | exynos_dp_dpms(display, DRM_MODE_DPMS_OFF); | 1359 | exynos_dp_dpms(display, DRM_MODE_DPMS_OFF); |
| 1362 | |||
| 1363 | exynos_dp_connector_destroy(&dp->connector); | ||
| 1364 | encoder->funcs->destroy(encoder); | ||
| 1365 | } | 1360 | } |
| 1366 | 1361 | ||
| 1367 | static const struct component_ops exynos_dp_ops = { | 1362 | static const struct component_ops exynos_dp_ops = { |
| @@ -71,13 +71,16 @@ static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode) · 70 unmodified lines | |||
| 71 | !atomic_read(&exynos_crtc->pending_flip), | 71 | !atomic_read(&exynos_crtc->pending_flip), |
| 72 | HZ/20)) | 72 | HZ/20)) |
| 73 | atomic_set(&exynos_crtc->pending_flip, 0); | 73 | atomic_set(&exynos_crtc->pending_flip, 0); |
| 74 | drm_vblank_off(crtc->dev, exynos_crtc->pipe); | 74 | drm_crtc_vblank_off(crtc); |
| 75 | } | 75 | } |
| 76 | 76 | ||
| 77 | if (manager->ops->dpms) | 77 | if (manager->ops->dpms) |
| 78 | manager->ops->dpms(manager, mode); | 78 | manager->ops->dpms(manager, mode); |
| 79 | 79 | ||
| 80 | exynos_crtc->dpms = mode; | 80 | exynos_crtc->dpms = mode; |
| 81 | |||
| 82 | if (mode == DRM_MODE_DPMS_ON) | ||
| 83 | drm_crtc_vblank_on(crtc); | ||
| 81 | } | 84 | } |
| 82 | 85 | ||
| 83 | static void exynos_drm_crtc_prepare(struct drm_crtc *crtc) | 86 | static void exynos_drm_crtc_prepare(struct drm_crtc *crtc) |
| @@ -338,14 +338,10 @@ err_del_component: · 337 unmodified lines | |||
| 338 | 338 | ||
| 339 | int exynos_dpi_remove(struct device *dev) | 339 | int exynos_dpi_remove(struct device *dev) |
| 340 | { | 340 | { |
| 341 | struct drm_encoder *encoder = exynos_dpi_display.encoder; | ||
| 342 | struct exynos_dpi *ctx = exynos_dpi_display.ctx; | 341 | struct exynos_dpi *ctx = exynos_dpi_display.ctx; |
| 343 | 342 | ||
| 344 | exynos_dpi_dpms(&exynos_dpi_display, DRM_MODE_DPMS_OFF); | 343 | exynos_dpi_dpms(&exynos_dpi_display, DRM_MODE_DPMS_OFF); |
| 345 | 344 | ||
| 346 | exynos_dpi_connector_destroy(&ctx->connector); | ||
| 347 | encoder->funcs->destroy(encoder); | ||
| 348 | |||
| 349 | if (ctx->panel) | 345 | if (ctx->panel) |
| 350 | drm_panel_detach(ctx->panel); | 346 | drm_panel_detach(ctx->panel); |
| 351 | 347 | ||
| @@ -87,16 +87,12 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags) · 86 unmodified lines | |||
| 87 | 87 | ||
| 88 | plane = exynos_plane_init(dev, possible_crtcs, | 88 | plane = exynos_plane_init(dev, possible_crtcs, |
| 89 | DRM_PLANE_TYPE_OVERLAY); | 89 | DRM_PLANE_TYPE_OVERLAY); |
| 90 | if (IS_ERR(plane)) | 90 | if (!IS_ERR(plane)) |
| 91 | goto err_mode_config_cleanup; | 91 | continue; |
| 92 | } | ||
| 93 | |||
| 94 | /* init kms poll for handling hpd */ | ||
| 95 | drm_kms_helper_poll_init(dev); | ||
| 96 | 92 | ||
| 97 | ret = drm_vblank_init(dev, MAX_CRTC); | 93 | ret = PTR_ERR(plane); |
| 98 | if (ret) | ||
| 99 | goto err_mode_config_cleanup; | 94 | goto err_mode_config_cleanup; |
| 95 | } | ||
| 100 | 96 | ||
| 101 | /* setup possible_clones. */ | 97 | /* setup possible_clones. */ |
| 102 | exynos_drm_encoder_setup(dev); | 98 | exynos_drm_encoder_setup(dev); |
| @@ -106,15 +102,16 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags) · 3 unmodified lines | |||
| 106 | /* Try to bind all sub drivers. */ | 102 | /* Try to bind all sub drivers. */ |
| 107 | ret = component_bind_all(dev->dev, dev); | 103 | ret = component_bind_all(dev->dev, dev); |
| 108 | if (ret) | 104 | if (ret) |
| 109 | goto err_cleanup_vblank; | 105 | goto err_mode_config_cleanup; |
| 110 | 106 | ||
| 111 | /* Probe non kms sub drivers and virtual display driver. */ | 107 | ret = drm_vblank_init(dev, dev->mode_config.num_crtc); |
| 112 | ret = exynos_drm_device_subdrv_probe(dev); | ||
| 113 | if (ret) | 108 | if (ret) |
| 114 | goto err_unbind_all; | 109 | goto err_unbind_all; |
| 115 | 110 | ||
| 116 | /* force connectors detection */ | 111 | /* Probe non kms sub drivers and virtual display driver. */ |
| 117 | drm_helper_hpd_irq_event(dev); | 112 | ret = exynos_drm_device_subdrv_probe(dev); |
| 113 | if (ret) | ||
| 114 | goto err_cleanup_vblank; | ||
| 118 | 115 | ||
| 119 | /* | 116 | /* |
| 120 | * enable drm irq mode. | 117 | * enable drm irq mode. |
| @@ -133,12 +130,18 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags) · 12 unmodified lines | |||
| 133 | */ | 130 | */ |
| 134 | dev->vblank_disable_allowed = true; | 131 | dev->vblank_disable_allowed = true; |
| 135 | 132 | ||
| 133 | /* init kms poll for handling hpd */ | ||
| 134 | drm_kms_helper_poll_init(dev); | ||
| 135 | |||
| 136 | /* force connectors detection */ | ||
| 137 | drm_helper_hpd_irq_event(dev); | ||
| 138 | |||
| 136 | return 0; | 139 | return 0; |
| 137 | 140 | ||
| 138 | err_unbind_all: | ||
| 139 | component_unbind_all(dev->dev, dev); | ||
| 140 | err_cleanup_vblank: | 141 | err_cleanup_vblank: |
| 141 | drm_vblank_cleanup(dev); | 142 | drm_vblank_cleanup(dev); |
| 143 | err_unbind_all: | ||
| 144 | component_unbind_all(dev->dev, dev); | ||
| 142 | err_mode_config_cleanup: | 145 | err_mode_config_cleanup: |
| 143 | drm_mode_config_cleanup(dev); | 146 | drm_mode_config_cleanup(dev); |
| 144 | drm_release_iommu_mapping(dev); | 147 | drm_release_iommu_mapping(dev); |
| @@ -155,8 +158,8 @@ static int exynos_drm_unload(struct drm_device *dev) · 10 unmodified lines | |||
| 155 | exynos_drm_fbdev_fini(dev); | 158 | exynos_drm_fbdev_fini(dev); |
| 156 | drm_kms_helper_poll_fini(dev); | 159 | drm_kms_helper_poll_fini(dev); |
| 157 | 160 | ||
| 158 | component_unbind_all(dev->dev, dev); | ||
| 159 | drm_vblank_cleanup(dev); | 161 | drm_vblank_cleanup(dev); |
| 162 | component_unbind_all(dev->dev, dev); | ||
| 160 | drm_mode_config_cleanup(dev); | 163 | drm_mode_config_cleanup(dev); |
| 161 | drm_release_iommu_mapping(dev); | 164 | drm_release_iommu_mapping(dev); |
| 162 | 165 | ||
| @@ -191,8 +194,12 @@ static int exynos_drm_resume(struct drm_device *dev) · 28 unmodified lines | |||
| 191 | 194 | ||
| 192 | drm_modeset_lock_all(dev); | 195 | drm_modeset_lock_all(dev); |
| 193 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 196 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
| 194 | if (connector->funcs->dpms) | 197 | if (connector->funcs->dpms) { |
| 195 | connector->funcs->dpms(connector, connector->dpms); | 198 | int dpms = connector->dpms; |
| 199 | |||
| 200 | connector->dpms = DRM_MODE_DPMS_OFF; | ||
| 201 | connector->funcs->dpms(connector, dpms); | ||
| 202 | } | ||
| 196 | } | 203 | } |
| 197 | drm_modeset_unlock_all(dev); | 204 | drm_modeset_unlock_all(dev); |
| 198 | 205 | ||
| @@ -1660,13 +1660,9 @@ static void exynos_dsi_unbind(struct device *dev, struct device *master, · 1659 unmodified lines | |||
| 1660 | void *data) | 1660 | void *data) |
| 1661 | { | 1661 | { |
| 1662 | struct exynos_dsi *dsi = exynos_dsi_display.ctx; | 1662 | struct exynos_dsi *dsi = exynos_dsi_display.ctx; |
| 1663 | struct drm_encoder *encoder = dsi->encoder; | ||
| 1664 | 1663 | ||
| 1665 | exynos_dsi_dpms(&exynos_dsi_display, DRM_MODE_DPMS_OFF); | 1664 | exynos_dsi_dpms(&exynos_dsi_display, DRM_MODE_DPMS_OFF); |
| 1666 | 1665 | ||
| 1667 | exynos_dsi_connector_destroy(&dsi->connector); | ||
| 1668 | encoder->funcs->destroy(encoder); | ||
| 1669 | |||
| 1670 | mipi_dsi_host_unregister(&dsi->dsi_host); | 1666 | mipi_dsi_host_unregister(&dsi->dsi_host); |
| 1671 | } | 1667 | } |
| 1672 | 1668 | ||
| @@ -630,7 +630,6 @@ static int vidi_remove(struct platform_device *pdev) · 629 unmodified lines | |||
| 630 | { | 630 | { |
| 631 | struct exynos_drm_manager *mgr = platform_get_drvdata(pdev); | 631 | struct exynos_drm_manager *mgr = platform_get_drvdata(pdev); |
| 632 | struct vidi_context *ctx = mgr->ctx; | 632 | struct vidi_context *ctx = mgr->ctx; |
| 633 | struct drm_encoder *encoder = ctx->encoder; | ||
| 634 | 633 | ||
| 635 | if (ctx->raw_edid != (struct edid *)fake_edid_info) { | 634 | if (ctx->raw_edid != (struct edid *)fake_edid_info) { |
| 636 | kfree(ctx->raw_edid); | 635 | kfree(ctx->raw_edid); |
| @@ -639,9 +638,6 @@ static int vidi_remove(struct platform_device *pdev) · 2 unmodified lines | |||
| 639 | return -EINVAL; | 638 | return -EINVAL; |
| 640 | } | 639 | } |
| 641 | 640 | ||
| 642 | encoder->funcs->destroy(encoder); | ||
| 643 | drm_connector_cleanup(&ctx->connector); | ||
| 644 | |||
| 645 | return 0; | 641 | return 0; |
| 646 | } | 642 | } |
| 647 | 643 | ||
| @@ -2312,12 +2312,6 @@ static int hdmi_bind(struct device *dev, struct device *master, void *data) · 2311 unmodified lines | |||
| 2312 | 2312 | ||
| 2313 | static void hdmi_unbind(struct device *dev, struct device *master, void *data) | 2313 | static void hdmi_unbind(struct device *dev, struct device *master, void *data) |
| 2314 | { | 2314 | { |
| 2315 | struct exynos_drm_display *display = get_hdmi_display(dev); | ||
| 2316 | struct drm_encoder *encoder = display->encoder; | ||
| 2317 | struct hdmi_context *hdata = display->ctx; | ||
| 2318 | |||
| 2319 | hdmi_connector_destroy(&hdata->connector); | ||
| 2320 | encoder->funcs->destroy(encoder); | ||
| 2321 | } | 2315 | } |
| 2322 | 2316 | ||
| 2323 | static const struct component_ops hdmi_component_ops = { | 2317 | static const struct component_ops hdmi_component_ops = { |