MLK-14237 video: mxsfb: fb1 maybe access when fb0 in blank state
authorFancy Fang <chen.fang@nxp.com>
Thu, 23 Feb 2017 01:36:26 +0000 (09:36 +0800)
committerNitin Garg <nitin.garg@nxp.com>
Mon, 19 Mar 2018 20:10:46 +0000 (15:10 -0500)
The overlay framebuffer fb1 access maybe accessed when fb0
is in the blank state in which all the lcd clocks have been
disabled.

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

index 25ad8db..cf8a13f 100644 (file)
@@ -1818,6 +1818,7 @@ static int overlayfb_set_par(struct fb_info *info)
 {
        int size, bpp;
        struct mxsfb_layer *ofb = (struct mxsfb_layer*)info->par;
+       struct mxsfb_info  *fbi = ofb->fbi;
        struct fb_var_screeninfo *var = &ofb->ol_fb->var;
 
        bpp = var->bits_per_pixel;
@@ -1827,6 +1828,15 @@ static int overlayfb_set_par(struct fb_info *info)
        if (ofb->video_mem_size < size)
                return -EINVAL;
 
+       if (!lock_fb_info(fbi->fb_info))
+               return -EINVAL;
+
+       if (fbi->cur_blank != FB_BLANK_UNBLANK) {
+               clk_enable_pix(fbi);
+               clk_enable_axi(fbi);
+               clk_enable_disp_axi(fbi);
+       }
+
        if (ofb->blank_state == FB_BLANK_UNBLANK)
                ofb->ops->disable(ofb);
 
@@ -1835,6 +1845,14 @@ static int overlayfb_set_par(struct fb_info *info)
        if (ofb->blank_state == FB_BLANK_UNBLANK)
                ofb->ops->enable(ofb);
 
+       if (fbi->cur_blank != FB_BLANK_UNBLANK) {
+               clk_disable_disp_axi(fbi);
+               clk_disable_axi(fbi);
+               clk_disable_pix(fbi);
+       }
+
+       unlock_fb_info(fbi->fb_info);
+
        if ((var->activate & FB_ACTIVATE_FORCE) &&
            (var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW)
                var->activate = FB_ACTIVATE_NOW;
@@ -1845,10 +1863,20 @@ static int overlayfb_set_par(struct fb_info *info)
 static int overlayfb_blank(int blank, struct fb_info *info)
 {
        struct mxsfb_layer *ofb = (struct mxsfb_layer*)info->par;
+       struct mxsfb_info  *fbi  = ofb->fbi;
 
        if (ofb->blank_state == blank)
                return 0;
 
+       if (!lock_fb_info(fbi->fb_info))
+               return -EINVAL;
+
+       if (fbi->cur_blank != FB_BLANK_UNBLANK) {
+               clk_enable_pix(fbi);
+               clk_enable_axi(fbi);
+               clk_enable_disp_axi(fbi);
+       }
+
        switch (blank) {
        case FB_BLANK_POWERDOWN:
        case FB_BLANK_VSYNC_SUSPEND:
@@ -1861,6 +1889,14 @@ static int overlayfb_blank(int blank, struct fb_info *info)
                break;
        }
 
+       if (fbi->cur_blank != FB_BLANK_UNBLANK) {
+               clk_disable_disp_axi(fbi);
+               clk_disable_axi(fbi);
+               clk_disable_pix(fbi);
+       }
+
+       unlock_fb_info(fbi->fb_info);
+
        ofb->blank_state = blank;
 
        return 0;
@@ -1876,6 +1912,16 @@ static int overlayfb_pan_display(struct fb_var_screeninfo *var,
 
        init_completion(&fbi->flip_complete);
 
+       if (!lock_fb_info(fbi->fb_info))
+               return -EINVAL;
+
+       if (fbi->cur_blank != FB_BLANK_UNBLANK) {
+               unlock_fb_info(fbi->fb_info);
+               return -EINVAL;
+       }
+
+       unlock_fb_info(fbi->fb_info);
+
        bytes_offset = info->fix.line_length * var->yoffset;
        writel(info->fix.smem_start + bytes_offset,
               fbi->base + LCDC_AS_NEXT_BUF);