diff options
author | Stefan Agner <stefan@agner.ch> | 2016-03-22 15:13:05 -0700 |
---|---|---|
committer | Stefan Agner <stefan.agner@toradex.com> | 2016-03-28 10:49:56 -0700 |
commit | d0171fbf707316a13a7de93624459abb130ca664 (patch) | |
tree | f3d60a1bd383ab0ca1f14960d088e84255e74278 | |
parent | 820d9b0b575e1c3ccdbf79d1adb48b2d9dbbdf4c (diff) |
drm/fsl-dcu: disable clock on initialization failure and remove
Fix error handling during probe by reordering initialization and
adding a error path which disables clock again. Also disable the
clock on remove.
Signed-off-by: Stefan Agner <stefan.agner@toradex.com>
-rw-r--r-- | drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c | 44 |
1 files changed, 21 insertions, 23 deletions
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c index cdefadbba9e2..96bb48b870ef 100644 --- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c @@ -331,6 +331,11 @@ static int fsl_dcu_drm_probe(struct platform_device *pdev) if (!fsl_dev) return -ENOMEM; + id = of_match_node(fsl_dcu_of_match, pdev->dev.of_node); + if (!id) + return -ENODEV; + fsl_dev->soc = id->data; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(dev, "could not get memory IO resource\n"); @@ -349,39 +354,29 @@ static int fsl_dcu_drm_probe(struct platform_device *pdev) return -ENXIO; } + fsl_dev->regmap = devm_regmap_init_mmio(dev, base, + &fsl_dcu_regmap_config); + if (IS_ERR(fsl_dev->regmap)) { + dev_err(dev, "regmap init failed\n"); + return PTR_ERR(fsl_dev->regmap); + } + fsl_dev->clk = devm_clk_get(dev, "dcu"); if (IS_ERR(fsl_dev->clk)) { - ret = PTR_ERR(fsl_dev->clk); dev_err(dev, "failed to get dcu clock\n"); - return ret; + return PTR_ERR(fsl_dev->clk); } - ret = clk_prepare(fsl_dev->clk); - if (ret < 0) { - dev_err(dev, "failed to prepare dcu clk\n"); - return ret; - } - ret = clk_enable(fsl_dev->clk); + ret = clk_prepare_enable(fsl_dev->clk); if (ret < 0) { dev_err(dev, "failed to enable dcu clk\n"); - clk_unprepare(fsl_dev->clk); return ret; } - fsl_dev->regmap = devm_regmap_init_mmio(dev, base, - &fsl_dcu_regmap_config); - if (IS_ERR(fsl_dev->regmap)) { - dev_err(dev, "regmap init failed\n"); - return PTR_ERR(fsl_dev->regmap); - } - - id = of_match_node(fsl_dcu_of_match, pdev->dev.of_node); - if (!id) - return -ENODEV; - fsl_dev->soc = id->data; - drm = drm_dev_alloc(driver, dev); - if (!drm) - return -ENOMEM; + if (!drm) { + ret = -ENOMEM; + goto disable_clk; + } fsl_dev->tcon = fsl_tcon_init(dev); fsl_dev->dev = dev; @@ -403,6 +398,8 @@ static int fsl_dcu_drm_probe(struct platform_device *pdev) unref: drm_dev_unref(drm); +disable_clk: + clk_disable_unprepare(fsl_dev->clk); return ret; } @@ -410,6 +407,7 @@ static int fsl_dcu_drm_remove(struct platform_device *pdev) { struct fsl_dcu_drm_device *fsl_dev = platform_get_drvdata(pdev); + clk_disable_unprepare(fsl_dev->clk); drm_put_dev(fsl_dev->drm); return 0; |