| .. | .. | 
|---|
 | 1 | +// SPDX-License-Identifier: GPL-2.0-or-later  | 
|---|
| 1 | 2 |  /* | 
|---|
| 2 | 3 |   * Support eMMa-PrP through mem2mem framework. | 
|---|
| 3 | 4 |   * | 
|---|
| .. | .. | 
|---|
| 10 | 11 |   * | 
|---|
| 11 | 12 |   * Copyright (c) 2011 Vista Silicon S.L. | 
|---|
| 12 | 13 |   * Javier Martin <javier.martin@vista-silicon.com> | 
|---|
| 13 |  | - *  | 
|---|
| 14 |  | - * This program is free software; you can redistribute it and/or modify  | 
|---|
| 15 |  | - * it under the terms of the GNU General Public License as published by the  | 
|---|
| 16 |  | - * Free Software Foundation; either version 2 of the  | 
|---|
| 17 |  | - * License, or (at your option) any later version  | 
|---|
| 18 | 14 |   */ | 
|---|
| 19 | 15 |  #include <linux/module.h> | 
|---|
| 20 | 16 |  #include <linux/clk.h> | 
|---|
| .. | .. | 
|---|
| 124 | 120 |  #define PRP_CNTL_RZ_FIFO_LEVEL(x)       ((x) << 27) | 
|---|
| 125 | 121 |  #define PRP_CNTL_CH2B1EN        (1 << 29) | 
|---|
| 126 | 122 |  #define PRP_CNTL_CH2B2EN        (1 << 30) | 
|---|
| 127 |  | -#define PRP_CNTL_CH2FEN         (1 << 31)  | 
|---|
 | 123 | +#define PRP_CNTL_CH2FEN         (1UL << 31)  | 
|---|
| 128 | 124 |   | 
|---|
| 129 | 125 |  #define PRP_SIZE_HEIGHT(x)	(x) | 
|---|
| 130 | 126 |  #define PRP_SIZE_WIDTH(x)	((x) << 16) | 
|---|
| .. | .. | 
|---|
| 149 | 145 |  #define PRP_INTR_ST_CH2OVF	(1 << 8) | 
|---|
| 150 | 146 |   | 
|---|
| 151 | 147 |  struct emmaprp_fmt { | 
|---|
| 152 |  | -	char	*name;  | 
|---|
| 153 | 148 |  	u32	fourcc; | 
|---|
| 154 | 149 |  	/* Types the format can be used for */ | 
|---|
| 155 | 150 |  	u32	types; | 
|---|
| .. | .. | 
|---|
| 157 | 152 |   | 
|---|
| 158 | 153 |  static struct emmaprp_fmt formats[] = { | 
|---|
| 159 | 154 |  	{ | 
|---|
| 160 |  | -		.name	= "YUV 4:2:0 Planar",  | 
|---|
| 161 | 155 |  		.fourcc	= V4L2_PIX_FMT_YUV420, | 
|---|
| 162 | 156 |  		.types	= MEM2MEM_CAPTURE, | 
|---|
| 163 | 157 |  	}, | 
|---|
| 164 | 158 |  	{ | 
|---|
| 165 |  | -		.name	= "4:2:2, packed, YUYV",  | 
|---|
| 166 | 159 |  		.fourcc	= V4L2_PIX_FMT_YUYV, | 
|---|
| 167 | 160 |  		.types	= MEM2MEM_OUTPUT, | 
|---|
| 168 | 161 |  	}, | 
|---|
| .. | .. | 
|---|
| 214 | 207 |  }; | 
|---|
| 215 | 208 |   | 
|---|
| 216 | 209 |  struct emmaprp_ctx { | 
|---|
 | 210 | +	struct v4l2_fh		fh;  | 
|---|
| 217 | 211 |  	struct emmaprp_dev	*dev; | 
|---|
| 218 | 212 |  	/* Abort requested by m2m */ | 
|---|
| 219 | 213 |  	int			aborting; | 
|---|
| 220 | 214 |  	struct emmaprp_q_data	q_data[2]; | 
|---|
| 221 |  | -	struct v4l2_m2m_ctx	*m2m_ctx;  | 
|---|
| 222 | 215 |  }; | 
|---|
| 223 | 216 |   | 
|---|
| 224 | 217 |  static struct emmaprp_q_data *get_q_data(struct emmaprp_ctx *ctx, | 
|---|
| .. | .. | 
|---|
| 247 | 240 |   | 
|---|
| 248 | 241 |  	dprintk(pcdev, "Aborting task\n"); | 
|---|
| 249 | 242 |   | 
|---|
| 250 |  | -	v4l2_m2m_job_finish(pcdev->m2m_dev, ctx->m2m_ctx);  | 
|---|
 | 243 | +	v4l2_m2m_job_finish(pcdev->m2m_dev, ctx->fh.m2m_ctx);  | 
|---|
| 251 | 244 |  } | 
|---|
| 252 | 245 |   | 
|---|
| 253 | 246 |  static inline void emmaprp_dump_regs(struct emmaprp_dev *pcdev) | 
|---|
| .. | .. | 
|---|
| 282 | 275 |  	dma_addr_t p_in, p_out; | 
|---|
| 283 | 276 |  	u32 tmp; | 
|---|
| 284 | 277 |   | 
|---|
| 285 |  | -	src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);  | 
|---|
| 286 |  | -	dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);  | 
|---|
 | 278 | +	src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);  | 
