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

Inki Dae inki.dae at samsung.com
Tue Nov 18 07:26:44 PST 2014


This patch makes vidi driver to be independent module.
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, which is required for modularity.

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