diff options
-rw-r--r-- | drivers/video/mxc/mxc_epdc_fb.c | 43 |
1 files changed, 39 insertions, 4 deletions
diff --git a/drivers/video/mxc/mxc_epdc_fb.c b/drivers/video/mxc/mxc_epdc_fb.c index 9589812f89d1..a26e1bc98bb7 100644 --- a/drivers/video/mxc/mxc_epdc_fb.c +++ b/drivers/video/mxc/mxc_epdc_fb.c @@ -1047,6 +1047,7 @@ static int mxc_epdc_fb_set_par(struct fb_info *info) int i; int ret; unsigned long flags; + __u32 xoffset_old, yoffset_old; /* * Can't change the FB parameters until current updates have completed. @@ -1055,7 +1056,15 @@ static int mxc_epdc_fb_set_par(struct fb_info *info) mxc_epdc_fb_flush_updates(fb_data); spin_lock_irqsave(&fb_data->queue_lock, flags); + /* + * Set all screeninfo except for xoffset/yoffset + * Subsequent call to pan_display will handle those. + */ + xoffset_old = fb_data->epdc_fb_var.xoffset; + yoffset_old = fb_data->epdc_fb_var.yoffset; fb_data->epdc_fb_var = *screeninfo; + fb_data->epdc_fb_var.xoffset = xoffset_old; + fb_data->epdc_fb_var.yoffset = yoffset_old; spin_unlock_irqrestore(&fb_data->queue_lock, flags); mutex_lock(&fb_data->pxp_mutex); @@ -1824,6 +1833,18 @@ static void epdc_submit_work_func(struct work_struct *work) continue; dev_dbg(fb_data->dev, "A collision update is ready to go!\n"); + + /* If update uses an out-of-date pan offset, we delete it */ + if (next_update->fb_offset != fb_data->fb_offset) { + dev_dbg(fb_data->dev, + "Dropping update (old pan offset)\n"); + list_del_init(&next_update->list); + /* Add to free buffer list */ + list_add_tail(&next_update->list, + &fb_data->upd_buf_free_list->list); + continue; + } + /* * We have a collision cleared, so select it for resubmission. * If an update is already selected, attempt to merge. @@ -1861,6 +1882,20 @@ static void epdc_submit_work_func(struct work_struct *work) dev_dbg(fb_data->dev, "Found a pending update!\n"); + /* + * Delete update if it is based on + * an out-of-date pan offset. + */ + if (next_update->fb_offset != fb_data->fb_offset) { + dev_dbg(fb_data->dev, + "Dropping update (old pan offset)\n"); + list_del_init(&next_update->list); + /* Add to free buffer list */ + list_add_tail(&next_update->list, + &fb_data->upd_buf_free_list->list); + continue; + } + if (!upd_data_list) { upd_data_list = next_update; list_del_init(&next_update->list); @@ -2430,8 +2465,8 @@ static int mxc_epdc_fb_pan_display(struct fb_var_screeninfo *var, u_int y_bottom; unsigned long flags; - dev_dbg(info->device, "%s: var->xoffset %d, info->var.xoffset %d\n", - __func__, var->xoffset, info->var.xoffset); + dev_dbg(info->device, "%s: var->yoffset %d, info->var.yoffset %d\n", + __func__, var->yoffset, info->var.yoffset); /* check if var is valid; also, xpan is not supported */ if (!var || (var->xoffset != info->var.xoffset) || (var->yoffset + var->yres > var->yres_virtual)) { @@ -2443,8 +2478,6 @@ static int mxc_epdc_fb_pan_display(struct fb_var_screeninfo *var, (fb_data->epdc_fb_var.yoffset == var->yoffset)) return 0; /* No change, do nothing */ - spin_lock_irqsave(&fb_data->queue_lock, flags); - y_bottom = var->yoffset; if (!(var->vmode & FB_VMODE_YWRAP)) @@ -2455,6 +2488,8 @@ static int mxc_epdc_fb_pan_display(struct fb_var_screeninfo *var, return -EINVAL; } + spin_lock_irqsave(&fb_data->queue_lock, flags); + fb_data->fb_offset = (var->yoffset * var->xres_virtual + var->xoffset) * (var->bits_per_pixel) / 8; |