|---|
 | 279 | +	dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);  | 
|---|
| 287 | 280 |   | 
|---|
| 288 | 281 |  	s_q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); | 
|---|
| 289 | 282 |  	s_width	= s_q_data->width; | 
|---|
| .. | .. | 
|---|
| 357 | 350 |  			pr_err("PrP bus error occurred, this transfer is probably corrupted\n"); | 
|---|
| 358 | 351 |  			writel(PRP_CNTL_SWRST, pcdev->base_emma + PRP_CNTL); | 
|---|
| 359 | 352 |  		} else if (irqst & PRP_INTR_ST_CH2B1CI) { /* buffer ready */ | 
|---|
| 360 |  | -			src_vb = v4l2_m2m_src_buf_remove(curr_ctx->m2m_ctx);  | 
|---|
| 361 |  | -			dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->m2m_ctx);  | 
|---|
 | 353 | +			src_vb = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);  | 
|---|
 | 354 | +			dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);  | 
|---|
| 362 | 355 |   | 
|---|
| 363 | 356 |  			dst_vb->vb2_buf.timestamp = src_vb->vb2_buf.timestamp; | 
|---|
| 364 | 357 |  			dst_vb->flags &= | 
|---|
| .. | .. | 
|---|
| 375 | 368 |  		} | 
|---|
| 376 | 369 |  	} | 
|---|
| 377 | 370 |   | 
|---|
| 378 |  | -	v4l2_m2m_job_finish(pcdev->m2m_dev, curr_ctx->m2m_ctx);  | 
|---|
 | 371 | +	v4l2_m2m_job_finish(pcdev->m2m_dev, curr_ctx->fh.m2m_ctx);  | 
|---|
| 379 | 372 |  	return IRQ_HANDLED; | 
|---|
| 380 | 373 |  } | 
|---|
| 381 | 374 |   | 
|---|
| .. | .. | 
|---|
| 385 | 378 |  static int vidioc_querycap(struct file *file, void *priv, | 
|---|
| 386 | 379 |  			   struct v4l2_capability *cap) | 
|---|
| 387 | 380 |  { | 
|---|
| 388 |  | -	strncpy(cap->driver, MEM2MEM_NAME, sizeof(cap->driver) - 1);  | 
|---|
| 389 |  | -	strncpy(cap->card, MEM2MEM_NAME, sizeof(cap->card) - 1);  | 
|---|
| 390 |  | -	cap->device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING;  | 
|---|
| 391 |  | -	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;  | 
|---|
 | 381 | +	strscpy(cap->driver, MEM2MEM_NAME, sizeof(cap->driver));  | 
|---|
 | 382 | +	strscpy(cap->card, MEM2MEM_NAME, sizeof(cap->card));  | 
|---|
| 392 | 383 |  	return 0; | 
|---|
| 393 | 384 |  } | 
|---|
| 394 | 385 |   | 
|---|
| .. | .. | 
|---|
| 413 | 404 |  	if (i < NUM_FORMATS) { | 
|---|
| 414 | 405 |  		/* Format found */ | 
|---|
| 415 | 406 |  		fmt = &formats[i]; | 
|---|
| 416 |  | -		strlcpy(f->description, fmt->name, sizeof(f->description) - 1);  | 
|---|
| 417 | 407 |  		f->pixelformat = fmt->fourcc; | 
|---|
| 418 | 408 |  		return 0; | 
|---|
| 419 | 409 |  	} | 
|---|
| .. | .. | 
|---|
| 439 | 429 |  	struct vb2_queue *vq; | 
|---|
| 440 | 430 |  	struct emmaprp_q_data *q_data; | 
|---|
| 441 | 431 |   | 
|---|
| 442 |  | -	vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);  | 
|---|
 | 432 | +	vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);  | 
|---|
| 443 | 433 |  	if (!vq) | 
|---|
| 444 | 434 |  		return -EINVAL; | 
|---|
| 445 | 435 |   | 
|---|
| .. | .. | 
|---|
| 544 | 534 |  	struct vb2_queue *vq; | 
|---|
| 545 | 535 |  	int ret; | 
|---|
| 546 | 536 |   | 
|---|
| 547 |  | -	vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);  | 
|---|
 | 537 | +	vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);  | 
|---|
| 548 | 538 |  	if (!vq) | 
|---|
| 549 | 539 |  		return -EINVAL; | 
|---|
| 550 | 540 |   | 
|---|
| .. | .. | 
|---|
| 600 | 590 |  	return vidioc_s_fmt(priv, f); | 
|---|
| 601 | 591 |  } | 
|---|
| 602 | 592 |   | 
|---|
| 603 |  | -static int vidioc_reqbufs(struct file *file, void *priv,  | 
|---|
| 604 |  | -			  struct v4l2_requestbuffers *reqbufs)  | 
|---|
| 605 |  | -{  | 
|---|
| 606 |  | -	struct emmaprp_ctx *ctx = priv;  | 
|---|
| 607 |  | -  | 
|---|
| 608 |  | -	return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs);  | 
|---|
| 609 |  | -}  | 
|---|
| 610 |  | -  | 
|---|
| 611 |  | -static int vidioc_querybuf(struct file *file, void *priv,  | 
|---|
| 612 |  | -			   struct v4l2_buffer *buf)  | 
|---|
| 613 |  | -{  | 
|---|
| 614 |  | -	struct emmaprp_ctx *ctx = priv;  | 
|---|
| 615 |  | -  | 
|---|
| 616 |  | -	return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf);  | 
|---|
| 617 |  | -}  | 
|---|
| 618 |  | -  | 
|---|
| 619 |  | -static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)  | 
|---|
| 620 |  | -{  | 
|---|
| 621 |  | -	struct emmaprp_ctx *ctx = priv;  | 
|---|
| 622 |  | -  | 
|---|
| 623 |  | -	return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);  | 
|---|
| 624 |  | -}  | 
|---|
| 625 |  | -  | 
|---|
| 626 |  | -static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)  | 
|---|
| 627 |  | -{  | 
|---|
| 628 |  | -	struct emmaprp_ctx *ctx = priv;  | 
|---|
| 629 |  | -  | 
|---|
| 630 |  | -	return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);  | 
|---|
| 631 |  | -}  | 
|---|
| 632 |  | -  | 
|---|
| 633 |  | -static int vidioc_streamon(struct file *file, void *priv,  | 
|---|
| 634 |  | -			   enum v4l2_buf_type type)  | 
|---|
| 635 |  | -{  | 
|---|
| 636 |  | -	struct emmaprp_ctx *ctx = priv;  | 
|---|
| 637 |  | -  | 
|---|
| 638 |  | -	return v4l2_m2m_streamon(file, ctx->m2m_ctx, type);  | 
|---|
| 639 |  | -}  | 
|---|
| 640 |  | -  | 
|---|
| 641 |  | -static int vidioc_streamoff(struct file *file, void *priv,  | 
|---|
| 642 |  | -			    enum v4l2_buf_type type)  | 
|---|
| 643 |  | -{  | 
|---|
| 644 |  | -	struct emmaprp_ctx *ctx = priv;  | 
|---|
| 645 |  | -  | 
|---|
| 646 |  | -	return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type);  | 
|---|
| 647 |  | -}  | 
|---|
| 648 |  | -  | 
|---|
| 649 | 593 |  static const struct v4l2_ioctl_ops emmaprp_ioctl_ops = { | 
|---|
| 650 | 594 |  	.vidioc_querycap	= vidioc_querycap, | 
|---|
| 651 | 595 |   | 
|---|
| .. | .. | 
|---|
| 659 | 603 |  	.vidioc_try_fmt_vid_out	= vidioc_try_fmt_vid_out, | 
|---|
| 660 | 604 |  	.vidioc_s_fmt_vid_out	= vidioc_s_fmt_vid_out, | 
|---|
| 661 | 605 |   | 
|---|
| 662 |  | -	.vidioc_reqbufs		= vidioc_reqbufs,  | 
|---|
| 663 |  | -	.vidioc_querybuf	= vidioc_querybuf,  | 
|---|
| 664 |  | -  | 
|---|
| 665 |  | -	.vidioc_qbuf		= vidioc_qbuf,  | 
|---|
| 666 |  | -	.vidioc_dqbuf		= vidioc_dqbuf,  | 
|---|
| 667 |  | -  | 
|---|
| 668 |  | -	.vidioc_streamon	= vidioc_streamon,  | 
|---|
| 669 |  | -	.vidioc_streamoff	= vidioc_streamoff,  | 
|---|
 | 606 | +	.vidioc_reqbufs		= v4l2_m2m_ioctl_reqbufs,  | 
|---|
 | 607 | +	.vidioc_querybuf	= v4l2_m2m_ioctl_querybuf,  | 
|---|
 | 608 | +	.vidioc_qbuf		= v4l2_m2m_ioctl_qbuf,  | 
|---|
 | 609 | +	.vidioc_dqbuf		= v4l2_m2m_ioctl_dqbuf,  | 
|---|
 | 610 | +	.vidioc_prepare_buf	= v4l2_m2m_ioctl_prepare_buf,  | 
|---|
 | 611 | +	.vidioc_expbuf		= v4l2_m2m_ioctl_expbuf,  | 
|---|
 | 612 | +	.vidioc_streamon	= v4l2_m2m_ioctl_streamon,  | 
|---|
 | 613 | +	.vidioc_streamoff	= v4l2_m2m_ioctl_streamoff,  | 
|---|
| 670 | 614 |  }; | 
|---|
| 671 | 615 |   | 
|---|
| 672 | 616 |   | 
|---|
| .. | .. | 
|---|
| 726 | 670 |  { | 
|---|
| 727 | 671 |  	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); | 
|---|
| 728 | 672 |  	struct emmaprp_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); | 
|---|
| 729 |  | -	v4l2_m2m_buf_queue(ctx->m2m_ctx, vbuf);  | 
|---|
 | 673 | +	v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);  | 
