staging: use videobuf2 framework for drivers/staging/dt3155v4l driver

This patch transforms drivers/staging/dt3155v4l driver to use videobuf2 framework.
Tested and works with "xawtv -f".

Either streaming API or read method should be selected during kernel configuration.

If both are selected into the driver (not possible without another patching),
either due to my misunderstanding or problems in xawtv (or both), I get kernel panic
after some start/stop of xawtv (not strictly reproducible).

Signed-off-by: Marin Mitov <mitov@issp.bas.bg>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
Marin Mitov 2011-05-28 21:45:27 +03:00 committed by Greg Kroah-Hartman
parent 7a1763320b
commit 8ded351ad1
3 changed files with 186 additions and 336 deletions

View File

@ -1,7 +1,7 @@
config VIDEO_DT3155
tristate "DT3155 frame grabber, Video4Linux interface"
depends on PCI && VIDEO_DEV && VIDEO_V4L2
select VIDEOBUF_DMA_CONTIG
select VIDEOBUF2_DMA_CONTIG
default n
---help---
Enables dt3155 device driver for the DataTranslation DT3155 frame grabber.
@ -18,3 +18,11 @@ config DT3155_CCIR
---help---
Select it for CCIR/50Hz (European region),
or leave it unselected for RS-170/60Hz (North America).
config DT3155_STREAMING
bool "Selects streaming capture method"
depends on VIDEO_DT3155
default y
---help---
Select it if you want to use streaming of memory mapped buffers
or leave it unselected if you want to use read method (one copy more).

View File

