diff options
author | Prabhakar Lad <prabhakar.csengg@gmail.com> | 2014-10-12 16:40:31 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@osg.samsung.com> | 2014-10-28 14:05:30 -0400 |
commit | e71a180628c71bbf69575f2801d3ce435e37c3db (patch) | |
tree | 1f26ae6b62b232f8b48d100ffebbb257a50ef5cf /drivers/media/platform/davinci | |
parent | bf69877d65df83ac4bf0e92e354e3a7b6c568291 (diff) |
[media] media: davinci: vpbe: initialize vb2 queue and DMA context in probe
this patch moves the initialization of vb2 queue and the DMA
context to probe() and clean up in remove() callback respectively.
Signed-off-by: Lad, Prabhakar <prabhakar.csengg@gmail.com>
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Diffstat (limited to 'drivers/media/platform/davinci')
-rw-r--r-- | drivers/media/platform/davinci/vpbe_display.c | 128 |
1 files changed, 60 insertions, 68 deletions
diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c index 73496d953ba0..ff9eac4050d0 100644 --- a/drivers/media/platform/davinci/vpbe_display.c +++ b/drivers/media/platform/davinci/vpbe_display.c | |||
@@ -207,10 +207,9 @@ static irqreturn_t venc_isr(int irq, void *arg) | |||
207 | */ | 207 | */ |
208 | static int vpbe_buffer_prepare(struct vb2_buffer *vb) | 208 | static int vpbe_buffer_prepare(struct vb2_buffer *vb) |
209 | { | 209 | { |
210 | struct vpbe_fh *fh = vb2_get_drv_priv(vb->vb2_queue); | ||
211 | struct vb2_queue *q = vb->vb2_queue; | 210 | struct vb2_queue *q = vb->vb2_queue; |
212 | struct vpbe_layer *layer = fh->layer; | 211 | struct vpbe_layer *layer = vb2_get_drv_priv(q); |
213 | struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev; | 212 | struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev; |
214 | unsigned long addr; | 213 | unsigned long addr; |
215 | 214 | ||
216 | v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, | 215 | v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, |
@@ -247,9 +246,8 @@ vpbe_buffer_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, | |||
247 | 246 | ||
248 | { | 247 | { |
249 | /* Get the file handle object and layer object */ | 248 | /* Get the file handle object and layer object */ |
250 | struct vpbe_fh *fh = vb2_get_drv_priv(vq); | 249 | struct vpbe_layer *layer = vb2_get_drv_priv(vq); |
251 | struct vpbe_layer *layer = fh->layer; | 250 | struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev; |
252 | struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev; | ||
253 | 251 | ||
254 | v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_buffer_setup\n"); | 252 | v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_buffer_setup\n"); |
255 | 253 | ||
@@ -271,12 +269,11 @@ vpbe_buffer_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, | |||
271 | static void vpbe_buffer_queue(struct vb2_buffer *vb) | 269 | static void vpbe_buffer_queue(struct vb2_buffer *vb) |
272 | { | 270 | { |
273 | /* Get the file handle object and layer object */ | 271 | /* Get the file handle object and layer object */ |
274 | struct vpbe_fh *fh = vb2_get_drv_priv(vb->vb2_queue); | ||
275 | struct vpbe_disp_buffer *buf = container_of(vb, | 272 | struct vpbe_disp_buffer *buf = container_of(vb, |
276 | struct vpbe_disp_buffer, vb); | 273 | struct vpbe_disp_buffer, vb); |
277 | struct vpbe_layer *layer = fh->layer; | 274 | struct vpbe_layer *layer = vb2_get_drv_priv(vb->vb2_queue); |
278 | struct vpbe_display *disp = fh->disp_dev; | 275 | struct vpbe_display *disp = layer->disp_dev; |
279 | struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev; | 276 | struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev; |
280 | unsigned long flags; | 277 | unsigned long flags; |
281 | 278 | ||
282 | v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, | 279 | v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, |
@@ -296,9 +293,8 @@ static void vpbe_buffer_queue(struct vb2_buffer *vb) | |||
296 | static void vpbe_buf_cleanup(struct vb2_buffer *vb) | 293 | static void vpbe_buf_cleanup(struct vb2_buffer *vb) |
297 | { | 294 | { |
298 | /* Get the file handle object and layer object */ | 295 | /* Get the file handle object and layer object */ |
299 | struct vpbe_fh *fh = vb2_get_drv_priv(vb->vb2_queue); | 296 | struct vpbe_layer *layer = vb2_get_drv_priv(vb->vb2_queue); |
300 | struct vpbe_layer *layer = fh->layer; | 297 | struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev; |
301 | struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev; | ||
302 | struct vpbe_disp_buffer *buf = container_of(vb, | 298 | struct vpbe_disp_buffer *buf = container_of(vb, |
303 | struct vpbe_disp_buffer, vb); | 299 | struct vpbe_disp_buffer, vb); |
304 | unsigned long flags; | 300 | unsigned long flags; |
@@ -314,16 +310,14 @@ static void vpbe_buf_cleanup(struct vb2_buffer *vb) | |||
314 | 310 | ||
315 | static void vpbe_wait_prepare(struct vb2_queue *vq) | 311 | static void vpbe_wait_prepare(struct vb2_queue *vq) |
316 | { | 312 | { |
317 | struct vpbe_fh *fh = vb2_get_drv_priv(vq); | 313 | struct vpbe_layer *layer = vb2_get_drv_priv(vq); |
318 | struct vpbe_layer *layer = fh->layer; | ||
319 | 314 | ||
320 | mutex_unlock(&layer->opslock); | 315 | mutex_unlock(&layer->opslock); |
321 | } | 316 | } |
322 | 317 | ||
323 | static void vpbe_wait_finish(struct vb2_queue *vq) | 318 | static void vpbe_wait_finish(struct vb2_queue *vq) |
324 | { | 319 | { |
325 | struct vpbe_fh *fh = vb2_get_drv_priv(vq); | 320 | struct vpbe_layer *layer = vb2_get_drv_priv(vq); |
326 | struct vpbe_layer *layer = fh->layer; | ||
327 | 321 | ||
328 | mutex_lock(&layer->opslock); | 322 | mutex_lock(&layer->opslock); |
329 | } | 323 | } |
@@ -339,8 +333,7 @@ static int vpbe_buffer_init(struct vb2_buffer *vb) | |||
339 | 333 | ||
340 | static int vpbe_start_streaming(struct vb2_queue *vq, unsigned int count) | 334 | static int vpbe_start_streaming(struct vb2_queue *vq, unsigned int count) |
341 | { | 335 | { |
342 | struct vpbe_fh *fh = vb2_get_drv_priv(vq); | 336 | struct vpbe_layer *layer = vb2_get_drv_priv(vq); |
343 | struct vpbe_layer *layer = fh->layer; | ||
344 | int ret; | 337 | int ret; |
345 | 338 | ||
346 | /* Get the next frame from the buffer queue */ | 339 | /* Get the next frame from the buffer queue */ |
@@ -354,7 +347,7 @@ static int vpbe_start_streaming(struct vb2_queue *vq, unsigned int count) | |||
354 | layer->field_id = 0; | 347 | layer->field_id = 0; |
355 | 348 | ||
356 | /* Set parameters in OSD and VENC */ | 349 | /* Set parameters in OSD and VENC */ |
357 | ret = vpbe_set_osd_display_params(fh->disp_dev, layer); | 350 | ret = vpbe_set_osd_display_params(layer->disp_dev, layer); |
358 | if (ret < 0) { | 351 | if (ret < 0) { |
359 | struct vpbe_disp_buffer *buf, *tmp; | 352 | struct vpbe_disp_buffer *buf, *tmp; |
360 | 353 | ||
@@ -379,9 +372,8 @@ static int vpbe_start_streaming(struct vb2_queue *vq, unsigned int count) | |||
379 | 372 | ||
380 | static void vpbe_stop_streaming(struct vb2_queue *vq) | 373 | static void vpbe_stop_streaming(struct vb2_queue *vq) |
381 | { | 374 | { |
382 | struct vpbe_fh *fh = vb2_get_drv_priv(vq); | 375 | struct vpbe_layer *layer = vb2_get_drv_priv(vq); |
383 | struct vpbe_layer *layer = fh->layer; | 376 | struct vpbe_display *disp = layer->disp_dev; |
384 | struct vpbe_display *disp = fh->disp_dev; | ||
385 | unsigned long flags; | 377 | unsigned long flags; |
386 | 378 | ||
387 | if (!vb2_is_streaming(vq)) | 379 | if (!vb2_is_streaming(vq)) |
@@ -1380,8 +1372,7 @@ static int vpbe_display_reqbufs(struct file *file, void *priv, | |||
1380 | struct vpbe_fh *fh = file->private_data; | 1372 | struct vpbe_fh *fh = file->private_data; |
1381 | struct vpbe_layer *layer = fh->layer; | 1373 | struct vpbe_layer *layer = fh->layer; |
1382 | struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev; | 1374 | struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev; |
1383 | struct vb2_queue *q; | 1375 | |
1384 | int ret; | ||
1385 | v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_display_reqbufs\n"); | 1376 | v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_display_reqbufs\n"); |
1386 | 1377 | ||
1387 | if (V4L2_BUF_TYPE_VIDEO_OUTPUT != req_buf->type) { | 1378 | if (V4L2_BUF_TYPE_VIDEO_OUTPUT != req_buf->type) { |
@@ -1394,39 +1385,14 @@ static int vpbe_display_reqbufs(struct file *file, void *priv, | |||
1394 | v4l2_err(&vpbe_dev->v4l2_dev, "not IO user\n"); | 1385 | v4l2_err(&vpbe_dev->v4l2_dev, "not IO user\n"); |
1395 | return -EBUSY; | 1386 | return -EBUSY; |
1396 | } | 1387 | } |
1397 | /* Initialize videobuf queue as per the buffer type */ | ||
1398 | layer->alloc_ctx = vb2_dma_contig_init_ctx(vpbe_dev->pdev); | ||
1399 | if (IS_ERR(layer->alloc_ctx)) { | ||
1400 | v4l2_err(&vpbe_dev->v4l2_dev, "Failed to get the context\n"); | ||
1401 | return PTR_ERR(layer->alloc_ctx); | ||
1402 | } | ||
1403 | q = &layer->buffer_queue; | ||
1404 | memset(q, 0, sizeof(*q)); | ||
1405 | q->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; | ||
1406 | q->io_modes = VB2_MMAP | VB2_USERPTR; | ||
1407 | q->drv_priv = fh; | ||
1408 | q->ops = &video_qops; | ||
1409 | q->mem_ops = &vb2_dma_contig_memops; | ||
1410 | q->buf_struct_size = sizeof(struct vpbe_disp_buffer); | ||
1411 | q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; | ||
1412 | q->min_buffers_needed = 1; | ||
1413 | |||
1414 | ret = vb2_queue_init(q); | ||
1415 | if (ret) { | ||
1416 | v4l2_err(&vpbe_dev->v4l2_dev, "vb2_queue_init() failed\n"); | ||
1417 | vb2_dma_contig_cleanup_ctx(layer->alloc_ctx); | ||
1418 | return ret; | ||
1419 | } | ||
1420 | /* Set io allowed member of file handle to TRUE */ | 1388 | /* Set io allowed member of file handle to TRUE */ |
1421 | fh->io_allowed = 1; | 1389 | fh->io_allowed = 1; |
1422 | /* Increment io usrs member of layer object to 1 */ | 1390 | /* Increment io usrs member of layer object to 1 */ |
1423 | layer->io_usrs = 1; | 1391 | layer->io_usrs = 1; |
1424 | /* Store type of memory requested in layer object */ | 1392 | /* Store type of memory requested in layer object */ |
1425 | layer->memory = req_buf->memory; | 1393 | layer->memory = req_buf->memory; |
1426 | /* Initialize buffer queue */ | ||
1427 | INIT_LIST_HEAD(&layer->dma_queue); | ||
1428 | /* Allocate buffers */ | 1394 | /* Allocate buffers */ |
1429 | return vb2_reqbufs(q, req_buf); | 1395 | return vb2_reqbufs(&layer->buffer_queue, req_buf); |
1430 | } | 1396 | } |
1431 | 1397 | ||
1432 | /* | 1398 | /* |
@@ -1551,9 +1517,6 @@ static int vpbe_display_release(struct file *file) | |||
1551 | osd_device->ops.disable_layer(osd_device, | 1517 | osd_device->ops.disable_layer(osd_device, |
1552 | layer->layer_info.id); | 1518 | layer->layer_info.id); |
1553 | layer->started = 0; | 1519 | layer->started = 0; |
1554 | /* Free buffers allocated */ | ||
1555 | vb2_queue_release(&layer->buffer_queue); | ||
1556 | vb2_dma_contig_cleanup_ctx(&layer->buffer_queue); | ||
1557 | } | 1520 | } |
1558 | 1521 | ||
1559 | /* Decrement layer usrs counter */ | 1522 | /* Decrement layer usrs counter */ |
@@ -1724,9 +1687,10 @@ static int register_device(struct vpbe_layer *vpbe_display_layer, | |||
1724 | */ | 1687 | */ |
1725 | static int vpbe_display_probe(struct platform_device *pdev) | 1688 | static int vpbe_display_probe(struct platform_device *pdev) |
1726 | { | 1689 | { |
1727 | struct vpbe_layer *vpbe_display_layer; | ||
1728 | struct vpbe_display *disp_dev; | 1690 | struct vpbe_display *disp_dev; |
1691 | struct v4l2_device *v4l2_dev; | ||
1729 | struct resource *res = NULL; | 1692 | struct resource *res = NULL; |
1693 | struct vb2_queue *q; | ||
1730 | int k; | 1694 | int k; |
1731 | int i; | 1695 | int i; |
1732 | int err; | 1696 | int err; |
@@ -1748,13 +1712,14 @@ static int vpbe_display_probe(struct platform_device *pdev) | |||
1748 | vpbe_device_get); | 1712 | vpbe_device_get); |
1749 | if (err < 0) | 1713 | if (err < 0) |
1750 | return err; | 1714 | return err; |
1715 | |||
1716 | v4l2_dev = &disp_dev->vpbe_dev->v4l2_dev; | ||
1751 | /* Initialize the vpbe display controller */ | 1717 | /* Initialize the vpbe display controller */ |
1752 | if (NULL != disp_dev->vpbe_dev->ops.initialize) { | 1718 | if (NULL != disp_dev->vpbe_dev->ops.initialize) { |
1753 | err = disp_dev->vpbe_dev->ops.initialize(&pdev->dev, | 1719 | err = disp_dev->vpbe_dev->ops.initialize(&pdev->dev, |
1754 | disp_dev->vpbe_dev); | 1720 | disp_dev->vpbe_dev); |
1755 | if (err) { | 1721 | if (err) { |
1756 | v4l2_err(&disp_dev->vpbe_dev->v4l2_dev, | 1722 | v4l2_err(v4l2_dev, "Error initing vpbe\n"); |
1757 | "Error initing vpbe\n"); | ||
1758 | err = -ENOMEM; | 1723 | err = -ENOMEM; |
1759 | goto probe_out; | 1724 | goto probe_out; |
1760 | } | 1725 | } |
@@ -1769,8 +1734,7 @@ static int vpbe_display_probe(struct platform_device *pdev) | |||
1769 | 1734 | ||
1770 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | 1735 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); |
1771 | if (!res) { | 1736 | if (!res) { |
1772 | v4l2_err(&disp_dev->vpbe_dev->v4l2_dev, | 1737 | v4l2_err(v4l2_dev, "Unable to get VENC interrupt resource\n"); |
1773 | "Unable to get VENC interrupt resource\n"); | ||
1774 | err = -ENODEV; | 1738 | err = -ENODEV; |
1775 | goto probe_out; | 1739 | goto probe_out; |
1776 | } | 1740 | } |
@@ -1779,30 +1743,57 @@ static int vpbe_display_probe(struct platform_device *pdev) | |||
1779 | err = devm_request_irq(&pdev->dev, irq, venc_isr, 0, | 1743 | err = devm_request_irq(&pdev->dev, irq, venc_isr, 0, |
1780 | VPBE_DISPLAY_DRIVER, disp_dev); | 1744 | VPBE_DISPLAY_DRIVER, disp_dev); |
1781 | if (err) { | 1745 | if (err) { |
1782 | v4l2_err(&disp_dev->vpbe_dev->v4l2_dev, | 1746 | v4l2_err(v4l2_dev, "VPBE IRQ request failed\n"); |
1783 | "Unable to request interrupt\n"); | ||
1784 | goto probe_out; | 1747 | goto probe_out; |
1785 | } | 1748 | } |
1786 | 1749 | ||
1787 | for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) { | 1750 | for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) { |
1751 | /* initialize vb2 queue */ | ||
1752 | q = &disp_dev->dev[i]->buffer_queue; | ||
1753 | memset(q, 0, sizeof(*q)); | ||
1754 | q->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; | ||
1755 | q->io_modes = VB2_MMAP | VB2_USERPTR; | ||
1756 | q->drv_priv = disp_dev->dev[i]; | ||
1757 | q->ops = &video_qops; | ||
1758 | q->mem_ops = &vb2_dma_contig_memops; | ||
1759 | q->buf_struct_size = sizeof(struct vpbe_disp_buffer); | ||
1760 | q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; | ||
1761 | q->min_buffers_needed = 1; | ||
1762 | |||
1763 | err = vb2_queue_init(q); | ||
1764 | if (err) { | ||
1765 | v4l2_err(v4l2_dev, "vb2_queue_init() failed\n"); | ||
1766 | goto probe_out; | ||
1767 | } | ||
1768 | |||
1769 | disp_dev->dev[i]->alloc_ctx = | ||
1770 | vb2_dma_contig_init_ctx(disp_dev->vpbe_dev->pdev); | ||
1771 | if (IS_ERR(disp_dev->dev[i]->alloc_ctx)) { | ||
1772 | v4l2_err(v4l2_dev, "Failed to get the context\n"); | ||
1773 | err = PTR_ERR(disp_dev->dev[i]->alloc_ctx); | ||
1774 | goto probe_out; | ||
1775 | } | ||
1776 | |||
1777 | INIT_LIST_HEAD(&disp_dev->dev[i]->dma_queue); | ||
1778 | |||
1788 | if (register_device(disp_dev->dev[i], disp_dev, pdev)) { | 1779 | if (register_device(disp_dev->dev[i], disp_dev, pdev)) { |
1789 | err = -ENODEV; | 1780 | err = -ENODEV; |
1790 | goto probe_out; | 1781 | goto probe_out; |
1791 | } | 1782 | } |
1792 | } | 1783 | } |
1793 | 1784 | ||
1794 | printk(KERN_DEBUG "Successfully completed the probing of vpbe v4l2 device\n"); | 1785 | v4l2_dbg(1, debug, v4l2_dev, |
1786 | "Successfully completed the probing of vpbe v4l2 device\n"); | ||
1787 | |||
1795 | return 0; | 1788 | return 0; |
1796 | 1789 | ||
1797 | probe_out: | 1790 | probe_out: |
1798 | for (k = 0; k < VPBE_DISPLAY_MAX_DEVICES; k++) { | 1791 | for (k = 0; k < VPBE_DISPLAY_MAX_DEVICES; k++) { |
1799 | /* Get the pointer to the layer object */ | ||
1800 | vpbe_display_layer = disp_dev->dev[k]; | ||
1801 | /* Unregister video device */ | 1792 | /* Unregister video device */ |
1802 | if (vpbe_display_layer) { | 1793 | if (disp_dev->dev[k] != NULL) { |
1803 | video_unregister_device( | 1794 | vb2_dma_contig_cleanup_ctx(disp_dev->dev[k]->alloc_ctx); |
1804 | &vpbe_display_layer->video_dev); | 1795 | video_unregister_device(&disp_dev->dev[k]->video_dev); |
1805 | kfree(disp_dev->dev[k]); | 1796 | kfree(disp_dev->dev[k]); |
1806 | } | 1797 | } |
1807 | } | 1798 | } |
1808 | return err; | 1799 | return err; |
@@ -1828,6 +1819,7 @@ static int vpbe_display_remove(struct platform_device *pdev) | |||
1828 | for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) { | 1819 | for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) { |
1829 | /* Get the pointer to the layer object */ | 1820 | /* Get the pointer to the layer object */ |
1830 | vpbe_display_layer = disp_dev->dev[i]; | 1821 | vpbe_display_layer = disp_dev->dev[i]; |
1822 | vb2_dma_contig_cleanup_ctx(vpbe_display_layer->alloc_ctx); | ||
1831 | /* Unregister video device */ | 1823 | /* Unregister video device */ |
1832 | video_unregister_device(&vpbe_display_layer->video_dev); | 1824 | video_unregister_device(&vpbe_display_layer->video_dev); |
1833 | 1825 | ||