Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3b548f4a authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge branch 'exynos-drm-fixes' of...

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
parents 03dca708 7afbfcc9
Loading
Loading
Loading
Loading
+33 −16
Original line number Diff line number Diff line
@@ -495,6 +495,12 @@ static struct component_match *exynos_drm_match_add(struct device *dev)

	mutex_lock(&drm_component_lock);

	/* Do not retry to probe if there is no any kms driver regitered. */
	if (list_empty(&drm_component_list)) {
		mutex_unlock(&drm_component_lock);
		return ERR_PTR(-ENODEV);
	}

	list_for_each_entry(cdev, &drm_component_list, list) {
		/*
		 * Add components to master only in case that crtc and
@@ -585,10 +591,21 @@ static int exynos_drm_platform_probe(struct platform_device *pdev)
		goto err_unregister_mixer_drv;
#endif

	match = exynos_drm_match_add(&pdev->dev);
	if (IS_ERR(match)) {
		ret = PTR_ERR(match);
		goto err_unregister_hdmi_drv;
	}

	ret = component_master_add_with_match(&pdev->dev, &exynos_drm_ops,
						match);
	if (ret < 0)
		goto err_unregister_hdmi_drv;

#ifdef CONFIG_DRM_EXYNOS_G2D
	ret = platform_driver_register(&g2d_driver);
	if (ret < 0)
		goto err_unregister_hdmi_drv;
		goto err_del_component_master;
#endif

#ifdef CONFIG_DRM_EXYNOS_FIMC
@@ -619,23 +636,9 @@ static int exynos_drm_platform_probe(struct platform_device *pdev)
		goto err_unregister_ipp_drv;
#endif

	match = exynos_drm_match_add(&pdev->dev);
	if (IS_ERR(match)) {
		ret = PTR_ERR(match);
		goto err_unregister_resources;
	}

	ret = component_master_add_with_match(&pdev->dev, &exynos_drm_ops,
						match);
	if (ret < 0)
		goto err_unregister_resources;

	return ret;

err_unregister_resources:

#ifdef CONFIG_DRM_EXYNOS_IPP
	exynos_platform_device_ipp_unregister();
err_unregister_ipp_drv:
	platform_driver_unregister(&ipp_driver);
err_unregister_gsc_drv:
@@ -658,9 +661,11 @@ static int exynos_drm_platform_probe(struct platform_device *pdev)

#ifdef CONFIG_DRM_EXYNOS_G2D
	platform_driver_unregister(&g2d_driver);
err_unregister_hdmi_drv:
err_del_component_master:
#endif
	component_master_del(&pdev->dev, &exynos_drm_ops);

err_unregister_hdmi_drv:
#ifdef CONFIG_DRM_EXYNOS_HDMI
	platform_driver_unregister(&hdmi_driver);
err_unregister_mixer_drv:
@@ -741,6 +746,18 @@ static int exynos_drm_init(void)
{
	int ret;

	/*
	 * Register device object only in case of Exynos SoC.
	 *
	 * Below codes resolves temporarily infinite loop issue incurred
	 * by Exynos drm driver when using multi-platform kernel.
	 * So these codes will be replaced with more generic way later.
	 */
	if (!of_machine_is_compatible("samsung,exynos3") &&
			!of_machine_is_compatible("samsung,exynos4") &&
			!of_machine_is_compatible("samsung,exynos5"))
		return -ENODEV;

	exynos_drm_pdev = platform_device_register_simple("exynos-drm", -1,
								NULL, 0);
	if (IS_ERR(exynos_drm_pdev))
+6 −3
Original line number Diff line number Diff line
@@ -302,10 +302,13 @@ static void g2d_fini_cmdlist(struct g2d_data *g2d)
	struct exynos_drm_subdrv *subdrv = &g2d->subdrv;

	kfree(g2d->cmdlist_node);

	if (g2d->cmdlist_pool_virt && g2d->cmdlist_pool) {
		dma_free_attrs(subdrv->drm_dev->dev, G2D_CMDLIST_POOL_SIZE,
				g2d->cmdlist_pool_virt,
				g2d->cmdlist_pool, &g2d->cmdlist_dma_attrs);
	}
}

static struct g2d_cmdlist_node *g2d_get_cmdlist(struct g2d_data *g2d)
{