aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/media-framework.txt13
-rw-r--r--drivers/media/media-device.c1
-rw-r--r--drivers/media/media-entity.c46
-rw-r--r--include/media/media-device.h4
-rw-r--r--include/media/media-entity.h9
5 files changed, 73 insertions, 0 deletions
diff --git a/Documentation/media-framework.txt b/Documentation/media-framework.txt
index ab17f33ddedc..78ae02095372 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.
258 258
259Graph traversal can be interrupted at any moment. No cleanup function call is 259Graph traversal can be interrupted at any moment. No cleanup function call is
260required and the graph structure can be freed normally. 260required and the graph structure can be freed normally.
261
262
263Use count and power handling
264----------------------------
265
266Due to the wide differences between drivers regarding power management needs,
267the media controller does not implement power management. However, the
268media_entity structure includes a use_count field that media drivers can use to
269track the number of users of every entity for power management needs.
270
271The use_count field is owned by media drivers and must not be touched by entity
272drivers. Access to the field must be protected by the media device graph_mutex
273lock.
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index a36509a1df09..d2bc809d7a2a 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)
73 mdev->entity_id = 1; 73 mdev->entity_id = 1;
74 INIT_LIST_HEAD(&mdev->entities); 74 INIT_LIST_HEAD(&mdev->entities);
75 spin_lock_init(&mdev->lock); 75 spin_lock_init(&mdev->lock);
76 mutex_init(&mdev->graph_mutex);
76 77
77 /* Register the device node. */ 78 /* Register the device node. */
78 mdev->devnode.fops = &media_device_fops; 79 mdev->devnode.fops = &media_device_fops;
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
index 166f2b5505ce..3e7e2d569cec 100644
--- a/drivers/media/media-entity.c
+++ b/drivers/media/media-entity.c
@@ -23,6 +23,7 @@
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/slab.h> 24#include <linux/slab.h>
25#include <media/media-entity.h> 25#include <media/media-entity.h>
26#include <media/media-device.h>
26 27
27/** 28/**
28 * media_entity_init - Initialize a media entity 29 * media_entity_init - Initialize a media entity
@@ -196,6 +197,51 @@ media_entity_graph_walk_next(struct media_entity_graph *graph)
196EXPORT_SYMBOL_GPL(media_entity_graph_walk_next); 197EXPORT_SYMBOL_GPL(media_entity_graph_walk_next);
197 198
198/* ----------------------------------------------------------------------------- 199/* -----------------------------------------------------------------------------
200 * Module use count
201 */
202
203/*
204 * media_entity_get - Get a reference to the parent module
205 * @entity: The entity
206 *
207 * Get a reference to the parent media device module.
208 *
209 * The function will return immediately if @entity is NULL.
210 *
211 * Return a pointer to the entity on success or NULL on failure.
212 */
213struct media_entity *media_entity_get(struct media_entity *entity)
214{
215 if (entity == NULL)
216 return NULL;
217
218 if (entity->parent->dev &&
219 !try_module_get(entity->parent->dev->driver->owner))
220 return NULL;
221
222 return entity;
223}
224EXPORT_SYMBOL_GPL(media_entity_get);
225
226/*
227 * media_entity_put - Release the reference to the parent module
228 * @entity: The entity
229 *
230 * Release the reference count acquired by media_entity_get().
231 *
232 * The function will return immediately if @entity is NULL.
233 */
234void media_entity_put(struct media_entity *entity)
235{
236 if (entity == NULL)
237 return;
238
239 if (entity->parent->dev)
240 module_put(entity->parent->dev->driver->owner);
241}
242EXPORT_SYMBOL_GPL(media_entity_put);
243
244/* -----------------------------------------------------------------------------
199 * Links management 245 * Links management
200 */ 246 */
201 247
diff --git a/include/media/media-device.h b/include/media/media-device.h
index a8390fe87e83..5d2bff4fc9e0 100644
--- a/include/media/media-device.h
+++ b/include/media/media-device.h
@@ -25,6 +25,7 @@
25 25
26#include <linux/device.h> 26#include <linux/device.h>
27#include <linux/list.h> 27#include <linux/list.h>
28#include <linux/mutex.h>
28#include <linux/spinlock.h> 29#include <linux/spinlock.h>
29 30
30#include <media/media-devnode.h> 31#include <media/media-devnode.h>
@@ -42,6 +43,7 @@
42 * @entity_id: ID of the next entity to be registered 43 * @entity_id: ID of the next entity to be registered
43 * @entities: List of registered entities 44 * @entities: List of registered entities
44 * @lock: Entities list lock 45 * @lock: Entities list lock
46 * @graph_mutex: Entities graph operation lock
45 * 47 *
46 * This structure represents an abstract high-level media device. It allows easy 48 * This structure represents an abstract high-level media device. It allows easy
47 * access to entities and provides basic media device-level support. The 49 * access to entities and provides basic media device-level support. The
@@ -69,6 +71,8 @@ struct media_device {
69 71
70 /* Protects the entities list */ 72 /* Protects the entities list */
71 spinlock_t lock; 73 spinlock_t lock;
74 /* Serializes graph operations. */
75 struct mutex graph_mutex;
72}; 76};
73 77
74/* media_devnode to media_device */ 78/* media_devnode to media_device */
diff --git a/include/media/media-entity.h b/include/media/media-entity.h
index 28f61f6ee549..a9b31d98e3c6 100644
--- a/include/media/media-entity.h
+++ b/include/media/media-entity.h
@@ -81,6 +81,12 @@ struct media_entity {
81 struct media_pad *pads; /* Pads array (num_pads elements) */ 81 struct media_pad *pads; /* Pads array (num_pads elements) */
82 struct media_link *links; /* Links array (max_links elements)*/ 82 struct media_link *links; /* Links array (max_links elements)*/
83 83
84 /* Reference counts must never be negative, but are signed integers on
85 * purpose: a simple WARN_ON(<0) check can be used to detect reference
86 * count bugs that would make them negative.
87 */
88 int use_count; /* Use count for the entity. */
89
84 union { 90 union {
85 /* Node specifications */ 91 /* Node specifications */
86 struct { 92 struct {
@@ -129,6 +135,9 @@ void media_entity_cleanup(struct media_entity *entity);
129int media_entity_create_link(struct media_entity *source, u16 source_pad, 135int media_entity_create_link(struct media_entity *source, u16 source_pad,
130 struct media_entity *sink, u16 sink_pad, u32 flags); 136 struct media_entity *sink, u16 sink_pad, u32 flags);
131 137
138struct media_entity *media_entity_get(struct media_entity *entity);
139void media_entity_put(struct media_entity *entity);
140
132void media_entity_graph_walk_start(struct media_entity_graph *graph, 141void media_entity_graph_walk_start(struct media_entity_graph *graph,
133 struct media_entity *entity); 142 struct media_entity *entity);
134struct media_entity * 143struct media_entity *