diff options
-rw-r--r-- | drivers/media/video/v4l2-subdev.c | 16 | ||||
-rw-r--r-- | include/media/v4l2-subdev.h | 7 |
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 | ||
106 | err: | 112 | err: |
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 | ||
115 | static int subdev_close(struct file *file) | 125 | static 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; | |||
42 | struct v4l2_event_subscription; | 42 | struct v4l2_event_subscription; |
43 | struct v4l2_fh; | 43 | struct v4l2_fh; |
44 | struct v4l2_subdev; | 44 | struct v4l2_subdev; |
45 | struct v4l2_subdev_fh; | ||
45 | struct tuner_setup; | 46 | struct 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 | */ |
435 | struct v4l2_subdev_internal_ops { | 440 | struct 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 |