All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] exynos_drm initialization fix
@ 2015-06-08 10:15 Andrzej Hajda
  2015-06-08 10:15 ` [PATCH 1/3] drm/exynos: consolidate driver/device initialization code Andrzej Hajda
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Andrzej Hajda @ 2015-06-08 10:15 UTC (permalink / raw)
  To: Inki Dae
  Cc: Andrzej Hajda, Marek Szyprowski, b.zolnierkie, dri-devel,
	linux-samsung-soc

Hi Inki,

Those patches fixes issue of exynos_drm initialization with more than one pipeline,
which is present in exynos_drm drivers for long time.
On most platforms at least two of three following pipelines are present:
1. VIDI.
2. FIMD/DECON -> DSI/DPI -> Panel.
3. MIXER/DECON -> HDMI -> TV.
In case we want use two or three pipelines simultaneously and one of KMS drivers
defers probing only some drivers will be bound to drm driver and usually only one
pipeline will be available. This patchset fixes it.

Beside bugfixing the patchset significantly simplifies and clears the code - about
300 lines removed.

The patchset is based on exynos-drm-next branch.
The patchset was tested on universal_c210 board.

Regards
Andrzej


Andrzej Hajda (3):
  drm/exynos: consolidate driver/device initialization code
  drm/exynos: fix broken component binding in case of multiple pipelines
  drm/exynos: remove SoC checking code

 drivers/gpu/drm/exynos/exynos7_drm_decon.c |  14 +-
 drivers/gpu/drm/exynos/exynos_dp_core.c    |  13 +-
 drivers/gpu/drm/exynos/exynos_drm_dpi.c    |  20 +-
 drivers/gpu/drm/exynos/exynos_drm_drv.c    | 427 +++++++++++------------------
 drivers/gpu/drm/exynos/exynos_drm_drv.h    |  17 --
 drivers/gpu/drm/exynos/exynos_drm_dsi.c    |  29 +-
 drivers/gpu/drm/exynos/exynos_drm_fimd.c   |  28 +-
 drivers/gpu/drm/exynos/exynos_drm_ipp.c    |  27 --
 drivers/gpu/drm/exynos/exynos_drm_vidi.c   |  53 +---
 drivers/gpu/drm/exynos/exynos_hdmi.c       |  22 +-
 drivers/gpu/drm/exynos/exynos_mixer.c      |  14 +-
 11 files changed, 187 insertions(+), 477 deletions(-)

-- 
1.9.1

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 1/3] drm/exynos: consolidate driver/device initialization code
  2015-06-08 10:15 [PATCH 0/3] exynos_drm initialization fix Andrzej Hajda
@ 2015-06-08 10:15 ` Andrzej Hajda
  2015-06-11 14:33   ` Inki Dae
  2015-06-08 10:15 ` [PATCH 2/3] drm/exynos: fix broken component binding in case of multiple pipelines Andrzej Hajda
  2015-06-08 10:15 ` [PATCH 3/3] drm/exynos: remove SoC checking code Andrzej Hajda
  2 siblings, 1 reply; 9+ messages in thread
From: Andrzej Hajda @ 2015-06-08 10:15 UTC (permalink / raw)
  To: Inki Dae
  Cc: Andrzej Hajda, Marek Szyprowski, b.zolnierkie, dri-devel,
	linux-samsung-soc

Code registering different drivers and simple platform devices was dispersed
across multiple sub-modules. This patch moves it to one place. As a result
initialization code is shorter and cleaner and should simplify further
development.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
 drivers/gpu/drm/exynos/exynos_drm_drv.c  | 221 +++++++++++++++++++------------
 drivers/gpu/drm/exynos/exynos_drm_drv.h  |  17 ---
 drivers/gpu/drm/exynos/exynos_drm_ipp.c  |  27 ----
 drivers/gpu/drm/exynos/exynos_drm_vidi.c |  35 -----
 4 files changed, 139 insertions(+), 161 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index 08b9a8c..5c5a72a 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -38,8 +38,6 @@
 #define DRIVER_MAJOR	1
 #define DRIVER_MINOR	0
 
-static struct platform_device *exynos_drm_pdev;
-
 static DEFINE_MUTEX(drm_component_lock);
 static LIST_HEAD(drm_component_list);
 
@@ -527,7 +525,41 @@ static const struct component_master_ops exynos_drm_ops = {
 	.unbind		= exynos_drm_unbind,
 };
 
+static int exynos_drm_platform_probe(struct platform_device *pdev)
+{
+	struct component_match *match;
+
+	pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+	exynos_drm_driver.num_ioctls = ARRAY_SIZE(exynos_ioctls);
+
+	match = exynos_drm_match_add(&pdev->dev);
+	if (IS_ERR(match)) {
+		return PTR_ERR(match);
+	}
+
+	return component_master_add_with_match(&pdev->dev, &exynos_drm_ops,
+					       match);
+}
+
+static int exynos_drm_platform_remove(struct platform_device *pdev)
+{
+	component_master_del(&pdev->dev, &exynos_drm_ops);
+	return 0;
+}
+
+static struct platform_driver exynos_drm_platform_driver = {
+	.probe	= exynos_drm_platform_probe,
+	.remove	= exynos_drm_platform_remove,
+	.driver	= {
+		.name	= "exynos-drm",
+		.pm	= &exynos_drm_pm_ops,
+	},
+};
+
 static struct platform_driver *const exynos_drm_kms_drivers[] = {
+#ifdef CONFIG_DRM_EXYNOS_VIDI
+	&vidi_driver,
+#endif
 #ifdef CONFIG_DRM_EXYNOS_FIMD
 	&fimd_driver,
 #endif
@@ -562,30 +594,109 @@ static struct platform_driver *const exynos_drm_non_kms_drivers[] = {
 #ifdef CONFIG_DRM_EXYNOS_IPP
 	&ipp_driver,
 #endif
+	&exynos_drm_platform_driver,
 };
 
-static int exynos_drm_platform_probe(struct platform_device *pdev)
+
+static struct platform_driver *const exynos_drm_drv_with_simple_dev[] = {
+#ifdef CONFIG_DRM_EXYNOS_VIDI
+	&vidi_driver,
+#endif
+#ifdef CONFIG_DRM_EXYNOS_IPP
+	&ipp_driver,
+#endif
+	&exynos_drm_platform_driver,
+};
+
+#define PDEV_COUNT ARRAY_SIZE(exynos_drm_drv_with_simple_dev)
+
+static struct platform_device *exynos_drm_pdevs[PDEV_COUNT];
+
+static void exynos_drm_unregister_devices(void)
 {
-	struct component_match *match;
+	int i = PDEV_COUNT;
 
-	pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
-	exynos_drm_driver.num_ioctls = ARRAY_SIZE(exynos_ioctls);
+	while (--i >= 0) {
+		platform_device_unregister(exynos_drm_pdevs[i]);
+		exynos_drm_pdevs[i] = NULL;
+	}
+}
 
-	match = exynos_drm_match_add(&pdev->dev);
-	if (IS_ERR(match)) {
-		return PTR_ERR(match);
+static int exynos_drm_register_devices(void)
+{
+	int i;
+
+	for (i = 0; i < PDEV_COUNT; ++i) {
+		struct platform_driver *d = exynos_drm_drv_with_simple_dev[i];
+		struct platform_device *pdev =
+			platform_device_register_simple(d->driver.name,-1, NULL,
+							0);
+
+		if (!IS_ERR(pdev)) {
+			exynos_drm_pdevs[i] = pdev;
+			continue;
+		}
+		while (--i >= 0) {
+			platform_device_unregister(exynos_drm_pdevs[i]);
+			exynos_drm_pdevs[i] = NULL;
+		}
+
+		return PTR_ERR(pdev);
 	}
 
-	return component_master_add_with_match(&pdev->dev, &exynos_drm_ops,
-					       match);
+	return 0;
 }
 
-static int exynos_drm_platform_remove(struct platform_device *pdev)
+static void exynos_drm_unregister_drivers(struct platform_driver * const *drv,
+					  int count)
 {
-	component_master_del(&pdev->dev, &exynos_drm_ops);
+	while (--count >= 0)
+		platform_driver_unregister(drv[count]);
+}
+
+static int exynos_drm_register_drivers(struct platform_driver * const *drv,
+				       int count)
+{
+	int i, ret;
+
+	for (i = 0; i < count; ++i) {
+		ret = platform_driver_register(drv[i]);
+		if (!ret)
+			continue;
+
+		while (--i >= 0)
+			platform_driver_unregister(drv[i]);
+
+		return ret;
+	}
+
 	return 0;
 }
 
+static inline int exynos_drm_register_kms_drivers(void)
+{
+	return exynos_drm_register_drivers(exynos_drm_kms_drivers,
+					ARRAY_SIZE(exynos_drm_kms_drivers));
+}
+
+static inline int exynos_drm_register_non_kms_drivers(void)
+{
+	return exynos_drm_register_drivers(exynos_drm_non_kms_drivers,
+					ARRAY_SIZE(exynos_drm_non_kms_drivers));
+}
+
+static inline void exynos_drm_unregister_kms_drivers(void)
+{
+	exynos_drm_unregister_drivers(exynos_drm_kms_drivers,
+					ARRAY_SIZE(exynos_drm_kms_drivers));
+}
+
+static inline void exynos_drm_unregister_non_kms_drivers(void)
+{
+	exynos_drm_unregister_drivers(exynos_drm_non_kms_drivers,
+					ARRAY_SIZE(exynos_drm_non_kms_drivers));
+}
+
 static const char * const strings[] = {
 	"samsung,exynos3",
 	"samsung,exynos4",
@@ -593,19 +704,10 @@ static const char * const strings[] = {
 	"samsung,exynos7",
 };
 
-static struct platform_driver exynos_drm_platform_driver = {
-	.probe	= exynos_drm_platform_probe,
-	.remove	= exynos_drm_platform_remove,
-	.driver	= {
-		.name	= "exynos-drm",
-		.pm	= &exynos_drm_pm_ops,
-	},
-};
-
 static int exynos_drm_init(void)
 {
 	bool is_exynos = false;
-	int ret, i, j;
+	int ret, i;
 
 	/*
 	 * Register device object only in case of Exynos SoC.
@@ -624,79 +726,34 @@ static int exynos_drm_init(void)
 	if (!is_exynos)
 		return -ENODEV;
 
-	exynos_drm_pdev = platform_device_register_simple("exynos-drm", -1,
-								NULL, 0);
-	if (IS_ERR(exynos_drm_pdev))
-		return PTR_ERR(exynos_drm_pdev);
-
-	ret = exynos_drm_probe_vidi();
-	if (ret < 0)
-		goto err_unregister_pd;
-
-	for (i = 0; i < ARRAY_SIZE(exynos_drm_kms_drivers); ++i) {
-		ret = platform_driver_register(exynos_drm_kms_drivers[i]);
-		if (ret < 0)
-			goto err_unregister_kms_drivers;
-	}
-
-	for (j = 0; j < ARRAY_SIZE(exynos_drm_non_kms_drivers); ++j) {
-		ret = platform_driver_register(exynos_drm_non_kms_drivers[j]);
-		if (ret < 0)
-			goto err_unregister_non_kms_drivers;
-	}
+	ret = exynos_drm_register_devices();
+	if (ret)
+		return ret;
 
-#ifdef CONFIG_DRM_EXYNOS_IPP
-	ret = exynos_platform_device_ipp_register();
-	if (ret < 0)
-		goto err_unregister_non_kms_drivers;
-#endif
+	ret = exynos_drm_register_kms_drivers();
+	if (ret)
+		goto err_unregister_pdevs;
 
-	ret = platform_driver_register(&exynos_drm_platform_driver);
+	ret = exynos_drm_register_non_kms_drivers();
 	if (ret)
-		goto err_unregister_resources;
+		goto err_unregister_kms_drivers;
 
 	return 0;
 
-err_unregister_resources:
-#ifdef CONFIG_DRM_EXYNOS_IPP
-	exynos_platform_device_ipp_unregister();
-#endif
-
-err_unregister_non_kms_drivers:
-	while (--j >= 0)
-		platform_driver_unregister(exynos_drm_non_kms_drivers[j]);
-
 err_unregister_kms_drivers:
-	while (--i >= 0)
-		platform_driver_unregister(exynos_drm_kms_drivers[i]);
+	exynos_drm_unregister_kms_drivers();
 
-	exynos_drm_remove_vidi();
-
-err_unregister_pd:
-	platform_device_unregister(exynos_drm_pdev);
+err_unregister_pdevs:
+	exynos_drm_unregister_devices();
 
 	return ret;
 }
 
 static void exynos_drm_exit(void)
 {
-	int i;
-
-#ifdef CONFIG_DRM_EXYNOS_IPP
-	exynos_platform_device_ipp_unregister();
-#endif
-
-	for (i = ARRAY_SIZE(exynos_drm_non_kms_drivers) - 1; i >= 0; --i)
-		platform_driver_unregister(exynos_drm_non_kms_drivers[i]);
-
-	for (i = ARRAY_SIZE(exynos_drm_kms_drivers) - 1; i >= 0; --i)
-		platform_driver_unregister(exynos_drm_kms_drivers[i]);
-
-	platform_driver_unregister(&exynos_drm_platform_driver);
-
-	exynos_drm_remove_vidi();
-
-	platform_device_unregister(exynos_drm_pdev);
+	exynos_drm_unregister_non_kms_drivers();
+	exynos_drm_unregister_kms_drivers();
+	exynos_drm_unregister_devices();
 }
 
 module_init(exynos_drm_init);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index 1c66f65..b308e90 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -295,15 +295,6 @@ int exynos_drm_device_subdrv_remove(struct drm_device *dev);
 int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file);
 void exynos_drm_subdrv_close(struct drm_device *dev, struct drm_file *file);
 
-#ifdef CONFIG_DRM_EXYNOS_IPP
-int exynos_platform_device_ipp_register(void);
-void exynos_platform_device_ipp_unregister(void);
-#else
-static inline int exynos_platform_device_ipp_register(void) { return 0; }
-static inline void exynos_platform_device_ipp_unregister(void) {}
-#endif
-
-
 #ifdef CONFIG_DRM_EXYNOS_DPI
 struct exynos_drm_display * exynos_dpi_probe(struct device *dev);
 int exynos_dpi_remove(struct exynos_drm_display *display);
@@ -316,14 +307,6 @@ static inline int exynos_dpi_remove(struct exynos_drm_display *display)
 }
 #endif
 
-#ifdef CONFIG_DRM_EXYNOS_VIDI
-int exynos_drm_probe_vidi(void);
-void exynos_drm_remove_vidi(void);
-#else
-static inline int exynos_drm_probe_vidi(void) { return 0; }
-static inline void exynos_drm_remove_vidi(void) {}
-#endif
-
 /* This function creates a encoder and a connector, and initializes them. */
 int exynos_drm_create_enc_conn(struct drm_device *dev,
 				struct exynos_drm_display *display);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
index b7f1cbc..f594dd7 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
@@ -45,9 +45,6 @@
 #define get_ipp_context(dev)	platform_get_drvdata(to_platform_device(dev))
 #define ipp_is_m2m_cmd(c)	(c == IPP_CMD_M2M)
 
-/* platform device pointer for ipp device. */
-static struct platform_device *exynos_drm_ipp_pdev;
-
 /*
  * A structure of event.
  *
@@ -102,30 +99,6 @@ static LIST_HEAD(exynos_drm_ippdrv_list);
 static DEFINE_MUTEX(exynos_drm_ippdrv_lock);
 static BLOCKING_NOTIFIER_HEAD(exynos_drm_ippnb_list);
 
-int exynos_platform_device_ipp_register(void)
-{
-	struct platform_device *pdev;
-
-	if (exynos_drm_ipp_pdev)
-		return -EEXIST;
-
-	pdev = platform_device_register_simple("exynos-drm-ipp", -1, NULL, 0);
-	if (IS_ERR(pdev))
-		return PTR_ERR(pdev);
-
-	exynos_drm_ipp_pdev = pdev;
-
-	return 0;
-}
-
-void exynos_platform_device_ipp_unregister(void)
-{
-	if (exynos_drm_ipp_pdev) {
-		platform_device_unregister(exynos_drm_ipp_pdev);
-		exynos_drm_ipp_pdev = NULL;
-	}
-}
-
 int exynos_drm_ippdrv_register(struct exynos_drm_ippdrv *ippdrv)
 {
 	mutex_lock(&exynos_drm_ippdrv_lock);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
index abe4ee0..f63ac58 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
@@ -571,38 +571,3 @@ struct platform_driver vidi_driver = {
 		.owner	= THIS_MODULE,
 	},
 };
-
-int exynos_drm_probe_vidi(void)
-{
-	struct platform_device *pdev;
-	int ret;
-
-	pdev = platform_device_register_simple("exynos-drm-vidi", -1, NULL, 0);
-	if (IS_ERR(pdev))
-		return PTR_ERR(pdev);
-
-	ret = platform_driver_register(&vidi_driver);
-	if (ret) {
-		platform_device_unregister(pdev);
-		return ret;
-	}
-
-	return ret;
-}
-
-static int exynos_drm_remove_vidi_device(struct device *dev, void *data)
-{
-	platform_device_unregister(to_platform_device(dev));
-
-	return 0;
-}
-
-void exynos_drm_remove_vidi(void)
-{
-	int ret = driver_for_each_device(&vidi_driver.driver, NULL, NULL,
-					 exynos_drm_remove_vidi_device);
-	/* silence compiler warning */
-	(void)ret;
-
-	platform_driver_unregister(&vidi_driver);
-}
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 2/3] drm/exynos: fix broken component binding in case of multiple pipelines
  2015-06-08 10:15 [PATCH 0/3] exynos_drm initialization fix Andrzej Hajda
  2015-06-08 10:15 ` [PATCH 1/3] drm/exynos: consolidate driver/device initialization code Andrzej Hajda
