All of lore.kernel.org
 help / color / mirror / Atom feed
From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
To: linux-media@vger.kernel.org, alsa-devel@alsa-project.org,
	linux-kernel@vger.kernel.org
Cc: sakari.ailus@maxwell.research.nokia.com
Subject: [PATCH v9 05/12] media: Entity use count
Date: Mon, 14 Feb 2011 13:21:00 +0100	[thread overview]
Message-ID: <1297686067-9666-6-git-send-email-laurent.pinchart@ideasonboard.com> (raw)
In-Reply-To: <1297686067-9666-1-git-send-email-laurent.pinchart@ideasonboard.com>

Due to the wide differences between drivers regarding power management
needs, the media controller does not implement power management.
However, the media_entity structure includes a use_count field that
media drivers can use to track the number of users of every entity for
power management needs.

The use_count field is owned by media drivers and must not be touched by
entity drivers. Access to the field must be protected by the media
device graph_mutex lock.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 Documentation/media-framework.txt |   13 ++++++++++
 drivers/media/media-device.c      |    1 +
 drivers/media/media-entity.c      |   46 +++++++++++++++++++++++++++++++++++++
 include/media/media-device.h      |    4 +++
 include/media/media-entity.h      |    9 +++++++
 5 files changed, 73 insertions(+), 0 deletions(-)

diff --git a/Documentation/media-framework.txt b/Documentation/media-framework.txt
index ab17f33..78ae020 100644
--- a/Documentation/media-framework.txt
+++ b/Documentation/media-framework.txt
@@ -258,3 +258,16 @@ When the graph traversal is complete the function will return NULL.
 
 Graph traversal can be interrupted at any moment. No cleanup function call is
 required and the graph structure can be freed normally.
+
+
+Use count and power handling
+----------------------------
+
+Due to the wide differences between drivers regarding power management needs,
+the media controller does not implement power management. However, the
+media_entity structure includes a use_count field that media drivers can use to
+track the number of users of every entity for power management needs.
+
+The use_count field is owned by media drivers and must not be touched by entity
+drivers. Access to the field must be protected by the media device graph_mutex
+lock.
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index a36509a..d2bc809 100644
--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -73,6 +73,7 @@ int __must_check media_device_register(struct media_device *mdev)
 	mdev->entity_id = 1;
 	INIT_LIST_HEAD(&mdev->entities);
 	spin_lock_init(&mdev->lock);
+	mutex_init(&mdev->graph_mutex);
 
 	/* Register the device node. */
 	mdev->devnode.fops = &media_device_fops;
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
index 166f2b5..3e7e2d5 100644
--- a/drivers/media/media-entity.c
+++ b/drivers/media/media-entity.c
@@ -23,6 +23,7 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <media/media-entity.h>
+#include <media/media-device.h>
 
 /**
  * media_entity_init - Initialize a media entity
@@ -196,6 +197,51 @@ media_entity_graph_walk_next(struct media_entity_graph *graph)
 EXPORT_SYMBOL_GPL(media_entity_graph_walk_next);
 
 /* -----------------------------------------------------------------------------
+ * Module use count
+ */
+
+/*
+ * media_entity_get - Get a reference to the parent module
+ * @entity: The entity
+ *
+ * Get a reference to the parent media device module.
+ *
+ * The function will return immediately if @entity is NULL.
+ *
+ * Return a pointer to the entity on success or NULL on failure.
+ */
+struct media_entity *media_entity_get(struct media_entity *entity)
+{
+	if (entity == NULL)
+		return NULL;
+
+	if (entity->parent->dev &&
+	    !try_module_get(entity->parent->dev->driver->owner))
+		return NULL;
+
+	return entity;
+}
+EXPORT_SYMBOL_GPL(media_entity_get);
+
+/*
+ * media_entity_put - Release the reference to the parent module
+ * @entity: The entity
+ *
+ * Release the reference count acquired by media_entity_get().
+ *
+ * The function will return immediately if @entity is NULL.
+ */
+void media_entity_put(struct media_entity *entity)
+{
+	if (entity == NULL)
+		return;
+
+	if (entity->parent->dev)
+		module_put(entity->parent->dev->driver->owner);
+}
+EXPORT_SYMBOL_GPL(media_entity_put);
+
+/* -----------------------------------------------------------------------------
  * Links management
  */
 
