diff options
author | Inki Dae <inki.dae@samsung.com> | 2012-06-27 03:36:12 -0400 |
---|---|---|
committer | Inki Dae <inki.dae@samsung.com> | 2012-07-26 22:13:56 -0400 |
commit | d3b62dbfc7b9bb013926f56db79b60f6c18c392f (patch) | |
tree | e7d6385b1635fca5dabfc2bf72fecdadb29f6a02 /drivers/gpu | |
parent | d7b8478aa9551bc6585c20287c4ed73007ea51fd (diff) |
drm/exynos: fixed edid data setting at vidi connection request
edid data from user should be allocated and copied into vidi context and also
freed with disconnection.
Signed-off-by: Inki Dae <inki.dae@samsung.com>
Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_vidi.c | 38 |
1 files changed, 31 insertions, 7 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c index dbbf2fc29ab6..1d7d03084acf 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c | |||
@@ -557,6 +557,8 @@ int vidi_connection_ioctl(struct drm_device *drm_dev, void *data, | |||
557 | struct exynos_drm_manager *manager; | 557 | struct exynos_drm_manager *manager; |
558 | struct exynos_drm_display_ops *display_ops; | 558 | struct exynos_drm_display_ops *display_ops; |
559 | struct drm_exynos_vidi_connection *vidi = data; | 559 | struct drm_exynos_vidi_connection *vidi = data; |
560 | struct edid *raw_edid; | ||
561 | int edid_len; | ||
560 | 562 | ||
561 | DRM_DEBUG_KMS("%s\n", __FILE__); | 563 | DRM_DEBUG_KMS("%s\n", __FILE__); |
562 | 564 | ||
@@ -565,11 +567,6 @@ int vidi_connection_ioctl(struct drm_device *drm_dev, void *data, | |||
565 | return -EINVAL; | 567 | return -EINVAL; |
566 | } | 568 | } |
567 | 569 | ||
568 | if (!vidi->edid) { | ||
569 | DRM_DEBUG_KMS("edid data is null.\n"); | ||
570 | return -EINVAL; | ||
571 | } | ||
572 | |||
573 | if (vidi->connection > 1) { | 570 | if (vidi->connection > 1) { |
574 | DRM_DEBUG_KMS("connection should be 0 or 1.\n"); | 571 | DRM_DEBUG_KMS("connection should be 0 or 1.\n"); |
575 | return -EINVAL; | 572 | return -EINVAL; |
@@ -596,8 +593,30 @@ int vidi_connection_ioctl(struct drm_device *drm_dev, void *data, | |||
596 | return -EINVAL; | 593 | return -EINVAL; |
597 | } | 594 | } |
598 | 595 | ||
599 | if (vidi->connection) | 596 | if (vidi->connection) { |
600 | ctx->raw_edid = (struct edid *)vidi->edid; | 597 | if (!vidi->edid) { |
598 | DRM_DEBUG_KMS("edid data is null.\n"); | ||
599 | return -EINVAL; | ||
600 | } | ||
601 | raw_edid = (struct edid *)vidi->edid; | ||
602 | edid_len = (1 + raw_edid->extensions) * EDID_LENGTH; | ||
603 | ctx->raw_edid = kzalloc(edid_len, GFP_KERNEL); | ||
604 | if (!ctx->raw_edid) { | ||
605 | DRM_DEBUG_KMS("failed to allocate raw_edid.\n"); | ||
606 | return -ENOMEM; | ||
607 | } | ||
608 | memcpy(ctx->raw_edid, raw_edid, edid_len); | ||
609 | } else { | ||
610 | /* | ||
611 | * with connection = 0, free raw_edid | ||
612 | * only if raw edid data isn't same as fake data. | ||
613 | */ | ||
614 | if (ctx->raw_edid && ctx->raw_edid != | ||
615 | (struct edid *)fake_edid_info) { | ||
616 | kfree(ctx->raw_edid); | ||
617 | ctx->raw_edid = NULL; | ||
618 | } | ||
619 | } | ||
601 | 620 | ||
602 | ctx->connected = vidi->connection; | 621 | ctx->connected = vidi->connection; |
603 | drm_helper_hpd_irq_event(ctx->subdrv.drm_dev); | 622 | drm_helper_hpd_irq_event(ctx->subdrv.drm_dev); |
@@ -649,6 +668,11 @@ static int __devexit vidi_remove(struct platform_device *pdev) | |||
649 | 668 | ||
650 | exynos_drm_subdrv_unregister(&ctx->subdrv); | 669 | exynos_drm_subdrv_unregister(&ctx->subdrv); |
651 | 670 | ||
671 | if (ctx->raw_edid != (struct edid *)fake_edid_info) { | ||
672 | kfree(ctx->raw_edid); | ||
673 | ctx->raw_edid = NULL; | ||
674 | } | ||
675 | |||
652 | kfree(ctx); | 676 | kfree(ctx); |
653 | 677 | ||
654 | return 0; | 678 | return 0; |