aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsensoray-dev <linux-dev@sensoray.com>2014-11-04 15:34:03 -0500
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>2014-11-11 05:47:22 -0500
commit9694fbec951b9aa56815d423f2c53d17a4a9635c (patch)
tree53e89ee94f14adc07a61528f0ee7533f70d06d40
parent6db47fa1f1a214bc1ea5a59a32f58188f6b255e9 (diff)
[media] s2255drv: fix spinlock issue
qlock spinlock controls access to buf_list and sequence. qlock spinlock should not be locked during a copy to video buffers, an operation that may sleep. Signed-off-by: Dean Anderson <linux-dev@sensoray.com> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
-rw-r--r--drivers/media/usb/s2255/s2255drv.c22
1 files changed, 10 insertions, 12 deletions
diff --git a/drivers/media/usb/s2255/s2255drv.c b/drivers/media/usb/s2255/s2255drv.c
index ccc00099b261..a56a05b0c4e1 100644
--- a/drivers/media/usb/s2255/s2255drv.c
+++ b/drivers/media/usb/s2255/s2255drv.c
@@ -558,27 +558,30 @@ static void s2255_fwchunk_complete(struct urb *urb)
558 558
559} 559}
560 560
561static int s2255_got_frame(struct s2255_vc *vc, int jpgsize) 561static void s2255_got_frame(struct s2255_vc *vc, int jpgsize)
562{ 562{
563 struct s2255_buffer *buf; 563 struct s2255_buffer *buf;
564 struct s2255_dev *dev = to_s2255_dev(vc->vdev.v4l2_dev); 564 struct s2255_dev *dev = to_s2255_dev(vc->vdev.v4l2_dev);
565 unsigned long flags = 0; 565 unsigned long flags = 0;
566 int rc = 0; 566
567 spin_lock_irqsave(&vc->qlock, flags); 567 spin_lock_irqsave(&vc->qlock, flags);
568 if (list_empty(&vc->buf_list)) { 568 if (list_empty(&vc->buf_list)) {
569 dprintk(dev, 1, "No active queue to serve\n"); 569 dprintk(dev, 1, "No active queue to serve\n");
570 rc = -1; 570 spin_unlock_irqrestore(&vc->qlock, flags);
571 goto unlock; 571 return;
572 } 572 }
573 buf = list_entry(vc->buf_list.next, 573 buf = list_entry(vc->buf_list.next,
574 struct s2255_buffer, list); 574 struct s2255_buffer, list);
575 list_del(&buf->list); 575 list_del(&buf->list);
576 v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp); 576 v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp);
577 buf->vb.v4l2_buf.field = vc->field;
578 buf->vb.v4l2_buf.sequence = vc->frame_count;
579 spin_unlock_irqrestore(&vc->qlock, flags);
580
577 s2255_fillbuff(vc, buf, jpgsize); 581 s2255_fillbuff(vc, buf, jpgsize);
582 /* tell v4l buffer was filled */
583 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE);
578 dprintk(dev, 2, "%s: [buf] [%p]\n", __func__, buf); 584 dprintk(dev, 2, "%s: [buf] [%p]\n", __func__, buf);
579unlock:
580 spin_unlock_irqrestore(&vc->qlock, flags);
581 return rc;
582} 585}
583 586
584static const struct s2255_fmt *format_by_fourcc(int fourcc) 587static const struct s2255_fmt *format_by_fourcc(int fourcc)
@@ -649,11 +652,6 @@ static void s2255_fillbuff(struct s2255_vc *vc,
649 } 652 }
650 dprintk(dev, 2, "s2255fill at : Buffer 0x%08lx size= %d\n", 653 dprintk(dev, 2, "s2255fill at : Buffer 0x%08lx size= %d\n",
651 (unsigned long)vbuf, pos); 654 (unsigned long)vbuf, pos);
652 /* tell v4l buffer was filled */
653 buf->vb.v4l2_buf.field = vc->field;
654 buf->vb.v4l2_buf.sequence = vc->frame_count;
655 v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp);
656 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE);
657} 655}
658 656
659 657