diff --git a/include/media/media-device.h b/include/media/media-device.h
index a8390fe..5d2bff4 100644
--- a/include/media/media-device.h
+++ b/include/media/media-device.h
@@ -25,6 +25,7 @@
 
 #include <linux/device.h>
 #include <linux/list.h>
+#include <linux/mutex.h>
 #include <linux/spinlock.h>
 
 #include <media/media-devnode.h>
@@ -42,6 +43,7 @@
  * @entity_id:	ID of the next entity to be registered
  * @entities:	List of registered entities
  * @lock:	Entities list lock
+ * @graph_mutex: Entities graph operation lock
  *
  * This structure represents an abstract high-level media device. It allows easy
  * access to entities and provides basic media device-level support. The
@@ -69,6 +71,8 @@ struct media_device {
 
 	/* Protects the entities list */
 	spinlock_t lock;
+	/* Serializes graph operations. */
+	struct mutex graph_mutex;
 };
 
 /* media_devnode to media_device */
diff --git a/include/media/media-entity.h b/include/media/media-entity.h
index 28f61f6..a9b31d9 100644
--- a/include/media/media-entity.h
+++ b/include/media/media-entity.h
@@ -81,6 +81,12 @@ struct media_entity {
 	struct media_pad *pads;		/* Pads array (num_pads elements) */
 	struct media_link *links;	/* Links array (max_links elements)*/
 
+	/* Reference counts must never be negative, but are signed integers on
+	 * purpose: a simple WARN_ON(<0) check can be used to detect reference
+	 * count bugs that would make them negative.
+	 */
+	int use_count;			/* Use count for the entity. */
+
 	union {
 		/* Node specifications */
 		struct {
@@ -129,6 +135,9 @@ void media_entity_cleanup(struct media_entity *entity);
 int media_entity_create_link(struct media_entity *source, u16 source_pad,
 		struct media_entity *sink, u16 sink_pad, u32 flags);
 
+struct media_entity *media_entity_get(struct media_entity *entity);
+void media_entity_put(struct media_entity *entity);
+
 void media_entity_graph_walk_start(struct media_entity_graph *graph,
 		struct media_entity *entity);
 struct media_entity *
-- 
1.7.3.4


  parent reply	other threads:[~2011-02-14 12:24 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-02-14 12:20 [PATCH v9 00/12] Media controller (core and V4L2) Laurent Pinchart
2011-02-14 12:20 ` [PATCH v9 01/12] media: Media device node support Laurent Pinchart
2011-02-18 22:33   ` [alsa-devel] " Mark Brown
2011-02-18 22:33     ` Mark Brown
2011-02-19 12:09     ` [alsa-devel] " Laurent Pinchart
2011-02-19 12:09       ` Laurent Pinchart
2011-02-14 12:20 ` [PATCH v9 02/12] media: Media device Laurent Pinchart
2011-02-14 12:20 ` [PATCH v9 03/12] media: Entities, pads and links Laurent Pinchart
2011-02-14 12:20 ` [PATCH v9 04/12] media: Entity graph traversal Laurent Pinchart
2011-02-14 12:21 ` Laurent Pinchart [this message]
2011-02-14 12:21 ` [PATCH v9 06/12] media: Media device information query Laurent Pinchart
2011-02-14 12:21 ` [PATCH v9 07/12] media: Entities, pads and links enumeration Laurent Pinchart
2011-02-14 12:21 ` [PATCH v9 08/12] media: Links setup Laurent Pinchart
2011-02-14 12:21 ` [PATCH v9 09/12] media: Pipelines and media streams Laurent Pinchart
2011-02-14 12:21 ` [PATCH v9 10/12] v4l: Add a media_device pointer to the v4l2_device structure Laurent Pinchart
2011-02-14 12:21 ` [PATCH v9 11/12] v4l: Make video_device inherit from media_entity Laurent Pinchart
2011-02-14 12:21 ` [PATCH v9 12/12] v4l: Make v4l2_subdev " Laurent Pinchart
2011-02-14 12:49 ` [PATCH v9 00/12] Media controller (core and V4L2) Hans Verkuil

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=1297686067-9666-6-git-send-email-laurent.pinchart@ideasonboard.com \
    --to=laurent.pinchart@ideasonboard.com \
    --cc=alsa-devel@alsa-project.org \
    --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.