diff options
author | Jiri Kosina <jkosina@suse.cz> | 2013-01-29 13:48:30 +0400 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2013-01-29 13:48:30 +0400 |
commit | 617677295b53a40d0e54aac4cbbc216ffbc755dd (patch) | |
tree | 51b9e87213243ed5efff252c8e8d8fec4eebc588 /drivers/media/platform/davinci/vpif_display.c | |
parent | 5c8d1b68e01a144813e38795fe6dbe7ebb506131 (diff) | |
parent | 6abb7c25775b7fb2225ad0508236d63ca710e65f (diff) | |
download | linux-617677295b53a40d0e54aac4cbbc216ffbc755dd.tar.xz |
Merge branch 'master' into for-next
Conflicts:
drivers/devfreq/exynos4_bus.c
Sync with Linus' tree to be able to apply patches that are
against newer code (mvneta).
Diffstat (limited to 'drivers/media/platform/davinci/vpif_display.c')
-rw-r--r-- | drivers/media/platform/davinci/vpif_display.c | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/drivers/media/platform/davinci/vpif_display.c b/drivers/media/platform/davinci/vpif_display.c index b716fbd4241f..9f2b603be9c9 100644 --- a/drivers/media/platform/davinci/vpif_display.c +++ b/drivers/media/platform/davinci/vpif_display.c @@ -177,11 +177,14 @@ static void vpif_buffer_queue(struct vb2_buffer *vb) struct vpif_disp_buffer, vb); struct channel_obj *ch = fh->channel; struct common_obj *common; + unsigned long flags; common = &ch->common[VPIF_VIDEO_INDEX]; /* add the buffer to the DMA queue */ + spin_lock_irqsave(&common->irqlock, flags); list_add_tail(&buf->list, &common->dma_queue); + spin_unlock_irqrestore(&common->irqlock, flags); } /* @@ -246,10 +249,13 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count) struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; struct vpif_params *vpif = &ch->vpifparams; unsigned long addr = 0; + unsigned long flags; int ret; /* If buffer queue is empty, return error */ + spin_lock_irqsave(&common->irqlock, flags); if (list_empty(&common->dma_queue)) { + spin_unlock_irqrestore(&common->irqlock, flags); vpif_err("buffer queue is empty\n"); return -EIO; } @@ -260,6 +266,7 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count) struct vpif_disp_buffer, list); list_del(&common->cur_frm->list); + spin_unlock_irqrestore(&common->irqlock, flags); /* Mark state of the current frame to active */ common->cur_frm->vb.state = VB2_BUF_STATE_ACTIVE; @@ -330,6 +337,7 @@ static int vpif_stop_streaming(struct vb2_queue *vq) struct vpif_fh *fh = vb2_get_drv_priv(vq); struct channel_obj *ch = fh->channel; struct common_obj *common; + unsigned long flags; if (!vb2_is_streaming(vq)) return 0; @@ -337,12 +345,14 @@ static int vpif_stop_streaming(struct vb2_queue *vq) common = &ch->common[VPIF_VIDEO_INDEX]; /* release all active buffers */ + spin_lock_irqsave(&common->irqlock, flags); while (!list_empty(&common->dma_queue)) { common->next_frm = list_entry(common->dma_queue.next, struct vpif_disp_buffer, list); list_del(&common->next_frm->list); vb2_buffer_done(&common->next_frm->vb, VB2_BUF_STATE_ERROR); } + spin_unlock_irqrestore(&common->irqlock, flags); return 0; } @@ -363,11 +373,13 @@ static void process_progressive_mode(struct common_obj *common) { unsigned long addr = 0; + spin_lock(&common->irqlock); /* Get the next buffer from buffer queue */ common->next_frm = list_entry(common->dma_queue.next, struct vpif_disp_buffer, list); /* Remove that buffer from the buffer queue */ list_del(&common->next_frm->list); + spin_unlock(&common->irqlock); /* Mark status of the buffer as active */ common->next_frm->vb.state = VB2_BUF_STATE_ACTIVE; @@ -398,16 +410,18 @@ static void process_interlaced_mode(int fid, struct common_obj *common) common->cur_frm = common->next_frm; } else if (1 == fid) { /* odd field */ + spin_lock(&common->irqlock); if (list_empty(&common->dma_queue) || (common->cur_frm != common->next_frm)) { + spin_unlock(&common->irqlock); return; } + spin_unlock(&common->irqlock); /* one field is displayed configure the next * frame if it is available else hold on current * frame */ /* Get next from the buffer queue */ process_progressive_mode(common); - } } @@ -437,8 +451,12 @@ static irqreturn_t vpif_channel_isr(int irq, void *dev_id) continue; if (1 == ch->vpifparams.std_info.frm_fmt) { - if (list_empty(&common->dma_queue)) + spin_lock(&common->irqlock); + if (list_empty(&common->dma_queue)) { + spin_unlock(&common->irqlock); continue; + } + spin_unlock(&common->irqlock); /* Progressive mode */ if (!channel_first_int[i][channel_id]) { @@ -972,9 +990,9 @@ static int vpif_reqbufs(struct file *file, void *priv, } /* Initialize videobuf2 queue as per the buffer type */ common->alloc_ctx = vb2_dma_contig_init_ctx(vpif_dev); - if (!common->alloc_ctx) { + if (IS_ERR(common->alloc_ctx)) { vpif_err("Failed to get the context\n"); - return -EINVAL; + return PTR_ERR(common->alloc_ctx); } q = &common->buffer_queue; q->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; @@ -1380,7 +1398,7 @@ vpif_enum_dv_timings(struct file *file, void *priv, int ret; ret = v4l2_subdev_call(ch->sd, video, enum_dv_timings, timings); - if (ret == -ENOIOCTLCMD && ret == -ENODEV) + if (ret == -ENOIOCTLCMD || ret == -ENODEV) return -EINVAL; return ret; } |