diff options
-rw-r--r-- | Documentation/media-framework.txt | 13 | ||||
-rw-r--r-- | drivers/media/media-device.c | 1 | ||||
-rw-r--r-- | drivers/media/media-entity.c | 46 | ||||
-rw-r--r-- | include/media/media-device.h | 4 | ||||
-rw-r--r-- | 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 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 | ||
259 | Graph traversal can be interrupted at any moment. No cleanup function call is | 259 | Graph traversal can be interrupted at any moment. No cleanup function call is |
260 | required and the graph structure can be freed normally. | 260 | required and the graph structure can be freed normally. |
261 | |||
262 | |||
263 | Use count and power handling | ||
264 | ---------------------------- | ||
265 | |||
266 | Due to the wide differences between drivers regarding power management needs, | ||
267 | the media controller does not implement power management. However, the | ||
268 | media_entity structure includes a use_count field that media drivers can use to | ||
269 | track the number of users of every entity for power management needs. | ||
270 | |||
271 | The use_count field is owned by media drivers and must not be touched by entity | ||
272 | drivers. Access to the field must be protected by the media device graph_mutex | ||
273 | lock. | ||
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) | |||
196 | EXPORT_SYMBOL_GPL(media_entity_graph_walk_next); | 197 | EXPORT_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 | */ | ||
213 | struct 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 | } | ||
224 | EXPORT_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 | */ | ||
234 | void 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 | } | ||
242 | EXPORT_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); | |||
129 | int media_entity_create_link(struct media_entity *source, u16 source_pad, | 135 | int 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 | ||
138 | struct media_entity *media_entity_get(struct media_entity *entity); | ||
139 | void media_entity_put(struct media_entity *entity); | ||
140 | |||
132 | void media_entity_graph_walk_start(struct media_entity_graph *graph, | 141 | void media_entity_graph_walk_start(struct media_entity_graph *graph, |
133 | struct media_entity *entity); | 142 | struct media_entity *entity); |
134 | struct media_entity * | 143 | struct media_entity * |