summaryrefslogtreecommitdiff
path: root/linux/drivers/media
diff options
context:
space:
mode:
Diffstat (limited to 'linux/drivers/media')
-rw-r--r--linux/drivers/media/dvb/frontends/zl10353.c3
-rw-r--r--linux/drivers/media/video/bt866.c1
-rw-r--r--linux/drivers/media/video/vivi.c191
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;