diff options
Diffstat (limited to 'drivers/media/video/v4l2-subdev.c')
-rw-r--r-- | drivers/media/video/v4l2-subdev.c | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/drivers/media/video/v4l2-subdev.c b/drivers/media/video/v4l2-subdev.c index 0c67f5a278fb..85573638aa1e 100644 --- a/drivers/media/video/v4l2-subdev.c +++ b/drivers/media/video/v4l2-subdev.c | |||
@@ -35,7 +35,10 @@ static int subdev_open(struct file *file) | |||
35 | { | 35 | { |
36 | struct video_device *vdev = video_devdata(file); | 36 | struct video_device *vdev = video_devdata(file); |
37 | struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev); | 37 | struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev); |
38 | struct v4l2_fh *vfh; | 38 | #if defined(CONFIG_MEDIA_CONTROLLER) |
39 | struct media_entity *entity; | ||
40 | #endif | ||
41 | struct v4l2_fh *vfh = NULL; | ||
39 | int ret; | 42 | int ret; |
40 | 43 | ||
41 | if (sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS) { | 44 | if (sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS) { |
@@ -58,11 +61,20 @@ static int subdev_open(struct file *file) | |||
58 | v4l2_fh_add(vfh); | 61 | v4l2_fh_add(vfh); |
59 | file->private_data = vfh; | 62 | file->private_data = vfh; |
60 | } | 63 | } |
61 | 64 | #if defined(CONFIG_MEDIA_CONTROLLER) | |
65 | if (sd->v4l2_dev->mdev) { | ||
66 | entity = media_entity_get(&sd->entity); | ||
67 | if (!entity) { | ||
68 | ret = -EBUSY; | ||
69 | goto err; | ||
70 | } | ||
71 | } | ||
72 | #endif | ||
62 | return 0; | 73 | return 0; |
63 | 74 | ||
64 | err: | 75 | err: |
65 | if (vfh != NULL) { | 76 | if (vfh != NULL) { |
77 | v4l2_fh_del(vfh); | ||
66 | v4l2_fh_exit(vfh); | 78 | v4l2_fh_exit(vfh); |
67 | kfree(vfh); | 79 | kfree(vfh); |
68 | } | 80 | } |
@@ -72,8 +84,16 @@ err: | |||
72 | 84 | ||
73 | static int subdev_close(struct file *file) | 85 | static int subdev_close(struct file *file) |
74 | { | 86 | { |
87 | #if defined(CONFIG_MEDIA_CONTROLLER) | ||
88 | struct video_device *vdev = video_devdata(file); | ||
89 | struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev); | ||
90 | #endif | ||
75 | struct v4l2_fh *vfh = file->private_data; | 91 | struct v4l2_fh *vfh = file->private_data; |
76 | 92 | ||
93 | #if defined(CONFIG_MEDIA_CONTROLLER) | ||
94 | if (sd->v4l2_dev->mdev) | ||
95 | media_entity_put(&sd->entity); | ||
96 | #endif | ||
77 | if (vfh != NULL) { | 97 | if (vfh != NULL) { |
78 | v4l2_fh_del(vfh); | 98 | v4l2_fh_del(vfh); |
79 | v4l2_fh_exit(vfh); | 99 | v4l2_fh_exit(vfh); |
@@ -172,5 +192,9 @@ void v4l2_subdev_init(struct v4l2_subdev *sd, const struct v4l2_subdev_ops *ops) | |||
172 | sd->grp_id = 0; | 192 | sd->grp_id = 0; |
173 | sd->dev_priv = NULL; | 193 | sd->dev_priv = NULL; |
174 | sd->host_priv = NULL; | 194 | sd->host_priv = NULL; |
195 | #if defined(CONFIG_MEDIA_CONTROLLER) | ||
196 | sd->entity.name = sd->name; | ||
197 | sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV; | ||
198 | #endif | ||
175 | } | 199 | } |
176 | EXPORT_SYMBOL(v4l2_subdev_init); | 200 | EXPORT_SYMBOL(v4l2_subdev_init); |