From: Wei Yongjun <yongjun_...@trendmicro.com.cn>

Fix the error handling to release all alloced resources before
return from tegra_dsi_probe() in the error handling case.

Signed-off-by: Wei Yongjun <yongjun_wei at trendmicro.com.cn>
---
 drivers/gpu/drm/tegra/dsi.c | 53 ++++++++++++++++++++++++++++++++-------------
 1 file changed, 38 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c
index d452faab..677ebca 100644
--- a/drivers/gpu/drm/tegra/dsi.c
+++ b/drivers/gpu/drm/tegra/dsi.c
@@ -847,61 +847,70 @@ static int tegra_dsi_probe(struct platform_device *pdev)
        dsi->lanes = 4;

        dsi->rst = devm_reset_control_get(&pdev->dev, "dsi");
-       if (IS_ERR(dsi->rst))
-               return PTR_ERR(dsi->rst);
+       if (IS_ERR(dsi->rst)) {
+               err = PTR_ERR(dsi->rst);
+               goto err_reset_control_get;
+       }

        dsi->clk = devm_clk_get(&pdev->dev, NULL);
        if (IS_ERR(dsi->clk)) {
                dev_err(&pdev->dev, "cannot get DSI clock\n");
-               return PTR_ERR(dsi->clk);
+               err = PTR_ERR(dsi->clk);
+               goto err_reset_control_get;
        }

        err = clk_prepare_enable(dsi->clk);
        if (err < 0) {
                dev_err(&pdev->dev, "cannot enable DSI clock\n");
-               return err;
+               goto err_reset_control_get;
        }

        dsi->clk_lp = devm_clk_get(&pdev->dev, "lp");
        if (IS_ERR(dsi->clk_lp)) {
                dev_err(&pdev->dev, "cannot get low-power clock\n");
-               return PTR_ERR(dsi->clk_lp);
+               err = PTR_ERR(dsi->clk_lp);
+               goto err_clk_get_lp;
        }

        err = clk_prepare_enable(dsi->clk_lp);
        if (err < 0) {
                dev_err(&pdev->dev, "cannot enable low-power clock\n");
-               return err;
+               goto err_clk_get_lp;
        }

        dsi->clk_parent = devm_clk_get(&pdev->dev, "parent");
        if (IS_ERR(dsi->clk_parent)) {
                dev_err(&pdev->dev, "cannot get parent clock\n");
-               return PTR_ERR(dsi->clk_parent);
+               err = PTR_ERR(dsi->clk_parent);
+               goto err_clk_get_parent;
        }

        err = clk_prepare_enable(dsi->clk_parent);
        if (err < 0) {
                dev_err(&pdev->dev, "cannot enable parent clock\n");
-               return err;
+               goto err_clk_get_parent;
        }

        err = tegra_dsi_setup_clocks(dsi);
        if (err < 0) {
                dev_err(&pdev->dev, "cannot setup clocks\n");
-               return err;
+               goto err_setup_clocks;
        }

        regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        dsi->regs = devm_ioremap_resource(&pdev->dev, regs);
-       if (IS_ERR(dsi->regs))
-               return PTR_ERR(dsi->regs);
+       if (IS_ERR(dsi->regs)) {
+               err = PTR_ERR(dsi->regs);
+               goto err_setup_clocks;
+       }

        tegra_dsi_initialize(dsi);

        dsi->mipi = tegra_mipi_request(&pdev->dev);
-       if (IS_ERR(dsi->mipi))
-               return PTR_ERR(dsi->mipi);
+       if (IS_ERR(dsi->mipi)) {
+               err = PTR_ERR(dsi->mipi);
+               goto err_setup_clocks;
+       }

        dsi->host.ops = &tegra_dsi_host_ops;
        dsi->host.dev = &pdev->dev;
@@ -909,7 +918,7 @@ static int tegra_dsi_probe(struct platform_device *pdev)
        err = mipi_dsi_host_register(&dsi->host);
        if (err < 0) {
                dev_err(&pdev->dev, "failed to register DSI host: %d\n", err);
-               return err;
+               goto err_host_register;
        }

        INIT_LIST_HEAD(&dsi->client.list);
@@ -920,12 +929,26 @@ static int tegra_dsi_probe(struct platform_device *pdev)
        if (err < 0) {
                dev_err(&pdev->dev, "failed to register host1x client: %d\n",
                        err);
-               return err;
+               goto err_client_register;
        }

        platform_set_drvdata(pdev, dsi);

        return 0;
+
+err_client_register:
+       mipi_dsi_host_unregister(&dsi->host);
+err_host_register:
+       tegra_mipi_free(dsi->mipi);
+err_setup_clocks:
+       clk_disable_unprepare(dsi->clk_parent);
+err_clk_get_parent:
+       clk_disable_unprepare(dsi->clk_lp);
+err_clk_get_lp:
+       clk_disable_unprepare(dsi->clk);
+err_reset_control_get:
+       tegra_output_remove(&dsi->output);
+       return err;
 }

 static int tegra_dsi_remove(struct platform_device *pdev)

Reply via email to