|---|
| 730 | 674 |  } | 
|---|
| 731 | 675 |   | 
|---|
| 732 | 676 |  static const struct vb2_ops emmaprp_qops = { | 
|---|
| .. | .. | 
|---|
| 744 | 688 |  	int ret; | 
|---|
| 745 | 689 |   | 
|---|
| 746 | 690 |  	src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; | 
|---|
| 747 |  | -	src_vq->io_modes = VB2_MMAP | VB2_USERPTR;  | 
|---|
 | 691 | +	src_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;  | 
|---|
| 748 | 692 |  	src_vq->drv_priv = ctx; | 
|---|
| 749 | 693 |  	src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); | 
|---|
| 750 | 694 |  	src_vq->ops = &emmaprp_qops; | 
|---|
| .. | .. | 
|---|
| 758 | 702 |  		return ret; | 
|---|
| 759 | 703 |   | 
|---|
| 760 | 704 |  	dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 
|---|
| 761 |  | -	dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;  | 
|---|
 | 705 | +	dst_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;  | 
|---|
| 762 | 706 |  	dst_vq->drv_priv = ctx; | 
|---|
| 763 | 707 |  	dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); | 
|---|
| 764 | 708 |  	dst_vq->ops = &emmaprp_qops; | 
|---|
| .. | .. | 
|---|
| 782 | 726 |  	if (!ctx) | 
|---|
| 783 | 727 |  		return -ENOMEM; | 
|---|
| 784 | 728 |   | 
|---|
| 785 |  | -	file->private_data = ctx;  | 
|---|
 | 729 | +	v4l2_fh_init(&ctx->fh, video_devdata(file));  | 
