drm/exynos: consider deferred probe case
authorInki Dae <inki.dae@samsung.com>
Thu, 29 May 2014 09:28:02 +0000 (18:28 +0900)
committerInki Dae <inki.dae@samsung.com>
Mon, 2 Jun 2014 05:29:39 +0000 (14:29 +0900)
This patch makes sure that exynos drm framework handles deferred
probe case correctly.

Sub drivers could be probed before resources, clock, regulator,
phy or panel, are ready for them so we should make sure that exynos
drm core waits until all resources are ready and sub drivers are
probed correctly.

Chagelog v2:
- Make sure that exynos drm core tries to bind sub drivers only in case that
  they have a pair: crtc and encoder/connector components should be a pair.
- Remove unnecessary patch:
  drm/exynos: mipi-dsi: consider panel driver-deferred probe
- Return error type correctly.

Signed-off-by: Inki Dae <inki.dae@samsung.com>
Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
drivers/gpu/drm/exynos/exynos_dp_core.c
drivers/gpu/drm/exynos/exynos_drm_dpi.c
drivers/gpu/drm/exynos/exynos_drm_drv.c
drivers/gpu/drm/exynos/exynos_drm_drv.h
drivers/gpu/drm/exynos/exynos_drm_dsi.c
drivers/gpu/drm/exynos/exynos_drm_fimd.c
drivers/gpu/drm/exynos/exynos_hdmi.c
drivers/gpu/drm/exynos/exynos_mixer.c

index 8b67f41..5e05dbc 100644 (file)
@@ -1325,12 +1325,26 @@ static const struct component_ops exynos_dp_ops = {
 
 static int exynos_dp_probe(struct platform_device *pdev)
 {
-       return exynos_drm_component_add(&pdev->dev, &exynos_dp_ops);
+       int ret;
+
+       ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR,
+                                       exynos_dp_display.type);
+       if (ret)
+               return ret;
+
+       ret = component_add(&pdev->dev, &exynos_dp_ops);
+       if (ret)
+               exynos_drm_component_del(&pdev->dev,
+                                               EXYNOS_DEVICE_TYPE_CONNECTOR);
+
+       return ret;
 }
 
 static int exynos_dp_remove(struct platform_device *pdev)
 {
-       exynos_drm_component_del(&pdev->dev, &exynos_dp_ops);
+       component_del(&pdev->dev, &exynos_dp_ops);
+       exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
+
        return 0;
 }
 
index a832364..f1b8587 100644 (file)
@@ -295,9 +295,15 @@ struct exynos_drm_display *exynos_dpi_probe(struct device *dev)
        struct exynos_dpi *ctx;
        int ret;
 
+       ret = exynos_drm_component_add(dev,
+                                       EXYNOS_DEVICE_TYPE_CONNECTOR,
+                                       exynos_dpi_display.type);
+       if (ret)
+               return ERR_PTR(ret);
+
        ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
        if (!ctx)
-               return NULL;
+               goto err_del_component;
 
        ctx->dev = dev;
        exynos_dpi_display.ctx = ctx;
@@ -306,16 +312,24 @@ struct exynos_drm_display *exynos_dpi_probe(struct device *dev)
        ret = exynos_dpi_parse_dt(ctx);
        if (ret < 0) {
                devm_kfree(dev, ctx);
-               return NULL;
+               goto err_del_component;
        }
 
        if (ctx->panel_node) {
                ctx->panel = of_drm_find_panel(ctx->panel_node);
-               if (!ctx->panel)
+               if (!ctx->panel) {
+                       exynos_drm_component_del(dev,
+                                               EXYNOS_DEVICE_TYPE_CONNECTOR);
                        return ERR_PTR(-EPROBE_DEFER);
+               }
        }
 
        return &exynos_dpi_display;
+
+err_del_component:
+       exynos_drm_component_del(dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
+
+       return NULL;
 }
 
 int exynos_dpi_remove(struct device *dev)
@@ -327,5 +341,7 @@ int exynos_dpi_remove(struct device *dev)
        encoder->funcs->destroy(encoder);
        drm_connector_cleanup(&ctx->connector);
 
+       exynos_drm_component_del(dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
+
        return 0;
 }
Simple merge
Simple merge