[media] v4l: subdev: Add new file operations
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Sun, 1 Aug 2010 22:05:09 +0000 (19:05 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Tue, 22 Mar 2011 07:53:27 +0000 (04:53 -0300)
V4L2 sub-devices store pad formats and crop settings in the file handle.
To let drivers initialize those settings properly, add an open operation
that is called when the subdev is opened as well as a corresponding
close operation.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/video/v4l2-subdev.c
include/media/v4l2-subdev.h

index 6cef6ad3c9ce7b6f7b50a3c10fdd5d7a888b5e0a..bc763db385df4af8d2bea5f5561a13cb0883b56d 100644 (file)
@@ -61,7 +61,7 @@ static int subdev_open(struct file *file)
        struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);
        struct v4l2_subdev_fh *subdev_fh;
 #if defined(CONFIG_MEDIA_CONTROLLER)
-       struct media_entity *entity;
+       struct media_entity *entity = NULL;
 #endif
        int ret;
 
@@ -101,9 +101,19 @@ static int subdev_open(struct file *file)
        }
 #endif
 
+       if (sd->internal_ops && sd->internal_ops->open) {
+               ret = sd->internal_ops->open(sd, subdev_fh);
+               if (ret < 0)
+                       goto err;
+       }
+
        return 0;
 
 err:
+#if defined(CONFIG_MEDIA_CONTROLLER)
+       if (entity)
+               media_entity_put(entity);
+#endif
        v4l2_fh_del(&subdev_fh->vfh);
        v4l2_fh_exit(&subdev_fh->vfh);
        subdev_fh_free(subdev_fh);
@@ -114,13 +124,13 @@ err:
 
 static int subdev_close(struct file *file)
 {
-#if defined(CONFIG_MEDIA_CONTROLLER)
        struct video_device *vdev = video_devdata(file);
        struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);
-#endif
        struct v4l2_fh *vfh = file->private_data;
        struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh);
 
+       if (sd->internal_ops && sd->internal_ops->close)
+               sd->internal_ops->close(sd, subdev_fh);
 #if defined(CONFIG_MEDIA_CONTROLLER)
        if (sd->v4l2_dev->mdev)
                media_entity_put(&sd->entity);
index 72f49eb3002babbab1e69a8aa49a68768c96037d..f5dddacf8499460d71c9e8152ef74e29f1da083b 100644 (file)
@@ -42,6 +42,7 @@ struct v4l2_ctrl_handler;
 struct v4l2_event_subscription;
 struct v4l2_fh;
 struct v4l2_subdev;
+struct v4l2_subdev_fh;
 struct tuner_setup;
 
 /* decode_vbi_line */
@@ -431,10 +432,16 @@ struct v4l2_subdev_ops {
  *
  * unregistered: called when this subdev is unregistered. When called the
  *     v4l2_dev field is still set to the correct v4l2_device.
+ *
+ * open: called when the subdev device node is opened by an application.
+ *
+ * close: called when the subdev device node is closed.
  */
 struct v4l2_subdev_internal_ops {
        int (*registered)(struct v4l2_subdev *sd);
        void (*unregistered)(struct v4l2_subdev *sd);
+       int (*open)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh);
+       int (*close)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh);
 };
 
 #define V4L2_SUBDEV_NAME_SIZE 32