diff --git a/drivers/mxc/ipu3/ipu_device.c b/drivers/mxc/ipu3/ipu_device.c index 8f6b957de3b0bd..f1f6ad16ff201f 100644 --- a/drivers/mxc/ipu3/ipu_device.c +++ b/drivers/mxc/ipu3/ipu_device.c @@ -286,6 +286,7 @@ struct ipu_task_entry { u8 task_in_list; u8 split_done; struct mutex split_lock; + struct mutex vdic_lock; wait_queue_head_t split_waitq; struct list_head node; @@ -1697,10 +1698,12 @@ static int queue_split_task(struct ipu_task_entry *t, int i, j; struct ipu_task_entry *tsk = NULL; struct mutex *lock = &t->split_lock; + struct mutex *vdic_lock = &t->vdic_lock; dev_dbg(t->dev, "Split task 0x%p, no-0x%x, size:%d\n", t, t->task_no, size); mutex_init(lock); + mutex_init(vdic_lock); init_waitqueue_head(&t->split_waitq); INIT_LIST_HEAD(&t->split_list); for (j = 0; j < size; j++) { @@ -2389,11 +2392,13 @@ static void vdi_split_process(struct ipu_soc *ipu, struct ipu_task_entry *t) u32 line_size; unsigned char *base_off; struct ipu_task_entry *parent = t->parent; + struct mutex *lock = &parent->vdic_lock; if (!parent) { dev_err(t->dev, "ERR[0x%x]invalid parent\n", t->task_no); return; } + mutex_lock(lock); stripe_mode = t->task_no & 0xf; task_no = t->task_no >> 4; @@ -2410,6 +2415,7 @@ static void vdi_split_process(struct ipu_soc *ipu, struct ipu_task_entry *t) vdi_size = vdi_save_lines * line_size; if (vdi_save_lines <= 0) { dev_err(t->dev, "[0x%p] vdi_save_line error\n", (void *)t); + mutex_unlock(lock); return; } @@ -2425,6 +2431,7 @@ static void vdi_split_process(struct ipu_soc *ipu, struct ipu_task_entry *t) if (parent->vditmpbuf[0] == NULL) { dev_err(t->dev, "[0x%p]Falied Alloc vditmpbuf[0]\n", (void *)t); + mutex_unlock(lock); return; } memset(parent->vditmpbuf[0], 0, vdi_size); @@ -2433,6 +2440,7 @@ static void vdi_split_process(struct ipu_soc *ipu, struct ipu_task_entry *t) if (parent->vditmpbuf[1] == NULL) { dev_err(t->dev, "[0x%p]Falied Alloc vditmpbuf[1]\n", (void *)t); + mutex_unlock(lock); return; } memset(parent->vditmpbuf[1], 0, vdi_size); @@ -2451,6 +2459,7 @@ static void vdi_split_process(struct ipu_soc *ipu, struct ipu_task_entry *t) } if (base_off == NULL) { dev_err(t->dev, "ERR[0x%p]Failed get virtual address\n", t); + mutex_unlock(lock); return; } @@ -2573,6 +2582,7 @@ static void vdi_split_process(struct ipu_soc *ipu, struct ipu_task_entry *t) } if (!pfn_valid(t->output.paddr >> PAGE_SHIFT)) iounmap(base_off); + mutex_unlock(lock); } static void do_task_release(struct ipu_task_entry *t, int fail)