aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/drivers/video/fbdev/imxfb.c
diff options
context:
space:
mode:
authorUwe Kleine-König <u.kleine-koenig@pengutronix.de>2016-05-04 11:43:18 +0200
committerTomi Valkeinen <tomi.valkeinen@ti.com>2016-05-10 11:42:25 +0300
commitcc6df3a24587b3c9f191e34ffb67e269766e2ffc (patch)
tree8a7c925440f444a1fb44477415b2e8a47e41b7ed /drivers/video/fbdev/imxfb.c
parentvideo: fbdev: imxfb: fix semantic of .get_power and .set_power (diff)
downloadwireguard-linux-cc6df3a24587b3c9f191e34ffb67e269766e2ffc.tar.xz
wireguard-linux-cc6df3a24587b3c9f191e34ffb67e269766e2ffc.zip
video: fbdev: imxfb: add some error handling
clk_prepare_enable can fail and if it does the controller must not be considered enabled. So check for errors, properly unwind and give the error code back to the caller. While touching the clock code also enable the clocks in the same direction and disable in reverse order. Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de> Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Diffstat (limited to 'drivers/video/fbdev/imxfb.c')
-rw-r--r--drivers/video/fbdev/imxfb.c35
1 files changed, 27 insertions, 8 deletions
diff --git a/drivers/video/fbdev/imxfb.c b/drivers/video/fbdev/imxfb.c
index 6d402c1a0f2b..fe0c4eeff2e4 100644
--- a/drivers/video/fbdev/imxfb.c
+++ b/drivers/video/fbdev/imxfb.c
@@ -473,11 +473,12 @@ static int imxfb_set_par(struct fb_info *info)
return 0;
}
-static void imxfb_enable_controller(struct imxfb_info *fbi)
+static int imxfb_enable_controller(struct imxfb_info *fbi)
{
+ int ret;
if (fbi->enabled)
- return;
+ return 0;
pr_debug("Enabling LCD controller\n");
@@ -496,10 +497,29 @@ static void imxfb_enable_controller(struct imxfb_info *fbi)
*/
writel(RMCR_LCDC_EN_MX1, fbi->regs + LCDC_RMCR);
- clk_prepare_enable(fbi->clk_ipg);
- clk_prepare_enable(fbi->clk_ahb);
- clk_prepare_enable(fbi->clk_per);
+ ret = clk_prepare_enable(fbi->clk_ipg);
+ if (ret)
+ goto err_enable_ipg;
+
+ ret = clk_prepare_enable(fbi->clk_ahb);
+ if (ret)
+ goto err_enable_ahb;
+
+ ret = clk_prepare_enable(fbi->clk_per);
+ if (ret)
+ goto err_enable_per;
+
fbi->enabled = true;
+ return 0;
+
+err_enable_per:
+ clk_disable_unprepare(fbi->clk_ahb);
+err_enable_ahb:
+ clk_disable_unprepare(fbi->clk_ipg);
+err_enable_ipg:
+ writel(0, fbi->regs + LCDC_RMCR);
+
+ return ret;
}
static void imxfb_disable_controller(struct imxfb_info *fbi)
@@ -510,8 +530,8 @@ static void imxfb_disable_controller(struct imxfb_info *fbi)
pr_debug("Disabling LCD controller\n");
clk_disable_unprepare(fbi->clk_per);
- clk_disable_unprepare(fbi->clk_ipg);
clk_disable_unprepare(fbi->clk_ahb);
+ clk_disable_unprepare(fbi->clk_ipg);
fbi->enabled = false;
writel(0, fbi->regs + LCDC_RMCR);
@@ -532,8 +552,7 @@ static int imxfb_blank(int blank, struct fb_info *info)
break;
case FB_BLANK_UNBLANK:
- imxfb_enable_controller(fbi);
- break;
+ return imxfb_enable_controller(fbi);
}
return 0;
}