Skip to content

Commit

Permalink
[media] davinci: vpif_capture: fix start/stop streaming locking
Browse files Browse the repository at this point in the history
Video capture subdevs may be over I2C and may sleep during xfer, so we
cannot do IRQ-disabled locking when calling the subdev.

The IRQ-disabled locking is meant to protect the DMA queue list
throughout the rest of the driver, so update the locking in
[start|stop]_streaming to protect just this list, and update the irqlock
comment to reflect what it actually protects.

Suggested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Kevin Hilman <khilman@baylibre.com>
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
  • Loading branch information
khilman authored and mchehab committed Jan 31, 2017
1 parent 2d40cb3 commit 62dd4ac
Show file tree
Hide file tree
Showing 2 changed files with 4 additions and 4 deletions.
6 changes: 3 additions & 3 deletions drivers/media/platform/davinci/vpif_capture.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,8 +175,6 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
unsigned long addr, flags;
int ret;

spin_lock_irqsave(&common->irqlock, flags);

/* Initialize field_id */
ch->field_id = 0;

Expand Down Expand Up @@ -207,6 +205,7 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
vpif_config_addr(ch, ret);

/* Get the next frame from the buffer queue */
spin_lock_irqsave(&common->irqlock, flags);
common->cur_frm = common->next_frm = list_entry(common->dma_queue.next,
struct vpif_cap_buffer, list);
/* Remove buffer from the buffer queue */
Expand Down Expand Up @@ -240,6 +239,7 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
return 0;

err:
spin_lock_irqsave(&common->irqlock, flags);
list_for_each_entry_safe(buf, tmp, &common->dma_queue, list) {
list_del(&buf->list);
vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_QUEUED);
Expand Down Expand Up @@ -283,7 +283,6 @@ static void vpif_stop_streaming(struct vb2_queue *vq)
vpif_dbg(1, debug, "stream off failed in subdev\n");

/* release all active buffers */
spin_lock_irqsave(&common->irqlock, flags);
if (common->cur_frm == common->next_frm) {
vb2_buffer_done(&common->cur_frm->vb.vb2_buf,
VB2_BUF_STATE_ERROR);
Expand All @@ -296,6 +295,7 @@ static void vpif_stop_streaming(struct vb2_queue *vq)
VB2_BUF_STATE_ERROR);
}

spin_lock_irqsave(&common->irqlock, flags);
while (!list_empty(&common->dma_queue)) {
common->next_frm = list_entry(common->dma_queue.next,
struct vpif_cap_buffer, list);
Expand Down
2 changes: 1 addition & 1 deletion drivers/media/platform/davinci/vpif_capture.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ struct common_obj {
struct vb2_queue buffer_queue;
/* Queue of filled frames */
struct list_head dma_queue;
/* Used in video-buf */
/* Protects the dma_queue field */
spinlock_t irqlock;
/* lock used to access this structure */
struct mutex lock;
Expand Down

0 comments on commit 62dd4ac

Please sign in to comment.