@ 2015-06-08 10:15 ` Andrzej Hajda
  2015-06-09 19:47   ` Gustavo Padovan
  2015-06-08 10:15 ` [PATCH 3/3] drm/exynos: remove SoC checking code Andrzej Hajda
  2 siblings, 1 reply; 9+ messages in thread
From: Andrzej Hajda @ 2015-06-08 10:15 UTC (permalink / raw)
  To: Inki Dae
  Cc: Andrzej Hajda, Marek Szyprowski, b.zolnierkie, dri-devel,
	linux-samsung-soc

In case there are multiple pipelines and deferred probe occurs, only components
of the first pipeline were bound. As a result only one pipeline was available.
The main cause of this issue was dynamic generation of component match table -
every component driver during probe registered itself on helper list, if there
was at least one pipeline present on this list component match table were
created without deferred components.
This patch removes this helper list, instead it creates match table from
existing devices requiring exynos_drm KMS drivers. This way match table do not
depend on probe/deferral order and contains all KMS components.
As a side effect patch makes the code cleaner and significantly smaller.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
 drivers/gpu/drm/exynos/exynos7_drm_decon.c |  14 +-
 drivers/gpu/drm/exynos/exynos_dp_core.c    |  13 +-
 drivers/gpu/drm/exynos/exynos_drm_dpi.c    |  20 +-
 drivers/gpu/drm/exynos/exynos_drm_drv.c    | 283 ++++++++---------------------
 drivers/gpu/drm/exynos/exynos_drm_dsi.c    |  29 +--
 drivers/gpu/drm/exynos/exynos_drm_fimd.c   |  28 +--
 drivers/gpu/drm/exynos/exynos_drm_vidi.c   |  18 +-
 drivers/gpu/drm/exynos/exynos_hdmi.c       |  22 +--
 drivers/gpu/drm/exynos/exynos_mixer.c      |  14 +-
 9 files changed, 99 insertions(+), 342 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
index d659ba2..22cb067 100644
--- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c
+++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
@@ -769,11 +769,6 @@ static int decon_probe(struct platform_device *pdev)
 	if (!ctx)
 		return -ENOMEM;
 
-	ret = exynos_drm_component_add(dev, EXYNOS_DEVICE_TYPE_CRTC,
-					EXYNOS_DISPLAY_TYPE_LCD);
-	if (ret)
-		return ret;
-
 	ctx->dev = dev;
 	ctx->suspended = true;
 
@@ -783,10 +778,8 @@ static int decon_probe(struct platform_device *pdev)
 	of_node_put(i80_if_timings);
 
 	ctx->regs = of_iomap(dev->of_node, 0);
-	if (!ctx->regs) {
-		ret = -ENOMEM;
-		goto err_del_component;
-	}
+	if (!ctx->regs)
+		return -ENOMEM;
 
 	ctx->pclk = devm_clk_get(dev, "pclk_decon0");
 	if (IS_ERR(ctx->pclk)) {
@@ -856,8 +849,6 @@ err_disable_pm_runtime:
 err_iounmap:
 	iounmap(ctx->regs);
 
-err_del_component:
-	exynos_drm_component_del(dev, EXYNOS_DEVICE_TYPE_CRTC);
 	return ret;
 }
 
@@ -870,7 +861,6 @@ static int decon_remove(struct platform_device *pdev)
 	iounmap(ctx->regs);
 
 	component_del(&pdev->dev, &decon_component_ops);
-	exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c
index c9995b1..bf1fce2 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.c
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.c
@@ -1344,11 +1344,6 @@ static int exynos_dp_probe(struct platform_device *pdev)
 	dp->display.ops = &exynos_dp_display_ops;
 	platform_set_drvdata(pdev, dp);
 
-	ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR,
-					dp->display.type);
-	if (ret)
-		return ret;
-
 	panel_node = of_parse_phandle(dev->of_node, "panel", 0);
 	if (panel_node) {
 		dp->panel = of_drm_find_panel(panel_node);
@@ -1369,18 +1364,12 @@ static int exynos_dp_probe(struct platform_device *pdev)
 			return -EPROBE_DEFER;
 	}
 
-	ret = component_add(&pdev->dev, &exynos_dp_ops);
-	if (ret)
-		exynos_drm_component_del(&pdev->dev,
-						EXYNOS_DEVICE_TYPE_CONNECTOR);
-
-	return ret;
+	return component_add(&pdev->dev, &exynos_dp_ops);
 }
 
 static int exynos_dp_remove(struct platform_device *pdev)
 {
 	component_del(&pdev->dev, &exynos_dp_ops);
-	exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dpi.c b/drivers/gpu/drm/exynos/exynos_drm_dpi.c
index 6dc328e..7cb6595 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dpi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dpi.c
@@ -313,33 +313,19 @@ struct exynos_drm_display *exynos_dpi_probe(struct device *dev)
 	ctx->dev = dev;
 	ctx->dpms_mode = DRM_MODE_DPMS_OFF;
 
-	ret = exynos_drm_component_add(dev,
-					EXYNOS_DEVICE_TYPE_CONNECTOR,
-					ctx->display.type);
-	if (ret)
-		return ERR_PTR(ret);
-
 	ret = exynos_dpi_parse_dt(ctx);
 	if (ret < 0) {
 		devm_kfree(dev, ctx);
-		goto err_del_component;
+		return NULL;
 	}
 
 	if (ctx->panel_node) {
 		ctx->panel = of_drm_find_panel(ctx->panel_node);
-		if (!ctx->panel) {
-			exynos_drm_component_del(dev,
-						EXYNOS_DEVICE_TYPE_CONNECTOR);
+		if (!ctx->panel)
 			return ERR_PTR(-EPROBE_DEFER);
-		}
 	}
 
 	return &ctx->display;
-
-err_del_component:
-	exynos_drm_component_del(dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
-
-	return NULL;
 }
 
 int exynos_dpi_remove(struct exynos_drm_display *display)
@@ -351,7 +337,5 @@ int exynos_dpi_remove(struct exynos_drm_display *display)
 	if (ctx->panel)
 		drm_panel_detach(ctx->panel);
 
-	exynos_drm_component_del(ctx->dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
-
 	return 0;
 }
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index 5c5a72a..cfbfb6c 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -38,17 +38,6 @@
 #define DRIVER_MAJOR	1
 #define DRIVER_MINOR	0
 
-static DEFINE_MUTEX(drm_component_lock);
-static LIST_HEAD(drm_component_list);
-
-struct component_dev {
-	struct list_head list;
-	struct device *crtc_dev;
-	struct device *conn_dev;
-	enum exynos_drm_output_type out_type;
-	unsigned int dev_type_flag;
-};
-
 static int exynos_drm_load(struct drm_device *dev, unsigned long flags)
 {
 	struct exynos_drm_private *private;
@@ -348,108 +337,70 @@ static const struct dev_pm_ops exynos_drm_pm_ops = {
 	SET_SYSTEM_SLEEP_PM_OPS(exynos_drm_sys_suspend, exynos_drm_sys_resume)
 };
 
-int exynos_drm_component_add(struct device *dev,
-				enum exynos_drm_device_type dev_type,
-				enum exynos_drm_output_type out_type)
-{
-	struct component_dev *cdev;
-
-	if (dev_type != EXYNOS_DEVICE_TYPE_CRTC &&
-			dev_type != EXYNOS_DEVICE_TYPE_CONNECTOR) {
-		DRM_ERROR("invalid device type.\n");
-		return -EINVAL;
-	}
-
-	mutex_lock(&drm_component_lock);
+/* forward declaration */
+static struct platform_driver exynos_drm_platform_driver;
 
-	/*
-	 * Make sure to check if there is a component which has two device
-	 * objects, for connector and for encoder/connector.
-	 * It should make sure that crtc and encoder/connector drivers are
-	 * ready before exynos drm core binds them.
-	 */
-	list_for_each_entry(cdev, &drm_component_list, list) {
-		if (cdev->out_type == out_type) {
-			/*
-			 * If crtc and encoder/connector device objects are
-			 * added already just return.
-			 */
-			if (cdev->dev_type_flag == (EXYNOS_DEVICE_TYPE_CRTC |
-						EXYNOS_DEVICE_TYPE_CONNECTOR)) {
-				mutex_unlock(&drm_component_lock);
-				return 0;
-			}
-
-			if (dev_type == EXYNOS_DEVICE_TYPE_CRTC) {
-				cdev->crtc_dev = dev;
-				cdev->dev_type_flag |= dev_type;
-			}
-
-			if (dev_type == EXYNOS_DEVICE_TYPE_CONNECTOR) {
-				cdev->conn_dev = dev;
-				cdev->dev_type_flag |= dev_type;
-			}
-
-			mutex_unlock(&drm_component_lock);
-			return 0;
-		}
-	}
-
-	mutex_unlock(&drm_component_lock);
-
-	cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
-	if (!cdev)
-		return -ENOMEM;
-
-	if (dev_type == EXYNOS_DEVICE_TYPE_CRTC)
-		cdev->crtc_dev = dev;
-	if (dev_type == EXYNOS_DEVICE_TYPE_CONNECTOR)
-		cdev->conn_dev = dev;
-
-	cdev->out_type = out_type;
-	cdev->dev_type_flag = dev_type;
-
-	mutex_lock(&drm_component_lock);
-	list_add_tail(&cdev->list, &drm_component_list);
-	mutex_unlock(&drm_component_lock);
-
-	return 0;
-}
-
-void exynos_drm_component_del(struct device *dev,
-				enum exynos_drm_device_type dev_type)
-{
-	struct component_dev *cdev, *next;
-
-	mutex_lock(&drm_component_lock);
-
-	list_for_each_entry_safe(cdev, next, &drm_component_list, list) {
-		if (dev_type == EXYNOS_DEVICE_TYPE_CRTC) {
-			if (cdev->crtc_dev == dev) {
-				cdev->crtc_dev = NULL;
-				cdev->dev_type_flag &= ~dev_type;
-			}
-		}
-
-		if (dev_type == EXYNOS_DEVICE_TYPE_CONNECTOR) {
-			if (cdev->conn_dev == dev) {
-				cdev->conn_dev = NULL;
-				cdev->dev_type_flag &= ~dev_type;
-			}
-		}
+/*
+ * Connector drivers should not be placed before associated crtc drivers,
+ * because connector requires pipe number of its crtc during initialization.
+ */
+static struct platform_driver *const exynos_drm_kms_drivers[] = {
+#ifdef CONFIG_DRM_EXYNOS_VIDI
+	&vidi_driver,
+#endif
+#ifdef CONFIG_DRM_EXYNOS_FIMD
+	&fimd_driver,
+#endif
+#ifdef CONFIG_DRM_EXYNOS5433_DECON
+	&exynos5433_decon_driver,
+#endif
+#ifdef CONFIG_DRM_EXYNOS7_DECON
+	&decon_driver,
+#endif
+#ifdef CONFIG_DRM_EXYNOS_DP
+	&dp_driver,
+#endif
+#ifdef CONFIG_DRM_EXYNOS_DSI
+	&dsi_driver,
+#endif
+#ifdef CONFIG_DRM_EXYNOS_HDMI
+	&mixer_driver,
+	&hdmi_driver,
+#endif
+};
 
-		/*
-		 * Release cdev object only in case that both of crtc and
-		 * encoder/connector device objects are NULL.
-		 */
-		if (!cdev->crtc_dev && !cdev->conn_dev) {
-			list_del(&cdev->list);
-			kfree(cdev);
-		}
-	}
+static struct platform_driver *const exynos_drm_non_kms_drivers[] = {
+#ifdef CONFIG_DRM_EXYNOS_MIC
+	&mic_driver,
+#endif
+#ifdef CONFIG_DRM_EXYNOS_G2D
+	&g2d_driver,
+#endif
+#ifdef CONFIG_DRM_EXYNOS_FIMC
+	&fimc_driver,
+#endif
+#ifdef CONFIG_DRM_EXYNOS_ROTATOR
+	&rotator_driver,
+#endif
+#ifdef CONFIG_DRM_EXYNOS_GSC
+	&gsc_driver,
+#endif
+#ifdef CONFIG_DRM_EXYNOS_IPP
+	&ipp_driver,
+#endif
+	&exynos_drm_platform_driver,
+};
 
-	mutex_unlock(&drm_component_lock);
-}
+static struct platform_driver *const exynos_drm_drv_with_simple_dev[] = {
+#ifdef CONFIG_DRM_EXYNOS_VIDI
+	&vidi_driver,
+#endif
+#ifdef CONFIG_DRM_EXYNOS_IPP
+	&ipp_driver,
+#endif
+	&exynos_drm_platform_driver,
+};
+#define PDEV_COUNT ARRAY_SIZE(exynos_drm_drv_with_simple_dev)
 
 static int compare_dev(struct device *dev, void *data)
 {
@@ -459,55 +410,22 @@ static int compare_dev(struct device *dev, void *data)
 static struct component_match *exynos_drm_match_add(struct device *dev)
 {
 	struct component_match *match = NULL;
-	struct component_dev *cdev;
-	unsigned int attach_cnt = 0;
-
-	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
-		 * encoder/connector device objects exist.
-		 */
-		if (!cdev->crtc_dev || !cdev->conn_dev)
-			continue;
-
-		attach_cnt++;
+	int i;
 
-		mutex_unlock(&drm_component_lock);
+	for (i = 0; i < ARRAY_SIZE(exynos_drm_kms_drivers); ++i) {
+		struct device_driver *drv = &exynos_drm_kms_drivers[i]->driver;
+		struct device *p = NULL, *d;
 
-		/*
-		 * fimd and dpi modules have same device object so add
-		 * only crtc device object in this case.
-		 */
-		if (cdev->crtc_dev == cdev->conn_dev) {
-			component_match_add(dev, &match, compare_dev,
-						cdev->crtc_dev);
-			goto out_lock;
+		while ((d = bus_find_device(&platform_bus_type, p, drv,
+					    (void *)platform_bus_type.match))) {
+			put_device(p);
+			component_match_add(dev, &match, compare_dev, d);
+			p = d;
 		}
-
-		/*
-		 * Do not chage below call order.
-		 * crtc device first should be added to master because
-		 * connector/encoder need pipe number of crtc when they
-		 * are created.
-		 */
-		component_match_add(dev, &match, compare_dev, cdev->crtc_dev);
-		component_match_add(dev, &match, compare_dev, cdev->conn_dev);
-
-out_lock:
-		mutex_lock(&drm_component_lock);
+		put_device(p);
 	}
 
-	mutex_unlock(&drm_component_lock);
-
-	return attach_cnt ? match : ERR_PTR(-EPROBE_DEFER);
+	return match ?: ERR_PTR(-ENODEV);
 }
 
 static int exynos_drm_bind(struct device *dev)
@@ -533,9 +451,8 @@ static int exynos_drm_platform_probe(struct platform_device *pdev)
 	exynos_drm_driver.num_ioctls = ARRAY_SIZE(exynos_ioctls);
 
 	match = exynos_drm_match_add(&pdev->dev);
-	if (IS_ERR(match)) {
+	if (IS_ERR(match))
 		return PTR_ERR(match);
-	}
 
 	return component_master_add_with_match(&pdev->dev, &exynos_drm_ops,
 					       match);
@@ -556,60 +473,6 @@ static struct platform_driver exynos_drm_platform_driver = {
 	},
 };
 
-static struct platform_driver *const exynos_drm_kms_drivers[] = {
-#ifdef CONFIG_DRM_EXYNOS_VIDI
-	&vidi_driver,
-#endif
-#ifdef CONFIG_DRM_EXYNOS_FIMD
-	&fimd_driver,
-#endif
-#ifdef CONFIG_DRM_EXYNOS7_DECON
-	&decon_driver,
-#endif
-#ifdef CONFIG_DRM_EXYNOS_DP
-	&dp_driver,
-#endif
-#ifdef CONFIG_DRM_EXYNOS_DSI
-	&dsi_driver,
-#endif
-#ifdef CONFIG_DRM_EXYNOS_HDMI
-	&mixer_driver,
-	&hdmi_driver,
-#endif
-};
-
-static struct platform_driver *const exynos_drm_non_kms_drivers[] = {
-#ifdef CONFIG_DRM_EXYNOS_G2D
-	&g2d_driver,
-#endif
-#ifdef CONFIG_DRM_EXYNOS_FIMC
-	&fimc_driver,
-#endif
-#ifdef CONFIG_DRM_EXYNOS_ROTATOR
-	&rotator_driver,
-#endif
-#ifdef CONFIG_DRM_EXYNOS_GSC
-	&gsc_driver,
-#endif
-#ifdef CONFIG_DRM_EXYNOS_IPP
-	&ipp_driver,
-#endif
-	&exynos_drm_platform_driver,
-};
-
-
-static struct platform_driver *const exynos_drm_drv_with_simple_dev[] = {
-#ifdef CONFIG_DRM_EXYNOS_VIDI
-	&vidi_driver,
-#endif
-#ifdef CONFIG_DRM_EXYNOS_IPP
-	&ipp_driver,
-#endif
-	&exynos_drm_platform_driver,
-};
-
-#define PDEV_COUNT ARRAY_SIZE(exynos_drm_drv_with_simple_dev)
-
 static struct platform_device *exynos_drm_pdevs[PDEV_COUNT];
 
 static void exynos_drm_unregister_devices(void)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 190f3b3..21fa58d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -1686,11 +1686,6 @@ static int exynos_dsi_probe(struct platform_device *pdev)
 	dsi->display.type = EXYNOS_DISPLAY_TYPE_LCD;
 	dsi->display.ops = &exynos_dsi_display_ops;
 
-	ret = exynos_drm_component_add(dev, EXYNOS_DEVICE_TYPE_CONNECTOR,
-				       dsi->display.type);
-	if (ret)
-		return ret;
-
 	/* To be checked as invalid one */
 	dsi->te_gpio = -ENOENT;
 
@@ -1706,7 +1701,7 @@ static int exynos_dsi_probe(struct platform_device *pdev)
 
 	ret = exynos_dsi_parse_dt(dsi);
 	if (ret)
-		goto err_del_component;
+		return ret;
 
 	dsi->supplies[0].supply = "vddcore";
 	dsi->supplies[1].supply = "vddio";
@@ -1735,22 +1730,19 @@ static int exynos_dsi_probe(struct platform_device *pdev)
 	dsi->reg_base = devm_ioremap_resource(dev, res);
 	if (IS_ERR(dsi->reg_base)) {
 		dev_err(dev, "failed to remap io region\n");
-		ret = PTR_ERR(dsi->reg_base);
-		goto err_del_component;
+		return PTR_ERR(dsi->reg_base);
 	}
 
 	dsi->phy = devm_phy_get(dev, "dsim");
 	if (IS_ERR(dsi->phy)) {
 		dev_info(dev, "failed to get dsim phy\n");
-		ret = PTR_ERR(dsi->phy);
-		goto err_del_component;
+		return PTR_ERR(dsi->phy);
 	}
 
 	dsi->irq = platform_get_irq(pdev, 0);
 	if (dsi->irq < 0) {
 		dev_err(dev, "failed to request dsi irq resource\n");
-		ret = dsi->irq;
-		goto err_del_component;
+		return dsi->irq;
 	}
 
 	irq_set_status_flags(dsi->irq, IRQ_NOAUTOEN);
@@ -1759,26 +1751,17 @@ static int exynos_dsi_probe(struct platform_device *pdev)
 					dev_name(dev), dsi);
 	if (ret) {
 		dev_err(dev, "failed to request dsi irq\n");
-		goto err_del_component;
+		return ret;
 	}
 
 	platform_set_drvdata(pdev, &dsi->display);
 
-	ret = component_add(dev, &exynos_dsi_component_ops);
-	if (ret)
-		goto err_del_component;
-
-	return ret;
-
-err_del_component:
-	exynos_drm_component_del(dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
-	return ret;
+	return component_add(dev, &exynos_dsi_component_ops);
 }
 
 static int exynos_dsi_remove(struct platform_device *pdev)
 {
 	component_del(&pdev->dev, &exynos_dsi_component_ops);
-	exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 9661853..ee98f77 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -1038,11 +1038,6 @@ static int fimd_probe(struct platform_device *pdev)
 	if (!ctx)
 		return -ENOMEM;
 
-	ret = exynos_drm_component_add(dev, EXYNOS_DEVICE_TYPE_CRTC,
-				       EXYNOS_DISPLAY_TYPE_LCD);
-	if (ret)
-		return ret;
-
 	ctx->dev = dev;
 	ctx->suspended = true;
 	ctx->driver_data = drm_fimd_get_driver_data(pdev);
@@ -1093,38 +1088,33 @@ static int fimd_probe(struct platform_device *pdev)
 	ctx->bus_clk = devm_clk_get(dev, "fimd");
 	if (IS_ERR(ctx->bus_clk)) {
 		dev_err(dev, "failed to get bus clock\n");
-		ret = PTR_ERR(ctx->bus_clk);
-		goto err_del_component;
+		return PTR_ERR(ctx->bus_clk);
 	}
 
 	ctx->lcd_clk = devm_clk_get(dev, "sclk_fimd");
 	if (IS_ERR(ctx->lcd_clk)) {
 		dev_err(dev, "failed to get lcd clock\n");
-		ret = PTR_ERR(ctx->lcd_clk);
-		goto err_del_component;
+		return PTR_ERR(ctx->lcd_clk);
 	}
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 
 	ctx->regs = devm_ioremap_resource(dev, res);
-	if (IS_ERR(ctx->regs)) {
-		ret = PTR_ERR(ctx->regs);
-		goto err_del_component;
-	}
+	if (IS_ERR(ctx->regs))
+		return PTR_ERR(ctx->regs);
 
 	res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
 					   ctx->i80_if ? "lcd_sys" : "vsync");
 	if (!res) {
 		dev_err(dev, "irq request failed.\n");
-		ret = -ENXIO;
-		goto err_del_component;
+		return -ENXIO;
 	}
 
 	ret = devm_request_irq(dev, res->start, fimd_irq_handler,
 							0, "drm_fimd", ctx);
 	if (ret) {
 		dev_err(dev, "irq request failed.\n");
-		goto err_del_component;
+		return ret;
 	}
 
 	init_waitqueue_head(&ctx->wait_vsync_queue);
@@ -1134,8 +1124,7 @@ static int fimd_probe(struct platform_device *pdev)
 
 	ctx->display = exynos_dpi_probe(dev);
 	if (IS_ERR(ctx->display)) {
-		ret = PTR_ERR(ctx->display);
-		goto err_del_component;
+		return PTR_ERR(ctx->display);
 	}
 
 	pm_runtime_enable(dev);
@@ -1149,8 +1138,6 @@ static int fimd_probe(struct platform_device *pdev)
 err_disable_pm_runtime:
 	pm_runtime_disable(dev);
 
-err_del_component:
-	exynos_drm_component_del(dev, EXYNOS_DEVICE_TYPE_CRTC);
 	return ret;
 }
 
@@ -1159,7 +1146,6 @@ static int fimd_remove(struct platform_device *pdev)
 	pm_runtime_disable(&pdev->dev);
 
 	component_del(&pdev->dev, &fimd_component_ops);
-	exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
index f63ac58..de53f73 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
@@ -507,16 +507,6 @@ static int vidi_probe(struct platform_device *pdev)
 	ctx->default_win = 0;
 	ctx->pdev = pdev;
 
-	ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC,
-					EXYNOS_DISPLAY_TYPE_VIDI);
-	if (ret)
-		return ret;
-
-	ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR,
-					ctx->display.type);
-	if (ret)
-		goto err_del_crtc_component;
-
 	INIT_WORK(&ctx->work, vidi_fake_vblank_handler);
 
 	mutex_init(&ctx->lock);
@@ -526,7 +516,7 @@ static int vidi_probe(struct platform_device *pdev)
 	ret = device_create_file(&pdev->dev, &dev_attr_connection);
 	if (ret < 0) {
 		DRM_ERROR("failed to create connection sysfs.\n");
-		goto err_del_conn_component;
+		return ret;
 	}
 
 	ret = component_add(&pdev->dev, &vidi_component_ops);
@@ -537,10 +527,6 @@ static int vidi_probe(struct platform_device *pdev)
 
 err_remove_file:
 	device_remove_file(&pdev->dev, &dev_attr_connection);
-err_del_conn_component:
-	exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
-err_del_crtc_component:
-	exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);
 
 	return ret;
 }
@@ -557,8 +543,6 @@ static int vidi_remove(struct platform_device *pdev)
 	}
 
 	component_del(&pdev->dev, &vidi_component_ops);
-	exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
-	exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 8c3c27b..99e2864 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -2360,20 +2360,13 @@ static int hdmi_probe(struct platform_device *pdev)
 	hdata->display.type = EXYNOS_DISPLAY_TYPE_HDMI;
 	hdata->display.ops = &hdmi_display_ops;
 
-	ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR,
-					hdata->display.type);
-	if (ret)
-		return ret;
-
 	mutex_init(&hdata->hdmi_mutex);
 
 	platform_set_drvdata(pdev, hdata);
 
 	match = of_match_node(hdmi_match_types, dev->of_node);
-	if (!match) {
-		ret = -ENODEV;
-		goto err_del_component;
-	}
+	if (!match)
+		return -ENODEV;
 
 	drv_data = (struct hdmi_driver_data *)match->data;
 	hdata->type = drv_data->type;
@@ -2393,13 +2386,13 @@ static int hdmi_probe(struct platform_device *pdev)
 	hdata->regs = devm_ioremap_resource(dev, res);
 	if (IS_ERR(hdata->regs)) {
 		ret = PTR_ERR(hdata->regs);
-		goto err_del_component;
+		return ret;
 	}
 
 	ret = devm_gpio_request(dev, hdata->hpd_gpio, "HPD");
 	if (ret) {
 		DRM_ERROR("failed to request HPD gpio\n");
-		goto err_del_component;
+		return ret;
 	}
 
 	ddc_node = hdmi_legacy_ddc_dt_binding(dev);
@@ -2410,8 +2403,7 @@ static int hdmi_probe(struct platform_device *pdev)
 	ddc_node = of_parse_phandle(dev->of_node, "ddc", 0);
 	if (!ddc_node) {
 		DRM_ERROR("Failed to find ddc node in device tree\n");
-		ret = -ENODEV;
-		goto err_del_component;
+		return -ENODEV;
 	}
 
 out_get_ddc_adpt:
@@ -2495,9 +2487,6 @@ err_hdmiphy:
 err_ddc:
 	put_device(&hdata->ddc_adpt->dev);
 
-err_del_component:
-	exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
-
 	return ret;
 }
 
@@ -2517,7 +2506,6 @@ static int hdmi_remove(struct platform_device *pdev)
 	pm_runtime_disable(&pdev->dev);
 	component_del(&pdev->dev, &hdmi_component_ops);
 
-	exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index 6bab717..43fa48c 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -1266,18 +1266,9 @@ static int mixer_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, ctx);
 
-	ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC,
-					EXYNOS_DISPLAY_TYPE_HDMI);
-	if (ret)
-		return ret;
-
 	ret = component_add(&pdev->dev, &mixer_component_ops);
-	if (ret) {
-		exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);
-		return ret;
-	}
-
-	pm_runtime_enable(dev);
+	if (!ret)
+		pm_runtime_enable(dev);
 
 	return ret;
 }
@@ -1287,7 +1278,6 @@ static int mixer_remove(struct platform_device *pdev)
 	pm_runtime_disable(&pdev->dev);
 
 	component_del(&pdev->dev, &mixer_component_ops);
-	exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);
 
 	return 0;
 }
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 3/3] drm/exynos: remove SoC checking code
  2015-06-08 10:15 [PATCH 0/3] exynos_drm initialization fix Andrzej Hajda
  2015-06-08 10:15 ` [PATCH 1/3] drm/exynos: consolidate driver/device initialization code Andrzej Hajda
  2015-06-08 10:15 ` [PATCH 2/3] drm/exynos: fix broken component binding in case of multiple pipelines Andrzej Hajda
@ 2015-06-08 10:15 ` Andrzej Hajda
  2015-06-09 19:46   ` Gustavo Padovan
  2 siblings, 1 reply; 9+ messages in thread
From: Andrzej Hajda @ 2015-06-08 10:15 UTC (permalink / raw)
  To: Inki Dae
  Cc: Andrzej Hajda, linux-samsung-soc, b.zolnierkie, dri-devel,
	Marek Szyprowski

SoC checking code is not necessary anymore, as exynos_drm_match_add and
exynos_drm_platform_probe already properly handles situation when there are
no Exynos DRM components.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
 drivers/gpu/drm/exynos/exynos_drm_drv.c | 27 +--------------------------
 1 file changed, 1 insertion(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index cfbfb6c..9ec4027 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -560,34 +560,9 @@ static inline void exynos_drm_unregister_non_kms_drivers(void)
 					ARRAY_SIZE(exynos_drm_non_kms_drivers));
 }
 
-static const char * const strings[] = {
-	"samsung,exynos3",
-	"samsung,exynos4",
-	"samsung,exynos5",
-	"samsung,exynos7",
-};
-
 static int exynos_drm_init(void)
 {
-	bool is_exynos = false;
-	int ret, i;
-
-	/*
-	 * 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.
-	 */
-	for (i = 0; i < ARRAY_SIZE(strings); i++) {
-		if (of_machine_is_compatible(strings[i])) {
-			is_exynos = true;
-			break;
-		}
-	}
-
-	if (!is_exynos)
-		return -ENODEV;
+	int ret;
 
 	ret = exynos_drm_register_devices();
 	if (ret)
-- 
1.9.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH 3/3] drm/exynos: remove SoC checking code
  2015-06-08 10:15 ` [PATCH 3/3] drm/exynos: remove SoC checking code Andrzej Hajda
