Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 242016
b: refs/heads/master
c: 61f5db5
h: refs/heads/master
v: v3
  • Loading branch information
Laurent Pinchart authored and Mauro Carvalho Chehab committed Mar 22, 2011
1 parent cac7831 commit c01dc80
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 7 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 2c0ab67be1b4197a4effac89bb0604832e38be8d
refs/heads/master: 61f5db549dde43fb91a8b337f3a4096e4076c2d9
23 changes: 23 additions & 0 deletions trunk/Documentation/video4linux/v4l2-framework.txt
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,26 @@ A sub-device driver initializes the v4l2_subdev struct using:
Afterwards you need to initialize subdev->name with a unique name and set the
module owner. This is done for you if you use the i2c helper functions.

If integration with the media framework is needed, you must initialize the
media_entity struct embedded in the v4l2_subdev struct (entity field) by
calling media_entity_init():

struct media_pad *pads = &my_sd->pads;
int err;

err = media_entity_init(&sd->entity, npads, pads, 0);

The pads array must have been previously initialized. There is no need to
manually set the struct media_entity type and name fields, but the revision
field must be initialized if needed.

A reference to the entity will be automatically acquired/released when the
subdev device node (if any) is opened/closed.

Don't forget to cleanup the media entity before the sub-device is destroyed:

media_entity_cleanup(&sd->entity);

A device (bridge) driver needs to register the v4l2_subdev with the
v4l2_device:

Expand All @@ -277,6 +297,9 @@ This can fail if the subdev module disappeared before it could be registered.
After this function was called successfully the subdev->dev field points to
the v4l2_device.

If the v4l2_device parent device has a non-NULL mdev field, the sub-device
entity will be automatically registered with the media device.

You can unregister a sub-device using:

v4l2_device_unregister_subdev(sd);
Expand Down
36 changes: 32 additions & 4 deletions trunk/drivers/media/video/v4l2-device.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,11 @@ void v4l2_device_unregister(struct v4l2_device *v4l2_dev)
EXPORT_SYMBOL_GPL(v4l2_device_unregister);

int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev,
struct v4l2_subdev *sd)
struct v4l2_subdev *sd)
{
#if defined(CONFIG_MEDIA_CONTROLLER)
struct media_entity *entity = &sd->entity;
#endif
int err;

/* Check for valid input */
Expand Down Expand Up @@ -147,6 +150,19 @@ int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev,
return err;
}

#if defined(CONFIG_MEDIA_CONTROLLER)
/* Register the entity. */
if (v4l2_dev->mdev) {
err = media_device_register_entity(v4l2_dev->mdev, entity);
if (err < 0) {
if (sd->internal_ops && sd->internal_ops->unregistered)
sd->internal_ops->unregistered(sd);
module_put(sd->owner);
return err;
}
}
#endif

spin_lock(&v4l2_dev->lock);
list_add_tail(&sd->list, &v4l2_dev->subdevs);
spin_unlock(&v4l2_dev->lock);
Expand Down Expand Up @@ -177,25 +193,37 @@ int v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev)
sd->owner);
if (err < 0)
return err;
#if defined(CONFIG_MEDIA_CONTROLLER)
sd->entity.v4l.major = VIDEO_MAJOR;
sd->entity.v4l.minor = vdev->minor;
#endif
}

return 0;
}
EXPORT_SYMBOL_GPL(v4l2_device_register_subdev_nodes);

void v4l2_device_unregister_subdev(struct v4l2_subdev *sd)
{
struct v4l2_device *v4l2_dev;

/* return if it isn't registered */
if (sd == NULL || sd->v4l2_dev == NULL)
return;

spin_lock(&sd->v4l2_dev->lock);
v4l2_dev = sd->v4l2_dev;

spin_lock(&v4l2_dev->lock);
list_del(&sd->list);
spin_unlock(&sd->v4l2_dev->lock);
spin_unlock(&v4l2_dev->lock);

if (sd->internal_ops && sd->internal_ops->unregistered)
sd->internal_ops->unregistered(sd);
sd->v4l2_dev = NULL;

#if defined(CONFIG_MEDIA_CONTROLLER)
if (v4l2_dev->mdev)
media_device_unregister_entity(&sd->entity);
#endif
video_unregister_device(&sd->devnode);
module_put(sd->owner);
}
Expand Down
28 changes: 26 additions & 2 deletions trunk/drivers/media/video/v4l2-subdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@ static int subdev_open(struct file *file)
{
struct video_device *vdev = video_devdata(file);
struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);
struct v4l2_fh *vfh;
#if defined(CONFIG_MEDIA_CONTROLLER)
struct media_entity *entity;
#endif
struct v4l2_fh *vfh = NULL;
int ret;

if (sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS) {
Expand All @@ -58,11 +61,20 @@ static int subdev_open(struct file *file)
v4l2_fh_add(vfh);
file->private_data = vfh;
}

#if defined(CONFIG_MEDIA_CONTROLLER)
if (sd->v4l2_dev->mdev) {
entity = media_entity_get(&sd->entity);
if (!entity) {
ret = -EBUSY;
goto err;
}
}
#endif
return 0;

err:
if (vfh != NULL) {
v4l2_fh_del(vfh);
v4l2_fh_exit(vfh);
kfree(vfh);
}
Expand All @@ -72,8 +84,16 @@ static int subdev_open(struct file *file)

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;

#if defined(CONFIG_MEDIA_CONTROLLER)
if (sd->v4l2_dev->mdev)
media_entity_put(&sd->entity);
#endif
if (vfh != NULL) {
v4l2_fh_del(vfh);
v4l2_fh_exit(vfh);
Expand Down Expand Up @@ -172,5 +192,9 @@ void v4l2_subdev_init(struct v4l2_subdev *sd, const struct v4l2_subdev_ops *ops)
sd->grp_id = 0;
sd->dev_priv = NULL;
sd->host_priv = NULL;
#if defined(CONFIG_MEDIA_CONTROLLER)
sd->entity.name = sd->name;
sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
#endif
}
EXPORT_SYMBOL(v4l2_subdev_init);
6 changes: 6 additions & 0 deletions trunk/include/media/v4l2-subdev.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#ifndef _V4L2_SUBDEV_H
#define _V4L2_SUBDEV_H

#include <media/media-entity.h>
#include <media/v4l2-common.h>
#include <media/v4l2-dev.h>
#include <media/v4l2-mediabus.h>
Expand Down Expand Up @@ -450,6 +451,9 @@ struct v4l2_subdev_internal_ops {
stand-alone or embedded in a larger struct.
*/
struct v4l2_subdev {
#if defined(CONFIG_MEDIA_CONTROLLER)
struct media_entity entity;
#endif
struct list_head list;
struct module *owner;
u32 flags;
Expand All @@ -472,6 +476,8 @@ struct v4l2_subdev {
unsigned int nevents;
};

#define media_entity_to_v4l2_subdev(ent) \
container_of(ent, struct v4l2_subdev, entity)
#define vdev_to_v4l2_subdev(vdev) \
container_of(vdev, struct v4l2_subdev, devnode)

Expand Down

0 comments on commit c01dc80

Please sign in to comment.