diff options
Diffstat (limited to 'linux/drivers/media')
-rw-r--r-- | linux/drivers/media/dvb/frontends/zl10353.c | 3 | ||||
-rw-r--r-- | linux/drivers/media/video/bt866.c | 1 | ||||
-rw-r--r-- | linux/drivers/media/video/vivi.c | 191 |
3 files changed, 119 insertions, 76 deletions
diff --git a/linux/drivers/media/dvb/frontends/zl10353.c b/linux/drivers/media/dvb/frontends/zl10353.c index 276612e00..bc8e7b0f5 100644 --- a/linux/drivers/media/dvb/frontends/zl10353.c +++ b/linux/drivers/media/dvb/frontends/zl10353.c @@ -149,7 +149,8 @@ static void zl10353_calc_nominal_rate(struct dvb_frontend *fe, break; } - value = (bw * (u64)10 * (1 << 23) / 7 * 125 + adc_clock / 2); + value = (u64)10 * (1 << 23) / 7 * 125; + value = (bw * value) + adc_clock / 2; do_div(value, adc_clock); *nominal_rate = value; diff --git a/linux/drivers/media/video/bt866.c b/linux/drivers/media/video/bt866.c index 1f9efb8b3..89161e867 100644 --- a/linux/drivers/media/video/bt866.c +++ b/linux/drivers/media/video/bt866.c @@ -301,7 +301,6 @@ static struct i2c_client bt866_client_tmpl = .addr = 0, .adapter = NULL, .driver = &i2c_driver_bt866, - .usage_count = 0 }; static int bt866_found_proc(struct i2c_adapter *adapter, diff --git a/linux/drivers/media/video/vivi.c b/linux/drivers/media/video/vivi.c index 01d5044ca..0305589d1 100644 --- a/linux/drivers/media/video/vivi.c +++ b/linux/drivers/media/video/vivi.c @@ -63,7 +63,6 @@ /* Declare static vars that will be used as parameters */ static unsigned int vid_limit = 16; /* Video memory limit, in Mb */ -static struct video_device vivi; /* Video device */ static int video_nr = -1; /* /dev/videoN, -1 for autodetect */ static int n_devs = 1; /* Number of virtual devices */ @@ -119,9 +118,9 @@ static struct v4l2_queryctrl vivi_qctrl[] = { static int qctl_regs[ARRAY_SIZE(vivi_qctrl)]; -#define dprintk(level, fmt, arg...) \ +#define dprintk(dev, level, fmt, arg...) \ do { \ - if (vivi.debug >= (level)) \ + if (dev->vfd->debug >= (level)) \ printk(KERN_DEBUG "vivi: " fmt , ## arg); \ } while (0) @@ -181,6 +180,7 @@ struct vivi_dev { #else struct semaphore lock; #endif + spinlock_t slock; int users; @@ -355,7 +355,7 @@ static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf) dev->timestr); /* FIXME: replacing to __copy_to_user */ if (copy_to_user(vbuf + pos, tmpbuf, wmax * 2) != 0) - dprintk(2, "vivifill copy_to_user failed.\n"); + dprintk(dev, 2, "vivifill copy_to_user failed.\n"); pos += wmax*2; } @@ -384,8 +384,8 @@ static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf) sprintf(dev->timestr, "%02d:%02d:%02d:%03d", dev->h, dev->m, dev->s, (dev->us + 500) / 1000); - dprintk(2, "vivifill at %s: Buffer 0x%08lx size= %d\n", dev->timestr, - (unsigned long)tmpbuf, pos); + dprintk(dev, 2, "vivifill at %s: Buffer 0x%08lx size= %d\n", + dev->timestr, (unsigned long)tmpbuf, pos); /* Advice that buffer was filled */ buf->vb.state = VIDEOBUF_DONE; @@ -406,10 +406,11 @@ static void vivi_thread_tick(struct vivi_dmaqueue *dma_q) int bc; + spin_lock(&dev->slock); /* Announces videobuf that all went ok */ for (bc = 0;; bc++) { if (list_empty(&dma_q->active)) { - dprintk(1, "No active queue to serve\n"); + dprintk(dev, 1, "No active queue to serve\n"); break; } @@ -419,11 +420,12 @@ static void vivi_thread_tick(struct vivi_dmaqueue *dma_q) /* Nobody is waiting something to be done, just return */ if (!waitqueue_active(&buf->vb.done)) { mod_timer(&dma_q->timeout, jiffies+BUFFER_TIMEOUT); + spin_unlock(&dev->slock); return; } do_gettimeofday(&buf->vb.ts); - dprintk(2, "[%p/%d] wakeup\n", buf, buf->vb. i); + dprintk(dev, 2, "[%p/%d] wakeup\n", buf, buf->vb. i); /* Fill buffer */ vivi_fillbuff(dev, buf); @@ -435,53 +437,67 @@ static void vivi_thread_tick(struct vivi_dmaqueue *dma_q) } } if (bc != 1) - dprintk(1, "%s: %d buffers handled (should be 1)\n", + dprintk(dev, 1, "%s: %d buffers handled (should be 1)\n", __FUNCTION__, bc); + spin_unlock(&dev->slock); } +#define frames_to_ms(frames) \ + ((frames * WAKE_NUMERATOR * 1000) / WAKE_DENOMINATOR) + static void vivi_sleep(struct vivi_dmaqueue *dma_q) { - int timeout; + struct vivi_dev *dev = container_of(dma_q, struct vivi_dev, vidq); + int timeout, running_time; DECLARE_WAITQUEUE(wait, current); - dprintk(1, "%s dma_q=0x%08lx\n", __FUNCTION__, (unsigned long)dma_q); + dprintk(dev, 1, "%s dma_q=0x%08lx\n", __FUNCTION__, + (unsigned long)dma_q); add_wait_queue(&dma_q->wq, &wait); #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) - if (!(q->rmmod || signal_pending(current))) { + if ((q->rmmod || signal_pending(current))) + goto stop_task; #else - if (!kthread_should_stop()) { + if (kthread_should_stop()) + goto stop_task; #endif - dma_q->frame++; - - /* Calculate time to wake up */ - timeout = dma_q->ini_jiffies+ - msecs_to_jiffies((dma_q->frame*WAKE_NUMERATOR * 1000) - / WAKE_DENOMINATOR) - jiffies; - - if (timeout <= 0) { - int old = dma_q->frame; - dma_q->frame = (jiffies_to_msecs(jiffies - - dma_q->ini_jiffies) * - WAKE_DENOMINATOR) / - (WAKE_NUMERATOR * 1000) + 1; - - timeout = dma_q->ini_jiffies+ - msecs_to_jiffies((dma_q->frame * - WAKE_NUMERATOR * 1000) - / WAKE_DENOMINATOR) - jiffies; - - dprintk(1, "underrun, losed %d frames. " - "Now, frame is %d. Waking on %d jiffies\n", - dma_q->frame-old, dma_q->frame, timeout); - } else - dprintk(1, "will sleep for %i jiffies\n", timeout); - - vivi_thread_tick(dma_q); - - schedule_timeout_interruptible(timeout); - } + running_time = jiffies - dma_q->ini_jiffies; + dma_q->frame++; + + /* Calculate time to wake up */ + timeout = msecs_to_jiffies(frames_to_ms(dma_q->frame)) - running_time; + + if (timeout > msecs_to_jiffies(frames_to_ms(2)) || timeout <= 0) { + int old = dma_q->frame; + int nframes; + + dma_q->frame = (jiffies_to_msecs(running_time) / + frames_to_ms(1)) + 1; + + timeout = msecs_to_jiffies(frames_to_ms(dma_q->frame)) + - running_time; + + if (unlikely (timeout <= 0)) + timeout = 1; + + nframes = (dma_q->frame > old)? + dma_q->frame - old : old - dma_q->frame; + + dprintk(dev, 1, "%ld: %s %d frames. " + "Current frame is %d. Will sleep for %d jiffies\n", + jiffies, + (dma_q->frame > old)? "Underrun, losed" : "Overrun of", + nframes, dma_q->frame, timeout); + } else + dprintk(dev, 1, "will sleep for %d jiffies\n", timeout); + + vivi_thread_tick(dma_q); + + schedule_timeout_interruptible(timeout); + +stop_task: remove_wait_queue(&dma_q->wq, &wait); try_to_freeze(); } @@ -489,6 +505,7 @@ static void vivi_sleep(struct vivi_dmaqueue *dma_q) static int vivi_thread(void *data) { struct vivi_dmaqueue *dma_q = data; + struct vivi_dev *dev = container_of(dma_q, struct vivi_dev, vidq); #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) daemonize(); @@ -504,7 +521,7 @@ static int vivi_thread(void *data) if (dma_q->notify != NULL) up(dma_q->notify); #endif - dprintk(1, "thread started\n"); + dprintk(dev, 1, "thread started\n"); mod_timer(&dma_q->timeout, jiffies+BUFFER_TIMEOUT); set_freezable(); @@ -519,7 +536,7 @@ static int vivi_thread(void *data) #endif break; } - dprintk(1, "thread: exit\n"); + dprintk(dev, 1, "thread: exit\n"); #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) dma_q->kthread = NULL; @@ -531,10 +548,12 @@ static int vivi_thread(void *data) static int vivi_start_thread(struct vivi_dmaqueue *dma_q) { + struct vivi_dev *dev = container_of(dma_q, struct vivi_dev, vidq); + dma_q->frame = 0; dma_q->ini_jiffies = jiffies; - dprintk(1, "%s\n", __FUNCTION__); + dprintk(dev, 1, "%s\n", __FUNCTION__); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0) dma_q->kthread = kthread_run(vivi_thread, dma_q, "vivi"); @@ -561,13 +580,15 @@ static int vivi_start_thread(struct vivi_dmaqueue *dma_q) /* Wakes thread */ wake_up_interruptible(&dma_q->wq); - dprintk(1, "returning from %s\n", __FUNCTION__); + dprintk(dev, 1, "returning from %s\n", __FUNCTION__); return 0; } static void vivi_stop_thread(struct vivi_dmaqueue *dma_q) { - dprintk(1, "%s\n", __FUNCTION__); + struct vivi_dev *dev = container_of(dma_q, struct vivi_dev, vidq); + + dprintk(dev, 1, "%s\n", __FUNCTION__); /* shutdown control thread */ if (dma_q->kthread) { #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) @@ -589,17 +610,19 @@ static void vivi_stop_thread(struct vivi_dmaqueue *dma_q) static int restart_video_queue(struct vivi_dmaqueue *dma_q) { + struct vivi_dev *dev = container_of(dma_q, struct vivi_dev, vidq); struct vivi_buffer *buf, *prev; - dprintk(1, "%s dma_q=0x%08lx\n", __FUNCTION__, (unsigned long)dma_q); + dprintk(dev, 1, "%s dma_q=0x%08lx\n", __FUNCTION__, + (unsigned long)dma_q); if (!list_empty(&dma_q->active)) { buf = list_entry(dma_q->active.next, struct vivi_buffer, vb.queue); - dprintk(2, "restart_queue [%p/%d]: restart dma\n", + dprintk(dev, 2, "restart_queue [%p/%d]: restart dma\n", buf, buf->vb.i); - dprintk(1, "Restarting video dma\n"); + dprintk(dev, 1, "Restarting video dma\n"); vivi_stop_thread(dma_q); /* cancel all outstanding capture / vbi requests */ @@ -623,13 +646,14 @@ static int restart_video_queue(struct vivi_dmaqueue *dma_q) list_del(&buf->vb.queue); list_add_tail(&buf->vb.queue, &dma_q->active); - dprintk(1, "Restarting video dma\n"); + dprintk(dev, 1, "Restarting video dma\n"); vivi_stop_thread(dma_q); vivi_start_thread(dma_q); buf->vb.state = VIDEOBUF_ACTIVE; mod_timer(&dma_q->timeout, jiffies+BUFFER_TIMEOUT); - dprintk(2, "[%p/%d] restart_queue - first active\n", + dprintk(dev, 2, + "[%p/%d] restart_queue - first active\n", buf, buf->vb.i); } else if (prev->vb.width == buf->vb.width && @@ -638,7 +662,8 @@ static int restart_video_queue(struct vivi_dmaqueue *dma_q) list_del(&buf->vb.queue); list_add_tail(&buf->vb.queue, &dma_q->active); buf->vb.state = VIDEOBUF_ACTIVE; - dprintk(2, "[%p/%d] restart_queue - move to active\n", + dprintk(dev, 2, + "[%p/%d] restart_queue - move to active\n", buf, buf->vb.i); } else { return 0; @@ -653,6 +678,8 @@ static void vivi_vid_timeout(unsigned long data) struct vivi_dmaqueue *vidq = &dev->vidq; struct vivi_buffer *buf; + spin_lock(&dev->slock); + while (!list_empty(&vidq->active)) { buf = list_entry(vidq->active.next, struct vivi_buffer, vb.queue); @@ -661,8 +688,9 @@ static void vivi_vid_timeout(unsigned long data) wake_up(&buf->vb.done); printk(KERN_INFO "vivi/0: [%p/%d] timeout\n", buf, buf->vb.i); } - restart_video_queue(vidq); + + spin_unlock(&dev->slock); } /* ------------------------------------------------------------------ @@ -671,7 +699,8 @@ static void vivi_vid_timeout(unsigned long data) static int buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size) { - struct vivi_fh *fh = vq->priv_data; + struct vivi_fh *fh = vq->priv_data; + struct vivi_dev *dev = fh->dev; *size = fh->width*fh->height*2; @@ -681,14 +710,18 @@ buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size) while (*size * *count > vid_limit * 1024 * 1024) (*count)--; - dprintk(1, "%s, count=%d, size=%d\n", __FUNCTION__, *count, *size); + dprintk(dev, 1, "%s, count=%d, size=%d\n", __FUNCTION__, + *count, *size); return 0; } static void free_buffer(struct videobuf_queue *vq, struct vivi_buffer *buf) { - dprintk(1, "%s\n", __FUNCTION__); + struct vivi_fh *fh = vq->priv_data; + struct vivi_dev *dev = fh->dev; + + dprintk(dev, 1, "%s\n", __FUNCTION__); if (in_interrupt()) BUG(); @@ -705,10 +738,11 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, enum v4l2_field field) { struct vivi_fh *fh = vq->priv_data; + struct vivi_dev *dev = fh->dev; struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb); int rc, init_buffer = 0; - dprintk(1, "%s, field=%d\n", __FUNCTION__, field); + dprintk(dev, 1, "%s, field=%d\n", __FUNCTION__, field); BUG_ON(NULL == fh->fmt); if (fh->width < 48 || fh->width > norm_maxw() || @@ -754,18 +788,18 @@ buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) struct vivi_buffer *prev; if (!list_empty(&vidq->queued)) { - dprintk(1, "adding vb queue=0x%08lx\n", + dprintk(dev, 1, "adding vb queue=0x%08lx\n", (unsigned long)&buf->vb.queue); list_add_tail(&buf->vb.queue, &vidq->queued); buf->vb.state = VIDEOBUF_QUEUED; - dprintk(2, "[%p/%d] buffer_queue - append to queued\n", + dprintk(dev, 2, "[%p/%d] buffer_queue - append to queued\n", buf, buf->vb.i); } else if (list_empty(&vidq->active)) { list_add_tail(&buf->vb.queue, &vidq->active); buf->vb.state = VIDEOBUF_ACTIVE; mod_timer(&vidq->timeout, jiffies+BUFFER_TIMEOUT); - dprintk(2, "[%p/%d] buffer_queue - first active\n", + dprintk(dev, 2, "[%p/%d] buffer_queue - first active\n", buf, buf->vb.i); vivi_start_thread(vidq); @@ -777,13 +811,15 @@ buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) prev->fmt == buf->fmt) { list_add_tail(&buf->vb.queue, &vidq->active); buf->vb.state = VIDEOBUF_ACTIVE; - dprintk(2, "[%p/%d] buffer_queue - append to active\n", + dprintk(dev, 2, + "[%p/%d] buffer_queue - append to active\n", buf, buf->vb.i); } else { list_add_tail(&buf->vb.queue, &vidq->queued); buf->vb.state = VIDEOBUF_QUEUED; - dprintk(2, "[%p/%d] buffer_queue - first queued\n", + dprintk(dev, 2, + "[%p/%d] buffer_queue - first queued\n", buf, buf->vb.i); } } @@ -797,7 +833,7 @@ static void buffer_release(struct videobuf_queue *vq, struct vivi_dev *dev = (struct vivi_dev *)fh->dev; struct vivi_dmaqueue *vidq = &dev->vidq; - dprintk(1, "%s\n", __FUNCTION__); + dprintk(dev, 1, "%s\n", __FUNCTION__); vivi_stop_thread(vidq); @@ -857,13 +893,16 @@ static int vidioc_g_fmt_cap(struct file *file, void *priv, static int vidioc_try_fmt_cap(struct file *file, void *priv, struct v4l2_format *f) { + struct vivi_fh *fh = priv; + struct vivi_dev *dev = fh->dev; struct vivi_fmt *fmt; enum v4l2_field field; unsigned int maxw, maxh; if (format.fourcc != f->fmt.pix.pixelformat) { - dprintk(1, "Fourcc format (0x%08x) invalid. Driver accepts " - "only 0x%08x\n", f->fmt.pix.pixelformat, format.fourcc); + dprintk(dev, 1, "Fourcc format (0x%08x) invalid. " + "Driver accepts only 0x%08x\n", + f->fmt.pix.pixelformat, format.fourcc); return -EINVAL; } fmt = &format; @@ -873,7 +912,7 @@ static int vidioc_try_fmt_cap(struct file *file, void *priv, if (field == V4L2_FIELD_ANY) { field = V4L2_FIELD_INTERLACED; } else if (V4L2_FIELD_INTERLACED != field) { - dprintk(1, "Field type invalid.\n"); + dprintk(dev, 1, "Field type invalid.\n"); return -EINVAL; } @@ -1082,7 +1121,7 @@ found: /* If more than one user, mutex should be added */ dev->users++; - dprintk(1, "open minor=%d type=%s users=%d\n", minor, + dprintk(dev, 1, "open minor=%d type=%s users=%d\n", minor, v4l2_type_names[V4L2_BUF_TYPE_VIDEO_CAPTURE], dev->users); /* allocate + initialize per filehandle data */ @@ -1115,7 +1154,7 @@ found: dev->h, dev->m, dev->s, (dev->us + 500) / 1000); videobuf_queue_vmalloc_init(&fh->vb_vidq, &vivi_video_qops, - NULL, NULL, fh->type, V4L2_FIELD_INTERLACED, + NULL, &dev->slock, fh->type, V4L2_FIELD_INTERLACED, sizeof(struct vivi_buffer), fh); return 0; @@ -1137,9 +1176,10 @@ static unsigned int vivi_poll(struct file *file, struct poll_table_struct *wait) { struct vivi_fh *fh = file->private_data; + struct vivi_dev *dev = fh->dev; struct videobuf_queue *q = &fh->vb_vidq; - dprintk(1, "%s\n", __FUNCTION__); + dprintk(dev, 1, "%s\n", __FUNCTION__); if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type) return POLLERR; @@ -1163,7 +1203,8 @@ static int vivi_close(struct inode *inode, struct file *file) dev->users--; - dprintk(1, "close called (minor=%d, users=%d)\n", minor, dev->users); + dprintk(dev, 1, "close called (minor=%d, users=%d)\n", + minor, dev->users); return 0; } @@ -1191,14 +1232,15 @@ static int vivi_release(void) static int vivi_mmap(struct file *file, struct vm_area_struct *vma) { - struct vivi_fh *fh = file->private_data; + struct vivi_fh *fh = file->private_data; + struct vivi_dev *dev = fh->dev; int ret; - dprintk(1, "mmap called, vma=0x%08lx\n", (unsigned long)vma); + dprintk(dev, 1, "mmap called, vma=0x%08lx\n", (unsigned long)vma); ret = videobuf_mmap_mapper(&fh->vb_vidq, vma); - dprintk(1, "vma start=0x%08lx, size=%ld, ret=%d\n", + dprintk(dev, 1, "vma start=0x%08lx, size=%ld, ret=%d\n", (unsigned long)vma->vm_start, (unsigned long)vma->vm_end-(unsigned long)vma->vm_start, ret); @@ -1272,6 +1314,7 @@ static int __init vivi_init(void) /* initialize locks */ mutex_init(&dev->lock); + spin_lock_init(&dev->slock); dev->vidq.timeout.function = vivi_vid_timeout; dev->vidq.timeout.data = (unsigned long)dev; |