diff options
Diffstat (limited to 'drivers/media/platform/soc_camera')
-rw-r--r-- | drivers/media/platform/soc_camera/atmel-isi.c | 12 | ||||
-rw-r--r-- | drivers/media/platform/soc_camera/mx2_camera.c | 3 | ||||
-rw-r--r-- | drivers/media/platform/soc_camera/mx3_camera.c | 10 | ||||
-rw-r--r-- | drivers/media/platform/soc_camera/omap1_camera.c | 3 | ||||
-rw-r--r-- | drivers/media/platform/soc_camera/pxa_camera.c | 3 | ||||
-rw-r--r-- | drivers/media/platform/soc_camera/rcar_vin.c | 98 | ||||
-rw-r--r-- | drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c | 11 | ||||
-rw-r--r-- | drivers/media/platform/soc_camera/soc_camera.c | 18 |
8 files changed, 69 insertions, 89 deletions
diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index 8efe4033760..8526bf5c842 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -455,8 +455,8 @@ static struct vb2_ops isi_video_qops = { .buf_queue = buffer_queue, .start_streaming = start_streaming, .stop_streaming = stop_streaming, - .wait_prepare = soc_camera_unlock, - .wait_finish = soc_camera_lock, + .wait_prepare = vb2_ops_wait_prepare, + .wait_finish = vb2_ops_wait_finish, }; /* ------------------------------------------------------------------ @@ -465,6 +465,8 @@ static struct vb2_ops isi_video_qops = { static int isi_camera_init_videobuf(struct vb2_queue *q, struct soc_camera_device *icd) { + struct soc_camera_host *ici = to_soc_camera_host(icd->parent); + q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; q->io_modes = VB2_MMAP; q->drv_priv = icd; @@ -472,6 +474,7 @@ static int isi_camera_init_videobuf(struct vb2_queue *q, q->ops = &isi_video_qops; q->mem_ops = &vb2_dma_contig_memops; q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; + q->lock = &ici->host_lock; return vb2_queue_init(q); } @@ -760,8 +763,9 @@ static int isi_camera_querycap(struct soc_camera_host *ici, { strcpy(cap->driver, "atmel-isi"); strcpy(cap->card, "Atmel Image Sensor Interface"); - cap->capabilities = (V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_STREAMING); + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; + return 0; } diff --git a/drivers/media/platform/soc_camera/mx2_camera.c b/drivers/media/platform/soc_camera/mx2_camera.c index ce72bd26a6a..192377f5584 100644 --- a/drivers/media/platform/soc_camera/mx2_camera.c +++ b/drivers/media/platform/soc_camera/mx2_camera.c @@ -1256,7 +1256,8 @@ static int mx2_camera_querycap(struct soc_camera_host *ici, { /* cap->name is set by the friendly caller:-> */ strlcpy(cap->card, MX2_CAM_DRIVER_DESCRIPTION, sizeof(cap->card)); - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; return 0; } diff --git a/drivers/media/platform/soc_camera/mx3_camera.c b/drivers/media/platform/soc_camera/mx3_camera.c index a60c3bb0e4c..3435fd2ca8e 100644 --- a/drivers/media/platform/soc_camera/mx3_camera.c +++ b/drivers/media/platform/soc_camera/mx3_camera.c @@ -435,14 +435,16 @@ static struct vb2_ops mx3_videobuf_ops = { .buf_queue = mx3_videobuf_queue, .buf_cleanup = mx3_videobuf_release, .buf_init = mx3_videobuf_init, - .wait_prepare = soc_camera_unlock, - .wait_finish = soc_camera_lock, + .wait_prepare = vb2_ops_wait_prepare, + .wait_finish = vb2_ops_wait_finish, .stop_streaming = mx3_stop_streaming, }; static int mx3_camera_init_videobuf(struct vb2_queue *q, struct soc_camera_device *icd) { + struct soc_camera_host *ici = to_soc_camera_host(icd->parent); + q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; q->io_modes = VB2_MMAP | VB2_USERPTR; q->drv_priv = icd; @@ -450,6 +452,7 @@ static int mx3_camera_init_videobuf(struct vb2_queue *q, q->mem_ops = &vb2_dma_contig_memops; q->buf_struct_size = sizeof(struct mx3_camera_buffer); q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; + q->lock = &ici->host_lock; return vb2_queue_init(q); } @@ -967,7 +970,8 @@ static int mx3_camera_querycap(struct soc_camera_host *ici, { /* cap->name is set by the firendly caller:-> */ strlcpy(cap->card, "i.MX3x Camera", sizeof(cap->card)); - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; return 0; } diff --git a/drivers/media/platform/soc_camera/omap1_camera.c b/drivers/media/platform/soc_camera/omap1_camera.c index e6b93281f24..16f65ecb70a 100644 --- a/drivers/media/platform/soc_camera/omap1_camera.c +++ b/drivers/media/platform/soc_camera/omap1_camera.c @@ -1427,7 +1427,8 @@ static int omap1_cam_querycap(struct soc_camera_host *ici, { /* cap->name is set by the friendly caller:-> */ strlcpy(cap->card, "OMAP1 Camera", sizeof(cap->card)); - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; return 0; } diff --git a/drivers/media/platform/soc_camera/pxa_camera.c b/drivers/media/platform/soc_camera/pxa_camera.c index 951226af0eb..8d6e343fec0 100644 --- a/drivers/media/platform/soc_camera/pxa_camera.c +++ b/drivers/media/platform/soc_camera/pxa_camera.c @@ -1576,7 +1576,8 @@ static int pxa_camera_querycap(struct soc_camera_host *ici, { /* cap->name is set by the firendly caller:-> */ strlcpy(cap->card, pxa_cam_driver_description, sizeof(cap->card)); - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; return 0; } diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c index 0c1f5564810..279ab9f6ae3 100644 --- a/drivers/media/platform/soc_camera/rcar_vin.c +++ b/drivers/media/platform/soc_camera/rcar_vin.c @@ -804,62 +804,26 @@ error: vb2_buffer_done(vb, VB2_BUF_STATE_ERROR); } -static void rcar_vin_videobuf_release(struct vb2_buffer *vb) +/* + * Wait for capture to stop and all in-flight buffers to be finished with by + * the video hardware. This must be called under &priv->lock + * + */ +static void rcar_vin_wait_stop_streaming(struct rcar_vin_priv *priv) { - struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue); - struct soc_camera_host *ici = to_soc_camera_host(icd->parent); - struct rcar_vin_priv *priv = ici->priv; - unsigned int i; - int buf_in_use = 0; - - spin_lock_irq(&priv->lock); - - /* Is the buffer in use by the VIN hardware? */ - for (i = 0; i < MAX_BUFFER_NUM; i++) { - if (priv->queue_buf[i] == vb) { - buf_in_use = 1; - break; - } - } - - if (buf_in_use) { - while (priv->state != STOPPED) { - - /* issue stop if running */ - if (priv->state == RUNNING) - rcar_vin_request_capture_stop(priv); + while (priv->state != STOPPED) { + /* issue stop if running */ + if (priv->state == RUNNING) + rcar_vin_request_capture_stop(priv); - /* wait until capturing has been stopped */ - if (priv->state == STOPPING) { - priv->request_to_stop = true; - spin_unlock_irq(&priv->lock); - wait_for_completion(&priv->capture_stop); - spin_lock_irq(&priv->lock); - } - } - /* - * Capturing has now stopped. The buffer we have been asked - * to release could be any of the current buffers in use, so - * release all buffers that are in use by HW - */ - for (i = 0; i < MAX_BUFFER_NUM; i++) { - if (priv->queue_buf[i]) { - vb2_buffer_done(priv->queue_buf[i], - VB2_BUF_STATE_ERROR); - priv->queue_buf[i] = NULL; - } + /* wait until capturing has been stopped */ + if (priv->state == STOPPING) { + priv->request_to_stop = true; + spin_unlock_irq(&priv->lock); + wait_for_completion(&priv->capture_stop); + spin_lock_irq(&priv->lock); } - } else { - list_del_init(to_buf_list(vb)); } - - spin_unlock_irq(&priv->lock); -} - -static int rcar_vin_videobuf_init(struct vb2_buffer *vb) -{ - INIT_LIST_HEAD(to_buf_list(vb)); - return 0; } static void rcar_vin_stop_streaming(struct vb2_queue *vq) @@ -868,21 +832,34 @@ static void rcar_vin_stop_streaming(struct vb2_queue *vq) struct soc_camera_host *ici = to_soc_camera_host(icd->parent); struct rcar_vin_priv *priv = ici->priv; struct list_head *buf_head, *tmp; + int i; spin_lock_irq(&priv->lock); - list_for_each_safe(buf_head, tmp, &priv->capture) + rcar_vin_wait_stop_streaming(priv); + + for (i = 0; i < MAX_BUFFER_NUM; i++) { + if (priv->queue_buf[i]) { + vb2_buffer_done(priv->queue_buf[i], + VB2_BUF_STATE_ERROR); + priv->queue_buf[i] = NULL; + } + } + + list_for_each_safe(buf_head, tmp, &priv->capture) { + vb2_buffer_done(&list_entry(buf_head, + struct rcar_vin_buffer, list)->vb, + VB2_BUF_STATE_ERROR); list_del_init(buf_head); + } spin_unlock_irq(&priv->lock); } static struct vb2_ops rcar_vin_vb2_ops = { .queue_setup = rcar_vin_videobuf_setup, - .buf_init = rcar_vin_videobuf_init, - .buf_cleanup = rcar_vin_videobuf_release, .buf_queue = rcar_vin_videobuf_queue, .stop_streaming = rcar_vin_stop_streaming, - .wait_prepare = soc_camera_unlock, - .wait_finish = soc_camera_lock, + .wait_prepare = vb2_ops_wait_prepare, + .wait_finish = vb2_ops_wait_finish, }; static irqreturn_t rcar_vin_irq(int irq, void *data) @@ -1799,13 +1776,17 @@ static int rcar_vin_querycap(struct soc_camera_host *ici, struct v4l2_capability *cap) { strlcpy(cap->card, "R_Car_VIN", sizeof(cap->card)); - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; + return 0; } static int rcar_vin_init_videobuf2(struct vb2_queue *vq, struct soc_camera_device *icd) { + struct soc_camera_host *ici = to_soc_camera_host(icd->parent); + vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; vq->io_modes = VB2_MMAP | VB2_USERPTR; vq->drv_priv = icd; @@ -1813,6 +1794,7 @@ static int rcar_vin_init_videobuf2(struct vb2_queue *vq, vq->mem_ops = &vb2_dma_contig_memops; vq->buf_struct_size = sizeof(struct rcar_vin_buffer); vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; + vq->lock = &ici->host_lock; return vb2_queue_init(vq); } diff --git a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c index 8b27b3eb2b2..9ce202f5393 100644 --- a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c +++ b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c @@ -496,8 +496,8 @@ static struct vb2_ops sh_mobile_ceu_videobuf_ops = { .buf_queue = sh_mobile_ceu_videobuf_queue, .buf_cleanup = sh_mobile_ceu_videobuf_release, .buf_init = sh_mobile_ceu_videobuf_init, - .wait_prepare = soc_camera_unlock, - .wait_finish = soc_camera_lock, + .wait_prepare = vb2_ops_wait_prepare, + .wait_finish = vb2_ops_wait_finish, .stop_streaming = sh_mobile_ceu_stop_streaming, }; @@ -1652,13 +1652,17 @@ static int sh_mobile_ceu_querycap(struct soc_camera_host *ici, struct v4l2_capability *cap) { strlcpy(cap->card, "SuperH_Mobile_CEU", sizeof(cap->card)); - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; + return 0; } static int sh_mobile_ceu_init_videobuf(struct vb2_queue *q, struct soc_camera_device *icd) { + struct soc_camera_host *ici = to_soc_camera_host(icd->parent); + q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; q->io_modes = VB2_MMAP | VB2_USERPTR; q->drv_priv = icd; @@ -1666,6 +1670,7 @@ static int sh_mobile_ceu_init_videobuf(struct vb2_queue *q, q->mem_ops = &vb2_dma_contig_memops; q->buf_struct_size = sizeof(struct sh_mobile_ceu_buffer); q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; + q->lock = &ici->host_lock; return vb2_queue_init(q); } diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c index b3db51c82bd..cee7b56f840 100644 --- a/drivers/media/platform/soc_camera/soc_camera.c +++ b/drivers/media/platform/soc_camera/soc_camera.c @@ -843,22 +843,6 @@ static unsigned int soc_camera_poll(struct file *file, poll_table *pt) return res; } -void soc_camera_lock(struct vb2_queue *vq) -{ - struct soc_camera_device *icd = vb2_get_drv_priv(vq); - struct soc_camera_host *ici = to_soc_camera_host(icd->parent); - mutex_lock(&ici->host_lock); -} -EXPORT_SYMBOL(soc_camera_lock); - -void soc_camera_unlock(struct vb2_queue *vq) -{ - struct soc_camera_device *icd = vb2_get_drv_priv(vq); - struct soc_camera_host *ici = to_soc_camera_host(icd->parent); - mutex_unlock(&ici->host_lock); -} -EXPORT_SYMBOL(soc_camera_unlock); - static struct v4l2_file_operations soc_camera_fops = { .owner = THIS_MODULE, .open = soc_camera_open, @@ -1813,8 +1797,6 @@ eadddev: mutex_unlock(&ici->clk_lock); } eadd: - video_device_release(icd->vdev); - icd->vdev = NULL; if (icd->vdev) { video_device_release(icd->vdev); icd->vdev = NULL; |