aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/video/v4l2-subdev.c16
-rw-r--r--include/media/v4l2-subdev.h7
2 files changed, 20 insertions, 3 deletions
diff --git a/drivers/media/video/v4l2-subdev.c b/drivers/media/video/v4l2-subdev.c
index 6cef6ad3c9ce..bc763db385df 100644
--- a/drivers/media/video/v4l2-subdev.c
+++ b/drivers/media/video/v4l2-subdev.c
@@ -61,7 +61,7 @@ static int subdev_open(struct file *file)
61 struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev); 61 struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);
62 struct v4l2_subdev_fh *subdev_fh; 62 struct v4l2_subdev_fh *subdev_fh;
63#if defined(CONFIG_MEDIA_CONTROLLER) 63#if defined(CONFIG_MEDIA_CONTROLLER)
64 struct media_entity *entity; 64 struct media_entity *entity = NULL;
65#endif 65#endif
66 int ret; 66 int ret;
67 67
@@ -101,9 +101,19 @@ static int subdev_open(struct file *file)
101 } 101 }
102#endif 102#endif
103 103
104 if (sd->internal_ops && sd->internal_ops->open) {
105 ret = sd->internal_ops->open(sd, subdev_fh);
106 if (ret < 0)
107 goto err;
108 }
109
104 return 0; 110 return 0;
105 111
106err: 112err:
113#if defined(CONFIG_MEDIA_CONTROLLER)
114 if (entity)
115 media_entity_put(entity);
116#endif
107 v4l2_fh_del(&subdev_fh->vfh); 117 v4l2_fh_del(&subdev_fh->vfh);
108 v4l2_fh_exit(&subdev_fh->vfh); 118 v4l2_fh_exit(&subdev_fh->vfh);
109 subdev_fh_free(subdev_fh); 119 subdev_fh_free(subdev_fh);
@@ -114,13 +124,13 @@ err:
114 124
115static int subdev_close(struct file *file) 125static int subdev_close(struct file *file)
116{ 126{
117#if defined(CONFIG_MEDIA_CONTROLLER)
118 struct video_device *vdev = video_devdata(file); 127 struct video_device *vdev = video_devdata(file);
119 struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev); 128 struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);
120#endif
121 struct v4l2_fh *vfh = file->private_data; 129 struct v4l2_fh *vfh = file->private_data;
122 struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh); 130 struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh);
123 131
132 if (sd->internal_ops && sd->internal_ops->close)
133 sd->internal_ops->close(sd, subdev_fh);
124#if defined(CONFIG_MEDIA_CONTROLLER) 134#if defined(CONFIG_MEDIA_CONTROLLER)
125 if (sd->v4l2_dev->mdev) 135 if (sd->v4l2_dev->mdev)
126 media_entity_put(&sd->entity); 136 media_entity_put(&sd->entity);
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
index 72f49eb3002b..f5dddacf8499 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -42,6 +42,7 @@ struct v4l2_ctrl_handler;
42struct v4l2_event_subscription; 42struct v4l2_event_subscription;
43struct v4l2_fh; 43struct v4l2_fh;
44struct v4l2_subdev; 44struct v4l2_subdev;
45struct v4l2_subdev_fh;
45struct tuner_setup; 46struct tuner_setup;
46 47
47/* decode_vbi_line */ 48/* decode_vbi_line */
@@ -431,10 +432,16 @@ struct v4l2_subdev_ops {
431 * 432 *
432 * unregistered: called when this subdev is unregistered. When called the 433 * unregistered: called when this subdev is unregistered. When called the
433 * v4l2_dev field is still set to the correct v4l2_device. 434 * v4l2_dev field is still set to the correct v4l2_device.
435 *
436 * open: called when the subdev device node is opened by an application.
437 *
438 * close: called when the subdev device node is closed.
434 */ 439 */
435struct v4l2_subdev_internal_ops { 440struct v4l2_subdev_internal_ops {
436 int (*registered)(struct v4l2_subdev *sd); 441 int (*registered)(struct v4l2_subdev *sd);
437 void (*unregistered)(struct v4l2_subdev *sd); 442 void (*unregistered)(struct v4l2_subdev *sd);
443 int (*open)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh);
444 int (*close)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh);
438}; 445};
439 446
440#define V4L2_SUBDEV_NAME_SIZE 32 447#define V4L2_SUBDEV_NAME_SIZE 32