diff options
Diffstat (limited to 'drivers/media/platform/davinci')
-rw-r--r-- | drivers/media/platform/davinci/Kconfig | 2 | ||||
-rw-r--r-- | drivers/media/platform/davinci/dm355_ccdc.c | 8 | ||||
-rw-r--r-- | drivers/media/platform/davinci/dm644x_ccdc.c | 16 | ||||
-rw-r--r-- | drivers/media/platform/davinci/isif.c | 5 | ||||
-rw-r--r-- | drivers/media/platform/davinci/vpbe.c | 10 | ||||
-rw-r--r-- | drivers/media/platform/davinci/vpbe_display.c | 303 | ||||
-rw-r--r-- | drivers/media/platform/davinci/vpbe_osd.c | 9 | ||||
-rw-r--r-- | drivers/media/platform/davinci/vpif.c | 8 | ||||
-rw-r--r-- | drivers/media/platform/davinci/vpif_capture.c | 34 | ||||
-rw-r--r-- | drivers/media/platform/davinci/vpif_display.c | 28 |
10 files changed, 267 insertions, 156 deletions
diff --git a/drivers/media/platform/davinci/Kconfig b/drivers/media/platform/davinci/Kconfig index 78e26d24f637..3c56037c82fc 100644 --- a/drivers/media/platform/davinci/Kconfig +++ b/drivers/media/platform/davinci/Kconfig @@ -101,7 +101,7 @@ config VIDEO_DM644X_VPBE tristate "DM644X VPBE HW module" depends on ARCH_DAVINCI_DM644x select VIDEO_VPSS_SYSTEM - select VIDEOBUF_DMA_CONTIG + select VIDEOBUF2_DMA_CONTIG help Enables VPBE modules used for display on a DM644x SoC. diff --git a/drivers/media/platform/davinci/dm355_ccdc.c b/drivers/media/platform/davinci/dm355_ccdc.c index ce0e4131c067..030950dcfb16 100644 --- a/drivers/media/platform/davinci/dm355_ccdc.c +++ b/drivers/media/platform/davinci/dm355_ccdc.c @@ -1003,7 +1003,7 @@ static int __devinit dm355_ccdc_probe(struct platform_device *pdev) status = PTR_ERR(ccdc_cfg.mclk); goto fail_nomap; } - if (clk_enable(ccdc_cfg.mclk)) { + if (clk_prepare_enable(ccdc_cfg.mclk)) { status = -ENODEV; goto fail_mclk; } @@ -1014,7 +1014,7 @@ static int __devinit dm355_ccdc_probe(struct platform_device *pdev) status = PTR_ERR(ccdc_cfg.sclk); goto fail_mclk; } - if (clk_enable(ccdc_cfg.sclk)) { + if (clk_prepare_enable(ccdc_cfg.sclk)) { status = -ENODEV; goto fail_sclk; } @@ -1034,8 +1034,10 @@ static int __devinit dm355_ccdc_probe(struct platform_device *pdev) printk(KERN_NOTICE "%s is registered with vpfe.\n", ccdc_hw_dev.name); return 0; fail_sclk: + clk_disable_unprepare(ccdc_cfg.sclk); clk_put(ccdc_cfg.sclk); fail_mclk: + clk_disable_unprepare(ccdc_cfg.mclk); clk_put(ccdc_cfg.mclk); fail_nomap: iounmap(ccdc_cfg.base_addr); @@ -1050,6 +1052,8 @@ static int dm355_ccdc_remove(struct platform_device *pdev) { struct resource *res; + clk_disable_unprepare(ccdc_cfg.sclk); + clk_disable_unprepare(ccdc_cfg.mclk); clk_put(ccdc_cfg.mclk); clk_put(ccdc_cfg.sclk); iounmap(ccdc_cfg.base_addr); diff --git a/drivers/media/platform/davinci/dm644x_ccdc.c b/drivers/media/platform/davinci/dm644x_ccdc.c index ee7942b1996e..0215ab6ebc90 100644 --- a/drivers/media/platform/davinci/dm644x_ccdc.c +++ b/drivers/media/platform/davinci/dm644x_ccdc.c @@ -994,7 +994,7 @@ static int __devinit dm644x_ccdc_probe(struct platform_device *pdev) status = PTR_ERR(ccdc_cfg.mclk); goto fail_nomap; } - if (clk_enable(ccdc_cfg.mclk)) { + if (clk_prepare_enable(ccdc_cfg.mclk)) { status = -ENODEV; goto fail_mclk; } @@ -1005,7 +1005,7 @@ static int __devinit dm644x_ccdc_probe(struct platform_device *pdev) status = PTR_ERR(ccdc_cfg.sclk); goto fail_mclk; } - if (clk_enable(ccdc_cfg.sclk)) { + if (clk_prepare_enable(ccdc_cfg.sclk)) { status = -ENODEV; goto fail_sclk; } @@ -1013,8 +1013,10 @@ static int __devinit dm644x_ccdc_probe(struct platform_device *pdev) printk(KERN_NOTICE "%s is registered with vpfe.\n", ccdc_hw_dev.name); return 0; fail_sclk: + clk_disable_unprepare(ccdc_cfg.sclk); clk_put(ccdc_cfg.sclk); fail_mclk: + clk_disable_unprepare(ccdc_cfg.mclk); clk_put(ccdc_cfg.mclk); fail_nomap: iounmap(ccdc_cfg.base_addr); @@ -1029,6 +1031,8 @@ static int dm644x_ccdc_remove(struct platform_device *pdev) { struct resource *res; + clk_disable_unprepare(ccdc_cfg.mclk); + clk_disable_unprepare(ccdc_cfg.sclk); clk_put(ccdc_cfg.mclk); clk_put(ccdc_cfg.sclk); iounmap(ccdc_cfg.base_addr); @@ -1046,8 +1050,8 @@ static int dm644x_ccdc_suspend(struct device *dev) /* Disable CCDC */ ccdc_enable(0); /* Disable both master and slave clock */ - clk_disable(ccdc_cfg.mclk); - clk_disable(ccdc_cfg.sclk); + clk_disable_unprepare(ccdc_cfg.mclk); + clk_disable_unprepare(ccdc_cfg.sclk); return 0; } @@ -1055,8 +1059,8 @@ static int dm644x_ccdc_suspend(struct device *dev) static int dm644x_ccdc_resume(struct device *dev) { /* Enable both master and slave clock */ - clk_enable(ccdc_cfg.mclk); - clk_enable(ccdc_cfg.sclk); + clk_prepare_enable(ccdc_cfg.mclk); + clk_prepare_enable(ccdc_cfg.sclk); /* Restore CCDC context */ ccdc_restore_context(); diff --git a/drivers/media/platform/davinci/isif.c b/drivers/media/platform/davinci/isif.c index b99d5423e3a8..2c26c3e1837e 100644 --- a/drivers/media/platform/davinci/isif.c +++ b/drivers/media/platform/davinci/isif.c @@ -1053,7 +1053,7 @@ static int __devinit isif_probe(struct platform_device *pdev) status = PTR_ERR(isif_cfg.mclk); goto fail_mclk; } - if (clk_enable(isif_cfg.mclk)) { + if (clk_prepare_enable(isif_cfg.mclk)) { status = -ENODEV; goto fail_mclk; } @@ -1125,6 +1125,7 @@ fail_nobase_res: i--; } fail_mclk: + clk_disable_unprepare(isif_cfg.mclk); clk_put(isif_cfg.mclk); vpfe_unregister_ccdc_device(&isif_hw_dev); return status; @@ -1145,6 +1146,8 @@ static int isif_remove(struct platform_device *pdev) i++; } vpfe_unregister_ccdc_device(&isif_hw_dev); + clk_disable_unprepare(isif_cfg.mclk); + clk_put(isif_cfg.mclk); return 0; } diff --git a/drivers/media/platform/davinci/vpbe.c b/drivers/media/platform/davinci/vpbe.c index 69d7a58c92c3..7f5cf9b347b2 100644 --- a/drivers/media/platform/davinci/vpbe.c +++ b/drivers/media/platform/davinci/vpbe.c @@ -612,7 +612,7 @@ static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev) ret = PTR_ERR(vpbe_dev->dac_clk); goto fail_mutex_unlock; } - if (clk_enable(vpbe_dev->dac_clk)) { + if (clk_prepare_enable(vpbe_dev->dac_clk)) { ret = -ENODEV; goto fail_mutex_unlock; } @@ -759,8 +759,10 @@ fail_kfree_encoders: fail_dev_unregister: v4l2_device_unregister(&vpbe_dev->v4l2_dev); fail_clk_put: - if (strcmp(vpbe_dev->cfg->module_name, "dm644x-vpbe-display") != 0) + if (strcmp(vpbe_dev->cfg->module_name, "dm644x-vpbe-display") != 0) { + clk_disable_unprepare(vpbe_dev->dac_clk); clk_put(vpbe_dev->dac_clk); + } fail_mutex_unlock: mutex_unlock(&vpbe_dev->lock); return ret; @@ -777,8 +779,10 @@ fail_mutex_unlock: static void vpbe_deinitialize(struct device *dev, struct vpbe_device *vpbe_dev) { v4l2_device_unregister(&vpbe_dev->v4l2_dev); - if (strcmp(vpbe_dev->cfg->module_name, "dm644x-vpbe-display") != 0) + if (strcmp(vpbe_dev->cfg->module_name, "dm644x-vpbe-display") != 0) { + clk_disable_unprepare(vpbe_dev->dac_clk); clk_put(vpbe_dev->dac_clk); + } kfree(vpbe_dev->amp); kfree(vpbe_dev->encoders); diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c index 161c77650e2f..2bfde7958fef 100644 --- a/drivers/media/platform/davinci/vpbe_display.c +++ b/drivers/media/platform/davinci/vpbe_display.c @@ -47,6 +47,9 @@ static int debug; module_param(debug, int, 0644); +static int vpbe_set_osd_display_params(struct vpbe_display *disp_dev, + struct vpbe_layer *layer); + static int venc_is_second_field(struct vpbe_display *disp_dev) { struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev; @@ -73,10 +76,11 @@ static void vpbe_isr_even_field(struct vpbe_display *disp_obj, if (layer->cur_frm == layer->next_frm) return; ktime_get_ts(&timevalue); - layer->cur_frm->ts.tv_sec = timevalue.tv_sec; - layer->cur_frm->ts.tv_usec = timevalue.tv_nsec / NSEC_PER_USEC; - layer->cur_frm->state = VIDEOBUF_DONE; - wake_up_interruptible(&layer->cur_frm->done); + layer->cur_frm->vb.v4l2_buf.timestamp.tv_sec = + timevalue.tv_sec; + layer->cur_frm->vb.v4l2_buf.timestamp.tv_usec = + timevalue.tv_nsec / NSEC_PER_USEC; + vb2_buffer_done(&layer->cur_frm->vb, VB2_BUF_STATE_DONE); /* Make cur_frm pointing to next_frm */ layer->cur_frm = layer->next_frm; } @@ -99,16 +103,14 @@ static void vpbe_isr_odd_field(struct vpbe_display *disp_obj, * otherwise hold on current frame * Get next from the buffer queue */ - layer->next_frm = list_entry( - layer->dma_queue.next, - struct videobuf_buffer, - queue); + layer->next_frm = list_entry(layer->dma_queue.next, + struct vpbe_disp_buffer, list); /* Remove that from the buffer queue */ - list_del(&layer->next_frm->queue); + list_del(&layer->next_frm->list); spin_unlock(&disp_obj->dma_queue_lock); /* Mark state of the frame to active */ - layer->next_frm->state = VIDEOBUF_ACTIVE; - addr = videobuf_to_dma_contig(layer->next_frm); + layer->next_frm->vb.state = VB2_BUF_STATE_ACTIVE; + addr = vb2_dma_contig_plane_dma_addr(&layer->next_frm->vb, 0); osd_device->ops.start_layer(osd_device, layer->layer_info.id, addr, @@ -199,39 +201,29 @@ static irqreturn_t venc_isr(int irq, void *arg) /* * vpbe_buffer_prepare() - * This is the callback function called from videobuf_qbuf() function + * This is the callback function called from vb2_qbuf() function * the buffer is prepared and user space virtual address is converted into * physical address */ -static int vpbe_buffer_prepare(struct videobuf_queue *q, - struct videobuf_buffer *vb, - enum v4l2_field field) +static int vpbe_buffer_prepare(struct vb2_buffer *vb) { - struct vpbe_fh *fh = q->priv_data; + struct vpbe_fh *fh = vb2_get_drv_priv(vb->vb2_queue); + struct vb2_queue *q = vb->vb2_queue; struct vpbe_layer *layer = fh->layer; struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev; unsigned long addr; - int ret; v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_buffer_prepare\n"); - /* If buffer is not initialized, initialize it */ - if (VIDEOBUF_NEEDS_INIT == vb->state) { - vb->width = layer->pix_fmt.width; - vb->height = layer->pix_fmt.height; - vb->size = layer->pix_fmt.sizeimage; - vb->field = field; - - ret = videobuf_iolock(q, vb, NULL); - if (ret < 0) { - v4l2_err(&vpbe_dev->v4l2_dev, "Failed to map \ - user address\n"); + if (vb->state != VB2_BUF_STATE_ACTIVE && + vb->state != VB2_BUF_STATE_PREPARED) { + vb2_set_plane_payload(vb, 0, layer->pix_fmt.sizeimage); + if (vb2_plane_vaddr(vb, 0) && + vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0)) return -EINVAL; - } - - addr = videobuf_to_dma_contig(vb); + addr = vb2_dma_contig_plane_dma_addr(vb, 0); if (q->streaming) { if (!IS_ALIGNED(addr, 8)) { v4l2_err(&vpbe_dev->v4l2_dev, @@ -240,7 +232,6 @@ static int vpbe_buffer_prepare(struct videobuf_queue *q, return -EINVAL; } } - vb->state = VIDEOBUF_PREPARED; } return 0; } @@ -249,22 +240,26 @@ static int vpbe_buffer_prepare(struct videobuf_queue *q, * vpbe_buffer_setup() * This function allocates memory for the buffers */ -static int vpbe_buffer_setup(struct videobuf_queue *q, - unsigned int *count, - unsigned int *size) +static int +vpbe_buffer_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, + unsigned int *nbuffers, unsigned int *nplanes, + unsigned int sizes[], void *alloc_ctxs[]) + { /* Get the file handle object and layer object */ - struct vpbe_fh *fh = q->priv_data; + struct vpbe_fh *fh = vb2_get_drv_priv(vq); struct vpbe_layer *layer = fh->layer; struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev; v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_buffer_setup\n"); - *size = layer->pix_fmt.sizeimage; - /* Store number of buffers allocated in numbuffer member */ - if (*count < VPBE_DEFAULT_NUM_BUFS) - *count = layer->numbuffers = VPBE_DEFAULT_NUM_BUFS; + if (*nbuffers < VPBE_DEFAULT_NUM_BUFS) + *nbuffers = layer->numbuffers = VPBE_DEFAULT_NUM_BUFS; + + *nplanes = 1; + sizes[0] = layer->pix_fmt.sizeimage; + alloc_ctxs[0] = layer->alloc_ctx; return 0; } @@ -273,11 +268,12 @@ static int vpbe_buffer_setup(struct videobuf_queue *q, * vpbe_buffer_queue() * This function adds the buffer to DMA queue */ -static void vpbe_buffer_queue(struct videobuf_queue *q, - struct videobuf_buffer *vb) +static void vpbe_buffer_queue(struct vb2_buffer *vb) { /* Get the file handle object and layer object */ - struct vpbe_fh *fh = q->priv_data; + struct vpbe_fh *fh = vb2_get_drv_priv(vb->vb2_queue); + struct vpbe_disp_buffer *buf = container_of(vb, + struct vpbe_disp_buffer, vb); struct vpbe_layer *layer = fh->layer; struct vpbe_display *disp = fh->disp_dev; struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev; @@ -288,39 +284,125 @@ static void vpbe_buffer_queue(struct videobuf_queue *q, /* add the buffer to the DMA queue */ spin_lock_irqsave(&disp->dma_queue_lock, flags); - list_add_tail(&vb->queue, &layer->dma_queue); + list_add_tail(&buf->list, &layer->dma_queue); spin_unlock_irqrestore(&disp->dma_queue_lock, flags); - /* Change state of the buffer */ - vb->state = VIDEOBUF_QUEUED; } /* - * vpbe_buffer_release() - * This function is called from the videobuf layer to free memory allocated to + * vpbe_buf_cleanup() + * This function is called from the vb2 layer to free memory allocated to * the buffers */ -static void vpbe_buffer_release(struct videobuf_queue *q, - struct videobuf_buffer *vb) +static void vpbe_buf_cleanup(struct vb2_buffer *vb) { /* Get the file handle object and layer object */ - struct vpbe_fh *fh = q->priv_data; + struct vpbe_fh *fh = vb2_get_drv_priv(vb->vb2_queue); struct vpbe_layer *layer = fh->layer; struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev; + struct vpbe_disp_buffer *buf = container_of(vb, + struct vpbe_disp_buffer, vb); + unsigned long flags; v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, - "vpbe_buffer_release\n"); + "vpbe_buf_cleanup\n"); + + spin_lock_irqsave(&layer->irqlock, flags); + if (vb->state == VB2_BUF_STATE_ACTIVE) + list_del_init(&buf->list); + spin_unlock_irqrestore(&layer->irqlock, flags); +} + +static void vpbe_wait_prepare(struct vb2_queue *vq) +{ + struct vpbe_fh *fh = vb2_get_drv_priv(vq); + struct vpbe_layer *layer = fh->layer; + + mutex_unlock(&layer->opslock); +} + +static void vpbe_wait_finish(struct vb2_queue *vq) +{ + struct vpbe_fh *fh = vb2_get_drv_priv(vq); + struct vpbe_layer *layer = fh->layer; + + mutex_lock(&layer->opslock); +} + +static int vpbe_buffer_init(struct vb2_buffer *vb) +{ + struct vpbe_disp_buffer *buf = container_of(vb, + struct vpbe_disp_buffer, vb); + + INIT_LIST_HEAD(&buf->list); + return 0; +} + +static int vpbe_start_streaming(struct vb2_queue *vq, unsigned int count) +{ + struct vpbe_fh *fh = vb2_get_drv_priv(vq); + struct vpbe_layer *layer = fh->layer; + struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev; + int ret; + + /* If buffer queue is empty, return error */ + if (list_empty(&layer->dma_queue)) { + v4l2_err(&vpbe_dev->v4l2_dev, "buffer queue is empty\n"); + return -EINVAL; + } + /* Get the next frame from the buffer queue */ + layer->next_frm = layer->cur_frm = list_entry(layer->dma_queue.next, + struct vpbe_disp_buffer, list); + /* Remove buffer from the buffer queue */ + list_del(&layer->cur_frm->list); + /* Mark state of the current frame to active */ + layer->cur_frm->vb.state = VB2_BUF_STATE_ACTIVE; + /* Initialize field_id and started member */ + layer->field_id = 0; + + /* Set parameters in OSD and VENC */ + ret = vpbe_set_osd_display_params(fh->disp_dev, layer); + if (ret < 0) + return ret; - if (V4L2_MEMORY_USERPTR != layer->memory) - videobuf_dma_contig_free(q, vb); + /* + * if request format is yuv420 semiplanar, need to + * enable both video windows + */ + layer->started = 1; + layer->layer_first_int = 1; + + return ret; +} + +static int vpbe_stop_streaming(struct vb2_queue *vq) +{ + struct vpbe_fh *fh = vb2_get_drv_priv(vq); + struct vpbe_layer *layer = fh->layer; + + if (!vb2_is_streaming(vq)) + return 0; + + /* release all active buffers */ + while (!list_empty(&layer->dma_queue)) { + layer->next_frm = list_entry(layer->dma_queue.next, + struct vpbe_disp_buffer, list); + list_del(&layer->next_frm->list); + vb2_buffer_done(&layer->next_frm->vb, VB2_BUF_STATE_ERROR); + } - vb->state = VIDEOBUF_NEEDS_INIT; + return 0; } -static struct videobuf_queue_ops video_qops = { - .buf_setup = vpbe_buffer_setup, +static struct vb2_ops video_qops = { + .queue_setup = vpbe_buffer_queue_setup, + .wait_prepare = vpbe_wait_prepare, + .wait_finish = vpbe_wait_finish, + .buf_init = vpbe_buffer_init, .buf_prepare = vpbe_buffer_prepare, + .start_streaming = vpbe_start_streaming, + .stop_streaming = vpbe_stop_streaming, + .buf_cleanup = vpbe_buf_cleanup, .buf_queue = vpbe_buffer_queue, - .buf_release = vpbe_buffer_release, }; static @@ -345,7 +427,7 @@ static int vpbe_set_osd_display_params(struct vpbe_display *disp_dev, unsigned long addr; int ret; - addr = videobuf_to_dma_contig(layer->cur_frm); + addr = vb2_dma_contig_plane_dma_addr(&layer->cur_frm->vb, 0); /* Set address in the display registers */ osd_device->ops.start_layer(osd_device, layer->layer_info.id, @@ -620,9 +702,12 @@ static int vpbe_display_querycap(struct file *file, void *priv, struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev; cap->version = VPBE_DISPLAY_VERSION_CODE; - cap->capabilities = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING; - strlcpy(cap->driver, VPBE_DISPLAY_DRIVER, sizeof(cap->driver)); - strlcpy(cap->bus_info, "platform", sizeof(cap->bus_info)); + cap->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING; + cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; + snprintf(cap->driver, sizeof(cap->driver), "%s", + dev_name(vpbe_dev->pdev)); + snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", + dev_name(vpbe_dev->pdev)); strlcpy(cap->card, vpbe_dev->cfg->module_name, sizeof(cap->card)); return 0; @@ -1161,7 +1246,7 @@ static int vpbe_display_streamoff(struct file *file, void *priv, osd_device->ops.disable_layer(osd_device, layer->layer_info.id); layer->started = 0; - ret = videobuf_streamoff(&layer->buffer_queue); + ret = vb2_streamoff(&layer->buffer_queue, buf_type); return ret; } @@ -1199,46 +1284,15 @@ static int vpbe_display_streamon(struct file *file, void *priv, } /* - * Call videobuf_streamon to start streaming + * Call vb2_streamon to start streaming * in videobuf */ - ret = videobuf_streamon(&layer->buffer_queue); + ret = vb2_streamon(&layer->buffer_queue, buf_type); if (ret) { v4l2_err(&vpbe_dev->v4l2_dev, - "error in videobuf_streamon\n"); + "error in vb2_streamon\n"); return ret; } - /* If buffer queue is empty, return error */ - if (list_empty(&layer->dma_queue)) { - v4l2_err(&vpbe_dev->v4l2_dev, "buffer queue is empty\n"); - goto streamoff; - } - /* Get the next frame from the buffer queue */ - layer->next_frm = layer->cur_frm = list_entry(layer->dma_queue.next, - struct videobuf_buffer, queue); - /* Remove buffer from the buffer queue */ - list_del(&layer->cur_frm->queue); - /* Mark state of the current frame to active */ - layer->cur_frm->state = VIDEOBUF_ACTIVE; - /* Initialize field_id and started member */ - layer->field_id = 0; - - /* Set parameters in OSD and VENC */ - ret = vpbe_set_osd_display_params(disp_dev, layer); - if (ret < 0) - goto streamoff; - - /* - * if request format is yuv420 semiplanar, need to - * enable both video windows - */ - layer->started = 1; - - layer->layer_first_int = 1; - - return ret; -streamoff: - ret = videobuf_streamoff(&layer->buffer_queue); return ret; } @@ -1265,10 +1319,10 @@ static int vpbe_display_dqbuf(struct file *file, void *priv, } if (file->f_flags & O_NONBLOCK) /* Call videobuf_dqbuf for non blocking mode */ - ret = videobuf_dqbuf(&layer->buffer_queue, buf, 1); + ret = vb2_dqbuf(&layer->buffer_queue, buf, 1); else /* Call videobuf_dqbuf for blocking mode */ - ret = videobuf_dqbuf(&layer->buffer_queue, buf, 0); + ret = vb2_dqbuf(&layer->buffer_queue, buf, 0); return ret; } @@ -1295,7 +1349,7 @@ static int vpbe_display_qbuf(struct file *file, void *priv, return -EACCES; } - return videobuf_qbuf(&layer->buffer_queue, p); + return vb2_qbuf(&layer->buffer_queue, p); } static int vpbe_display_querybuf(struct file *file, void *priv, @@ -1304,7 +1358,6 @@ static int vpbe_display_querybuf(struct file *file, void *priv, struct vpbe_fh *fh = file->private_data; struct vpbe_layer *layer = fh->layer; struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev; - int ret; v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_QUERYBUF, layer id = %d\n", @@ -1314,11 +1367,8 @@ static int vpbe_display_querybuf(struct file *file, void *priv, v4l2_err(&vpbe_dev->v4l2_dev, "Invalid buffer type\n"); return -EINVAL; } - - /* Call videobuf_querybuf to get information */ - ret = videobuf_querybuf(&layer->buffer_queue, buf); - - return ret; + /* Call vb2_querybuf to get information */ + return vb2_querybuf(&layer->buffer_queue, buf); } static int vpbe_display_reqbufs(struct file *file, void *priv, @@ -1327,8 +1377,8 @@ static int vpbe_display_reqbufs(struct file *file, void *priv, struct vpbe_fh *fh = file->private_data; struct vpbe_layer *layer = fh->layer; struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev; + struct vb2_queue *q; int ret; - v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_display_reqbufs\n"); if (V4L2_BUF_TYPE_VIDEO_OUTPUT != req_buf->type) { @@ -1342,15 +1392,26 @@ static int vpbe_display_reqbufs(struct file *file, void *priv, return -EBUSY; } /* Initialize videobuf queue as per the buffer type */ - videobuf_queue_dma_contig_init(&layer->buffer_queue, - &video_qops, - vpbe_dev->pdev, - &layer->irqlock, - V4L2_BUF_TYPE_VIDEO_OUTPUT, - layer->pix_fmt.field, - sizeof(struct videobuf_buffer), - fh, NULL); + layer->alloc_ctx = vb2_dma_contig_init_ctx(vpbe_dev->pdev); + if (!layer->alloc_ctx) { + v4l2_err(&vpbe_dev->v4l2_dev, "Failed to get the context\n"); + return -EINVAL; + } + q = &layer->buffer_queue; + memset(q, 0, sizeof(*q)); + q->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + q->io_modes = VB2_MMAP | VB2_USERPTR; + q->drv_priv = fh; + q->ops = &video_qops; + q->mem_ops = &vb2_dma_contig_memops; + q->buf_struct_size = sizeof(struct vpbe_disp_buffer); + ret = vb2_queue_init(q); + if (ret) { + v4l2_err(&vpbe_dev->v4l2_dev, "vb2_queue_init() failed\n"); + vb2_dma_contig_cleanup_ctx(layer->alloc_ctx); + return ret; + } /* Set io allowed member of file handle to TRUE */ fh->io_allowed = 1; /* Increment io usrs member of layer object to 1 */ @@ -1360,9 +1421,7 @@ static int vpbe_display_reqbufs(struct file *file, void *priv, /* Initialize buffer queue */ INIT_LIST_HEAD(&layer->dma_queue); /* Allocate buffers */ - ret = videobuf_reqbufs(&layer->buffer_queue, req_buf); - - return ret; + return vb2_reqbufs(q, req_buf); } /* @@ -1381,7 +1440,7 @@ static int vpbe_display_mmap(struct file *filep, struct vm_area_struct *vma) if (mutex_lock_interruptible(&layer->opslock)) return -ERESTARTSYS; - ret = videobuf_mmap_mapper(&layer->buffer_queue, vma); + ret = vb2_mmap(&layer->buffer_queue, vma); mutex_unlock(&layer->opslock); return ret; } @@ -1398,7 +1457,7 @@ static unsigned int vpbe_display_poll(struct file *filep, poll_table *wait) v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_display_poll\n"); if (layer->started) { mutex_lock(&layer->opslock); - err = videobuf_poll_stream(filep, &layer->buffer_queue, wait); + err = vb2_poll(&layer->buffer_queue, filep, wait); mutex_unlock(&layer->opslock); } return err; @@ -1488,8 +1547,8 @@ static int vpbe_display_release(struct file *file) layer->layer_info.id); layer->started = 0; /* Free buffers allocated */ - videobuf_queue_cancel(&layer->buffer_queue); - videobuf_mmap_free(&layer->buffer_queue); + vb2_queue_release(&layer->buffer_queue); + vb2_dma_contig_cleanup_ctx(&layer->buffer_queue); } /* Decrement layer usrs counter */ diff --git a/drivers/media/platform/davinci/vpbe_osd.c b/drivers/media/platform/davinci/vpbe_osd.c index bba299dbf396..707f243f810d 100644 --- a/drivers/media/platform/davinci/vpbe_osd.c +++ b/drivers/media/platform/davinci/vpbe_osd.c @@ -62,7 +62,7 @@ static inline u32 osd_set(struct osd_state *sd, u32 mask, u32 offset) { struct osd_state *osd = sd; - u32 addr = osd->osd_base + offset; + void __iomem *addr = osd->osd_base + offset; u32 val = readl(addr) | mask; writel(val, addr); @@ -74,7 +74,7 @@ static inline u32 osd_clear(struct osd_state *sd, u32 mask, u32 offset) { struct osd_state *osd = sd; - u32 addr = osd->osd_base + offset; + void __iomem *addr = osd->osd_base + offset; u32 val = readl(addr) & ~mask; writel(val, addr); @@ -87,7 +87,7 @@ static inline u32 osd_modify(struct osd_state *sd, u32 mask, u32 val, { struct osd_state *osd = sd; - u32 addr = osd->osd_base + offset; + void __iomem *addr = osd->osd_base + offset; u32 new_val = (readl(addr) & ~mask) | (val & mask); writel(new_val, addr); @@ -1559,8 +1559,7 @@ static int osd_probe(struct platform_device *pdev) ret = -ENODEV; goto free_mem; } - osd->osd_base = (unsigned long)ioremap_nocache(res->start, - osd->osd_size); + osd->osd_base = ioremap_nocache(res->start, osd->osd_size); if (!osd->osd_base) { dev_err(osd->dev, "Unable to map the OSD region\n"); ret = -ENODEV; diff --git a/drivers/media/platform/davinci/vpif.c b/drivers/media/platform/davinci/vpif.c index cff3c0ab501f..0d6cc8e4deb2 100644 --- a/drivers/media/platform/davinci/vpif.c +++ b/drivers/media/platform/davinci/vpif.c @@ -444,7 +444,7 @@ static int __devinit vpif_probe(struct platform_device *pdev) status = PTR_ERR(vpif_clk); goto clk_fail; } - clk_enable(vpif_clk); + clk_prepare_enable(vpif_clk); spin_lock_init(&vpif_lock); dev_info(&pdev->dev, "vpif probe success\n"); @@ -460,7 +460,7 @@ fail: static int __devexit vpif_remove(struct platform_device *pdev) { if (vpif_clk) { - clk_disable(vpif_clk); + clk_disable_unprepare(vpif_clk); clk_put(vpif_clk); } @@ -472,13 +472,13 @@ static int __devexit vpif_remove(struct platform_device *pdev) #ifdef CONFIG_PM static int vpif_suspend(struct device *dev) { - clk_disable(vpif_clk); + clk_disable_unprepare(vpif_clk); return 0; } static int vpif_resume(struct device *dev) { - clk_enable(vpif_clk); + clk_prepare_enable(vpif_clk); return 0; } diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c index fcabc023885d..a409ccefb380 100644 --- a/drivers/media/platform/davinci/vpif_capture.c +++ b/drivers/media/platform/davinci/vpif_capture.c @@ -201,13 +201,16 @@ static void vpif_buffer_queue(struct vb2_buffer *vb) struct vpif_cap_buffer *buf = container_of(vb, struct vpif_cap_buffer, vb); struct common_obj *common; + unsigned long flags; common = &ch->common[VPIF_VIDEO_INDEX]; vpif_dbg(2, debug, "vpif_buffer_queue\n"); + spin_lock_irqsave(&common->irqlock, flags); /* add the buffer to the DMA queue */ list_add_tail(&buf->list, &common->dma_queue); + spin_unlock_irqrestore(&common->irqlock, flags); } /** @@ -278,10 +281,13 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count) struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; struct vpif_params *vpif = &ch->vpifparams; unsigned long addr = 0; + unsigned long flags; int ret; - /* If buffer queue is empty, return error */ + /* If buffer queue is empty, return error */ + spin_lock_irqsave(&common->irqlock, flags); if (list_empty(&common->dma_queue)) { + spin_unlock_irqrestore(&common->irqlock, flags); vpif_dbg(1, debug, "buffer queue is empty\n"); return -EIO; } @@ -291,6 +297,7 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count) struct vpif_cap_buffer, list); /* Remove buffer from the buffer queue */ list_del(&common->cur_frm->list); + spin_unlock_irqrestore(&common->irqlock, flags); /* Mark state of the current frame to active */ common->cur_frm->vb.state = VB2_BUF_STATE_ACTIVE; /* Initialize field_id and started member */ @@ -362,6 +369,7 @@ static int vpif_stop_streaming(struct vb2_queue *vq) struct vpif_fh *fh = vb2_get_drv_priv(vq); struct channel_obj *ch = fh->channel; struct common_obj *common; + unsigned long flags; if (!vb2_is_streaming(vq)) return 0; @@ -369,12 +377,14 @@ static int vpif_stop_streaming(struct vb2_queue *vq) common = &ch->common[VPIF_VIDEO_INDEX]; /* release all active buffers */ + spin_lock_irqsave(&common->irqlock, flags); while (!list_empty(&common->dma_queue)) { common->next_frm = list_entry(common->dma_queue.next, struct vpif_cap_buffer, list); list_del(&common->next_frm->list); vb2_buffer_done(&common->next_frm->vb, VB2_BUF_STATE_ERROR); } + spin_unlock_irqrestore(&common->irqlock, flags); return 0; } @@ -420,10 +430,12 @@ static void vpif_schedule_next_buffer(struct common_obj *common) { unsigned long addr = 0; + spin_lock(&common->irqlock); common->next_frm = list_entry(common->dma_queue.next, struct vpif_cap_buffer, list); /* Remove that buffer from the buffer queue */ list_del(&common->next_frm->list); + spin_unlock(&common->irqlock); common->next_frm->vb.state = VB2_BUF_STATE_ACTIVE; addr = vb2_dma_contig_plane_dma_addr(&common->next_frm->vb, 0); @@ -468,8 +480,12 @@ static irqreturn_t vpif_channel_isr(int irq, void *dev_id) /* Check the field format */ if (1 == ch->vpifparams.std_info.frm_fmt) { /* Progressive mode */ - if (list_empty(&common->dma_queue)) + spin_lock(&common->irqlock); + if (list_empty(&common->dma_queue)) { + spin_unlock(&common->irqlock); continue; + } + spin_unlock(&common->irqlock); if (!channel_first_int[i][channel_id]) vpif_process_buffer_complete(common); @@ -513,9 +529,13 @@ static irqreturn_t vpif_channel_isr(int irq, void *dev_id) vpif_process_buffer_complete(common); } else if (1 == fid) { /* odd field */ + spin_lock(&common->irqlock); if (list_empty(&common->dma_queue) || - (common->cur_frm != common->next_frm)) + (common->cur_frm != common->next_frm)) { + spin_unlock(&common->irqlock); continue; + } + spin_unlock(&common->irqlock); vpif_schedule_next_buffer(common); } @@ -1004,9 +1024,9 @@ static int vpif_reqbufs(struct file *file, void *priv, /* Initialize videobuf2 queue as per the buffer type */ common->alloc_ctx = vb2_dma_contig_init_ctx(vpif_dev); - if (!common->alloc_ctx) { + if (IS_ERR(common->alloc_ctx)) { vpif_err("Failed to get the context\n"); - return -EINVAL; + return PTR_ERR(common->alloc_ctx); } q = &common->buffer_queue; q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; @@ -1715,7 +1735,7 @@ vpif_enum_dv_timings(struct file *file, void *priv, int ret; ret = v4l2_subdev_call(ch->sd, video, enum_dv_timings, timings); - if (ret == -ENOIOCTLCMD && ret == -ENODEV) + if (ret == -ENOIOCTLCMD || ret == -ENODEV) return -EINVAL; return ret; } @@ -1735,7 +1755,7 @@ vpif_query_dv_timings(struct file *file, void *priv, int ret; ret = v4l2_subdev_call(ch->sd, video, query_dv_timings, timings); - if (ret == -ENOIOCTLCMD && ret == -ENODEV) + if (ret == -ENOIOCTLCMD || ret == -ENODEV) return -ENODATA; return ret; } diff --git a/drivers/media/platform/davinci/vpif_display.c b/drivers/media/platform/davinci/vpif_display.c index b716fbd4241f..9f2b603be9c9 100644 --- a/drivers/media/platform/davinci/vpif_display.c +++ b/drivers/media/platform/davinci/vpif_display.c @@ -177,11 +177,14 @@ static void vpif_buffer_queue(struct vb2_buffer *vb) struct vpif_disp_buffer, vb); struct channel_obj *ch = fh->channel; struct common_obj *common; + unsigned long flags; common = &ch->common[VPIF_VIDEO_INDEX]; /* add the buffer to the DMA queue */ + spin_lock_irqsave(&common->irqlock, flags); list_add_tail(&buf->list, &common->dma_queue); + spin_unlock_irqrestore(&common->irqlock, flags); } /* @@ -246,10 +249,13 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count) struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; struct vpif_params *vpif = &ch->vpifparams; unsigned long addr = 0; + unsigned long flags; int ret; /* If buffer queue is empty, return error */ + spin_lock_irqsave(&common->irqlock, flags); if (list_empty(&common->dma_queue)) { + spin_unlock_irqrestore(&common->irqlock, flags); vpif_err("buffer queue is empty\n"); return -EIO; } @@ -260,6 +266,7 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count) struct vpif_disp_buffer, list); list_del(&common->cur_frm->list); + spin_unlock_irqrestore(&common->irqlock, flags); /* Mark state of the current frame to active */ common->cur_frm->vb.state = VB2_BUF_STATE_ACTIVE; @@ -330,6 +337,7 @@ static int vpif_stop_streaming(struct vb2_queue *vq) struct vpif_fh *fh = vb2_get_drv_priv(vq); struct channel_obj *ch = fh->channel; struct common_obj *common; + unsigned long flags; if (!vb2_is_streaming(vq)) return 0; @@ -337,12 +345,14 @@ static int vpif_stop_streaming(struct vb2_queue *vq) common = &ch->common[VPIF_VIDEO_INDEX]; /* release all active buffers */ + spin_lock_irqsave(&common->irqlock, flags); while (!list_empty(&common->dma_queue)) { common->next_frm = list_entry(common->dma_queue.next, struct vpif_disp_buffer, list); list_del(&common->next_frm->list); vb2_buffer_done(&common->next_frm->vb, VB2_BUF_STATE_ERROR); } + spin_unlock_irqrestore(&common->irqlock, flags); return 0; } @@ -363,11 +373,13 @@ static void process_progressive_mode(struct common_obj *common) { unsigned long addr = 0; + spin_lock(&common->irqlock); /* Get the next buffer from buffer queue */ common->next_frm = list_entry(common->dma_queue.next, struct vpif_disp_buffer, list); /* Remove that buffer from the buffer queue */ list_del(&common->next_frm->list); + spin_unlock(&common->irqlock); /* Mark status of the buffer as active */ common->next_frm->vb.state = VB2_BUF_STATE_ACTIVE; @@ -398,16 +410,18 @@ static void process_interlaced_mode(int fid, struct common_obj *common) common->cur_frm = common->next_frm; } else if (1 == fid) { /* odd field */ + spin_lock(&common->irqlock); if (list_empty(&common->dma_queue) || (common->cur_frm != common->next_frm)) { + spin_unlock(&common->irqlock); return; } + spin_unlock(&common->irqlock); /* one field is displayed configure the next * frame if it is available else hold on current * frame */ /* Get next from the buffer queue */ process_progressive_mode(common); - } } @@ -437,8 +451,12 @@ static irqreturn_t vpif_channel_isr(int irq, void *dev_id) continue; if (1 == ch->vpifparams.std_info.frm_fmt) { - if (list_empty(&common->dma_queue)) + spin_lock(&common->irqlock); + if (list_empty(&common->dma_queue)) { + spin_unlock(&common->irqlock); continue; + } + spin_unlock(&common->irqlock); /* Progressive mode */ if (!channel_first_int[i][channel_id]) { @@ -972,9 +990,9 @@ static int vpif_reqbufs(struct file *file, void *priv, } /* Initialize videobuf2 queue as per the buffer type */ common->alloc_ctx = vb2_dma_contig_init_ctx(vpif_dev); - if (!common->alloc_ctx) { + if (IS_ERR(common->alloc_ctx)) { vpif_err("Failed to get the context\n"); - return -EINVAL; + return PTR_ERR(common->alloc_ctx); } q = &common->buffer_queue; q->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; @@ -1380,7 +1398,7 @@ vpif_enum_dv_timings(struct file *file, void *priv, int ret; ret = v4l2_subdev_call(ch->sd, video, enum_dv_timings, timings); - if (ret == -ENOIOCTLCMD && ret == -ENODEV) + if (ret == -ENOIOCTLCMD || ret == -ENODEV) return -EINVAL; return ret; } |