MLK-13706 video: mxsfb: defer fb probe when dispdrv is not ready
authorFancy Fang <chen.fang@nxp.com>
Fri, 30 Dec 2016 07:21:28 +0000 (15:21 +0800)
committerNitin Garg <nitin.garg@nxp.com>
Mon, 19 Mar 2018 19:58:16 +0000 (14:58 -0500)
Some dispdrv depends on several other modules. For example, mipi dsi
depends on gpio and gpio-reset modules. And in some cases, during
the mipi dsi initialization process, the gpio or gpio-reset is not
loaded yet, so defer the fb probing until all the depending modules
loaded completed.

Signed-off-by: Fancy Fang <chen.fang@nxp.com>
drivers/video/fbdev/mxc/mipi_dsi_northwest.c
drivers/video/fbdev/mxc/mxc_dispdrv.c
drivers/video/fbdev/mxsfb.c

index 722cf9a..02b53c9 100644 (file)
@@ -153,8 +153,14 @@ static int mipi_dsi_disp_init(struct mxc_dispdrv_handle *disp,
 {
        struct mipi_dsi_info *mipi_dsi = mxc_dispdrv_getdata(disp);
        struct device *dev = &mipi_dsi->pdev->dev;
+       struct device_node *np = dev->of_node;
+       struct reset_control *reset = NULL;
        int ret = 0;
 
+       reset = of_reset_control_get(np, NULL);
+       if (IS_ERR(reset))
+               return PTR_ERR(reset);
+
        ret = mipi_dsi_lcd_init(mipi_dsi, setting);
        if (ret) {
                dev_err(dev, "failed to init mipi dsi lcd\n");
index d8501eb..77c0d50 100644 (file)
@@ -89,7 +89,7 @@ EXPORT_SYMBOL_GPL(mxc_dispdrv_unregister);
 struct mxc_dispdrv_handle *mxc_dispdrv_gethandle(char *name,
        struct mxc_dispdrv_setting *setting)
 {
-       int ret, found = 0;
+       int ret = -ENODEV, found = 0;
        struct mxc_dispdrv_entry *entry;
 
        mutex_lock(&dispdrv_lock);
@@ -106,7 +106,7 @@ struct mxc_dispdrv_handle *mxc_dispdrv_gethandle(char *name,
        }
        mutex_unlock(&dispdrv_lock);
 
-       return found ? (struct mxc_dispdrv_handle *)entry:ERR_PTR(-ENODEV);
+       return found ? (struct mxc_dispdrv_handle *)entry:ERR_PTR(ret);
 }
 EXPORT_SYMBOL_GPL(mxc_dispdrv_gethandle);
 
index 503ac9b..499b890 100644 (file)
@@ -1284,7 +1284,7 @@ static int mxsfb_init_fbinfo(struct mxsfb_info *host)
        return 0;
 }
 
-static void mxsfb_dispdrv_init(struct platform_device *pdev,
+static int mxsfb_dispdrv_init(struct platform_device *pdev,
                              struct fb_info *fbi)
 {
        struct mxsfb_info *host = fbi->par;
@@ -1299,13 +1299,17 @@ static void mxsfb_dispdrv_init(struct platform_device *pdev,
 
        host->dispdrv = mxc_dispdrv_gethandle(disp_dev, &setting);
        if (IS_ERR(host->dispdrv)) {
+               if (PTR_ERR(host->dispdrv) == -EPROBE_DEFER)
+                       return PTR_ERR(host->dispdrv);
+
                host->dispdrv = NULL;
                dev_info(dev, "failed to find mxc display driver %s\n",
                         disp_dev);
-       } else {
+       } else
                dev_info(dev, "registered mxc display driver %s\n",
                         disp_dev);
-       }
+
+       return 0;
 }
 
 static void mxsfb_free_videomem(struct mxsfb_info *host)
@@ -1502,7 +1506,13 @@ static int mxsfb_probe(struct platform_device *pdev)
        if (ret != 0)
                goto fb_pm_runtime_disable;
 
-       mxsfb_dispdrv_init(pdev, fb_info);
+       ret = mxsfb_dispdrv_init(pdev, fb_info);
+       if (ret != 0) {
+               if (ret == -EPROBE_DEFER)
+                       dev_info(&pdev->dev,
+                                "Defer fb probe due to dispdrv not ready\n");
+               goto fb_pm_runtime_disable;
+       }
 
        if (!host->dispdrv) {
                pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
@@ -1540,10 +1550,12 @@ static int mxsfb_probe(struct platform_device *pdev)
 fb_unregister:
        unregister_framebuffer(fb_info);
 fb_destroy:
-       if (host->enabled)
-               clk_disable_unprepare(host->clk_pix);
        fb_destroy_modelist(&fb_info->modelist);
 fb_pm_runtime_disable:
+       clk_disable_pix(host);
+       clk_disable_axi(host);
+       clk_disable_disp_axi(host);
+
        pm_runtime_disable(&host->pdev->dev);
        devm_kfree(&pdev->dev, fb_info->pseudo_palette);
 fb_release: