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..
This commit is contained in:
Matt Sealey
2010-09-09 12:41:12 -05:00
parent c6ba22c9eb
commit a64c5f15de
2 changed files with 12 additions and 2 deletions

View File

@@ -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;

View File

@@ -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;