From a64c5f15decbf1dd55b27c54f2d91612e34fe16b Mon Sep 17 00:00:00 2001 From: Matt Sealey Date: Thu, 9 Sep 2010 12:41:12 -0500 Subject: [PATCH] VPU allocation fails for some reason - actually the reason is that fbi->fix.line_length can be zero. In this situation, DON'T try and dma_alloc_writecombine with 0 length, or it'll OOPS. As a side effect of not doing this, the V4L driver would happily go off and touch a framebuffer address that was invalid, and there may have been a slight SNAFU with a divide by zero on the VPU framebuffer. Arnaud Patard from Mandriva noticed these a long while ago, but now here they are. BUG: these are temporary hacks, let's try and work out why line_length is 0.. --- drivers/media/video/mxc/output/mxc_v4l2_output.c | 5 +++++ drivers/video/mxc/mxc_ipuv3_fb.c | 9 +++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/media/video/mxc/output/mxc_v4l2_output.c b/drivers/media/video/mxc/output/mxc_v4l2_output.c index 7eda128100f..1f6c5e79ece 100644 --- a/drivers/media/video/mxc/output/mxc_v4l2_output.c +++ b/drivers/media/video/mxc/output/mxc_v4l2_output.c @@ -1344,6 +1344,10 @@ static int mxc_v4l2out_streamon(vout_data * vout) vout->display_buf_size = vout->xres * vout->yres * fbi->var.bits_per_pixel / 8; + /* avoid crashing if the YUV overlay was not allocated. Temporary workaround. + thanks to Arnaud Patard, Mandriva. Hacked in by Matt at Genesi */ + + if (fbi && fbi->screen_base) { /* fill black color for init fb, we assume fb has double buffer*/ if (format_is_yuv(vout->v2f.fmt.pix.pixelformat)) { int i; @@ -1386,6 +1390,7 @@ static int mxc_v4l2out_streamon(vout_data * vout) } else memset(fbi->screen_base, 0x0, fbi->fix.line_length * fbi->var.yres_virtual); + } // NEKO if (INTERLACED_CONTENT(vout)) vout->post_proc_ch = MEM_VDI_PRP_VF_MEM; diff --git a/drivers/video/mxc/mxc_ipuv3_fb.c b/drivers/video/mxc/mxc_ipuv3_fb.c index 36b879aa5c8..7491b812f9d 100644 --- a/drivers/video/mxc/mxc_ipuv3_fb.c +++ b/drivers/video/mxc/mxc_ipuv3_fb.c @@ -693,7 +693,9 @@ static int mxcfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) vtotal = var->yres + var->lower_margin + var->vsync_len + var->upper_margin; var->pixclock = (vtotal * htotal * 6UL) / 100UL; - var->pixclock = KHZ2PICOS(var->pixclock); + + if (var->pixclock) /* avoid div0 error, Arnaud Patard, Mandriva */ + var->pixclock = KHZ2PICOS(var->pixclock); dev_dbg(info->device, "pixclock set for 60Hz refresh = %u ps\n", var->pixclock); @@ -1445,10 +1447,13 @@ static int mxcfb_map_video_memory(struct fb_info *fbi) fbi->fix.smem_len = fbi->var.yres_virtual * fbi->fix.line_length; - fbi->screen_base = dma_alloc_writecombine(fbi->device, + /* line_length is 0 sometimes (BAH!) so temporarily hack it so this doesn't OOPS */ + if (fbi->fix.smem_len) + fbi->screen_base = dma_alloc_writecombine(fbi->device, fbi->fix.smem_len, (dma_addr_t *)&fbi->fix.smem_start, GFP_DMA); + if (fbi->screen_base == 0) { dev_err(fbi->device, "Unable to allocate framebuffer memory\n"); fbi->fix.smem_len = 0;