[RFC PATCH v3 3/4] drm/exynos: make vidi driver to be independent driver

Inki Dae inki.dae at samsung.com
Thu Nov 20 02:24:47 PST 2014


This patch makes vidi driver to be independent driver.
For this, it removes register codes to vidi driver
from exynos_drm_drv module and adds module_init/exit
for vidi driver so that this driver can be called
independently.

In addition, this patch adds component support to vidi driver
so that this driver can be bound independently.

Changelog v3:
- none

Changelog v2:
- none

Signed-off-by: Inki Dae <inki.dae at samsung.com>
---
 drivers/gpu/drm/exynos/exynos_drm_drv.c  |   12 +----
 drivers/gpu/drm/exynos/exynos_drm_drv.h  |    9 ----
 drivers/gpu/drm/exynos/exynos_drm_vidi.c |   81 +++++++++++++++++++-----------
 3 files changed, 54 insertions(+), 48 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index 7f1186e..3ac39b6 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -608,19 +608,12 @@ static int exynos_drm_init(void)
 	if (IS_ERR(exynos_drm_pdev))
 		return PTR_ERR(exynos_drm_pdev);
 
-	ret = exynos_drm_probe_vidi();
-	if (ret < 0)
-		goto err_unregister_pd;
-
 	ret = platform_driver_register(&exynos_drm_platform_driver);
 	if (ret)
-		goto err_remove_vidi;
+		goto err_unregister_pd;
 
 	return 0;
 
-err_remove_vidi:
-	exynos_drm_remove_vidi();
-
 err_unregister_pd:
 	platform_device_unregister(exynos_drm_pdev);
 
@@ -630,9 +623,6 @@ err_unregister_pd:
 static void exynos_drm_exit(void)
 {
 	platform_driver_unregister(&exynos_drm_platform_driver);
-
-	exynos_drm_remove_vidi();
-
 	platform_device_unregister(exynos_drm_pdev);
 }
 
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index 5b3305c..7c2ba06 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -310,14 +310,6 @@ exynos_dpi_probe(struct device *dev) { return NULL; }
 static inline int exynos_dpi_remove(struct device *dev) { return 0; }
 #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);
@@ -333,5 +325,4 @@ extern int exynos_drm_non_kms_register(unsigned int device_type);
 extern void exynos_drm_non_kms_unregister(unsigned int device_type);
 
 extern struct platform_driver exynos_drm_common_hdmi_driver;
-extern struct platform_driver vidi_driver;
 #endif
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
index 50faf91..e1153aa 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
@@ -14,6 +14,7 @@
 
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
+#include <linux/component.h>
 
 #include <drm/exynos_drm.h>
 
@@ -48,10 +49,10 @@ struct vidi_win_data {
 
 struct vidi_context {
 	struct drm_device		*drm_dev;
+	struct platform_device		*pdev;
 	struct drm_crtc			*crtc;
 	struct drm_encoder		*encoder;
 	struct drm_connector		connector;
-	struct exynos_drm_subdrv	subdrv;
 	struct vidi_win_data		win_data[WINDOWS_NR];
 	struct edid			*raw_edid;
 	unsigned int			clkdiv;
@@ -561,14 +562,13 @@ static struct exynos_drm_display vidi_display = {
 	.ops = &vidi_display_ops,
 };
 
-static int vidi_subdrv_probe(struct drm_device *drm_dev, struct device *dev)
+static int vidi_bind(struct device *dev, struct device *master, void *data)
 {
-	struct exynos_drm_manager *mgr = get_vidi_mgr(dev);
-	struct vidi_context *ctx = mgr->ctx;
-	struct drm_crtc *crtc = ctx->crtc;
+	struct drm_crtc *crtc = vidi_manager.crtc;
+	struct drm_device *drm_dev = data;
 	int ret;
 
-	vidi_mgr_initialize(mgr, drm_dev);
+	vidi_mgr_initialize(&vidi_manager, drm_dev);
 
 	ret = exynos_drm_crtc_create(&vidi_manager);
 	if (ret) {
@@ -586,20 +586,42 @@ static int vidi_subdrv_probe(struct drm_device *drm_dev, struct device *dev)
 	return 0;
 }
 
+static void vidi_unbind(struct device *dev, struct device *master,
+			void *data)
+{
+}
+
+static const struct component_ops vidi_component_ops = {
+	.bind	= vidi_bind,
+	.unbind = vidi_unbind,
+};
+
 static int vidi_probe(struct platform_device *pdev)
 {
-	struct exynos_drm_subdrv *subdrv;
 	struct vidi_context *ctx;
 	int ret;
 
+	ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC,
+					vidi_manager.type);
+	if (ret)
+		return ret;
+
+	ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR,
+					vidi_display.type);
+	if (ret)
+		goto err_del_crtc_component;
+
 	ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
-	if (!ctx)
-		return -ENOMEM;
+	if (!ctx) {
+		ret = -ENOMEM;
+		goto err_del_conn_component;
+	}
 
 	ctx->default_win = 0;
 
 	INIT_WORK(&ctx->work, vidi_fake_vblank_handler);
 
+	ctx->pdev = pdev;
 	vidi_manager.ctx = ctx;
 	vidi_display.ctx = ctx;
 
@@ -607,23 +629,21 @@ static int vidi_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, &vidi_manager);
 
-	subdrv = &ctx->subdrv;
-	subdrv->dev = &pdev->dev;
-	subdrv->probe = vidi_subdrv_probe;
-
-	ret = exynos_drm_subdrv_register(subdrv);
-	if (ret < 0) {
-		dev_err(&pdev->dev, "failed to register drm vidi device\n");
-		return ret;
-	}
-
 	ret = device_create_file(&pdev->dev, &dev_attr_connection);
-	if (ret < 0) {
-		exynos_drm_subdrv_unregister(subdrv);
+	if (ret < 0)
 		DRM_INFO("failed to create connection sysfs.\n");
-	}
 
-	return 0;
+	ret = component_add(&pdev->dev, &vidi_component_ops);
+	if (ret)
+		goto err_del_conn_component;
+
+	return ret;
+
+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;
 }
 
 static int vidi_remove(struct platform_device *pdev)
@@ -638,6 +658,10 @@ static int vidi_remove(struct platform_device *pdev)
 		return -EINVAL;
 	}
 
+	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;
 }
 
@@ -650,7 +674,7 @@ struct platform_driver vidi_driver = {
 	},
 };
 
-int exynos_drm_probe_vidi(void)
+static int exynos_drm_vidi_init(void)
 {
 	struct platform_device *pdev;
 	int ret;
@@ -668,12 +692,13 @@ int exynos_drm_probe_vidi(void)
 	return ret;
 }
 
-void exynos_drm_remove_vidi(void)
+void exynos_drm_vidi_exit(void)
 {
 	struct vidi_context *ctx = vidi_manager.ctx;
-	struct exynos_drm_subdrv *subdrv = &ctx->subdrv;
-	struct platform_device *pdev = to_platform_device(subdrv->dev);
 
 	platform_driver_unregister(&vidi_driver);
-	platform_device_unregister(pdev);
+	platform_device_unregister(ctx->pdev);
 }
+
+module_init(exynos_drm_vidi_init);
+module_exit(exynos_drm_vidi_exit);
-- 
1.7.9.5



More information about the dri-devel mailing list