@ 2015-06-09 19:46   ` Gustavo Padovan
  2015-06-10  2:14     ` Hyungwon Hwang
  0 siblings, 1 reply; 9+ messages in thread
From: Gustavo Padovan @ 2015-06-09 19:46 UTC (permalink / raw)
  To: Andrzej Hajda
  Cc: linux-samsung-soc, b.zolnierkie, dri-devel, Marek Szyprowski

Hi Andrzej,

2015-06-08 Andrzej Hajda <a.hajda@samsung.com>:

> SoC checking code is not necessary anymore, as exynos_drm_match_add and
> exynos_drm_platform_probe already properly handles situation when there are
> no Exynos DRM components.
> 
> Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
> ---
>  drivers/gpu/drm/exynos/exynos_drm_drv.c | 27 +--------------------------
>  1 file changed, 1 insertion(+), 26 deletions(-)

This series looks goods to me and works fine on my snow machine:

Tested-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

	Gustavo
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 2/3] drm/exynos: fix broken component binding in case of multiple pipelines
  2015-06-08 10:15 ` [PATCH 2/3] drm/exynos: fix broken component binding in case of multiple pipelines Andrzej Hajda
@ 2015-06-09 19:47   ` Gustavo Padovan
  2015-06-10  7:49     ` [PATCH v2 " Andrzej Hajda
  0 siblings, 1 reply; 9+ messages in thread
From: Gustavo Padovan @ 2015-06-09 19:47 UTC (permalink / raw)
  To: Andrzej Hajda
  Cc: linux-samsung-soc, b.zolnierkie, dri-devel, Marek Szyprowski

Hi Andrzej,

2015-06-08 Andrzej Hajda <a.hajda@samsung.com>:

> In case there are multiple pipelines and deferred probe occurs, only components
> of the first pipeline were bound. As a result only one pipeline was available.
> The main cause of this issue was dynamic generation of component match table -
> every component driver during probe registered itself on helper list, if there
> was at least one pipeline present on this list component match table were
> created without deferred components.
> This patch removes this helper list, instead it creates match table from
> existing devices requiring exynos_drm KMS drivers. This way match table do not
> depend on probe/deferral order and contains all KMS components.
> As a side effect patch makes the code cleaner and significantly smaller.
> 
> Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
> ---
>  drivers/gpu/drm/exynos/exynos7_drm_decon.c |  14 +-
>  drivers/gpu/drm/exynos/exynos_dp_core.c    |  13 +-
>  drivers/gpu/drm/exynos/exynos_drm_dpi.c    |  20 +-
>  drivers/gpu/drm/exynos/exynos_drm_drv.c    | 283 ++++++++---------------------
>  drivers/gpu/drm/exynos/exynos_drm_dsi.c    |  29 +--
>  drivers/gpu/drm/exynos/exynos_drm_fimd.c   |  28 +--
>  drivers/gpu/drm/exynos/exynos_drm_vidi.c   |  18 +-
>  drivers/gpu/drm/exynos/exynos_hdmi.c       |  22 +--
>  drivers/gpu/drm/exynos/exynos_mixer.c      |  14 +-
>  9 files changed, 99 insertions(+), 342 deletions(-)
> 
> diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
> index d659ba2..22cb067 100644
> --- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c
> +++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
> @@ -769,11 +769,6 @@ static int decon_probe(struct platform_device *pdev)
>  	if (!ctx)
>  		return -ENOMEM;
>  
> -	ret = exynos_drm_component_add(dev, EXYNOS_DEVICE_TYPE_CRTC,
> -					EXYNOS_DISPLAY_TYPE_LCD);

Please also remove enum exynos_drm_device_type, with this patch it is
not used anymore.

	Gustavo
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 3/3] drm/exynos: remove SoC checking code
  2015-06-09 19:46   ` Gustavo Padovan
@ 2015-06-10  2:14     ` Hyungwon Hwang
  0 siblings, 0 replies; 9+ messages in thread
From: Hyungwon Hwang @ 2015-06-10  2:14 UTC (permalink / raw)
  To: Andrzej Hajda
  Cc: Gustavo Padovan, linux-samsung-soc, b.zolnierkie, dri-devel,
	Marek Szyprowski

Hi Andrzej,

On Tue, 09 Jun 2015 16:46:52 -0300
Gustavo Padovan <gustavo@padovan.org> wrote:

> Hi Andrzej,
> 
> 2015-06-08 Andrzej Hajda <a.hajda@samsung.com>:
> 
> > SoC checking code is not necessary anymore, as exynos_drm_match_add
> > and exynos_drm_platform_probe already properly handles situation
> > when there are no Exynos DRM components.
> > 
> > Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
> > ---
> >  drivers/gpu/drm/exynos/exynos_drm_drv.c | 27
> > +-------------------------- 1 file changed, 1 insertion(+), 26
> > deletions(-)
> 
> This series looks goods to me and works fine on my snow machine:
> 
> Tested-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
> 
> 	Gustavo

It looks good to me.

Reviewed-by: Hyungwon Hwang <human.hwang@samsung.com>

> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2 2/3] drm/exynos: fix broken component binding in case of multiple pipelines
  2015-06-09 19:47   ` Gustavo Padovan
@ 2015-06-10  7:49     ` Andrzej Hajda
  0 siblings, 0 replies; 9+ messages in thread
From: Andrzej Hajda @ 2015-06-10  7:49 UTC (permalink / raw)
  To: Inki Dae
  Cc: linux-samsung-soc, b.zolnierkie, dri-devel, Andrzej Hajda,
	Marek Szyprowski

In case there are multiple pipelines and deferred probe occurs, only components
of the first pipeline were bound. As a result only one pipeline was available.
The main cause of this issue was dynamic generation of component match table -
every component driver during probe registered itself on helper list, if there
was at least one pipeline present on this list component match table were
created without deferred components.
This patch removes this helper list, instead it creates match table from
existing devices requiring exynos_drm KMS drivers. This way match table do not
depend on probe/deferral order and contains all KMS components.
As a side effect patch makes the code cleaner and significantly smaller.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
v2:
- removed unused types (as pointed out by Gustavo) and variables,
- fixed two gotos to removed label in dsi driver.
---
 drivers/gpu/drm/exynos/exynos7_drm_decon.c |  14 +-
 drivers/gpu/drm/exynos/exynos_dp_core.c    |  14 +-
 drivers/gpu/drm/exynos/exynos_drm_dpi.c    |  20 +-
 drivers/gpu/drm/exynos/exynos_drm_drv.c    | 283 ++++++++---------------------
 drivers/gpu/drm/exynos/exynos_drm_drv.h    |  14 --
 drivers/gpu/drm/exynos/exynos_drm_dsi.c    |  35 +---
 drivers/gpu/drm/exynos/exynos_drm_fimd.c   |  28 +--
 drivers/gpu/drm/exynos/exynos_drm_vidi.c   |  18 +-
 drivers/gpu/drm/exynos/exynos_hdmi.c       |  22 +--
 drivers/gpu/drm/exynos/exynos_mixer.c      |  14 +-
 10 files changed, 101 insertions(+), 361 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
index d659ba2..22cb067 100644
--- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c
+++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
@@ -769,11 +769,6 @@ static int decon_probe(struct platform_device *pdev)
 	if (!ctx)
 		return -ENOMEM;
 
-	ret = exynos_drm_component_add(dev, EXYNOS_DEVICE_TYPE_CRTC,
-					EXYNOS_DISPLAY_TYPE_LCD);
-	if (ret)
-		return ret;
-
 	ctx->dev = dev;
 	ctx->suspended = true;
 
@@ -783,10 +778,8 @@ static int decon_probe(struct platform_device *pdev)
 	of_node_put(i80_if_timings);
 
 	ctx->regs = of_iomap(dev->of_node, 0);
-	if (!ctx->regs) {
-		ret = -ENOMEM;
-		goto err_del_component;
-	}
+	if (!ctx->regs)
+		return -ENOMEM;
 
 	ctx->pclk = devm_clk_get(dev, "pclk_decon0");
 	if (IS_ERR(ctx->pclk)) {
@@ -856,8 +849,6 @@ err_disable_pm_runtime:
 err_iounmap:
 	iounmap(ctx->regs);
 
-err_del_component:
-	exynos_drm_component_del(dev, EXYNOS_DEVICE_TYPE_CRTC);
 	return ret;
 }
 
@@ -870,7 +861,6 @@ static int decon_remove(struct platform_device *pdev)
 	iounmap(ctx->regs);
 
 	component_del(&pdev->dev, &decon_component_ops);
-	exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c
index c9995b1..1057cc2 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.c
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.c
@@ -1333,7 +1333,6 @@ static int exynos_dp_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct device_node *panel_node, *bridge_node, *endpoint;
 	struct exynos_dp_device *dp;
-	int ret;
 
 	dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device),
 				GFP_KERNEL);
@@ -1344,11 +1343,6 @@ static int exynos_dp_probe(struct platform_device *pdev)
 	dp->display.ops = &exynos_dp_display_ops;
 	platform_set_drvdata(pdev, dp);
 
-	ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR,
-					dp->display.type);
-	if (ret)
-		return ret;
-
 	panel_node = of_parse_phandle(dev->of_node, "panel", 0);
 	if (panel_node) {
 		dp->panel = of_drm_find_panel(panel_node);
@@ -1369,18 +1363,12 @@ static int exynos_dp_probe(struct platform_device *pdev)
 			return -EPROBE_DEFER;
 	}
 
-	ret = component_add(&pdev->dev, &exynos_dp_ops);
-	if (ret)
-		exynos_drm_component_del(&pdev->dev,
-						EXYNOS_DEVICE_TYPE_CONNECTOR);
-
-	return ret;
+	return component_add(&pdev->dev, &exynos_dp_ops);
 }
 
 static int exynos_dp_remove(struct platform_device *pdev)
 {
 	component_del(&pdev->dev, &exynos_dp_ops);
-	exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dpi.c b/drivers/gpu/drm/exynos/exynos_drm_dpi.c
index 6dc328e..7cb6595 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dpi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dpi.c
@@ -313,33 +313,19 @@ struct exynos_drm_display *exynos_dpi_probe(struct device *dev)
 	ctx->dev = dev;
 	ctx->dpms_mode = DRM_MODE_DPMS_OFF;
 
-	ret = exynos_drm_component_add(dev,
-					EXYNOS_DEVICE_TYPE_CONNECTOR,
-					ctx->display.type);
-	if (ret)
-		return ERR_PTR(ret);
-
 	ret = exynos_dpi_parse_dt(ctx);
 	if (ret < 0) {
 		devm_kfree(dev, ctx);
-		goto err_del_component;
+		return NULL;
 	}
 
 	if (ctx->panel_node) {
 		ctx->panel = of_drm_find_panel(ctx->panel_node);
-		if (!ctx->panel) {
-			exynos_drm_component_del(dev,
-						EXYNOS_DEVICE_TYPE_CONNECTOR);
+		if (!ctx->panel)
 			return ERR_PTR(-EPROBE_DEFER);
-		}
 	}
 
 	return &ctx->display;
-
-err_del_component:
-	exynos_drm_component_del(dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
-
-	return NULL;
 }
 
 int exynos_dpi_remove(struct exynos_drm_display *display)
@@ -351,7 +337,5 @@ int exynos_dpi_remove(struct exynos_drm_display *display)
 	if (ctx->panel)
 		drm_panel_detach(ctx->panel);
 
-	exynos_drm_component_del(ctx->dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
-
 	return 0;
 }
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index 5c5a72a..cfbfb6c 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -38,17 +38,6 @@
 #define DRIVER_MAJOR	1
 #define DRIVER_MINOR	0
 
-static DEFINE_MUTEX(drm_component_lock);
-static LIST_HEAD(drm_component_list);
-
-struct component_dev {
-	struct list_head list;
-	struct device *crtc_dev;
-	struct device *conn_dev;
-	enum exynos_drm_output_type out_type;
-	unsigned int dev_type_flag;
-};
-
 static int exynos_drm_load(struct drm_device *dev, unsigned long flags)
 {
 	struct exynos_drm_private *private;
@@ -348,108 +337,70 @@ static const struct dev_pm_ops exynos_drm_pm_ops = {
 	SET_SYSTEM_SLEEP_PM_OPS(exynos_drm_sys_suspend, exynos_drm_sys_resume)
 };
 
-int exynos_drm_component_add(struct device *dev,
-				enum exynos_drm_device_type dev_type,
-				enum exynos_drm_output_type out_type)
-{
-	struct component_dev *cdev;
-
-	if (dev_type != EXYNOS_DEVICE_TYPE_CRTC &&
-			dev_type != EXYNOS_DEVICE_TYPE_CONNECTOR) {
-		DRM_ERROR("invalid device type.\n");
-		return -EINVAL;
-	}
-
-	mutex_lock(&drm_component_lock);
+/* forward declaration */
+static struct platform_driver exynos_drm_platform_driver;
 
-	/*
-	 * Make sure to check if there is a component which has two device
-	 * objects, for connector and for encoder/connector.
-	 * It should make sure that crtc and encoder/connector drivers are
-	 * ready before exynos drm core binds them.
-	 */
-	list_for_each_entry(cdev, &drm_component_list, list) {
-		if (cdev->out_type == out_type) {
-			/*
-			 * If crtc and encoder/connector device objects are
-			 * added already just return.
-			 */
-			if (cdev->dev_type_flag == (EXYNOS_DEVICE_TYPE_CRTC |
-						EXYNOS_DEVICE_TYPE_CONNECTOR)) {
-				mutex_unlock(&drm_component_lock);
-				return 0;
-			}
-
-			if (dev_type == EXYNOS_DEVICE_TYPE_CRTC) {
-				cdev->crtc_dev = dev;
-				cdev->dev_type_flag |= dev_type;
-			}
-
-			if (dev_type == EXYNOS_DEVICE_TYPE_CONNECTOR) {
-				cdev->conn_dev = dev;
-				cdev->dev_type_flag |= dev_type;
-			}
-
-			mutex_unlock(&drm_component_lock);
-			return 0;
-		}
-	}
-
-	mutex_unlock(&drm_component_lock);
-
-	cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
-	if (!cdev)
-		return -ENOMEM;
-
-	if (dev_type == EXYNOS_DEVICE_TYPE_CRTC)
-		cdev->crtc_dev = dev;
-	if (dev_type == EXYNOS_DEVICE_TYPE_CONNECTOR)
-		cdev->conn_dev = dev;
-
-	cdev->out_type = out_type;
-	cdev->dev_type_flag = dev_type;
-
-	mutex_lock(&drm_component_lock);
-	list_add_tail(&cdev->list, &drm_component_list);
-	mutex_unlock(&drm_component_lock);
-
-	return 0;
-}
-
-void exynos_drm_component_del(struct device *dev,
-				enum exynos_drm_device_type dev_type)
-{
-	struct component_dev *cdev, *next;
-
-	mutex_lock(&drm_component_lock);
-
-	list_for_each_entry_safe(cdev, next, &drm_component_list, list) {
-		if (dev_type == EXYNOS_DEVICE_TYPE_CRTC) {
-			if (cdev->crtc_dev == dev) {
-				cdev->crtc_dev = NULL;
-				cdev->dev_type_flag &= ~dev_type;
-			}
-		}
-
-		if (dev_type == EXYNOS_DEVICE_TYPE_CONNECTOR) {
-			if (cdev->conn_dev == dev) {
-				cdev->conn_dev = NULL;
-				cdev->dev_type_flag &= ~dev_type;
-			}
-		}
+/*
+ * Connector drivers should not be placed before associated crtc drivers,
+ * because connector requires pipe number of its crtc during initialization.
+ */
+static struct platform_driver *const exynos_drm_kms_drivers[] = {
+#ifdef CONFIG_DRM_EXYNOS_VIDI
+	&vidi_driver,
+#endif
+#ifdef CONFIG_DRM_EXYNOS_FIMD
+	&fimd_driver,
+#endif
+#ifdef CONFIG_DRM_EXYNOS5433_DECON
+	&exynos5433_decon_driver,
+#endif
+#ifdef CONFIG_DRM_EXYNOS7_DECON
+	&decon_driver,
+#endif
+#ifdef CONFIG_DRM_EXYNOS_DP
+	&dp_driver,
+#endif
+#ifdef CONFIG_DRM_EXYNOS_DSI
+	&dsi_driver,
+#endif
+#ifdef CONFIG_DRM_EXYNOS_HDMI
+	&mixer_driver,
+	&hdmi_driver,
+#endif
+};
 
-		/*
-		 * Release cdev object only in case that both of crtc and
-		 * encoder/connector device objects are NULL.
-		 */
-		if (!cdev->crtc_dev && !cdev->conn_dev) {
-			list_del(&cdev->list);
-			kfree(cdev);
-		}
-	}
+static struct platform_driver *const exynos_drm_non_kms_drivers[] = {
+#ifdef CONFIG_DRM_EXYNOS_MIC
+	&mic_driver,
+#endif
+#ifdef CONFIG_DRM_EXYNOS_G2D
+	&g2d_driver,
+#endif
+#ifdef CONFIG_DRM_EXYNOS_FIMC
+	&fimc_driver,
+#endif
+#ifdef CONFIG_DRM_EXYNOS_ROTATOR
+	&rotator_driver,
+#endif
+#ifdef CONFIG_DRM_EXYNOS_GSC
+	&gsc_driver,
+#endif
+#ifdef CONFIG_DRM_EXYNOS_IPP
+	&ipp_driver,
+#endif
+	&exynos_drm_platform_driver,
+};
 
-	mutex_unlock(&drm_component_lock);
-}
+static struct platform_driver *const exynos_drm_drv_with_simple_dev[] = {
+#ifdef CONFIG_DRM_EXYNOS_VIDI
+	&vidi_driver,
+#endif
+#ifdef CONFIG_DRM_EXYNOS_IPP
+	&ipp_driver,
+#endif
+	&exynos_drm_platform_driver,
+};
+#define PDEV_COUNT ARRAY_SIZE(exynos_drm_drv_with_simple_dev)
 
 static int compare_dev(struct device *dev, void *data)
 {
@@ -459,55 +410,22 @@ static int compare_dev(struct device *dev, void *data)
 static struct component_match *exynos_drm_match_add(struct device *dev)
 {
 	struct component_match *match = NULL;
-	struct component_dev *cdev;
-	unsigned int attach_cnt = 0;
-
-	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
-		 * encoder/connector device objects exist.
-		 */
-		if (!cdev->crtc_dev || !cdev->conn_dev)
-			continue;
-
-		attach_cnt++;
+	int i;
 
-		mutex_unlock(&drm_component_lock);
+	for (i = 0; i < ARRAY_SIZE(exynos_drm_kms_drivers); ++i) {
+		struct device_driver *drv = &exynos_drm_kms_drivers[i]->driver;
+		struct device *p = NULL, *d;
 
-		/*
-		 * fimd and dpi modules have same device object so add
-		 * only crtc device object in this case.
-		 */
-		if (cdev->crtc_dev == cdev->conn_dev) {
-			component_match_add(dev, &match, compare_dev,
-						cdev->crtc_dev);
-			goto out_lock;
+		while ((d = bus_find_device(&platform_bus_type, p, drv,
+					    (void *)platform_bus_type.match))) {
+			put_device(p);
+			component_match_add(dev, &match, compare_dev, d);
+			p = d;
 		}
-
-		/*
-		 * Do not chage below call order.
-		 * crtc device first should be added to master because
-		 * connector/encoder need pipe number of crtc when they
-		 * are created.
-		 */
-		component_match_add(dev, &match, compare_dev, cdev->crtc_dev);
-		component_match_add(dev, &match, compare_dev, cdev->conn_dev);
-
-out_lock:
-		mutex_lock(&drm_component_lock);
+		put_device(p);
 	}
 
-	mutex_unlock(&drm_component_lock);
-
-	return attach_cnt ? match : ERR_PTR(-EPROBE_DEFER);
+	return match ?: ERR_PTR(-ENODEV);
 }
 
 static int exynos_drm_bind(struct device *dev)
@@ -533,9 +451,8 @@ static int exynos_drm_platform_probe(struct platform_device *pdev)
 	exynos_drm_driver.num_ioctls = ARRAY_SIZE(exynos_ioctls);
 
 	match = exynos_drm_match_add(&pdev->dev);
-	if (IS_ERR(match)) {
+	if (IS_ERR(match))
 		return PTR_ERR(match);
-	}
 
 	return component_master_add_with_match(&pdev->dev, &exynos_drm_ops,
 					       match);
@@ -556,60 +473,6 @@ static struct platform_driver exynos_drm_platform_driver = {
 	},
 };
 
-static struct platform_driver *const exynos_drm_kms_drivers[] = {
-#ifdef CONFIG_DRM_EXYNOS_VIDI
-	&vidi_driver,
-#endif
-#ifdef CONFIG_DRM_EXYNOS_FIMD
-	&fimd_driver,
-#endif
-#ifdef CONFIG_DRM_EXYNOS7_DECON
-	&decon_driver,
-#endif
-#ifdef CONFIG_DRM_EXYNOS_DP
-	&dp_driver,
-#endif
-#ifdef CONFIG_DRM_EXYNOS_DSI
-	&dsi_driver,
-#endif
-#ifdef CONFIG_DRM_EXYNOS_HDMI
-	&mixer_driver,
-	&hdmi_driver,
-#endif
-};
-
-static struct platform_driver *const exynos_drm_non_kms_drivers[] = {
-#ifdef CONFIG_DRM_EXYNOS_G2D
-	&g2d_driver,
-#endif
-#ifdef CONFIG_DRM_EXYNOS_FIMC
-	&fimc_driver,
-#endif
-#ifdef CONFIG_DRM_EXYNOS_ROTATOR
-	&rotator_driver,
-#endif
-#ifdef CONFIG_DRM_EXYNOS_GSC
-	&gsc_driver,
-#endif
-#ifdef CONFIG_DRM_EXYNOS_IPP
-	&ipp_driver,
-#endif
-	&exynos_drm_platform_driver,
-};
-
-
-static struct platform_driver *const exynos_drm_drv_with_simple_dev[] = {
-#ifdef CONFIG_DRM_EXYNOS_VIDI
-	&vidi_driver,
-#endif
-#ifdef CONFIG_DRM_EXYNOS_IPP
-	&ipp_driver,
-#endif
-	&exynos_drm_platform_driver,
-};
-
-#define PDEV_COUNT ARRAY_SIZE(exynos_drm_drv_with_simple_dev)
-
 static struct platform_device *exynos_drm_pdevs[PDEV_COUNT];
 
 static void exynos_drm_unregister_devices(void)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index b308e90..6b4958b 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -25,13 +25,6 @@
 #define to_exynos_crtc(x)	container_of(x, struct exynos_drm_crtc, base)
 #define to_exynos_plane(x)	container_of(x, struct exynos_drm_plane, base)
 
-/* This enumerates device type. */
-enum exynos_drm_device_type {
-	EXYNOS_DEVICE_TYPE_NONE,
-	EXYNOS_DEVICE_TYPE_CRTC,
-	EXYNOS_DEVICE_TYPE_CONNECTOR,
-};
-
 /* this enumerates display type. */
 enum exynos_drm_output_type {
 	EXYNOS_DISPLAY_TYPE_NONE,
@@ -311,13 +304,6 @@ static inline int exynos_dpi_remove(struct exynos_drm_display *display)
 int exynos_drm_create_enc_conn(struct drm_device *dev,
 				struct exynos_drm_display *display);
 
-int exynos_drm_component_add(struct device *dev,
-				enum exynos_drm_device_type dev_type,
-				enum exynos_drm_output_type out_type);
-
-void exynos_drm_component_del(struct device *dev,
-				enum exynos_drm_device_type dev_type);
-
 extern struct platform_driver fimd_driver;
 extern struct platform_driver decon_driver;
 extern struct platform_driver dp_driver;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 190f3b3..0fe32b8 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -1686,11 +1686,6 @@ static int exynos_dsi_probe(struct platform_device *pdev)
 	dsi->display.type = EXYNOS_DISPLAY_TYPE_LCD;
 	dsi->display.ops = &exynos_dsi_display_ops;
 
-	ret = exynos_drm_component_add(dev, EXYNOS_DEVICE_TYPE_CONNECTOR,
-				       dsi->display.type);
-	if (ret)
-		return ret;
-
 	/* To be checked as invalid one */
 	dsi->te_gpio = -ENOENT;
 
@@ -1706,7 +1701,7 @@ static int exynos_dsi_probe(struct platform_device *pdev)
 
 	ret = exynos_dsi_parse_dt(dsi);
 	if (ret)
-		goto err_del_component;
+		return ret;
 
 	dsi->supplies[0].supply = "vddcore";
 	dsi->supplies[1].supply = "vddio";
@@ -1720,37 +1715,32 @@ static int exynos_dsi_probe(struct platform_device *pdev)
 	dsi->pll_clk = devm_clk_get(dev, "pll_clk");
 	if (IS_ERR(dsi->pll_clk)) {
 		dev_info(dev, "failed to get dsi pll input clock\n");
-		ret = PTR_ERR(dsi->pll_clk);
-		goto err_del_component;
+		return PTR_ERR(dsi->pll_clk);
 	}
 
 	dsi->bus_clk = devm_clk_get(dev, "bus_clk");
 	if (IS_ERR(dsi->bus_clk)) {
 		dev_info(dev, "failed to get dsi bus clock\n");
-		ret = PTR_ERR(dsi->bus_clk);
-		goto err_del_component;
+		return PTR_ERR(dsi->bus_clk);
 	}
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	dsi->reg_base = devm_ioremap_resource(dev, res);
 	if (IS_ERR(dsi->reg_base)) {
 		dev_err(dev, "failed to remap io region\n");
-		ret = PTR_ERR(dsi->reg_base);
-		goto err_del_component;
+		return PTR_ERR(dsi->reg_base);
 	}
 
 	dsi->phy = devm_phy_get(dev, "dsim");
 	if (IS_ERR(dsi->phy)) {
 		dev_info(dev, "failed to get dsim phy\n");
-		ret = PTR_ERR(dsi->phy);
-		goto err_del_component;
+		return PTR_ERR(dsi->phy);
 	}
 
 	dsi->irq = platform_get_irq(pdev, 0);
 	if (dsi->irq < 0) {
 		dev_err(dev, "failed to request dsi irq resource\n");
-		ret = dsi->irq;
-		goto err_del_component;
+		return dsi->irq;
 	}
 
 	irq_set_status_flags(dsi->irq, IRQ_NOAUTOEN);
@@ -1759,26 +1749,17 @@ static int exynos_dsi_probe(struct platform_device *pdev)
 					dev_name(dev), dsi);
 	if (ret) {
 		dev_err(dev, "failed to request dsi irq\n");
-		goto err_del_component;
+		return ret;
 	}
 
 	platform_set_drvdata(pdev, &dsi->display);
 
-	ret = component_add(dev, &exynos_dsi_component_ops);
-	if (ret)
-		goto err_del_component;
-
-	return ret;
-
-err_del_component:
-	exynos_drm_component_del(dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
-	return ret;
+	return component_add(dev, &exynos_dsi_component_ops);
 }
 
 static int exynos_dsi_remove(struct platform_device *pdev)
 {
 	component_del(&pdev->dev, &exynos_dsi_component_ops);
-	exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 9661853..ee98f77 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -1038,11 +1038,6 @@ static int fimd_probe(struct platform_device *pdev)
 	if (!ctx)
 		return -ENOMEM;
 
-	ret = exynos_drm_component_add(dev, EXYNOS_DEVICE_TYPE_CRTC,
-				       EXYNOS_DISPLAY_TYPE_LCD);
-	if (ret)
-		return ret;
-
 	ctx->dev = dev;
 	ctx->suspended = true;
 	ctx->driver_data = drm_fimd_get_driver_data(pdev);
@@ -1093,38 +1088,33 @@ static int fimd_probe(struct platform_device *pdev)
 	ctx->bus_clk = devm_clk_get(dev, "fimd");
 	if (IS_ERR(ctx->bus_clk)) {
 		dev_err(dev, "failed to get bus clock\n");
-		ret = PTR_ERR(ctx->bus_clk);
-		goto err_del_component;
+		return PTR_ERR(ctx->bus_clk);
 	}
 
 	ctx->lcd_clk = devm_clk_get(dev, "sclk_fimd");
 	if (IS_ERR(ctx->lcd_clk)) {
 		dev_err(dev, "failed to get lcd clock\n");
-		ret = PTR_ERR(ctx->lcd_clk);
-		goto err_del_component;
+		return PTR_ERR(ctx->lcd_clk);
 	}
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 
 	ctx->regs = devm_ioremap_resource(dev, res);
-	if (IS_ERR(ctx->regs)) {
-		ret = PTR_ERR(ctx->regs);
-		goto err_del_component;
-	}
+	if (IS_ERR(ctx->regs))
+		return PTR_ERR(ctx->regs);
 
 	res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
 					   ctx->i80_if ? "lcd_sys" : "vsync");
 	if (!res) {
 		dev_err(dev, "irq request failed.\n");
-		ret = -ENXIO;
-		goto err_del_component;
+		return -ENXIO;
 	}
 
 	ret = devm_request_irq(dev, res->start, fimd_irq_handler,
 							0, "drm_fimd", ctx);
 	if (ret) {
 		dev_err(dev, "irq request failed.\n");
-		goto err_del_component;
+		return ret;
 	}
 
 	init_waitqueue_head(&ctx->wait_vsync_queue);
@@ -1134,8 +1124,7 @@ static int fimd_probe(struct platform_device *pdev)
 
 	ctx->display = exynos_dpi_probe(dev);
 	if (IS_ERR(ctx->display)) {
-		ret = PTR_ERR(ctx->display);
-		goto err_del_component;
+		return PTR_ERR(ctx->display);
 	}
 
 	pm_runtime_enable(dev);
@@ -1149,8 +1138,6 @@ static int fimd_probe(struct platform_device *pdev)
 err_disable_pm_runtime:
 	pm_runtime_disable(dev);
 
-err_del_component:
-	exynos_drm_component_del(dev, EXYNOS_DEVICE_TYPE_CRTC);
 	return ret;
 }
 
@@ -1159,7 +1146,6 @@ static int fimd_remove(struct platform_device *pdev)
 	pm_runtime_disable(&pdev->dev);
 
 	component_del(&pdev->dev, &fimd_component_ops);
-	exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
index f63ac58..de53f73 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
@@ -507,16 +507,6 @@ static int vidi_probe(struct platform_device *pdev)
 	ctx->default_win = 0;
 	ctx->pdev = pdev;
 
-	ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC,
-					EXYNOS_DISPLAY_TYPE_VIDI);
-	if (ret)
-		return ret;
-
-	ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR,
-					ctx->display.type);
-	if (ret)
-		goto err_del_crtc_component;
-
 	INIT_WORK(&ctx->work, vidi_fake_vblank_handler);
 
 	mutex_init(&ctx->lock);
@@ -526,7 +516,7 @@ static int vidi_probe(struct platform_device *pdev)
 	ret = device_create_file(&pdev->dev, &dev_attr_connection);
 	if (ret < 0) {
 		DRM_ERROR("failed to create connection sysfs.\n");
-		goto err_del_conn_component;
+		return ret;
 	}
 
 	ret = component_add(&pdev->dev, &vidi_component_ops);
@@ -537,10 +527,6 @@ static int vidi_probe(struct platform_device *pdev)
 
 err_remove_file:
 	device_remove_file(&pdev->dev, &dev_attr_connection);
-err_del_conn_component:
-	exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
-err_del_crtc_component:
-	exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);
 
 	return ret;
 }
@@ -557,8 +543,6 @@ static int vidi_remove(struct platform_device *pdev)
 	}
 
 	component_del(&pdev->dev, &vidi_component_ops);
-	exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
-	exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 8c3c27b..99e2864 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -2360,20 +2360,13 @@ static int hdmi_probe(struct platform_device *pdev)
 	hdata->display.type = EXYNOS_DISPLAY_TYPE_HDMI;
 	hdata->display.ops = &hdmi_display_ops;
 
-	ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR,
-					hdata->display.type);
-	if (ret)
-		return ret;
-
 	mutex_init(&hdata->hdmi_mutex);
 
 	platform_set_drvdata(pdev, hdata);
 
 	match = of_match_node(hdmi_match_types, dev->of_node);
-	if (!match) {
-		ret = -ENODEV;
-		goto err_del_component;
-	}
+	if (!match)
+		return -ENODEV;
 
 	drv_data = (struct hdmi_driver_data *)match->data;
 	hdata->type = drv_data->type;
@@ -2393,13 +2386,13 @@ static int hdmi_probe(struct platform_device *pdev)
 	hdata->regs = devm_ioremap_resource(dev, res);
 	if (IS_ERR(hdata->regs)) {
 		ret = PTR_ERR(hdata->regs);
-		goto err_del_component;
+		return ret;
 	}
 
 	ret = devm_gpio_request(dev, hdata->hpd_gpio, "HPD");
 	if (ret) {
 		DRM_ERROR("failed to request HPD gpio\n");
-		goto err_del_component;
+		return ret;
 	}
 
 	ddc_node = hdmi_legacy_ddc_dt_binding(dev);
@@ -2410,8 +2403,7 @@ static int hdmi_probe(struct platform_device *pdev)
 	ddc_node = of_parse_phandle(dev->of_node, "ddc", 0);
 	if (!ddc_node) {
 		DRM_ERROR("Failed to find ddc node in device tree\n");
-		ret = -ENODEV;
-		goto err_del_component;
+		return -ENODEV;
 	}
 
 out_get_ddc_adpt:
@@ -2495,9 +2487,6 @@ err_hdmiphy:
 err_ddc:
 	put_device(&hdata->ddc_adpt->dev);
 
-err_del_component:
-	exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
-
 	return ret;
 }
 
@@ -2517,7 +2506,6 @@ static int hdmi_remove(struct platform_device *pdev)
 	pm_runtime_disable(&pdev->dev);
 	component_del(&pdev->dev, &hdmi_component_ops);
 
-	exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index 6bab717..43fa48c 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -1266,18 +1266,9 @@ static int mixer_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, ctx);
 
-	ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC,
-					EXYNOS_DISPLAY_TYPE_HDMI);
-	if (ret)
-		return ret;
-
 	ret = component_add(&pdev->dev, &mixer_component_ops);
-	if (ret) {
-		exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);
-		return ret;
-	}
-
-	pm_runtime_enable(dev);
+	if (!ret)
+		pm_runtime_enable(dev);
 
 	return ret;
 }
@@ -1287,7 +1278,6 @@ static int mixer_remove(struct platform_device *pdev)
 	pm_runtime_disable(&pdev->dev);
 
 	component_del(&pdev->dev, &mixer_component_ops);
-	exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);
 
 	return 0;
 }
-- 
1.9.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/3] drm/exynos: consolidate driver/device initialization code
  2015-06-08 10:15 ` [PATCH 1/3] drm/exynos: consolidate driver/device initialization code Andrzej Hajda