|---|
 | 730 | +	file->private_data = &ctx->fh;  | 
|---|
| 786 | 731 |  	ctx->dev = pcdev; | 
|---|
| 787 | 732 |   | 
|---|
| 788 | 733 |  	if (mutex_lock_interruptible(&pcdev->dev_mutex)) { | 
|---|
| .. | .. | 
|---|
| 790 | 735 |  		return -ERESTARTSYS; | 
|---|
| 791 | 736 |  	} | 
|---|
| 792 | 737 |   | 
|---|
| 793 |  | -	ctx->m2m_ctx = v4l2_m2m_ctx_init(pcdev->m2m_dev, ctx, &queue_init);  | 
|---|
 | 738 | +	ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(pcdev->m2m_dev, ctx, &queue_init);  | 
|---|
| 794 | 739 |   | 
|---|
| 795 |  | -	if (IS_ERR(ctx->m2m_ctx)) {  | 
|---|
| 796 |  | -		int ret = PTR_ERR(ctx->m2m_ctx);  | 
|---|
 | 740 | +	if (IS_ERR(ctx->fh.m2m_ctx)) {  | 
|---|
 | 741 | +		int ret = PTR_ERR(ctx->fh.m2m_ctx);  | 
|---|
| 797 | 742 |   | 
|---|
| 798 | 743 |  		mutex_unlock(&pcdev->dev_mutex); | 
|---|
| 799 | 744 |  		kfree(ctx); | 
|---|
| .. | .. | 
|---|
| 804 | 749 |  	clk_prepare_enable(pcdev->clk_emma_ahb); | 
|---|
| 805 | 750 |  	ctx->q_data[V4L2_M2M_SRC].fmt = &formats[1]; | 
|---|
| 806 | 751 |  	ctx->q_data[V4L2_M2M_DST].fmt = &formats[0]; | 
|---|
 | 752 | +	v4l2_fh_add(&ctx->fh);  | 
|---|
| 807 | 753 |  	mutex_unlock(&pcdev->dev_mutex); | 
|---|
| 808 | 754 |   | 
|---|
| 809 |  | -	dprintk(pcdev, "Created instance %p, m2m_ctx: %p\n", ctx, ctx->m2m_ctx);  | 
|---|
 | 755 | +	dprintk(pcdev, "Created instance %p, m2m_ctx: %p\n", ctx, ctx->fh.m2m_ctx);  | 
|---|
| 810 | 756 |   | 
|---|
| 811 | 757 |  	return 0; | 
|---|
| 812 | 758 |  } | 
|---|
| .. | .. | 
|---|
| 821 | 767 |  	mutex_lock(&pcdev->dev_mutex); | 
|---|
| 822 | 768 |  	clk_disable_unprepare(pcdev->clk_emma_ahb); | 
|---|
| 823 | 769 |  	clk_disable_unprepare(pcdev->clk_emma_ipg); | 
|---|
| 824 |  | -	v4l2_m2m_ctx_release(ctx->m2m_ctx);  | 
|---|
 | 770 | +	v4l2_fh_del(&ctx->fh);  | 
|---|
 | 771 | +	v4l2_fh_exit(&ctx->fh);  | 
|---|
 | 772 | +	v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);  | 
