Merge tag 'media/v4.16-2' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 6 Feb 2018 19:27:48 +0000 (11:27 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 6 Feb 2018 19:27:48 +0000 (11:27 -0800)
Pull media updates from Mauro Carvalho Chehab:

 - videobuf2 was moved to a media/common dir, as it is now used by the
   DVB subsystem too

 - Digital TV core memory mapped support interface

 - new sensor driver: ov7740

 - several improvements at ddbridge driver

 - new V4L2 driver: IPU3 CIO2 CSI-2 receiver unit, found on some Intel
   SoCs

 - new tuner driver: tda18250

 - finally got rid of all LIRC staging drivers

 - as we don't have old lirc drivers anymore, restruct the lirc device
   code

 - add support for UVC metadata

 - add a new staging driver for NVIDIA Tegra Video Decoder Engine

 - DVB kAPI headers moved to include/media

 - synchronize the kAPI and uAPI for the DVB subsystem, removing the gap
   for non-legacy APIs

 - reduce the kAPI gap for V4L2

 - lots of other driver enhancements, cleanups, etc.

* tag 'media/v4.16-2' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (407 commits)
  media: v4l2-compat-ioctl32.c: make ctrl_is_pointer work for subdevs
  media: v4l2-compat-ioctl32.c: refactor compat ioctl32 logic
  media: v4l2-compat-ioctl32.c: don't copy back the result for certain errors
  media: v4l2-compat-ioctl32.c: drop pr_info for unknown buffer type
  media: v4l2-compat-ioctl32.c: copy clip list in put_v4l2_window32
  media: v4l2-compat-ioctl32.c: fix ctrl_is_pointer
  media: v4l2-compat-ioctl32.c: copy m.userptr in put_v4l2_plane32
  media: v4l2-compat-ioctl32.c: avoid sizeof(type)
  media: v4l2-compat-ioctl32.c: move 'helper' functions to __get/put_v4l2_format32
  media: v4l2-compat-ioctl32.c: fix the indentation
  media: v4l2-compat-ioctl32.c: add missing VIDIOC_PREPARE_BUF
  media: v4l2-ioctl.c: don't copy back the result for -ENOTTY
  media: v4l2-ioctl.c: use check_fmt for enum/g/s/try_fmt
  media: vivid: fix module load error when enabling fb and no_error_inj=1
  media: dvb_demux: improve debug messages
  media: dvb_demux: Better handle discontinuity errors
  media: cxusb, dib0700: ignore XC2028_I2C_FLUSH
  media: ts2020: avoid integer overflows on 32 bit machines
  media: i2c: ov7740: use gpio/consumer.h instead of gpio.h
  media: entity: Add a nop variant of media_entity_cleanup
  ...

46 files changed:
1  2 
MAINTAINERS
arch/arm/boot/dts/omap3-n900.dts
drivers/media/cec/cec-api.c
drivers/media/common/siano/smsdvb-debugfs.c
drivers/media/common/videobuf2/videobuf2-core.c
drivers/media/common/videobuf2/videobuf2-v4l2.c
drivers/media/dvb-core/dmxdev.c
drivers/media/dvb-core/dvb_ca_en50221.c
drivers/media/dvb-core/dvb_frontend.c
drivers/media/firewire/firedtv-ci.c
drivers/media/pci/cx18/cx18-fileops.c
drivers/media/pci/ddbridge/ddbridge-core.c
drivers/media/pci/meye/meye.c
drivers/media/pci/saa7134/saa7134-video.c
drivers/media/pci/zoran/zoran_driver.c
drivers/media/platform/davinci/vpfe_capture.c
drivers/media/platform/exynos-gsc/gsc-m2m.c
drivers/media/platform/m2m-deinterlace.c
drivers/media/platform/omap/omap_vout.c
drivers/media/platform/s5p-mfc/s5p_mfc.c
drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c
drivers/media/platform/soc_camera/soc_camera.c
drivers/media/platform/vivid/vivid-core.c
drivers/media/platform/vivid/vivid-radio-rx.c
drivers/media/platform/vivid/vivid-radio-tx.c
drivers/media/radio/radio-cadet.c
drivers/media/radio/radio-si476x.c
drivers/media/radio/si470x/radio-si470x-common.c
drivers/media/rc/lirc_dev.c
drivers/media/usb/cpia2/cpia2_v4l.c
drivers/media/usb/cx231xx/cx231xx-video.c
drivers/media/usb/gspca/gspca.c
drivers/media/usb/hdpvr/hdpvr-video.c
drivers/media/usb/pvrusb2/pvrusb2-v4l2.c
drivers/media/usb/stkwebcam/stk-webcam.c
drivers/media/usb/tm6000/tm6000-video.c
drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c
drivers/media/usb/ttusb-dec/ttusb_dec.c
drivers/media/usb/uvc/uvc_queue.c
drivers/media/usb/uvc/uvc_v4l2.c
drivers/media/usb/uvc/uvcvideo.h
drivers/media/v4l2-core/v4l2-dev.c
include/media/v4l2-ctrls.h
include/media/v4l2-dev.h
include/media/videobuf2-core.h
include/media/videobuf2-v4l2.h

diff --cc MAINTAINERS
Simple merge
Simple merge
index 9d6c496f756cd5481e4c01b4e9dc331f7f21e4d4,37e468074dc16e1495042a8dd726a0fcc3070e93..ecc89d9a279b288419c9a1a227b2e3c5607cbb64
@@@ -43,15 -43,14 +43,14 @@@ static inline struct cec_devnode *cec_d
  
  /* CEC file operations */
  
 -static unsigned int cec_poll(struct file *filp,
 +static __poll_t cec_poll(struct file *filp,
                             struct poll_table_struct *poll)
  {
-       struct cec_devnode *devnode = cec_devnode_data(filp);
        struct cec_fh *fh = filp->private_data;
        struct cec_adapter *adap = fh->adap;
 -      unsigned int res = 0;
 +      __poll_t res = 0;
  
-       if (!devnode->registered)
+       if (!cec_is_registered(adap))
                return POLLERR | POLLHUP;
        mutex_lock(&adap->lock);
        if (adap->is_configured &&
index 3fe0eb740a6dce297b129799a55e0289d553ee9d,5eada88414d1dc8d94503cb583253627e0946d01..bc198f84b9cd0d06e0af783331259b43802613c7
@@@ -1164,7 -1321,12 +1321,12 @@@ static __poll_t dvb_dvr_poll(struct fil
  {
        struct dvb_device *dvbdev = file->private_data;
        struct dmxdev *dmxdev = dvbdev->priv;
 -      unsigned int mask = 0;
 +      __poll_t mask = 0;
+ #ifndef DVB_MMAP
+       bool need_ringbuffer = false;
+ #else
+       const bool need_ringbuffer = true;
+ #endif
  
        dprintk("%s\n", __func__);
  
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index aab53641838b7a7c77ad9e9d71f6b2531c73aefc,6ef5b24eb1d87096779034ec143463e27b5ba6b2..b3544988586e881397847260ab984abb126b66c8
@@@ -335,149 -457,337 +457,336 @@@ static long ir_lirc_ioctl(struct file *
                        break;
                }
  
-               result = get_user(mode, (__u32 __user *)arg);
-               if (!result && !(LIRC_MODE2REC(mode) & d->features))
-                       result = -EINVAL;
-               /*
-                * FIXME: We should actually set the mode somehow but
-                * for now, lirc_serial doesn't support mode changing either
-                */
+               if (!ret)
+                       fh->rec_mode = val;
+               break;
+       case LIRC_GET_SEND_MODE:
+               if (!dev->tx_ir)
+                       ret = -ENOTTY;
+               else
+                       val = fh->send_mode;
+               break;
+       case LIRC_SET_SEND_MODE:
+               if (!dev->tx_ir)
+                       ret = -ENOTTY;
+               else if (!(val == LIRC_MODE_PULSE || val == LIRC_MODE_SCANCODE))
+                       ret = -EINVAL;
+               else
+                       fh->send_mode = val;
+               break;
+       /* TX settings */
+       case LIRC_SET_TRANSMITTER_MASK:
+               if (!dev->s_tx_mask)
+                       ret = -ENOTTY;
+               else
+                       ret = dev->s_tx_mask(dev, val);
+               break;
+       case LIRC_SET_SEND_CARRIER:
+               if (!dev->s_tx_carrier)
+                       ret = -ENOTTY;
+               else
+                       ret = dev->s_tx_carrier(dev, val);
+               break;
+       case LIRC_SET_SEND_DUTY_CYCLE:
+               if (!dev->s_tx_duty_cycle)
+                       ret = -ENOTTY;
+               else if (val <= 0 || val >= 100)
+                       ret = -EINVAL;
+               else
+                       ret = dev->s_tx_duty_cycle(dev, val);
+               break;
+       /* RX settings */
+       case LIRC_SET_REC_CARRIER:
+               if (!dev->s_rx_carrier_range)
+                       ret = -ENOTTY;
+               else if (val <= 0)
+                       ret = -EINVAL;
+               else
+                       ret = dev->s_rx_carrier_range(dev, fh->carrier_low,
+                                                     val);
+               break;
+       case LIRC_SET_REC_CARRIER_RANGE:
+               if (!dev->s_rx_carrier_range)
+                       ret = -ENOTTY;
+               else if (val <= 0)
+                       ret = -EINVAL;
+               else
+                       fh->carrier_low = val;
+               break;
+       case LIRC_GET_REC_RESOLUTION:
+               if (!dev->rx_resolution)
+                       ret = -ENOTTY;
+               else
+                       val = dev->rx_resolution / 1000;
                break;
-       case LIRC_GET_LENGTH:
-               result = put_user(d->code_length, (__u32 __user *)arg);
+       case LIRC_SET_WIDEBAND_RECEIVER:
+               if (!dev->s_learning_mode)
+                       ret = -ENOTTY;
+               else
+                       ret = dev->s_learning_mode(dev, !!val);
                break;
+       case LIRC_SET_MEASURE_CARRIER_MODE:
+               if (!dev->s_carrier_report)
+                       ret = -ENOTTY;
+               else
+                       ret = dev->s_carrier_report(dev, !!val);
+               break;
+       /* Generic timeout support */
+       case LIRC_GET_MIN_TIMEOUT:
+               if (!dev->max_timeout)
+                       ret = -ENOTTY;
+               else
+                       val = DIV_ROUND_UP(dev->min_timeout, 1000);
+               break;
+       case LIRC_GET_MAX_TIMEOUT:
+               if (!dev->max_timeout)
+                       ret = -ENOTTY;
+               else
+                       val = dev->max_timeout / 1000;
+               break;
+       case LIRC_SET_REC_TIMEOUT:
+               if (!dev->max_timeout) {
+                       ret = -ENOTTY;
+               } else if (val > U32_MAX / 1000) {
+                       /* Check for multiply overflow */
+                       ret = -EINVAL;
+               } else {
+                       u32 tmp = val * 1000;
+                       if (tmp < dev->min_timeout || tmp > dev->max_timeout)
+                               ret = -EINVAL;
+                       else if (dev->s_timeout)
+                               ret = dev->s_timeout(dev, tmp);
+                       else if (!ret)
+                               dev->timeout = tmp;
+               }
+               break;
+       case LIRC_SET_REC_TIMEOUT_REPORTS:
+               if (!dev->timeout)
+                       ret = -ENOTTY;
+               else
+                       fh->send_timeout_reports = !!val;
+               break;
        default:
-               result = -ENOTTY;
+               ret = -ENOTTY;
        }
  
+       if (!ret && _IOC_DIR(cmd) & _IOC_READ)
+               ret = put_user(val, argp);
  out:
-       mutex_unlock(&d->mutex);
-       return result;
+       mutex_unlock(&dev->lock);
+       return ret;
  }
- EXPORT_SYMBOL(lirc_dev_fop_ioctl);
  
- ssize_t lirc_dev_fop_read(struct file *file,
-                         char __user *buffer,
-                         size_t length,
-                         loff_t *ppos)
 -static unsigned int ir_lirc_poll(struct file *file,
 -                               struct poll_table_struct *wait)
++static __poll_t ir_lirc_poll(struct file *file, struct poll_table_struct *wait)
  {
-       struct lirc_dev *d = file->private_data;
-       unsigned char *buf;
-       int ret, written = 0;
-       DECLARE_WAITQUEUE(wait, current);
+       struct lirc_fh *fh = file->private_data;
+       struct rc_dev *rcdev = fh->rc;
 -      unsigned int events = 0;
++      __poll_t events = 0;
+       poll_wait(file, &fh->wait_poll, wait);
+       if (!rcdev->registered) {
+               events = POLLHUP | POLLERR;
+       } else if (rcdev->driver_type != RC_DRIVER_IR_RAW_TX) {
+               if (fh->rec_mode == LIRC_MODE_SCANCODE &&
+                   !kfifo_is_empty(&fh->scancodes))
+                       events = POLLIN | POLLRDNORM;
+               if (fh->rec_mode == LIRC_MODE_MODE2 &&
+                   !kfifo_is_empty(&fh->rawir))
+                       events = POLLIN | POLLRDNORM;
+       }
  
-       buf = kzalloc(d->buf->chunk_size, GFP_KERNEL);
-       if (!buf)
-               return -ENOMEM;
+       return events;
+ }
  
-       dev_dbg(&d->dev, LOGHEAD "read called\n", d->name, d->minor);
+ static ssize_t ir_lirc_read_mode2(struct file *file, char __user *buffer,
+                                 size_t length)
+ {
+       struct lirc_fh *fh = file->private_data;
+       struct rc_dev *rcdev = fh->rc;
+       unsigned int copied;
+       int ret;
  
-       ret = mutex_lock_interruptible(&d->mutex);
-       if (ret) {
-               kfree(buf);
-               return ret;
-       }
+       if (length < sizeof(unsigned int) || length % sizeof(unsigned int))
+               return -EINVAL;
  
-       if (!d->attached) {
-               ret = -ENODEV;
-               goto out_locked;
-       }
+       do {
+               if (kfifo_is_empty(&fh->rawir)) {
+                       if (file->f_flags & O_NONBLOCK)
+                               return -EAGAIN;
  
-       if (!LIRC_CAN_REC(d->features)) {
-               ret = -EINVAL;
-               goto out_locked;
-       }
+                       ret = wait_event_interruptible(fh->wait_poll,
+                                       !kfifo_is_empty(&fh->rawir) ||
+                                       !rcdev->registered);
+                       if (ret)
+                               return ret;
+               }
  
-       if (length % d->buf->chunk_size) {
-               ret = -EINVAL;
-               goto out_locked;
-       }
+               if (!rcdev->registered)
+                       return -ENODEV;
  
-       /*
-        * we add ourselves to the task queue before buffer check
-        * to avoid losing scan code (in case when queue is awaken somewhere
-        * between while condition checking and scheduling)
-        */
-       add_wait_queue(&d->buf->wait_poll, &wait);
+               ret = mutex_lock_interruptible(&rcdev->lock);
+               if (ret)
+                       return ret;
+               ret = kfifo_to_user(&fh->rawir, buffer, length, &copied);
+               mutex_unlock(&rcdev->lock);
+               if (ret)
+                       return ret;
+       } while (copied == 0);
  
-       /*
-        * while we didn't provide 'length' bytes, device is opened in blocking
-        * mode and 'copy_to_user' is happy, wait for data.
-        */
-       while (written < length && ret == 0) {
-               if (lirc_buffer_empty(d->buf)) {
-                       /* According to the read(2) man page, 'written' can be
-                        * returned as less than 'length', instead of blocking
-                        * again, returning -EWOULDBLOCK, or returning
-                        * -ERESTARTSYS
-                        */
-                       if (written)
-                               break;
-                       if (file->f_flags & O_NONBLOCK) {
-                               ret = -EWOULDBLOCK;
-                               break;
-                       }
-                       if (signal_pending(current)) {
-                               ret = -ERESTARTSYS;
-                               break;
-                       }
-                       mutex_unlock(&d->mutex);
-                       set_current_state(TASK_INTERRUPTIBLE);
-                       schedule();
-                       set_current_state(TASK_RUNNING);
-                       ret = mutex_lock_interruptible(&d->mutex);
-                       if (ret) {
-                               remove_wait_queue(&d->buf->wait_poll, &wait);
-                               goto out_unlocked;
-                       }
-                       if (!d->attached) {
-                               ret = -ENODEV;
-                               goto out_locked;
-                       }
-               } else {
-                       lirc_buffer_read(d->buf, buf);
-                       ret = copy_to_user((void __user *)buffer+written, buf,
-                                          d->buf->chunk_size);
-                       if (!ret)
-                               written += d->buf->chunk_size;
-                       else
-                               ret = -EFAULT;
+       return copied;
+ }
+ static ssize_t ir_lirc_read_scancode(struct file *file, char __user *buffer,
+                                    size_t length)
+ {
+       struct lirc_fh *fh = file->private_data;
+       struct rc_dev *rcdev = fh->rc;
+       unsigned int copied;
+       int ret;
+       if (length < sizeof(struct lirc_scancode) ||
+           length % sizeof(struct lirc_scancode))
+               return -EINVAL;
+       do {
+               if (kfifo_is_empty(&fh->scancodes)) {
+                       if (file->f_flags & O_NONBLOCK)
+                               return -EAGAIN;
+                       ret = wait_event_interruptible(fh->wait_poll,
+                                       !kfifo_is_empty(&fh->scancodes) ||
+                                       !rcdev->registered);
+                       if (ret)
+                               return ret;
                }
-       }
  
-       remove_wait_queue(&d->buf->wait_poll, &wait);
+               if (!rcdev->registered)
+                       return -ENODEV;
+               ret = mutex_lock_interruptible(&rcdev->lock);
+               if (ret)
+                       return ret;
+               ret = kfifo_to_user(&fh->scancodes, buffer, length, &copied);
+               mutex_unlock(&rcdev->lock);
+               if (ret)
+                       return ret;
+       } while (copied == 0);
+       return copied;
+ }
  
- out_locked:
-       mutex_unlock(&d->mutex);
+ static ssize_t ir_lirc_read(struct file *file, char __user *buffer,
+                           size_t length, loff_t *ppos)
+ {
+       struct lirc_fh *fh = file->private_data;
+       struct rc_dev *rcdev = fh->rc;
+       if (rcdev->driver_type == RC_DRIVER_IR_RAW_TX)
+               return -EINVAL;
  
- out_unlocked:
-       kfree(buf);
+       if (!rcdev->registered)
+               return -ENODEV;
  
-       return ret ? ret : written;
+       if (fh->rec_mode == LIRC_MODE_MODE2)
+               return ir_lirc_read_mode2(file, buffer, length);
+       else /* LIRC_MODE_SCANCODE */
+               return ir_lirc_read_scancode(file, buffer, length);
  }
- EXPORT_SYMBOL(lirc_dev_fop_read);
  
- void lirc_init_pdata(struct inode *inode, struct file *file)
+ static const struct file_operations lirc_fops = {
+       .owner          = THIS_MODULE,
+       .write          = ir_lirc_transmit_ir,
+       .unlocked_ioctl = ir_lirc_ioctl,
+ #ifdef CONFIG_COMPAT
+       .compat_ioctl   = ir_lirc_ioctl,
+ #endif
+       .read           = ir_lirc_read,
+       .poll           = ir_lirc_poll,
+       .open           = ir_lirc_open,
+       .release        = ir_lirc_close,
+       .llseek         = no_llseek,
+ };
+ static void lirc_release_device(struct device *ld)
  {
-       struct lirc_dev *d = container_of(inode->i_cdev, struct lirc_dev, cdev);
+       struct rc_dev *rcdev = container_of(ld, struct rc_dev, lirc_dev);
  
-       file->private_data = d;
+       put_device(&rcdev->dev);
  }
- EXPORT_SYMBOL(lirc_init_pdata);
  
void *lirc_get_pdata(struct file *file)
int ir_lirc_register(struct rc_dev *dev)
  {
-       struct lirc_dev *d = file->private_data;
+       int err, minor;
+       minor = ida_simple_get(&lirc_ida, 0, RC_DEV_MAX, GFP_KERNEL);
+       if (minor < 0)
+               return minor;
+       device_initialize(&dev->lirc_dev);
+       dev->lirc_dev.class = lirc_class;
+       dev->lirc_dev.parent = &dev->dev;
+       dev->lirc_dev.release = lirc_release_device;
+       dev->lirc_dev.devt = MKDEV(MAJOR(lirc_base_dev), minor);
+       dev_set_name(&dev->lirc_dev, "lirc%d", minor);
  
-       return d->data;
+       INIT_LIST_HEAD(&dev->lirc_fh);
+       spin_lock_init(&dev->lirc_fh_lock);
+       cdev_init(&dev->lirc_cdev, &lirc_fops);
+       err = cdev_device_add(&dev->lirc_cdev, &dev->lirc_dev);
+       if (err)
+               goto out_ida;
+       get_device(&dev->dev);
+       dev_info(&dev->dev, "lirc_dev: driver %s registered at minor = %d",
+                dev->driver_name, minor);
+       return 0;
+ out_ida:
+       ida_simple_remove(&lirc_ida, minor);
+       return err;
  }
- EXPORT_SYMBOL(lirc_get_pdata);
  
+ void ir_lirc_unregister(struct rc_dev *dev)
+ {
+       unsigned long flags;
+       struct lirc_fh *fh;
+       dev_dbg(&dev->dev, "lirc_dev: driver %s unregistered from minor = %d\n",
+               dev->driver_name, MINOR(dev->lirc_dev.devt));
+       spin_lock_irqsave(&dev->lirc_fh_lock, flags);
+       list_for_each_entry(fh, &dev->lirc_fh, list)
+               wake_up_poll(&fh->wait_poll, POLLHUP | POLLERR);
+       spin_unlock_irqrestore(&dev->lirc_fh_lock, flags);
  
- static int __init lirc_dev_init(void)
+       cdev_device_del(&dev->lirc_cdev, &dev->lirc_dev);
+       ida_simple_remove(&lirc_ida, MINOR(dev->lirc_dev.devt));
+ }
+ int __init lirc_dev_init(void)
  {
        int retval;
  
Simple merge
index b72d02e225fd600b85205aba0fb899ddf979c407,101649770ef47c42e9d5450097da6662fa70c6bd..87e18d0c57664d999a8d37e8d684466ebbd5adf6
        return ret;
  }
  
 -static unsigned int dev_poll(struct file *file, poll_table *wait)
 +static __poll_t dev_poll(struct file *file, poll_table *wait)
  {
        struct gspca_dev *gspca_dev = video_drvdata(file);
 -      unsigned long req_events = poll_requested_events(wait);
 -      int ret = 0;
 +      __poll_t req_events = poll_requested_events(wait);
 +      __poll_t ret = 0;
  
-       PDEBUG(D_FRAM, "poll");
+       gspca_dbg(gspca_dev, D_FRAM, "poll\n");
  
        if (req_events & POLLPRI)
                ret |= v4l2_ctrl_poll(file, wait);
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index e55efc62a9503957ff3d320471feb104467acbf8,f3ee4c7c2fb398cb5b0b548f50c2b9a0c25cbe40..aa16c064294f0139188950bdf72f8cbdb7e5c1ba
@@@ -871,11 -944,27 +944,27 @@@ unsigned long vb2_get_unmapped_area(str
   * The return values from this function are intended to be directly returned
   * from poll handler in driver.
   */
 -unsigned int vb2_core_poll(struct vb2_queue *q, struct file *file,
 +__poll_t vb2_core_poll(struct vb2_queue *q, struct file *file,
                           poll_table *wait);
  
+ /**
+  * vb2_read() - implements read() syscall logic.
+  * @q:                pointer to &struct vb2_queue with videobuf2 queue.
+  * @data:     pointed to target userspace buffer
+  * @count:    number of bytes to read
+  * @ppos:     file handle position tracking pointer
+  * @nonblock: mode selector (1 means blocking calls, 0 means nonblocking)
+  */
  size_t vb2_read(struct vb2_queue *q, char __user *data, size_t count,
                loff_t *ppos, int nonblock);
+ /**
+  * vb2_read() - implements write() syscall logic.
+  * @q:                pointer to &struct vb2_queue with videobuf2 queue.
+  * @data:     pointed to target userspace buffer
+  * @count:    number of bytes to write
+  * @ppos:     file handle position tracking pointer
+  * @nonblock: mode selector (1 means blocking calls, 0 means nonblocking)
+  */
  size_t vb2_write(struct vb2_queue *q, const char __user *data, size_t count,
                loff_t *ppos, int nonblock);
  
Simple merge