Commit f0beea8f authored by Laurent Pinchart's avatar Laurent Pinchart Committed by Mauro Carvalho Chehab

[media] v4l: subdev: Add new file operations

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: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: default avatarHans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 7cd5a16b
...@@ -61,7 +61,7 @@ static int subdev_open(struct file *file) ...@@ -61,7 +61,7 @@ static int subdev_open(struct file *file)
struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev); struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);
struct v4l2_subdev_fh *subdev_fh; struct v4l2_subdev_fh *subdev_fh;
#if defined(CONFIG_MEDIA_CONTROLLER) #if defined(CONFIG_MEDIA_CONTROLLER)
struct media_entity *entity; struct media_entity *entity = NULL;
#endif #endif
int ret; int ret;
...@@ -101,9 +101,19 @@ static int subdev_open(struct file *file) ...@@ -101,9 +101,19 @@ static int subdev_open(struct file *file)
} }
#endif #endif
if (sd->internal_ops && sd->internal_ops->open) {
ret = sd->internal_ops->open(sd, subdev_fh);
if (ret < 0)
goto err;
}
return 0; return 0;
err: err:
#if defined(CONFIG_MEDIA_CONTROLLER)
if (entity)
media_entity_put(entity);
#endif
v4l2_fh_del(&subdev_fh->vfh); v4l2_fh_del(&subdev_fh->vfh);
v4l2_fh_exit(&subdev_fh->vfh); v4l2_fh_exit(&subdev_fh->vfh);
subdev_fh_free(subdev_fh); subdev_fh_free(subdev_fh);
...@@ -114,13 +124,13 @@ static int subdev_open(struct file *file) ...@@ -114,13 +124,13 @@ static int subdev_open(struct file *file)
static int subdev_close(struct file *file) static int subdev_close(struct file *file)
{ {
#if defined(CONFIG_MEDIA_CONTROLLER)
struct video_device *vdev = video_devdata(file); struct video_device *vdev = video_devdata(file);
struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev); struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);
#endif
struct v4l2_fh *vfh = file->private_data; struct v4l2_fh *vfh = file->private_data;
struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh); 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 defined(CONFIG_MEDIA_CONTROLLER)
if (sd->v4l2_dev->mdev) if (sd->v4l2_dev->mdev)
media_entity_put(&sd->entity); media_entity_put(&sd->entity);
......
...@@ -42,6 +42,7 @@ struct v4l2_ctrl_handler; ...@@ -42,6 +42,7 @@ struct v4l2_ctrl_handler;
struct v4l2_event_subscription; struct v4l2_event_subscription;
struct v4l2_fh; struct v4l2_fh;
struct v4l2_subdev; struct v4l2_subdev;
struct v4l2_subdev_fh;
struct tuner_setup; struct tuner_setup;
/* decode_vbi_line */ /* decode_vbi_line */
...@@ -431,10 +432,16 @@ struct v4l2_subdev_ops { ...@@ -431,10 +432,16 @@ struct v4l2_subdev_ops {
* *
* unregistered: called when this subdev is unregistered. When called the * unregistered: called when this subdev is unregistered. When called the
* v4l2_dev field is still set to the correct v4l2_device. * 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 { struct v4l2_subdev_internal_ops {
int (*registered)(struct v4l2_subdev *sd); int (*registered)(struct v4l2_subdev *sd);
void (*unregistered)(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 #define V4L2_SUBDEV_NAME_SIZE 32
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment