From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
To: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org,
alsa-devel@alsa-project.org
Cc: sakari.ailus@maxwell.research.nokia.com,
broonie@opensource.wolfsonmicro.com, clemens@ladisch.de
Subject: [PATCH v8 12/12] v4l: Make v4l2_subdev inherit from media_entity
Date: Thu, 27 Jan 2011 13:30:37 +0100 [thread overview]
Message-ID: <1296131437-29954-13-git-send-email-laurent.pinchart@ideasonboard.com> (raw)
In-Reply-To: <1296131437-29954-1-git-send-email-laurent.pinchart@ideasonboard.com>
V4L2 subdevices are media entities. As such they need to inherit from
(include) the media_entity structure.
When registering/unregistering the subdevice, the media entity is
automatically registered/unregistered. The entity is acquired on device
open and released on device close.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
---
Documentation/video4linux/v4l2-framework.txt | 23 ++++++++++++++
drivers/media/video/v4l2-device.c | 39 ++++++++++++++++++++----
drivers/media/video/v4l2-subdev.c | 41 ++++++++++++++++++++++++-
include/media/v4l2-subdev.h | 10 ++++++
4 files changed, 104 insertions(+), 9 deletions(-)
diff --git a/Documentation/video4linux/v4l2-framework.txt b/Documentation/video4linux/v4l2-framework.txt
index f231bc20..d0fb880 100644
--- a/Documentation/video4linux/v4l2-framework.txt
+++ b/Documentation/video4linux/v4l2-framework.txt
@@ -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:
@@ -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);
diff --git a/drivers/media/video/v4l2-device.c b/drivers/media/video/v4l2-device.c
index 5c16a12..69cb429 100644
--- a/drivers/media/video/v4l2-device.c
+++ b/drivers/media/video/v4l2-device.c
@@ -116,8 +116,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
struct video_device *vdev;
int err;
@@ -135,7 +138,16 @@ int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev,
err = v4l2_ctrl_add_handler(v4l2_dev->ctrl_handler, sd->ctrl_handler);
if (err)
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) {
+ module_put(sd->owner);
+ return err;
+ }
+ }
+#endif
sd->v4l2_dev = v4l2_dev;
spin_lock(&v4l2_dev->lock);
list_add_tail(&sd->list, &v4l2_dev->subdevs);
@@ -150,26 +162,39 @@ int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev,
if (sd->flags & V4L2_SUBDEV_FL_HAS_DEVNODE) {
err = __video_register_device(vdev, VFL_TYPE_SUBDEV, -1, 1,
sd->owner);
- if (err < 0)
+ if (err < 0) {
v4l2_device_unregister_subdev(sd);
+ return err;
+ }
}
-
- return err;
+#if defined(CONFIG_MEDIA_CONTROLLER)
+ entity->v4l.major = VIDEO_MAJOR;
+ entity->v4l.minor = vdev->minor;
+#endif
+ return 0;
}
EXPORT_SYMBOL_GPL(v4l2_device_register_subdev);
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);
sd->v4l2_dev = NULL;
module_put(sd->owner);
+#if defined(CONFIG_MEDIA_CONTROLLER)
+ if (v4l2_dev->mdev)
+ media_device_unregister_entity(&sd->entity);
+#endif
video_unregister_device(&sd->devnode);
}
EXPORT_SYMBOL_GPL(v4l2_device_unregister_subdev);
diff --git a/drivers/media/video/v4l2-subdev.c b/drivers/media/video/v4l2-subdev.c
index fbccefd..a49856a 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)
{
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->initialized)
@@ -61,11 +64,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);
}
@@ -75,8 +87,16 @@ err:
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);
@@ -176,5 +196,22 @@ void v4l2_subdev_init(struct v4l2_subdev *sd, const struct v4l2_subdev_ops *ops)
sd->dev_priv = NULL;
sd->host_priv = NULL;
sd->initialized = 1;
+#if defined(CONFIG_MEDIA_CONTROLLER)
+ sd->entity.name = sd->name;
+ sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+#endif
}
EXPORT_SYMBOL(v4l2_subdev_init);
+
+#if defined(CONFIG_MEDIA_CONTROLLER)
+int v4l2_subdev_set_power(struct media_entity *entity, int power)
+{
+ struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
+
+ dev_dbg(entity->parent->dev,
+ "%s power%s\n", entity->name, power ? "on" : "off");
+
+ return v4l2_subdev_call(sd, core, s_power, power);
+}
+EXPORT_SYMBOL_GPL(v4l2_subdev_set_power);
+#endif
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
index 68cbe48..7d55b0c 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -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>
@@ -437,6 +438,9 @@ struct v4l2_subdev_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;
@@ -458,6 +462,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)
@@ -486,6 +492,10 @@ static inline void *v4l2_get_subdev_hostdata(const struct v4l2_subdev *sd)
void v4l2_subdev_init(struct v4l2_subdev *sd,
const struct v4l2_subdev_ops *ops);
+#if defined(CONFIG_MEDIA_CONTROLLER)
+int v4l2_subdev_set_power(struct media_entity *entity, int power);
+#endif
+
/* Call an ops of a v4l2_subdev, doing the right checks against
NULL pointers.
--
1.7.3.4
next prev parent reply other threads:[~2011-01-27 12:30 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-01-27 12:30 [PATCH v8 00/12] Media controller (core and V4L2) Laurent Pinchart
2011-01-27 12:30 ` Laurent Pinchart
2011-01-27 12:30 ` [PATCH v8 01/12] media: Media device node support Laurent Pinchart
2011-01-27 12:30 ` Laurent Pinchart
2011-01-27 12:30 ` [PATCH v8 02/12] media: Media device Laurent Pinchart
2011-01-27 12:30 ` [PATCH v8 03/12] media: Entities, pads and links Laurent Pinchart
2011-01-27 12:30 ` Laurent Pinchart
2011-01-28 10:53 ` Sakari Ailus
2011-02-08 13:46 ` Laurent Pinchart
2011-02-08 13:46 ` Laurent Pinchart
2011-02-04 10:20 ` Hans Verkuil
2011-02-08 13:35 ` Laurent Pinchart
2011-02-08 13:35 ` Laurent Pinchart
2011-01-27 12:30 ` [PATCH v8 04/12] media: Entity graph traversal Laurent Pinchart
2011-01-27 12:30 ` Laurent Pinchart
2011-01-27 12:30 ` [PATCH v8 05/12] media: Entity use count Laurent Pinchart
2011-02-04 10:22 ` Hans Verkuil
2011-02-04 12:34 ` Sakari Ailus
2011-02-04 13:19 ` Hans Verkuil
2011-02-08 12:57 ` Laurent Pinchart
2011-02-08 12:57 ` Laurent Pinchart
2011-01-27 12:30 ` [PATCH v8 06/12] media: Media device information query Laurent Pinchart
2011-01-27 12:30 ` [PATCH v8 07/12] media: Entities, pads and links enumeration Laurent Pinchart
2011-01-27 12:30 ` Laurent Pinchart
2011-02-13 21:59 ` Sylwester Nawrocki
2011-02-14 12:11 ` Laurent Pinchart
2011-02-14 12:11 ` Laurent Pinchart
2011-01-27 12:30 ` [PATCH v8 08/12] media: Links setup Laurent Pinchart
2011-01-27 12:30 ` Laurent Pinchart
2011-01-27 12:30 ` [PATCH v8 09/12] media: Pipelines and media streams Laurent Pinchart
2011-01-27 12:30 ` Laurent Pinchart
2011-01-27 12:30 ` [PATCH v8 10/12] v4l: Add a media_device pointer to the v4l2_device structure Laurent Pinchart
2011-01-27 12:30 ` [PATCH v8 11/12] v4l: Make video_device inherit from media_entity Laurent Pinchart
2011-01-27 12:30 ` Laurent Pinchart [this message]
2011-01-28 2:38 ` [PATCH v8 00/12] Media controller (core and V4L2) Raymond Yau
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1296131437-29954-13-git-send-email-laurent.pinchart@ideasonboard.com \
--to=laurent.pinchart@ideasonboard.com \
--cc=alsa-devel@alsa-project.org \
--cc=broonie@opensource.wolfsonmicro.com \
--cc=clemens@ladisch.de \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-media@vger.kernel.org \
--cc=sakari.ailus@maxwell.research.nokia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.