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@xxxxxxxxxxx> --- 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 -- To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html