@ 2015-06-11 14:33   ` Inki Dae
  0 siblings, 0 replies; 9+ messages in thread
From: Inki Dae @ 2015-06-11 14:33 UTC (permalink / raw)
  To: Andrzej Hajda
  Cc: Marek Szyprowski, b.zolnierkie, dri-devel, linux-samsung-soc

On 2015년 06월 08일 19:15, Andrzej Hajda wrote:
> Code registering different drivers and simple platform devices was dispersed
> across multiple sub-modules. This patch moves it to one place. As a result
> initialization code is shorter and cleaner and should simplify further
> development.

Applied all patches

Thanks,
Inki Dae

> 
> Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
> ---
>  drivers/gpu/drm/exynos/exynos_drm_drv.c  | 221 +++++++++++++++++++------------
>  drivers/gpu/drm/exynos/exynos_drm_drv.h  |  17 ---
>  drivers/gpu/drm/exynos/exynos_drm_ipp.c  |  27 ----
>  drivers/gpu/drm/exynos/exynos_drm_vidi.c |  35 -----
>  4 files changed, 139 insertions(+), 161 deletions(-)
> 
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
> index 08b9a8c..5c5a72a 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
> @@ -38,8 +38,6 @@
>  #define DRIVER_MAJOR	1
>  #define DRIVER_MINOR	0
>  
> -static struct platform_device *exynos_drm_pdev;
> -
>  static DEFINE_MUTEX(drm_component_lock);
>  static LIST_HEAD(drm_component_list);
>  
> @@ -527,7 +525,41 @@ static const struct component_master_ops exynos_drm_ops = {
>  	.unbind		= exynos_drm_unbind,
>  };
>  
> +static int exynos_drm_platform_probe(struct platform_device *pdev)
> +{
> +	struct component_match *match;
> +
> +	pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
> +	exynos_drm_driver.num_ioctls = ARRAY_SIZE(exynos_ioctls);
> +
> +	match = exynos_drm_match_add(&pdev->dev);
> +	if (IS_ERR(match)) {
> +		return PTR_ERR(match);
> +	}
> +
> +	return component_master_add_with_match(&pdev->dev, &exynos_drm_ops,
> +					       match);
> +}
> +
> +static int exynos_drm_platform_remove(struct platform_device *pdev)
> +{
> +	component_master_del(&pdev->dev, &exynos_drm_ops);
> +	return 0;
> +}
> +
> +static struct platform_driver exynos_drm_platform_driver = {
> +	.probe	= exynos_drm_platform_probe,
> +	.remove	= exynos_drm_platform_remove,
> +	.driver	= {
> +		.name	= "exynos-drm",
> +		.pm	= &exynos_drm_pm_ops,
> +	},
> +};
> +
>  static struct platform_driver *const exynos_drm_kms_drivers[] = {
> +#ifdef CONFIG_DRM_EXYNOS_VIDI
> +	&vidi_driver,
> +#endif
>  #ifdef CONFIG_DRM_EXYNOS_FIMD
>  	&fimd_driver,
>  #endif
> @@ -562,30 +594,109 @@ static struct platform_driver *const exynos_drm_non_kms_drivers[] = {
>  #ifdef CONFIG_DRM_EXYNOS_IPP
>  	&ipp_driver,
>  #endif
> +	&exynos_drm_platform_driver,
>  };
>  
> -static int exynos_drm_platform_probe(struct platform_device *pdev)
> +
> +static struct platform_driver *const exynos_drm_drv_with_simple_dev[] = {
> +#ifdef CONFIG_DRM_EXYNOS_VIDI
> +	&vidi_driver,
> +#endif
> +#ifdef CONFIG_DRM_EXYNOS_IPP
> +	&ipp_driver,
> +#endif
> +	&exynos_drm_platform_driver,
> +};
> +
> +#define PDEV_COUNT ARRAY_SIZE(exynos_drm_drv_with_simple_dev)
> +
> +static struct platform_device *exynos_drm_pdevs[PDEV_COUNT];
> +
> +static void exynos_drm_unregister_devices(void)
>  {
> -	struct component_match *match;
> +	int i = PDEV_COUNT;
>  
> -	pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
> -	exynos_drm_driver.num_ioctls = ARRAY_SIZE(exynos_ioctls);
> +	while (--i >= 0) {
> +		platform_device_unregister(exynos_drm_pdevs[i]);
> +		exynos_drm_pdevs[i] = NULL;
> +	}
> +}
>  
> -	match = exynos_drm_match_add(&pdev->dev);
> -	if (IS_ERR(match)) {
> -		return PTR_ERR(match);
> +static int exynos_drm_register_devices(void)
> +{
> +	int i;
> +
> +	for (i = 0; i < PDEV_COUNT; ++i) {
> +		struct platform_driver *d = exynos_drm_drv_with_simple_dev[i];
> +		struct platform_device *pdev =
> +			platform_device_register_simple(d->driver.name,-1, NULL,
> +							0);
> +
> +		if (!IS_ERR(pdev)) {
> +			exynos_drm_pdevs[i] = pdev;
> +			continue;
> +		}
> +		while (--i >= 0) {
> +			platform_device_unregister(exynos_drm_pdevs[i]);
> +			exynos_drm_pdevs[i] = NULL;
> +		}
> +
> +		return PTR_ERR(pdev);
>  	}
>  
> -	return component_master_add_with_match(&pdev->dev, &exynos_drm_ops,
> -					       match);
> +	return 0;
>  }
>  
> -static int exynos_drm_platform_remove(struct platform_device *pdev)
> +static void exynos_drm_unregister_drivers(struct platform_driver * const *drv,
> +					  int count)
>  {
> -	component_master_del(&pdev->dev, &exynos_drm_ops);
> +	while (--count >= 0)
> +		platform_driver_unregister(drv[count]);
> +}
> +
> +static int exynos_drm_register_drivers(struct platform_driver * const *drv,
> +				       int count)
> +{
> +	int i, ret;
> +
> +	for (i = 0; i < count; ++i) {
> +		ret = platform_driver_register(drv[i]);
> +		if (!ret)
> +			continue;
> +
> +		while (--i >= 0)
> +			platform_driver_unregister(drv[i]);
> +
> +		return ret;
> +	}
> +
>  	return 0;
>  }
>  
> +static inline int exynos_drm_register_kms_drivers(void)
> +{
> +	return exynos_drm_register_drivers(exynos_drm_kms_drivers,
> +					ARRAY_SIZE(exynos_drm_kms_drivers));
> +}
> +
> +static inline int exynos_drm_register_non_kms_drivers(void)
> +{
> +	return exynos_drm_register_drivers(exynos_drm_non_kms_drivers,
> +					ARRAY_SIZE(exynos_drm_non_kms_drivers));
> +}
> +
> +static inline void exynos_drm_unregister_kms_drivers(void)
> +{
> +	exynos_drm_unregister_drivers(exynos_drm_kms_drivers,
> +					ARRAY_SIZE(exynos_drm_kms_drivers));
> +}
> +
> +static inline void exynos_drm_unregister_non_kms_drivers(void)
> +{
> +	exynos_drm_unregister_drivers(exynos_drm_non_kms_drivers,
> +					ARRAY_SIZE(exynos_drm_non_kms_drivers));
> +}
> +
>  static const char * const strings[] = {
>  	"samsung,exynos3",
>  	"samsung,exynos4",
> @@ -593,19 +704,10 @@ static const char * const strings[] = {
>  	"samsung,exynos7",
>  };
>  
> -static struct platform_driver exynos_drm_platform_driver = {
> -	.probe	= exynos_drm_platform_probe,
> -	.remove	= exynos_drm_platform_remove,
> -	.driver	= {
> -		.name	= "exynos-drm",
> -		.pm	= &exynos_drm_pm_ops,
> -	},
> -};
> -
>  static int exynos_drm_init(void)
>  {
>  	bool is_exynos = false;
> -	int ret, i, j;
> +	int ret, i;
>  
>  	/*
>  	 * Register device object only in case of Exynos SoC.
> @@ -624,79 +726,34 @@ static int exynos_drm_init(void)
>  	if (!is_exynos)
>  		return -ENODEV;
>  
> -	exynos_drm_pdev = platform_device_register_simple("exynos-drm", -1,
> -								NULL, 0);
> -	if (IS_ERR(exynos_drm_pdev))
> -		return PTR_ERR(exynos_drm_pdev);
> -
> -	ret = exynos_drm_probe_vidi();
> -	if (ret < 0)
> -		goto err_unregister_pd;
> -
> -	for (i = 0; i < ARRAY_SIZE(exynos_drm_kms_drivers); ++i) {
> -		ret = platform_driver_register(exynos_drm_kms_drivers[i]);
> -		if (ret < 0)
> -			goto err_unregister_kms_drivers;
> -	}
> -
> -	for (j = 0; j < ARRAY_SIZE(exynos_drm_non_kms_drivers); ++j) {
> -		ret = platform_driver_register(exynos_drm_non_kms_drivers[j]);
> -		if (ret < 0)
> -			goto err_unregister_non_kms_drivers;
> -	}
> +	ret = exynos_drm_register_devices();
> +	if (ret)
> +		return ret;
>  
> -#ifdef CONFIG_DRM_EXYNOS_IPP
> -	ret = exynos_platform_device_ipp_register();
> -	if (ret < 0)
> -		goto err_unregister_non_kms_drivers;
> -#endif
> +	ret = exynos_drm_register_kms_drivers();
> +	if (ret)
> +		goto err_unregister_pdevs;
>  
> -	ret = platform_driver_register(&exynos_drm_platform_driver);
> +	ret = exynos_drm_register_non_kms_drivers();
>  	if (ret)
> -		goto err_unregister_resources;
> +		goto err_unregister_kms_drivers;
>  
>  	return 0;
>  
> -err_unregister_resources:
> -#ifdef CONFIG_DRM_EXYNOS_IPP
> -	exynos_platform_device_ipp_unregister();
> -#endif
> -
> -err_unregister_non_kms_drivers:
> -	while (--j >= 0)
> -		platform_driver_unregister(exynos_drm_non_kms_drivers[j]);
> -
>  err_unregister_kms_drivers:
> -	while (--i >= 0)
> -		platform_driver_unregister(exynos_drm_kms_drivers[i]);
> +	exynos_drm_unregister_kms_drivers();
>  
> -	exynos_drm_remove_vidi();
> -
> -err_unregister_pd:
> -	platform_device_unregister(exynos_drm_pdev);
> +err_unregister_pdevs:
> +	exynos_drm_unregister_devices();
>  
>  	return ret;
>  }
>  
>  static void exynos_drm_exit(void)
>  {
> -	int i;
> -
> -#ifdef CONFIG_DRM_EXYNOS_IPP
> -	exynos_platform_device_ipp_unregister();
> -#endif
> -
> -	for (i = ARRAY_SIZE(exynos_drm_non_kms_drivers) - 1; i >= 0; --i)
> -		platform_driver_unregister(exynos_drm_non_kms_drivers[i]);
> -
> -	for (i = ARRAY_SIZE(exynos_drm_kms_drivers) - 1; i >= 0; --i)
> -		platform_driver_unregister(exynos_drm_kms_drivers[i]);
> -
> -	platform_driver_unregister(&exynos_drm_platform_driver);
> -
> -	exynos_drm_remove_vidi();
> -
> -	platform_device_unregister(exynos_drm_pdev);
> +	exynos_drm_unregister_non_kms_drivers();
> +	exynos_drm_unregister_kms_drivers();
> +	exynos_drm_unregister_devices();
>  }
>  
>  module_init(exynos_drm_init);
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
> index 1c66f65..b308e90 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
> +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
> @@ -295,15 +295,6 @@ int exynos_drm_device_subdrv_remove(struct drm_device *dev);
>  int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file);
>  void exynos_drm_subdrv_close(struct drm_device *dev, struct drm_file *file);
>  
> -#ifdef CONFIG_DRM_EXYNOS_IPP
> -int exynos_platform_device_ipp_register(void);
> -void exynos_platform_device_ipp_unregister(void);
> -#else
> -static inline int exynos_platform_device_ipp_register(void) { return 0; }
> -static inline void exynos_platform_device_ipp_unregister(void) {}
> -#endif
> -
> -
>  #ifdef CONFIG_DRM_EXYNOS_DPI
>  struct exynos_drm_display * exynos_dpi_probe(struct device *dev);
>  int exynos_dpi_remove(struct exynos_drm_display *display);
> @@ -316,14 +307,6 @@ static inline int exynos_dpi_remove(struct exynos_drm_display *display)
>  }
>  #endif
>  
> -#ifdef CONFIG_DRM_EXYNOS_VIDI
> -int exynos_drm_probe_vidi(void);
> -void exynos_drm_remove_vidi(void);
> -#else
> -static inline int exynos_drm_probe_vidi(void) { return 0; }
> -static inline void exynos_drm_remove_vidi(void) {}
> -#endif
> -
>  /* This function creates a encoder and a connector, and initializes them. */
>  int exynos_drm_create_enc_conn(struct drm_device *dev,
>  				struct exynos_drm_display *display);
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
> index b7f1cbc..f594dd7 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
> @@ -45,9 +45,6 @@
>  #define get_ipp_context(dev)	platform_get_drvdata(to_platform_device(dev))
>  #define ipp_is_m2m_cmd(c)	(c == IPP_CMD_M2M)
>  
> -/* platform device pointer for ipp device. */
> -static struct platform_device *exynos_drm_ipp_pdev;
> -
>  /*
>   * A structure of event.
>   *
> @@ -102,30 +99,6 @@ static LIST_HEAD(exynos_drm_ippdrv_list);
>  static DEFINE_MUTEX(exynos_drm_ippdrv_lock);
>  static BLOCKING_NOTIFIER_HEAD(exynos_drm_ippnb_list);
>  
> -int exynos_platform_device_ipp_register(void)
> -{
> -	struct platform_device *pdev;
> -
> -	if (exynos_drm_ipp_pdev)
> -		return -EEXIST;
> -
> -	pdev = platform_device_register_simple("exynos-drm-ipp", -1, NULL, 0);
> -	if (IS_ERR(pdev))
> -		return PTR_ERR(pdev);
> -
> -	exynos_drm_ipp_pdev = pdev;
> -
> -	return 0;
> -}
> -
> -void exynos_platform_device_ipp_unregister(void)
> -{
> -	if (exynos_drm_ipp_pdev) {
> -		platform_device_unregister(exynos_drm_ipp_pdev);
> -		exynos_drm_ipp_pdev = NULL;
> -	}
> -}
> -
>  int exynos_drm_ippdrv_register(struct exynos_drm_ippdrv *ippdrv)
>  {
>  	mutex_lock(&exynos_drm_ippdrv_lock);
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
> index abe4ee0..f63ac58 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
> @@ -571,38 +571,3 @@ struct platform_driver vidi_driver = {
>  		.owner	= THIS_MODULE,
>  	},
>  };
> -
> -int exynos_drm_probe_vidi(void)
> -{
> -	struct platform_device *pdev;
> -	int ret;
> -
> -	pdev = platform_device_register_simple("exynos-drm-vidi", -1, NULL, 0);
> -	if (IS_ERR(pdev))
> -		return PTR_ERR(pdev);
> -
> -	ret = platform_driver_register(&vidi_driver);
> -	if (ret) {
> -		platform_device_unregister(pdev);
> -		return ret;
> -	}
> -
> -	return ret;
> -}
> -
> -static int exynos_drm_remove_vidi_device(struct device *dev, void *data)
> -{
> -	platform_device_unregister(to_platform_device(dev));
> -
> -	return 0;
> -}
> -
> -void exynos_drm_remove_vidi(void)
> -{
> -	int ret = driver_for_each_device(&vidi_driver.driver, NULL, NULL,
> -					 exynos_drm_remove_vidi_device);
> -	/* silence compiler warning */
> -	(void)ret;
> -
> -	platform_driver_unregister(&vidi_driver);
> -}
> 

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2015-06-11 14:33 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-06-08 10:15 [PATCH 0/3] exynos_drm initialization fix Andrzej Hajda
2015-06-08 10:15 ` [PATCH 1/3] drm/exynos: consolidate driver/device initialization code Andrzej Hajda
2015-06-11 14:33   ` Inki Dae
2015-06-08 10:15 ` [PATCH 2/3] drm/exynos: fix broken component binding in case of multiple pipelines Andrzej Hajda
2015-06-09 19:47   ` Gustavo Padovan
2015-06-10  7:49     ` [PATCH v2 " Andrzej Hajda
2015-06-08 10:15 ` [PATCH 3/3] drm/exynos: remove SoC checking code Andrzej Hajda
2015-06-09 19:46   ` Gustavo Padovan
2015-06-10  2:14     ` Hyungwon Hwang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.