@ -24,7 +24,7 @@
#include <linux/kthread.h>
#include <media/v4l2-dev.h>
#include <media/v4l2-ioctl.h>
#include <media/videobuf-dma-contig.h>
#include <media/videobuf2-dma-contig.h>
#include "dt3155v4l.h"
@ -38,6 +38,12 @@
#define DT3155_BUF_SIZE (768 * 576)
#ifdef CONFIG_DT3155_STREAMING
#define DT3155_CAPTURE_METHOD V4L2_CAP_STREAMING
#else
#define DT3155_CAPTURE_METHOD V4L2_CAP_READWRITE
#endif
/* global initializers (for all boards) */
#ifdef CONFIG_DT3155_CCIR
static const u8 csr2_init = VT_50HZ;
@ -197,14 +203,14 @@ static int wait_i2c_reg(void __iomem *addr)
static int
dt3155_start_acq(struct dt3155_priv *pd)
{
struct videobuf_buffer *vb = pd->curr_buf;
struct vb2_buffer *vb = pd->curr_buf;
dma_addr_t dma_addr;
dma_addr = videobuf_to_dma_contig(vb);
dma_addr = vb2_dma_contig_plane_paddr(vb, 0);
iowrite32(dma_addr, pd->regs + EVEN_DMA_START);
iowrite32(dma_addr + vb->width, pd->regs + ODD_DMA_START);
iowrite32(vb->width, pd->regs + EVEN_DMA_STRIDE);
iowrite32(vb->width, pd->regs + ODD_DMA_STRIDE);
iowrite32(dma_addr + img_width, pd->regs + ODD_DMA_START);
iowrite32(img_width, pd->regs + EVEN_DMA_STRIDE);
iowrite32(img_width, pd->regs + ODD_DMA_STRIDE);
/* enable interrupts, clear all irq flags */
iowrite32(FLD_START_EN | FLD_END_ODD_EN | FLD_START |
FLD_END_EVEN | FLD_END_ODD, pd->regs + INT_CSR);
@ -221,95 +227,110 @@ dt3155_start_acq(struct dt3155_priv *pd)
return 0; /* success */
}
/*
* driver-specific callbacks (vb2_ops)
*/
static int
dt3155_stop_acq(struct dt3155_priv *pd)
dt3155_queue_setup(struct vb2_queue *q, unsigned int *num_buffers,
unsigned int *num_planes, unsigned long sizes[],
void *alloc_ctxs[])
{
int tmp;
struct dt3155_priv *pd = vb2_get_drv_priv(q);
void *ret;
/* stop the board */
wait_i2c_reg(pd->regs);
write_i2c_reg(pd->regs, CSR2, pd->csr2);
/* disable all irqs, clear all irq flags */
iowrite32(FLD_START | FLD_END_EVEN | FLD_END_ODD, pd->regs + INT_CSR);
write_i2c_reg(pd->regs, EVEN_CSR, CSR_ERROR | CSR_DONE);
write_i2c_reg(pd->regs, ODD_CSR, CSR_ERROR | CSR_DONE);
tmp = ioread32(pd->regs + CSR1) & (FLD_CRPT_EVEN | FLD_CRPT_ODD);
if (tmp)
printk(KERN_ERR "dt3155: corrupted field %u\n", tmp);
iowrite32(FIFO_EN | SRST | FLD_CRPT_ODD | FLD_CRPT_EVEN |
FLD_DN_ODD | FLD_DN_EVEN | CAP_CONT_EVEN | CAP_CONT_ODD,
pd->regs + CSR1);
if (*num_buffers == 0)
*num_buffers = 1;
*num_planes = 1;
sizes[0] = img_width * img_height;
if (pd->q->alloc_ctx[0])
return 0;
ret = vb2_dma_contig_init_ctx(&pd->pdev->dev);
if (IS_ERR(ret))
return PTR_ERR(ret);
pd->q->alloc_ctx[0] = ret;
return 0;
}
/* Locking: Caller holds q->vb_lock */
static int
dt3155_buf_setup(struct videobuf_queue *q, unsigned int *count,
unsigned int *size)
static void
dt3155_wait_prepare(struct vb2_queue *q)
{
*size = img_width * img_height;
struct dt3155_priv *pd = vb2_get_drv_priv(q);
mutex_unlock(pd->vdev->lock);
}
static void
dt3155_wait_finish(struct vb2_queue *q)
{
struct dt3155_priv *pd = vb2_get_drv_priv(q);
mutex_lock(pd->vdev->lock);
}
static int
dt3155_buf_prepare(struct vb2_buffer *vb)
{
vb2_set_plane_payload(vb, 0, img_width * img_height);
return 0;
}
/* Locking: Caller holds q->vb_lock */
static int
dt3155_buf_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
enum v4l2_field field)
dt3155_start_streaming(struct vb2_queue *q)
{
int ret = 0;
vb->width = img_width;
vb->height = img_height;
vb->size = img_width * img_height;
vb->field = field;
if (vb->state == VIDEOBUF_NEEDS_INIT)
ret = videobuf_iolock(q, vb, NULL);
if (ret) {
vb->state = VIDEOBUF_ERROR;
printk(KERN_ERR "ERROR: videobuf_iolock() failed\n");
videobuf_dma_contig_free(q, vb); /* FIXME: needed? */
} else
vb->state = VIDEOBUF_PREPARED;
return ret;
return 0;
}
static int
dt3155_stop_streaming(struct vb2_queue *q)
{
struct dt3155_priv *pd = vb2_get_drv_priv(q);
struct vb2_buffer *vb;
spin_lock_irq(&pd->lock);
while (!list_empty(&pd->dmaq)) {
vb = list_first_entry(&pd->dmaq, typeof(*vb), done_entry);
list_del(&vb->done_entry);
vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
}
spin_unlock_irq(&pd->lock);
msleep(45); /* irq hendler will stop the hardware */
return 0;
}
/* Locking: Caller holds q->vb_lock & q->irqlock */
static void
dt3155_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
dt3155_buf_queue(struct vb2_buffer *vb)
{
struct dt3155_priv *pd = q->priv_data;
struct dt3155_priv *pd = vb2_get_drv_priv(vb->vb2_queue);
if (vb->state != VIDEOBUF_NEEDS_INIT) {
vb->state = VIDEOBUF_QUEUED;
list_add_tail(&vb->queue, &pd->dmaq);
wake_up_interruptible_sync(&pd->do_dma);
} else
vb->state = VIDEOBUF_ERROR;
/* pd->q->streaming = 1 when dt3155_buf_queue() is invoked */
spin_lock_irq(&pd->lock);
if (pd->curr_buf)
list_add_tail(&vb->done_entry, &pd->dmaq);
else {
pd->curr_buf = vb;
dt3155_start_acq(pd);
}
spin_unlock_irq(&pd->lock);
}
/*
* end driver-specific callbacks
*/
/* Locking: Caller holds q->vb_lock */
static void
dt3155_buf_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
{
if (vb->state == VIDEOBUF_ACTIVE)
videobuf_waiton(q, vb, 0, 0); /* FIXME: cannot be interrupted */
videobuf_dma_contig_free(q, vb);
vb->state = VIDEOBUF_NEEDS_INIT;
}
static struct videobuf_queue_ops vbq_ops = {
.buf_setup = dt3155_buf_setup,
const struct vb2_ops q_ops = {
.queue_setup = dt3155_queue_setup,
.wait_prepare = dt3155_wait_prepare,
.wait_finish = dt3155_wait_finish,
.buf_prepare = dt3155_buf_prepare,
.start_streaming = dt3155_start_streaming,
.stop_streaming = dt3155_stop_streaming,
.buf_queue = dt3155_buf_queue,
.buf_release = dt3155_buf_release,
};
static irqreturn_t
dt3155_irq_handler_even(int irq, void *dev_id)
{
struct dt3155_priv *ipd = dev_id;
struct videobuf_buffer *ivb;
struct vb2_buffer *ivb;
dma_addr_t dma_addr;
u32 tmp;
@ -341,33 +362,22 @@ dt3155_irq_handler_even(int irq, void *dev_id)
}
spin_lock(&ipd->lock);
if (ipd->curr_buf && ipd->curr_buf->state == VIDEOBUF_ACTIVE) {
if (waitqueue_active(&ipd->curr_buf->done)) {
do_gettimeofday(&ipd->curr_buf->ts);
ipd->curr_buf->field_count = ipd->field_count;
ipd->curr_buf->state = VIDEOBUF_DONE;
wake_up(&ipd->curr_buf->done);
} else {
ivb = ipd->curr_buf;
goto load_dma;
}
} else
if (ipd->curr_buf) {
do_gettimeofday(&ipd->curr_buf->v4l2_buf.timestamp);
ipd->curr_buf->v4l2_buf.sequence = (ipd->field_count) >> 1;
vb2_buffer_done(ipd->curr_buf, VB2_BUF_STATE_DONE);
}
if (!ipd->q->streaming || list_empty(&ipd->dmaq))
goto stop_dma;
if (list_empty(&ipd->dmaq))
goto stop_dma;
ivb = list_first_entry(&ipd->dmaq, typeof(*ivb), queue);
list_del(&ivb->queue);
if (ivb->state == VIDEOBUF_QUEUED) {
ivb->state = VIDEOBUF_ACTIVE;
ipd->curr_buf = ivb;
} else
goto stop_dma;
load_dma:
dma_addr = videobuf_to_dma_contig(ivb);
ivb = list_first_entry(&ipd->dmaq, typeof(*ivb), done_entry);
list_del(&ivb->done_entry);
ipd->curr_buf = ivb;
dma_addr = vb2_dma_contig_plane_paddr(ivb, 0);
iowrite32(dma_addr, ipd->regs + EVEN_DMA_START);
iowrite32(dma_addr + ivb->width, ipd->regs + ODD_DMA_START);
iowrite32(ivb->width, ipd->regs + EVEN_DMA_STRIDE);
iowrite32(ivb->width, ipd->regs + ODD_DMA_STRIDE);
iowrite32(dma_addr + img_width, ipd->regs + ODD_DMA_START);
iowrite32(img_width, ipd->regs + EVEN_DMA_STRIDE);
iowrite32(img_width, ipd->regs + ODD_DMA_STRIDE);
mmiowb();
/* enable interrupts, clear all irq flags */
iowrite32(FLD_START_EN | FLD_END_ODD_EN | FLD_START |
@ -379,68 +389,40 @@ stop_dma:
ipd->curr_buf = NULL;
/* stop the board */
write_i2c_reg_nowait(ipd->regs, CSR2, ipd->csr2);
iowrite32(FIFO_EN | SRST | FLD_CRPT_ODD | FLD_CRPT_EVEN |
FLD_DN_ODD | FLD_DN_EVEN, ipd->regs + CSR1);
/* disable interrupts, clear all irq flags */
iowrite32(FLD_START | FLD_END_EVEN | FLD_END_ODD, ipd->regs + INT_CSR);
spin_unlock(&ipd->lock);
return IRQ_HANDLED;
}
static int
dt3155_threadfn(void *arg)
{
struct dt3155_priv *pd = arg;
struct videobuf_buffer *vb;
unsigned long flags;
while (1) {
wait_event_interruptible(pd->do_dma,
kthread_should_stop() || !list_empty(&pd->dmaq));
if (kthread_should_stop())
break;
spin_lock_irqsave(&pd->lock, flags);
if (pd->curr_buf) /* dma is active */
goto done;
if (list_empty(&pd->dmaq)) /* no empty biffers */
goto done;
vb = list_first_entry(&pd->dmaq, typeof(*vb), queue);
list_del(&vb->queue);
if (vb->state == VIDEOBUF_QUEUED) {
vb->state = VIDEOBUF_ACTIVE;
pd->curr_buf = vb;
spin_unlock_irqrestore(&pd->lock, flags);
/* start dma */
dt3155_start_acq(pd);
continue;
} else
printk(KERN_DEBUG "%s(): This is a BUG\n", __func__);
done:
spin_unlock_irqrestore(&pd->lock, flags);
}
return 0;
}
static int
dt3155_open(struct file *filp)
{
int ret = 0;
struct dt3155_priv *pd = video_drvdata(filp);
printk(KERN_INFO "dt3155: open(): minor: %i\n", pd->vdev->minor);
printk(KERN_INFO "dt3155: open(): minor: %i, users: %i\n",
pd->vdev->minor, pd->users);
if (mutex_lock_interruptible(&pd->mux) == -EINTR)
return -ERESTARTSYS;
if (!pd->users) {
pd->vidq = kzalloc(sizeof(*pd->vidq), GFP_KERNEL);
if (!pd->vidq) {
pd->q = kzalloc(sizeof(*pd->q), GFP_KERNEL);
if (!pd->q) {
printk(KERN_ERR "dt3155: error: alloc queue\n");
ret = -ENOMEM;
goto err_alloc_queue;
}
videobuf_queue_dma_contig_init(pd->vidq, &vbq_ops,
&pd->pdev->dev, &pd->lock,
V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE,
sizeof(struct videobuf_buffer), pd, NULL);
pd->q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
pd->q->io_modes = VB2_READ | VB2_MMAP;
pd->q->ops = &q_ops;
pd->q->mem_ops = &vb2_dma_contig_memops;
pd->q->drv_priv = pd;
pd->curr_buf = NULL;
pd->field_count = 0;
vb2_queue_init(pd->q); /* cannot fail */
INIT_LIST_HEAD(&pd->dmaq);
spin_lock_init(&pd->lock);
/* disable all irqs, clear all irq flags */
iowrite32(FLD_START | FLD_END_EVEN | FLD_END_ODD,
pd->regs + INT_CSR);
@ -451,26 +433,13 @@ dt3155_open(struct file *filp)
printk(KERN_ERR "dt3155: error: request_irq\n");
goto err_request_irq;
}
pd->curr_buf = NULL;
pd->thread = kthread_run(dt3155_threadfn, pd,
"dt3155_thread_%i", pd->vdev->minor);
if (IS_ERR(pd->thread)) {
printk(KERN_ERR "dt3155: kthread_run() failed\n");
ret = PTR_ERR(pd->thread);
goto err_thread;
}
pd->field_count = 0;
}
pd->users++;
goto done;
err_thread:
free_irq(pd->pdev->irq, pd);
return 0; /* success */
err_request_irq:
kfree(pd->vidq);
pd->vidq = NULL;
kfree(pd->q);
pd->q = NULL;
err_alloc_queue:
done:
mutex_unlock(&pd->mux);
return ret;
}
@ -478,61 +447,29 @@ static int
dt3155_release(struct file *filp)
{
struct dt3155_priv *pd = video_drvdata(filp);
struct videobuf_buffer *tmp;
unsigned long flags;
int ret = 0;
printk(KERN_INFO "dt3155: release(): minor: %i\n", pd->vdev->minor);
printk(KERN_INFO "dt3155: release(): minor: %i, users: %i\n",
pd->vdev->minor, pd->users - 1);
if (mutex_lock_interruptible(&pd->mux) == -EINTR)
return -ERESTARTSYS;
pd->users--;
BUG_ON(pd->users < 0);
if (pd->acq_fp == filp) {
spin_lock_irqsave(&pd->lock, flags);
INIT_LIST_HEAD(&pd->dmaq); /* queue is emptied */
tmp = pd->curr_buf;
spin_unlock_irqrestore(&pd->lock, flags);
if (tmp)
videobuf_waiton(pd->vidq, tmp, 0, 1); /* block, interruptible */
dt3155_stop_acq(pd);
videobuf_stop(pd->vidq);
pd->acq_fp = NULL;
pd->streaming = 0;
}
if (!pd->users) {
kthread_stop(pd->thread);
vb2_queue_release(pd->q);
free_irq(pd->pdev->irq, pd);
kfree(pd->vidq);
pd->vidq = NULL;
if (pd->q->alloc_ctx[0])
vb2_dma_contig_cleanup_ctx(pd->q->alloc_ctx[0]);
kfree(pd->q);
pd->q = NULL;
}
mutex_unlock(&pd->mux);
return ret;
return 0;
}
static ssize_t
dt3155_read(struct file *filp, char __user *user, size_t size, loff_t *loff)
{
struct dt3155_priv *pd = video_drvdata(filp);
int ret;
if (mutex_lock_interruptible(&pd->mux) == -EINTR)
return -ERESTARTSYS;
if (!pd->acq_fp) {
pd->acq_fp = filp;
pd->streaming = 0;
} else if (pd->acq_fp != filp) {
ret = -EBUSY;
goto done;
} else if (pd->streaming == 1) {
ret = -EINVAL;
goto done;
}
ret = videobuf_read_stream(pd->vidq, user, size, loff, 0,
filp->f_flags & O_NONBLOCK);
done:
mutex_unlock(&pd->mux);
return ret;
return vb2_read(pd->q, user, size, loff, filp->f_flags & O_NONBLOCK);
}
static unsigned int
@ -540,7 +477,7 @@ dt3155_poll(struct file *filp, struct poll_table_struct *polltbl)
{
struct dt3155_priv *pd = video_drvdata(filp);
return videobuf_poll_stream(filp, pd->vidq, polltbl);
return vb2_poll(pd->q, filp, polltbl);
}
static int
@ -548,7 +485,7 @@ dt3155_mmap(struct file *filp, struct vm_area_struct *vma)
{
struct dt3155_priv *pd = video_drvdata(filp);
return videobuf_mmap_mapper(pd->vidq, vma);
return vb2_mmap(pd->q, vma);
}
static const struct v4l2_file_operations dt3155_fops = {
@ -565,46 +502,16 @@ static int
dt3155_ioc_streamon(struct file *filp, void *p, enum v4l2_buf_type type)
{
struct dt3155_priv *pd = video_drvdata(filp);
int ret = -ERESTARTSYS;
if (mutex_lock_interruptible(&pd->mux) == -EINTR)
return ret;
if (!pd->acq_fp) {
ret = videobuf_streamon(pd->vidq);
if (ret)
goto unlock;
pd->acq_fp = filp;
pd->streaming = 1;
wake_up_interruptible_sync(&pd->do_dma);
} else if (pd->acq_fp == filp) {
pd->streaming = 1;
ret = videobuf_streamon(pd->vidq);
if (!ret)
wake_up_interruptible_sync(&pd->do_dma);
} else
ret = -EBUSY;
unlock:
mutex_unlock(&pd->mux);
return ret;
return vb2_streamon(pd->q, type);
}
static int
dt3155_ioc_streamoff(struct file *filp, void *p, enum v4l2_buf_type type)
{
struct dt3155_priv *pd = video_drvdata(filp);
struct videobuf_buffer *tmp;
unsigned long flags;
int ret;
ret = videobuf_streamoff(pd->vidq);
if (ret)
return ret;
spin_lock_irqsave(&pd->lock, flags);
tmp = pd->curr_buf;
spin_unlock_irqrestore(&pd->lock, flags);
if (tmp)
videobuf_waiton(pd->vidq, tmp, 0, 1); /* block, interruptible */
return ret;
return vb2_streamoff(pd->q, type);
}
static int
@ -618,8 +525,7 @@ dt3155_ioc_querycap(struct file *filp, void *p, struct v4l2_capability *cap)
cap->version =
KERNEL_VERSION(DT3155_VER_MAJ, DT3155_VER_MIN, DT3155_VER_EXT);
cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
V4L2_CAP_STREAMING |
V4L2_CAP_READWRITE;
DT3155_CAPTURE_METHOD;
return 0;
}
@ -667,93 +573,39 @@ dt3155_ioc_try_fmt_vid_cap(struct file *filp, void *p, struct v4l2_format *f)
static int
dt3155_ioc_s_fmt_vid_cap(struct file *filp, void *p, struct v4l2_format *f)
{
struct dt3155_priv *pd = video_drvdata(filp);
int ret = -ERESTARTSYS;
if (mutex_lock_interruptible(&pd->mux) == -EINTR)
return ret;
if (!pd->acq_fp) {
pd->acq_fp = filp;
pd->streaming = 0;
} else if (pd->acq_fp != filp) {
ret = -EBUSY;
goto done;
}
/* FIXME: we don't change the format for now
if (pd->vidq->streaming || pd->vidq->reading || pd->curr_buff) {
ret = -EBUSY;
goto done;
}
*/
ret = dt3155_ioc_g_fmt_vid_cap(filp, p, f);
done:
mutex_unlock(&pd->mux);
return ret;
return dt3155_ioc_g_fmt_vid_cap(filp, p, f);
}
static int
dt3155_ioc_reqbufs(struct file *filp, void *p, struct v4l2_requestbuffers *b)
{
struct dt3155_priv *pd = video_drvdata(filp);
struct videobuf_queue *q = pd->vidq;
int ret = -ERESTARTSYS;
if (b->memory != V4L2_MEMORY_MMAP)
return -EINVAL;
if (mutex_lock_interruptible(&pd->mux) == -EINTR)
return ret;
if (!pd->acq_fp)
pd->acq_fp = filp;
else if (pd->acq_fp != filp) {
ret = -EBUSY;
goto done;
}
pd->streaming = 1;
ret = 0;
done:
mutex_unlock(&pd->mux);
if (ret)
return ret;
if (b->count)
ret = videobuf_reqbufs(q, b);
else { /* FIXME: is it necessary? */
printk(KERN_DEBUG "dt3155: request to free buffers\n");
/* ret = videobuf_mmap_free(q); */
ret = dt3155_ioc_streamoff(filp, p,
V4L2_BUF_TYPE_VIDEO_CAPTURE);
}
return ret;
return vb2_reqbufs(pd->q, b);
}
static int
dt3155_ioc_querybuf(struct file *filp, void *p, struct v4l2_buffer *b)
{
struct dt3155_priv *pd = video_drvdata(filp);
struct videobuf_queue *q = pd->vidq;
return videobuf_querybuf(q, b);
return vb2_querybuf(pd->q, b);
}
static int
dt3155_ioc_qbuf(struct file *filp, void *p, struct v4l2_buffer *b)
{
struct dt3155_priv *pd = video_drvdata(filp);
struct videobuf_queue *q = pd->vidq;
int ret;
ret = videobuf_qbuf(q, b);
if (ret)
return ret;
return videobuf_querybuf(q, b);
return vb2_qbuf(pd->q, b);
}
static int
dt3155_ioc_dqbuf(struct file *filp, void *p, struct v4l2_buffer *b)
{
struct dt3155_priv *pd = video_drvdata(filp);
struct videobuf_queue *q = pd->vidq;
return videobuf_dqbuf(q, b, filp->f_flags & O_NONBLOCK);
return vb2_dqbuf(pd->q, b, filp->f_flags & O_NONBLOCK);
}
static int
@ -880,21 +732,21 @@ static const struct v4l2_ioctl_ops dt3155_ioctl_ops = {
};
static int __devinit
dt3155_init_board(struct pci_dev *dev)
dt3155_init_board(struct pci_dev *pdev)
{
struct dt3155_priv *pd = pci_get_drvdata(dev);
struct dt3155_priv *pd = pci_get_drvdata(pdev);
void *buf_cpu;
dma_addr_t buf_dma;
int i;
u8 tmp;
pci_set_master(dev); /* dt3155 needs it */
pci_set_master(pdev); /* dt3155 needs it */
/* resetting the adapter */
iowrite32(FLD_CRPT_ODD | FLD_CRPT_EVEN | FLD_DN_ODD | FLD_DN_EVEN,
pd->regs + CSR1);
mmiowb();
msleep(10);
msleep(20);
/* initializing adaper registers */
iowrite32(FIFO_EN | SRST, pd->regs + CSR1);
@ -949,7 +801,7 @@ dt3155_init_board(struct pci_dev *dev)
write_i2c_reg(pd->regs, AD_CMD, VIDEO_CNL_1 | SYNC_CNL_1 | SYNC_LVL_3);
/* allocate memory, and initialize the DMA machine */
buf_cpu = dma_alloc_coherent(&dev->dev, DT3155_BUF_SIZE, &buf_dma,
buf_cpu = dma_alloc_coherent(&pdev->dev, DT3155_BUF_SIZE, &buf_dma,
GFP_KERNEL);
if (!buf_cpu) {
printk(KERN_ERR "dt3155: dma_alloc_coherent "
@ -975,7 +827,7 @@ dt3155_init_board(struct pci_dev *dev)
iowrite32(FIFO_EN | SRST | FLD_DN_EVEN | FLD_DN_ODD, pd->regs + CSR1);
/* deallocate memory */
dma_free_coherent(&dev->dev, DT3155_BUF_SIZE, buf_cpu, buf_dma);
dma_free_coherent(&pdev->dev, DT3155_BUF_SIZE, buf_cpu, buf_dma);
if (tmp & BUSY_EVEN) {
printk(KERN_ERR "dt3155: BUSY_EVEN not cleared\n");
return -EIO;
@ -996,7 +848,7 @@ static struct video_device dt3155_vdev = {
/* same as in drivers/base/dma-coherent.c */
struct dma_coherent_mem {
void *virt_base;
u32 device_base;
dma_addr_t device_base;
int size;
int flags;
unsigned long *bitmap;
@ -1058,18 +910,18 @@ dt3155_free_coherent(struct device *dev)
}
static int __devinit
dt3155_probe(struct pci_dev *dev, const struct pci_device_id *id)
dt3155_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
int err;
struct dt3155_priv *pd;
printk(KERN_INFO "dt3155: probe()\n");
err = dma_set_mask(&dev->dev, DMA_BIT_MASK(32));
err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
if (err) {
printk(KERN_ERR "dt3155: cannot set dma_mask\n");
return -ENODEV;
}
err = dma_set_coherent_mask(&dev->dev, DMA_BIT_MASK(32));
err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
if (err) {
printk(KERN_ERR "dt3155: cannot set dma_coherent_mask\n");
return -ENODEV;
@ -1085,31 +937,31 @@ dt3155_probe(struct pci_dev *dev, const struct pci_device_id *id)
goto err_video_device_alloc;
}
*pd->vdev = dt3155_vdev;
pci_set_drvdata(dev, pd); /* for use in dt3155_remove() */
pci_set_drvdata(pdev, pd); /* for use in dt3155_remove() */
video_set_drvdata(pd->vdev, pd); /* for use in video_fops */
pd->users = 0;
pd->acq_fp = NULL;
pd->pdev = dev;
pd->pdev = pdev;
INIT_LIST_HEAD(&pd->dmaq);
init_waitqueue_head(&pd->do_dma);
mutex_init(&pd->mux);
pd->vdev->lock = &pd->mux; /* for locking v4l2_file_operations */
spin_lock_init(&pd->lock);
pd->csr2 = csr2_init;
pd->config = config_init;
err = pci_enable_device(pd->pdev);
err = pci_enable_device(pdev);
if (err) {
printk(KERN_ERR "dt3155: pci_dev not enabled\n");
goto err_enable_dev;
}
err = pci_request_region(pd->pdev, 0, pci_name(pd->pdev));
err = pci_request_region(pdev, 0, pci_name(pdev));
if (err)
goto err_req_region;
pd->regs = pci_iomap(pd->pdev, 0, pci_resource_len(pd->pdev, 0));
pd->regs = pci_iomap(pdev, 0, pci_resource_len(pd->pdev, 0));
if (!pd->regs) {
err = -ENOMEM;
printk(KERN_ERR "dt3155: pci_iomap failed\n");
goto err_pci_iomap;
}
err = dt3155_init_board(pd->pdev);
err = dt3155_init_board(pdev);
if (err) {
printk(KERN_ERR "dt3155: dt3155_init_board failed\n");
goto err_init_board;
@ -1119,7 +971,7 @@ dt3155_probe(struct pci_dev *dev, const struct pci_device_id *id)
printk(KERN_ERR "dt3155: Cannot register video device\n");
goto err_init_board;
}
err = dt3155_alloc_coherent(&dev->dev, DT3155_CHUNK_SIZE,
err = dt3155_alloc_coherent(&pdev->dev, DT3155_CHUNK_SIZE,
DMA_MEMORY_MAP);
if (err)
printk(KERN_INFO "dt3155: preallocated 8 buffers\n");
@ -1127,11 +979,11 @@ dt3155_probe(struct pci_dev *dev, const struct pci_device_id *id)
return 0; /* success */
err_init_board:
pci_iounmap(pd->pdev, pd->regs);
pci_iounmap(pdev, pd->regs);
err_pci_iomap:
pci_release_region(pd->pdev, 0);
pci_release_region(pdev, 0);
err_req_region:
pci_disable_device(pd->pdev);
pci_disable_device(pdev);
err_enable_dev:
video_device_release(pd->vdev);
err_video_device_alloc:
@ -1140,16 +992,16 @@ err_video_device_alloc:
}
static void __devexit
dt3155_remove(struct pci_dev *dev)
dt3155_remove(struct pci_dev *pdev)
{
struct dt3155_priv *pd = pci_get_drvdata(dev);
struct dt3155_priv *pd = pci_get_drvdata(pdev);
printk(KERN_INFO "dt3155: remove()\n");
dt3155_free_coherent(&dev->dev);
dt3155_free_coherent(&pdev->dev);
video_unregister_device(pd->vdev);
pci_iounmap(dev, pd->regs);
pci_release_region(pd->pdev, 0);
pci_disable_device(pd->pdev);
pci_iounmap(pdev, pd->regs);
pci_release_region(pdev, 0);
pci_disable_device(pdev);
/*
* video_device_release() is invoked automatically
* see: struct video_device dt3155_vdev

View File

@ -179,18 +179,13 @@ struct dt3155_stats {
* struct dt3155_priv - private data structure
*
* @vdev: pointer to video_device structure
* @acq_fp pointer to filp that starts acquisition
* @streaming streaming is negotiated
* @pdev: pointer to pci_dev structure
* @vidq pointer to videobuf_queue structure
* @q pointer to vb2_queue structure
* @curr_buf: pointer to curren buffer
* @thread pointer to worker thraed
* @irq_handler: irq handler for the driver
* @qt_ops local copy of dma-contig qtype_ops
* @dmaq queue for dma buffers
* @do_dma wait queue of the kernel thread
* @mux: mutex to protect the instance
* @lock spinlock for videobuf queues
* @irq_handler: irq handler for the driver
* @dmaq queue for dma buffers
* @lock spinlock for dma queue
* @field_count fields counter
* @stats: statistics structure
* @users open count
@ -200,17 +195,12 @@ struct dt3155_stats {
*/
struct dt3155_priv {
struct video_device *vdev;
struct file *acq_fp;
int streaming;
struct pci_dev *pdev;
struct videobuf_queue *vidq;
struct videobuf_buffer *curr_buf;
struct task_struct *thread;
irq_handler_t irq_handler;
struct videobuf_qtype_ops qt_ops;
struct list_head dmaq;
wait_queue_head_t do_dma;
struct vb2_queue *q;
struct vb2_buffer *curr_buf;
struct mutex mux;
irq_handler_t irq_handler;
struct list_head dmaq;
spinlock_t lock;
unsigned int field_count;
struct dt3155_stats stats;