aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/video/au0828/au0828-video.c82
-rw-r--r--drivers/media/video/au0828/au0828.h2
2 files changed, 56 insertions, 28 deletions
diff --git a/drivers/media/video/au0828/au0828-video.c b/drivers/media/video/au0828/au0828-video.c
index 8d11e544c879..cf8fc6274713 100644
--- a/drivers/media/video/au0828/au0828-video.c
+++ b/drivers/media/video/au0828/au0828-video.c
@@ -122,6 +122,7 @@ static void au0828_irq_callback(struct urb *urb)
122{ 122{
123 struct au0828_dmaqueue *dma_q = urb->context; 123 struct au0828_dmaqueue *dma_q = urb->context;
124 struct au0828_dev *dev = container_of(dma_q, struct au0828_dev, vidq); 124 struct au0828_dev *dev = container_of(dma_q, struct au0828_dev, vidq);
125 unsigned long flags = 0;
125 int rc, i; 126 int rc, i;
126 127
127 switch (urb->status) { 128 switch (urb->status) {
@@ -139,9 +140,9 @@ static void au0828_irq_callback(struct urb *urb)
139 } 140 }
140 141
141 /* Copy data from URB */ 142 /* Copy data from URB */
142 spin_lock(&dev->slock); 143 spin_lock_irqsave(&dev->slock, flags);
143 rc = dev->isoc_ctl.isoc_copy(dev, urb); 144 rc = dev->isoc_ctl.isoc_copy(dev, urb);
144 spin_unlock(&dev->slock); 145 spin_unlock_irqrestore(&dev->slock, flags);
145 146
146 /* Reset urb buffers */ 147 /* Reset urb buffers */
147 for (i = 0; i < urb->number_of_packets; i++) { 148 for (i = 0; i < urb->number_of_packets; i++) {
@@ -312,9 +313,6 @@ static inline void buffer_filled(struct au0828_dev *dev,
312 313
313 list_del(&buf->vb.queue); 314 list_del(&buf->vb.queue);
314 wake_up(&buf->vb.done); 315 wake_up(&buf->vb.done);
315
316 /* Reset the timer for "no video condition" */
317 mod_timer(&dev->vid_timeout, jiffies + (HZ / 10));
318} 316}
319 317
320static inline void vbi_buffer_filled(struct au0828_dev *dev, 318static inline void vbi_buffer_filled(struct au0828_dev *dev,
@@ -332,9 +330,6 @@ static inline void vbi_buffer_filled(struct au0828_dev *dev,
332 330
333 list_del(&buf->vb.queue); 331 list_del(&buf->vb.queue);
334 wake_up(&buf->vb.done); 332 wake_up(&buf->vb.done);
335
336 /* Reset the timer for "no video condition" */
337 mod_timer(&dev->vbi_timeout, jiffies + (HZ / 10));
338} 333}
339 334
340/* 335/*
@@ -603,6 +598,15 @@ static inline int au0828_isoc_copy(struct au0828_dev *dev, struct urb *urb)
603 outp = NULL; 598 outp = NULL;
604 else 599 else
605 outp = videobuf_to_vmalloc(&buf->vb); 600 outp = videobuf_to_vmalloc(&buf->vb);
601
602 /* As long as isoc traffic is arriving, keep
603 resetting the timer */
604 if (dev->vid_timeout_running)
605 mod_timer(&dev->vid_timeout,
606 jiffies + (HZ / 10));
607 if (dev->vbi_timeout_running)
608 mod_timer(&dev->vbi_timeout,
609 jiffies + (HZ / 10));
606 } 610 }
607 611
608 if (buf != NULL) { 612 if (buf != NULL) {
@@ -922,18 +926,22 @@ void au0828_vid_buffer_timeout(unsigned long data)
922 struct au0828_dmaqueue *dma_q = &dev->vidq; 926 struct au0828_dmaqueue *dma_q = &dev->vidq;
923 struct au0828_buffer *buf; 927 struct au0828_buffer *buf;
924 unsigned char *vid_data; 928 unsigned char *vid_data;
929 unsigned long flags = 0;
925 930
926 spin_lock(&dev->slock); 931 spin_lock_irqsave(&dev->slock, flags);
927 932
928 buf = dev->isoc_ctl.buf; 933 buf = dev->isoc_ctl.buf;
929 if (buf != NULL) { 934 if (buf != NULL) {
930 vid_data = videobuf_to_vmalloc(&buf->vb); 935 vid_data = videobuf_to_vmalloc(&buf->vb);
931 memset(vid_data, 0x00, buf->vb.size); /* Blank green frame */ 936 memset(vid_data, 0x00, buf->vb.size); /* Blank green frame */
932 buffer_filled(dev, dma_q, buf); 937 buffer_filled(dev, dma_q, buf);
933 get_next_buf(dma_q, &buf);
934 } 938 }
939 get_next_buf(dma_q, &buf);
940
941 if (dev->vid_timeout_running == 1)
942 mod_timer(&dev->vid_timeout, jiffies + (HZ / 10));
935 943
936 spin_unlock(&dev->slock); 944 spin_unlock_irqrestore(&dev->slock, flags);
937} 945}
938 946
939void au0828_vbi_buffer_timeout(unsigned long data) 947void au0828_vbi_buffer_timeout(unsigned long data)
@@ -942,18 +950,21 @@ void au0828_vbi_buffer_timeout(unsigned long data)
942 struct au0828_dmaqueue *dma_q = &dev->vbiq; 950 struct au0828_dmaqueue *dma_q = &dev->vbiq;
943 struct au0828_buffer *buf; 951 struct au0828_buffer *buf;
944 unsigned char *vbi_data; 952 unsigned char *vbi_data;
953 unsigned long flags = 0;
945 954
946 spin_lock(&dev->slock); 955 spin_lock_irqsave(&dev->slock, flags);
947 956
948 buf = dev->isoc_ctl.vbi_buf; 957 buf = dev->isoc_ctl.vbi_buf;
949 if (buf != NULL) { 958 if (buf != NULL) {
950 vbi_data = videobuf_to_vmalloc(&buf->vb); 959 vbi_data = videobuf_to_vmalloc(&buf->vb);
951 memset(vbi_data, 0x00, buf->vb.size); 960 memset(vbi_data, 0x00, buf->vb.size);
952 vbi_buffer_filled(dev, dma_q, buf); 961 vbi_buffer_filled(dev, dma_q, buf);
953 vbi_get_next_buf(dma_q, &buf);
954 } 962 }
963 vbi_get_next_buf(dma_q, &buf);
955 964
956 spin_unlock(&dev->slock); 965 if (dev->vbi_timeout_running == 1)
966 mod_timer(&dev->vbi_timeout, jiffies + (HZ / 10));
967 spin_unlock_irqrestore(&dev->slock, flags);
957} 968}
958 969
959 970
@@ -1026,16 +1037,6 @@ static int au0828_v4l2_open(struct file *filp)
1026 V4L2_FIELD_SEQ_TB, 1037 V4L2_FIELD_SEQ_TB,
1027 sizeof(struct au0828_buffer), fh, NULL); 1038 sizeof(struct au0828_buffer), fh, NULL);
1028 1039
1029 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1030 dev->vid_timeout.function = au0828_vid_buffer_timeout;
1031 dev->vid_timeout.data = (unsigned long) dev;
1032 init_timer(&dev->vid_timeout);
1033 } else {
1034 dev->vbi_timeout.function = au0828_vbi_buffer_timeout;
1035 dev->vbi_timeout.data = (unsigned long) dev;
1036 init_timer(&dev->vbi_timeout);
1037 }
1038
1039 return ret; 1040 return ret;
1040} 1041}
1041 1042
@@ -1046,13 +1047,19 @@ static int au0828_v4l2_close(struct file *filp)
1046 struct au0828_dev *dev = fh->dev; 1047 struct au0828_dev *dev = fh->dev;
1047 1048
1048 if (res_check(fh, AU0828_RESOURCE_VIDEO)) { 1049 if (res_check(fh, AU0828_RESOURCE_VIDEO)) {
1049 del_timer(&dev->vid_timeout); 1050 /* Cancel timeout thread in case they didn't call streamoff */
1051 dev->vid_timeout_running = 0;
1052 del_timer_sync(&dev->vid_timeout);
1053
1050 videobuf_stop(&fh->vb_vidq); 1054 videobuf_stop(&fh->vb_vidq);
1051 res_free(fh, AU0828_RESOURCE_VIDEO); 1055 res_free(fh, AU0828_RESOURCE_VIDEO);
1052 } 1056 }
1053 1057
1054 if (res_check(fh, AU0828_RESOURCE_VBI)) { 1058 if (res_check(fh, AU0828_RESOURCE_VBI)) {
1055 del_timer(&dev->vbi_timeout); 1059 /* Cancel timeout thread in case they didn't call streamoff */
1060 dev->vbi_timeout_running = 0;
1061 del_timer_sync(&dev->vbi_timeout);
1062
1056 videobuf_stop(&fh->vb_vbiq); 1063 videobuf_stop(&fh->vb_vbiq);
1057 res_free(fh, AU0828_RESOURCE_VBI); 1064 res_free(fh, AU0828_RESOURCE_VBI);
1058 } 1065 }
@@ -1638,10 +1645,15 @@ static int vidioc_streamon(struct file *file, void *priv,
1638 v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 1); 1645 v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 1);
1639 } 1646 }
1640 1647
1641 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) 1648 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1642 rc = videobuf_streamon(&fh->vb_vidq); 1649 rc = videobuf_streamon(&fh->vb_vidq);
1643 else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) 1650 dev->vid_timeout_running = 1;
1651 mod_timer(&dev->vid_timeout, jiffies + (HZ / 10));
1652 } else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
1644 rc = videobuf_streamon(&fh->vb_vbiq); 1653 rc = videobuf_streamon(&fh->vb_vbiq);
1654 dev->vbi_timeout_running = 1;
1655 mod_timer(&dev->vbi_timeout, jiffies + (HZ / 10));
1656 }
1645 1657
1646 return rc; 1658 return rc;
1647} 1659}
@@ -1668,6 +1680,9 @@ static int vidioc_streamoff(struct file *file, void *priv,
1668 fh, type, fh->resources, dev->resources); 1680 fh, type, fh->resources, dev->resources);
1669 1681
1670 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { 1682 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1683 dev->vid_timeout_running = 0;
1684 del_timer_sync(&dev->vid_timeout);
1685
1671 v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0); 1686 v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0);
1672 rc = au0828_stream_interrupt(dev); 1687 rc = au0828_stream_interrupt(dev);
1673 if (rc != 0) 1688 if (rc != 0)
@@ -1682,6 +1697,9 @@ static int vidioc_streamoff(struct file *file, void *priv,
1682 videobuf_streamoff(&fh->vb_vidq); 1697 videobuf_streamoff(&fh->vb_vidq);
1683 res_free(fh, AU0828_RESOURCE_VIDEO); 1698 res_free(fh, AU0828_RESOURCE_VIDEO);
1684 } else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { 1699 } else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
1700 dev->vbi_timeout_running = 0;
1701 del_timer_sync(&dev->vbi_timeout);
1702
1685 videobuf_streamoff(&fh->vb_vbiq); 1703 videobuf_streamoff(&fh->vb_vbiq);
1686 res_free(fh, AU0828_RESOURCE_VBI); 1704 res_free(fh, AU0828_RESOURCE_VBI);
1687 } 1705 }
@@ -1901,6 +1919,14 @@ int au0828_analog_register(struct au0828_dev *dev,
1901 INIT_LIST_HEAD(&dev->vbiq.active); 1919 INIT_LIST_HEAD(&dev->vbiq.active);
1902 INIT_LIST_HEAD(&dev->vbiq.queued); 1920 INIT_LIST_HEAD(&dev->vbiq.queued);
1903 1921
1922 dev->vid_timeout.function = au0828_vid_buffer_timeout;
1923 dev->vid_timeout.data = (unsigned long) dev;
1924 init_timer(&dev->vid_timeout);
1925
1926 dev->vbi_timeout.function = au0828_vbi_buffer_timeout;
1927 dev->vbi_timeout.data = (unsigned long) dev;
1928 init_timer(&dev->vbi_timeout);
1929
1904 dev->width = NTSC_STD_W; 1930 dev->width = NTSC_STD_W;
1905 dev->height = NTSC_STD_H; 1931 dev->height = NTSC_STD_H;
1906 dev->field_size = dev->width * dev->height; 1932 dev->field_size = dev->width * dev->height;
diff --git a/drivers/media/video/au0828/au0828.h b/drivers/media/video/au0828/au0828.h
index ef46a889da20..9cde35321824 100644
--- a/drivers/media/video/au0828/au0828.h
+++ b/drivers/media/video/au0828/au0828.h
@@ -205,7 +205,9 @@ struct au0828_dev {
205 struct video_device *vdev; 205 struct video_device *vdev;
206 struct video_device *vbi_dev; 206 struct video_device *vbi_dev;
207 struct timer_list vid_timeout; 207 struct timer_list vid_timeout;
208 int vid_timeout_running;
208 struct timer_list vbi_timeout; 209 struct timer_list vbi_timeout;
210 int vbi_timeout_running;
209 int width; 211 int width;
210 int height; 212 int height;
211 int vbi_width; 213 int vbi_width;