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

Reply via email to