|---|
| 825 | 773 |  	mutex_unlock(&pcdev->dev_mutex); | 
|---|
| 826 | 774 |  	kfree(ctx); | 
|---|
| 827 | 775 |   | 
|---|
| 828 | 776 |  	return 0; | 
|---|
| 829 | 777 |  } | 
|---|
| 830 | 778 |   | 
|---|
| 831 |  | -static __poll_t emmaprp_poll(struct file *file,  | 
|---|
| 832 |  | -				 struct poll_table_struct *wait)  | 
|---|
| 833 |  | -{  | 
|---|
| 834 |  | -	struct emmaprp_dev *pcdev = video_drvdata(file);  | 
|---|
| 835 |  | -	struct emmaprp_ctx *ctx = file->private_data;  | 
|---|
| 836 |  | -	__poll_t res;  | 
|---|
| 837 |  | -  | 
|---|
| 838 |  | -	mutex_lock(&pcdev->dev_mutex);  | 
|---|
| 839 |  | -	res = v4l2_m2m_poll(file, ctx->m2m_ctx, wait);  | 
|---|
| 840 |  | -	mutex_unlock(&pcdev->dev_mutex);  | 
|---|
| 841 |  | -	return res;  | 
|---|
| 842 |  | -}  | 
|---|
| 843 |  | -  | 
|---|
| 844 |  | -static int emmaprp_mmap(struct file *file, struct vm_area_struct *vma)  | 
|---|
| 845 |  | -{  | 
|---|
| 846 |  | -	struct emmaprp_dev *pcdev = video_drvdata(file);  | 
|---|
| 847 |  | -	struct emmaprp_ctx *ctx = file->private_data;  | 
|---|
| 848 |  | -	int ret;  | 
|---|
| 849 |  | -  | 
|---|
| 850 |  | -	if (mutex_lock_interruptible(&pcdev->dev_mutex))  | 
|---|
| 851 |  | -		return -ERESTARTSYS;  | 
|---|
| 852 |  | -	ret = v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);  | 
|---|
| 853 |  | -	mutex_unlock(&pcdev->dev_mutex);  | 
|---|
| 854 |  | -	return ret;  | 
|---|
| 855 |  | -}  | 
|---|
| 856 |  | -  | 
|---|
| 857 | 779 |  static const struct v4l2_file_operations emmaprp_fops = { | 
|---|
| 858 | 780 |  	.owner		= THIS_MODULE, | 
|---|
| 859 | 781 |  	.open		= emmaprp_open, | 
|---|
| 860 | 782 |  	.release	= emmaprp_release, | 
|---|
| 861 |  | -	.poll		= emmaprp_poll,  | 
|---|
 | 783 | +	.poll		= v4l2_m2m_fop_poll,  | 
|---|
| 862 | 784 |  	.unlocked_ioctl	= video_ioctl2, | 
|---|
| 863 |  | -	.mmap		= emmaprp_mmap,  | 
|---|
 | 785 | +	.mmap		= v4l2_m2m_fop_mmap,  | 
|---|
| 864 | 786 |  }; | 
|---|
| 865 | 787 |   | 
|---|
| 866 | 788 |  static const struct video_device emmaprp_videodev = { | 
|---|
| .. | .. | 
|---|
| 870 | 792 |  	.minor		= -1, | 
|---|
| 871 | 793 |  	.release	= video_device_release, | 
|---|
| 872 | 794 |  	.vfl_dir	= VFL_DIR_M2M, | 
|---|
 | 795 | +	.device_caps	= V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING,  | 
|---|
| 873 | 796 |  }; | 
|---|
| 874 | 797 |   | 
|---|
| 875 | 798 |  static const struct v4l2_m2m_ops m2m_ops = { | 
|---|
| .. | .. | 
|---|
| 946 | 869 |  		goto rel_vdev; | 
|---|
| 947 | 870 |  	} | 
|---|
| 948 | 871 |   | 
|---|
| 949 |  | -	ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);  | 
|---|
 | 872 | +	ret = video_register_device(vfd, VFL_TYPE_VIDEO, 0);  | 
|---|
| 950 | 873 |  	if (ret) { | 
|---|
| 951 | 874 |  		v4l2_err(&pcdev->v4l2_dev, "Failed to register video device\n"); | 
|---|
| 952 | 875 |  		goto rel_m2m; | 
|---|