diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-11 11:49:23 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-11 11:49:23 -0800 |
commit | 2183a58803c2bbd87c2d0057eed6779ec4718d4d (patch) | |
tree | 910860a2f0c1f22efe840428f11077a5bd478933 /drivers/media/pci/solo6x10 | |
parent | e28870f9b3e92cd3570925089c6bb789c2603bc4 (diff) | |
parent | 71947828caef0c83d4245f7d1eaddc799b4ff1d1 (diff) | |
download | linux-2183a58803c2bbd87c2d0057eed6779ec4718d4d.tar.gz linux-2183a58803c2bbd87c2d0057eed6779ec4718d4d.tar.bz2 linux-2183a58803c2bbd87c2d0057eed6779ec4718d4d.zip |
Merge tag 'media/v3.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab:
- Two new dvb frontend drivers: mn88472 and mn88473
- A new driver for some PCIe DVBSky cards
- A new remote controller driver: meson-ir
- One LIRC staging driver got rewritten and promoted to mainstream:
igorplugusb
- A new tuner driver (m88rs6000t)
- The old omap2 media driver got removed from staging. This driver
uses an old DMA API and it is likely broken on recent kernels.
Nobody cared enough to fix it
- Media bus format moved to a separate header, as DRM will also use the
definitions there
- mem2mem_testdev were renamed to vim2m, in order to use the same
naming convention taken by the other virtual test driver (vivid)
- Added a new driver for coda SoC (coda-jpeg)
- The cx88 driver got converted to use videobuf2 core
- Make DMABUF export buffer to work with DMA Scatter/Gather and Vmalloc
cores
- Lots of other fixes, improvements and cleanups on the drivers.
* tag 'media/v3.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (384 commits)
[media] mn88473: One function call less in mn88473_init() after error
[media] mn88473: Remove uneeded check before release_firmware()
[media] lirc_zilog: Deletion of unnecessary checks before vfree()
[media] MAINTAINERS: Add myself as img-ir maintainer
[media] img-ir: Don't set driver's module owner
[media] img-ir: Depend on METAG or MIPS or COMPILE_TEST
[media] img-ir/hw: Drop [un]register_decoder declarations
[media] img-ir/hw: Fix potential deadlock stopping timer
[media] img-ir/hw: Always read data to clear buffer
[media] redrat3: ensure dma is setup properly
[media] ddbridge: remove unneeded check before dvb_unregister_device()
[media] si2157: One function call less in si2157_init() after error
[media] tuners: remove uneeded checks before release_firmware()
[media] arm: omap2: rx51-peripherals: fix build warning
[media] stv090x: add an extra protetion against buffer overflow
[media] stv090x: Remove an unreachable code
[media] stv090x: Some whitespace cleanups
[media] em28xx: checkpatch cleanup: whitespaces/new lines cleanups
[media] si2168: add support for firmware files in new format
[media] si2168: debug printout for firmware version
...
Diffstat (limited to 'drivers/media/pci/solo6x10')
-rw-r--r-- | drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c | 88 | ||||
-rw-r--r-- | drivers/media/pci/solo6x10/solo6x10.h | 1 |
2 files changed, 51 insertions, 38 deletions
diff --git a/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c b/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c index 28023f9f1dc7..6e933d383fa2 100644 --- a/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c +++ b/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c @@ -463,7 +463,6 @@ static int solo_fill_jpeg(struct solo_enc_dev *solo_enc, struct solo_dev *solo_dev = solo_enc->solo_dev; struct sg_table *vbuf = vb2_dma_sg_plane_desc(vb, 0); int frame_size; - int ret; vb->v4l2_buf.flags |= V4L2_BUF_FLAG_KEYFRAME; @@ -473,22 +472,10 @@ static int solo_fill_jpeg(struct solo_enc_dev *solo_enc, frame_size = ALIGN(vop_jpeg_size(vh) + solo_enc->jpeg_len, DMA_ALIGN); vb2_set_plane_payload(vb, 0, vop_jpeg_size(vh) + solo_enc->jpeg_len); - /* may discard all previous data in vbuf->sgl */ - if (!dma_map_sg(&solo_dev->pdev->dev, vbuf->sgl, vbuf->nents, - DMA_FROM_DEVICE)) - return -ENOMEM; - ret = solo_send_desc(solo_enc, solo_enc->jpeg_len, vbuf, + return solo_send_desc(solo_enc, solo_enc->jpeg_len, vbuf, vop_jpeg_offset(vh) - SOLO_JPEG_EXT_ADDR(solo_dev), frame_size, SOLO_JPEG_EXT_ADDR(solo_dev), SOLO_JPEG_EXT_SIZE(solo_dev)); - dma_unmap_sg(&solo_dev->pdev->dev, vbuf->sgl, vbuf->nents, - DMA_FROM_DEVICE); - - /* add the header only after dma_unmap_sg() */ - sg_copy_from_buffer(vbuf->sgl, vbuf->nents, - solo_enc->jpeg_header, solo_enc->jpeg_len); - - return ret; } static int solo_fill_mpeg(struct solo_enc_dev *solo_enc, @@ -498,7 +485,6 @@ static int solo_fill_mpeg(struct solo_enc_dev *solo_enc, struct sg_table *vbuf = vb2_dma_sg_plane_desc(vb, 0); int frame_off, frame_size; int skip = 0; - int ret; if (vb2_plane_size(vb, 0) < vop_mpeg_size(vh)) return -EIO; @@ -521,21 +507,9 @@ static int solo_fill_mpeg(struct solo_enc_dev *solo_enc, sizeof(*vh)) % SOLO_MP4E_EXT_SIZE(solo_dev); frame_size = ALIGN(vop_mpeg_size(vh) + skip, DMA_ALIGN); - /* may discard all previous data in vbuf->sgl */ - if (!dma_map_sg(&solo_dev->pdev->dev, vbuf->sgl, vbuf->nents, - DMA_FROM_DEVICE)) - return -ENOMEM; - ret = solo_send_desc(solo_enc, skip, vbuf, frame_off, frame_size, + return solo_send_desc(solo_enc, skip, vbuf, frame_off, frame_size, SOLO_MP4E_EXT_ADDR(solo_dev), SOLO_MP4E_EXT_SIZE(solo_dev)); - dma_unmap_sg(&solo_dev->pdev->dev, vbuf->sgl, vbuf->nents, - DMA_FROM_DEVICE); - - /* add the header only after dma_unmap_sg() */ - if (!vop_type(vh)) - sg_copy_from_buffer(vbuf->sgl, vbuf->nents, - solo_enc->vop, solo_enc->vop_len); - return ret; } static int solo_enc_fillbuf(struct solo_enc_dev *solo_enc, @@ -703,9 +677,7 @@ static int solo_ring_thread(void *data) if (timeout == -ERESTARTSYS || kthread_should_stop()) break; - solo_irq_off(solo_dev, SOLO_IRQ_ENCODER); solo_handle_ring(solo_dev); - solo_irq_on(solo_dev, SOLO_IRQ_ENCODER); try_to_freeze(); } @@ -720,7 +692,10 @@ static int solo_enc_queue_setup(struct vb2_queue *q, unsigned int *num_planes, unsigned int sizes[], void *alloc_ctxs[]) { + struct solo_enc_dev *solo_enc = vb2_get_drv_priv(q); + sizes[0] = FRAME_BUF_SIZE; + alloc_ctxs[0] = solo_enc->alloc_ctx; *num_planes = 1; if (*num_buffers < MIN_VID_BUFFERS) @@ -770,26 +745,51 @@ static void solo_ring_stop(struct solo_dev *solo_dev) static int solo_enc_start_streaming(struct vb2_queue *q, unsigned int count) { struct solo_enc_dev *solo_enc = vb2_get_drv_priv(q); - int ret; - ret = solo_enc_on(solo_enc); - if (ret) - return ret; - return solo_ring_start(solo_enc->solo_dev); + return solo_enc_on(solo_enc); } static void solo_enc_stop_streaming(struct vb2_queue *q) { struct solo_enc_dev *solo_enc = vb2_get_drv_priv(q); + unsigned long flags; + spin_lock_irqsave(&solo_enc->av_lock, flags); solo_enc_off(solo_enc); - INIT_LIST_HEAD(&solo_enc->vidq_active); - solo_ring_stop(solo_enc->solo_dev); + while (!list_empty(&solo_enc->vidq_active)) { + struct solo_vb2_buf *buf = list_entry( + solo_enc->vidq_active.next, + struct solo_vb2_buf, list); + + list_del(&buf->list); + vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR); + } + spin_unlock_irqrestore(&solo_enc->av_lock, flags); +} + +static void solo_enc_buf_finish(struct vb2_buffer *vb) +{ + struct solo_enc_dev *solo_enc = vb2_get_drv_priv(vb->vb2_queue); + struct sg_table *vbuf = vb2_dma_sg_plane_desc(vb, 0); + + switch (solo_enc->fmt) { + case V4L2_PIX_FMT_MPEG4: + case V4L2_PIX_FMT_H264: + if (vb->v4l2_buf.flags & V4L2_BUF_FLAG_KEYFRAME) + sg_copy_from_buffer(vbuf->sgl, vbuf->nents, + solo_enc->vop, solo_enc->vop_len); + break; + default: /* V4L2_PIX_FMT_MJPEG */ + sg_copy_from_buffer(vbuf->sgl, vbuf->nents, + solo_enc->jpeg_header, solo_enc->jpeg_len); + break; + } } static struct vb2_ops solo_enc_video_qops = { .queue_setup = solo_enc_queue_setup, .buf_queue = solo_enc_buf_queue, + .buf_finish = solo_enc_buf_finish, .start_streaming = solo_enc_start_streaming, .stop_streaming = solo_enc_stop_streaming, .wait_prepare = vb2_ops_wait_prepare, @@ -1263,6 +1263,11 @@ static struct solo_enc_dev *solo_enc_alloc(struct solo_dev *solo_dev, return ERR_PTR(-ENOMEM); hdl = &solo_enc->hdl; + solo_enc->alloc_ctx = vb2_dma_sg_init_ctx(&solo_dev->pdev->dev); + if (IS_ERR(solo_enc->alloc_ctx)) { + ret = PTR_ERR(solo_enc->alloc_ctx); + goto hdl_free; + } v4l2_ctrl_handler_init(hdl, 10); v4l2_ctrl_new_std(hdl, &solo_ctrl_ops, V4L2_CID_BRIGHTNESS, 0, 255, 1, 128); @@ -1366,6 +1371,7 @@ pci_free: solo_enc->desc_items, solo_enc->desc_dma); hdl_free: v4l2_ctrl_handler_free(hdl); + vb2_dma_sg_cleanup_ctx(solo_enc->alloc_ctx); kfree(solo_enc); return ERR_PTR(ret); } @@ -1375,8 +1381,12 @@ static void solo_enc_free(struct solo_enc_dev *solo_enc) if (solo_enc == NULL) return; + pci_free_consistent(solo_enc->solo_dev->pdev, + sizeof(struct solo_p2m_desc) * solo_enc->desc_nelts, + solo_enc->desc_items, solo_enc->desc_dma); video_unregister_device(solo_enc->vfd); v4l2_ctrl_handler_free(&solo_enc->hdl); + vb2_dma_sg_cleanup_ctx(solo_enc->alloc_ctx); kfree(solo_enc); } @@ -1419,13 +1429,15 @@ int solo_enc_v4l2_init(struct solo_dev *solo_dev, unsigned nr) solo_dev->v4l2_enc[0]->vfd->num, solo_dev->v4l2_enc[solo_dev->nr_chans - 1]->vfd->num); - return 0; + return solo_ring_start(solo_dev); } void solo_enc_v4l2_exit(struct solo_dev *solo_dev) { int i; + solo_ring_stop(solo_dev); + for (i = 0; i < solo_dev->nr_chans; i++) solo_enc_free(solo_dev->v4l2_enc[i]); diff --git a/drivers/media/pci/solo6x10/solo6x10.h b/drivers/media/pci/solo6x10/solo6x10.h index 72017b7f0a75..bd8edfa319b8 100644 --- a/drivers/media/pci/solo6x10/solo6x10.h +++ b/drivers/media/pci/solo6x10/solo6x10.h @@ -180,6 +180,7 @@ struct solo_enc_dev { u32 sequence; struct vb2_queue vidq; struct list_head vidq_active; + void *alloc_ctx; int desc_count; int desc_nelts; struct solo_p2m_desc *desc_items; |