aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2014-11-12 18:09:29 -0500
committerDave Airlie <airlied@redhat.com>2014-11-12 18:09:29 -0500
commit3b548f4a69b02091031ee60c9a477463f7145963 (patch)
tree0aabea2387ef8f9e297410e083eb51963fcf1b23
parent03dca708521d30153fc5c7e2ff136f780a7372c9 (diff)
parent7afbfcc9ae6af259351e6fa6b931b1a38b62d9ab (diff)
Merge branch 'exynos-drm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos into drm-fixes
Now exynos drm driver incurs infinite loop issue on multi-platform reported by Matwey V.Korniliv like below, http://comments.gmane.org/gmane.comp.video.dri.devel/117622 This issue is because non kms drivers enabled are probed before a component master tries to bring up. This patch set resolves the infinite loop issue and also includes fixups relevant to exynos drm internal issues. * 'exynos-drm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos: drm/exynos: fix possible infinite loop issue drm/exynos: g2d: fix null pointer dereference drm/exynos: resolve infinite loop issue on non multi-platform drm/exynos: resolve infinite loop issue on multi-platform
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_drv.c49
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_g2d.c9
2 files changed, 39 insertions, 19 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index c57466edf45b..e5c4c6c8c967 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -495,6 +495,12 @@ static struct component_match *exynos_drm_match_add(struct device *dev)
495 495
496 mutex_lock(&drm_component_lock); 496 mutex_lock(&drm_component_lock);
497 497
498 /* Do not retry to probe if there is no any kms driver regitered. */
499 if (list_empty(&drm_component_list)) {
500 mutex_unlock(&drm_component_lock);
501 return ERR_PTR(-ENODEV);
502 }
503
498 list_for_each_entry(cdev, &drm_component_list, list) { 504 list_for_each_entry(cdev, &drm_component_list, list) {
499 /* 505 /*
500 * Add components to master only in case that crtc and 506 * Add components to master only in case that crtc and
@@ -585,10 +591,21 @@ static int exynos_drm_platform_probe(struct platform_device *pdev)
585 goto err_unregister_mixer_drv; 591 goto err_unregister_mixer_drv;
586#endif 592#endif
587 593
594 match = exynos_drm_match_add(&pdev->dev);
595 if (IS_ERR(match)) {
596 ret = PTR_ERR(match);
597 goto err_unregister_hdmi_drv;
598 }
599
600 ret = component_master_add_with_match(&pdev->dev, &exynos_drm_ops,
601 match);
602 if (ret < 0)
603 goto err_unregister_hdmi_drv;
604
588#ifdef CONFIG_DRM_EXYNOS_G2D 605#ifdef CONFIG_DRM_EXYNOS_G2D
589 ret = platform_driver_register(&g2d_driver); 606 ret = platform_driver_register(&g2d_driver);
590 if (ret < 0) 607 if (ret < 0)
591 goto err_unregister_hdmi_drv; 608 goto err_del_component_master;
592#endif 609#endif
593 610
594#ifdef CONFIG_DRM_EXYNOS_FIMC 611#ifdef CONFIG_DRM_EXYNOS_FIMC
@@ -619,23 +636,9 @@ static int exynos_drm_platform_probe(struct platform_device *pdev)
619 goto err_unregister_ipp_drv; 636 goto err_unregister_ipp_drv;
620#endif 637#endif
621 638
622 match = exynos_drm_match_add(&pdev->dev);
623 if (IS_ERR(match)) {
624 ret = PTR_ERR(match);
625 goto err_unregister_resources;
626 }
627
628 ret = component_master_add_with_match(&pdev->dev, &exynos_drm_ops,
629 match);
630 if (ret < 0)
631 goto err_unregister_resources;
632
633 return ret; 639 return ret;
634 640
635err_unregister_resources:
636
637#ifdef CONFIG_DRM_EXYNOS_IPP 641#ifdef CONFIG_DRM_EXYNOS_IPP
638 exynos_platform_device_ipp_unregister();
639err_unregister_ipp_drv: 642err_unregister_ipp_drv:
640 platform_driver_unregister(&ipp_driver); 643 platform_driver_unregister(&ipp_driver);
641err_unregister_gsc_drv: 644err_unregister_gsc_drv:
@@ -658,9 +661,11 @@ err_unregister_g2d_drv:
658 661
659#ifdef CONFIG_DRM_EXYNOS_G2D 662#ifdef CONFIG_DRM_EXYNOS_G2D
660 platform_driver_unregister(&g2d_driver); 663 platform_driver_unregister(&g2d_driver);
661err_unregister_hdmi_drv: 664err_del_component_master:
662#endif 665#endif
666 component_master_del(&pdev->dev, &exynos_drm_ops);
663 667
668err_unregister_hdmi_drv:
664#ifdef CONFIG_DRM_EXYNOS_HDMI 669#ifdef CONFIG_DRM_EXYNOS_HDMI
665 platform_driver_unregister(&hdmi_driver); 670 platform_driver_unregister(&hdmi_driver);
666err_unregister_mixer_drv: 671err_unregister_mixer_drv:
@@ -741,6 +746,18 @@ static int exynos_drm_init(void)
741{ 746{
742 int ret; 747 int ret;
743 748
749 /*
750 * Register device object only in case of Exynos SoC.
751 *
752 * Below codes resolves temporarily infinite loop issue incurred
753 * by Exynos drm driver when using multi-platform kernel.
754 * So these codes will be replaced with more generic way later.
755 */
756 if (!of_machine_is_compatible("samsung,exynos3") &&
757 !of_machine_is_compatible("samsung,exynos4") &&
758 !of_machine_is_compatible("samsung,exynos5"))
759 return -ENODEV;
760
744 exynos_drm_pdev = platform_device_register_simple("exynos-drm", -1, 761 exynos_drm_pdev = platform_device_register_simple("exynos-drm", -1,
745 NULL, 0); 762 NULL, 0);
746 if (IS_ERR(exynos_drm_pdev)) 763 if (IS_ERR(exynos_drm_pdev))
diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
index df7a77d3eff8..6ff8599f6cbf 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
@@ -302,9 +302,12 @@ static void g2d_fini_cmdlist(struct g2d_data *g2d)
302 struct exynos_drm_subdrv *subdrv = &g2d->subdrv; 302 struct exynos_drm_subdrv *subdrv = &g2d->subdrv;
303 303
304 kfree(g2d->cmdlist_node); 304 kfree(g2d->cmdlist_node);
305 dma_free_attrs(subdrv->drm_dev->dev, G2D_CMDLIST_POOL_SIZE, 305
306 g2d->cmdlist_pool_virt, 306 if (g2d->cmdlist_pool_virt && g2d->cmdlist_pool) {
307 g2d->cmdlist_pool, &g2d->cmdlist_dma_attrs); 307 dma_free_attrs(subdrv->drm_dev->dev, G2D_CMDLIST_POOL_SIZE,
308 g2d->cmdlist_pool_virt,
309 g2d->cmdlist_pool, &g2d->cmdlist_dma_attrs);
310 }
308} 311}
309 312
310static struct g2d_cmdlist_node *g2d_get_cmdlist(struct g2d_data *g2d) 313static struct g2d_cmdlist_node *g2d_get_cmdlist(struct g2d_data *g2d)