static int dlfb_handle_damage(struct dlfb_data *dlfb, int x, int y, int width, int height)
{
- int i;
+ int i, ret;
char *cmd;
cycles_t start_cycles, end_cycles;
int bytes_sent = 0;
start_cycles = get_cycles();
+ mutex_lock(&dlfb->render_mutex);
+
aligned_x = DL_ALIGN_DOWN(x, sizeof(unsigned long));
width = DL_ALIGN_UP(width + (x-aligned_x), sizeof(unsigned long));
x = aligned_x;
if ((width <= 0) ||
(x + width > dlfb->info->var.xres) ||
- (y + height > dlfb->info->var.yres))
- return -EINVAL;
+ (y + height > dlfb->info->var.yres)) {
+ ret = -EINVAL;
+ goto unlock_ret;
+ }
- if (!atomic_read(&dlfb->usb_active))
- return 0;
+ if (!atomic_read(&dlfb->usb_active)) {
+ ret = 0;
+ goto unlock_ret;
+ }
urb = dlfb_get_urb(dlfb);
- if (!urb)
- return 0;
+ if (!urb) {
+ ret = 0;
+ goto unlock_ret;
+ }
cmd = urb->transfer_buffer;
for (i = y; i < y + height ; i++) {
>> 10)), /* Kcycles */
&dlfb->cpu_kcycles_used);
- return 0;
+ ret = 0;
+
+unlock_ret:
+ mutex_unlock(&dlfb->render_mutex);
+ return ret;
}
static void dlfb_init_damage(struct dlfb_data *dlfb)
int bytes_identical = 0;
int bytes_rendered = 0;
+ mutex_lock(&dlfb->render_mutex);
+
if (!fb_defio)
- return;
+ goto unlock_ret;
if (!atomic_read(&dlfb->usb_active))
- return;
+ goto unlock_ret;
start_cycles = get_cycles();
urb = dlfb_get_urb(dlfb);
if (!urb)
- return;
+ goto unlock_ret;
cmd = urb->transfer_buffer;
atomic_add(((unsigned int) ((end_cycles - start_cycles)
>> 10)), /* Kcycles */
&dlfb->cpu_kcycles_used);
+unlock_ret:
+ mutex_unlock(&dlfb->render_mutex);
}
static int dlfb_get_edid(struct dlfb_data *dlfb, char *edid, int len)
cancel_work_sync(&dlfb->damage_work);
+ mutex_destroy(&dlfb->render_mutex);
+
if (info->cmap.len != 0)
fb_dealloc_cmap(&info->cmap);
if (info->monspecs.modedb)
dlfb->ops = dlfb_ops;
info->fbops = &dlfb->ops;
+ mutex_init(&dlfb->render_mutex);
dlfb_init_damage(dlfb);
spin_lock_init(&dlfb->damage_lock);
INIT_WORK(&dlfb->damage_work, dlfb_damage_work);