linux-omap 2.6.37: sync with OE .dev
[glsdk/meta-ti-glsdk.git] / recipes-bsp / linux / linux-omap / media / 0012-media-Entity-use-count.patch
1 From 3be6a2d10ff0cad0b240c65054da28395b014f82 Mon Sep 17 00:00:00 2001
2 From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
3 Date: Sun, 7 Mar 2010 20:04:59 +0200
4 Subject: [PATCH 12/43] media: Entity use count
6 Due to the wide differences between drivers regarding power management
7 needs, the media controller does not implement power management.
8 However, the media_entity structure includes a use_count field that
9 media drivers can use to track the number of users of every entity for
10 power management needs.
12 The use_count field is owned by media drivers and must not be touched by
13 entity drivers. Access to the field must be protected by the media
14 device graph_mutex lock.
16 Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
17 ---
18  Documentation/media-framework.txt |   13 ++++++++++
19  drivers/media/media-device.c      |    1 +
20  drivers/media/media-entity.c      |   46 +++++++++++++++++++++++++++++++++++++
21  include/media/media-device.h      |    4 +++
22  include/media/media-entity.h      |    5 ++++
23  5 files changed, 69 insertions(+), 0 deletions(-)
25 diff --git a/Documentation/media-framework.txt b/Documentation/media-framework.txt
26 index 88fe379..9017a41 100644
27 --- a/Documentation/media-framework.txt
28 +++ b/Documentation/media-framework.txt
29 @@ -258,3 +258,16 @@ When the graph traversal is complete the function will return NULL.
30  
31  Graph traversal can be interrupted at any moment. No cleanup function call is
32  required and the graph structure can be freed normally.
33 +
34 +
35 +Use count and power handling
36 +----------------------------
37 +
38 +Due to the wide differences between drivers regarding power management needs,
39 +the media controller does not implement power management. However, the
40 +media_entity structure includes a use_count field that media drivers can use to
41 +track the number of users of every entity for power management needs.
42 +
43 +The use_count field is owned by media drivers and must not be touched by entity
44 +drivers. Access to the field must be protected by the media device graph_mutex
45 +lock.
46 diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
47 index b8a3ace..e4c2157 100644
48 --- a/drivers/media/media-device.c
49 +++ b/drivers/media/media-device.c
50 @@ -73,6 +73,7 @@ int __must_check media_device_register(struct media_device *mdev)
51         mdev->entity_id = 1;
52         INIT_LIST_HEAD(&mdev->entities);
53         spin_lock_init(&mdev->lock);
54 +       mutex_init(&mdev->graph_mutex);
55  
56         /* Register the device node. */
57         mdev->devnode.fops = &media_device_fops;
58 diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
59 index a805f20..fe6bfd2 100644
60 --- a/drivers/media/media-entity.c
61 +++ b/drivers/media/media-entity.c
62 @@ -23,6 +23,7 @@
63  #include <linux/module.h>
64  #include <linux/slab.h>
65  #include <media/media-entity.h>
66 +#include <media/media-device.h>
67  
68  /**
69   * media_entity_init - Initialize a media entity
70 @@ -196,6 +197,51 @@ media_entity_graph_walk_next(struct media_entity_graph *graph)
71  EXPORT_SYMBOL_GPL(media_entity_graph_walk_next);
72  
73  /* -----------------------------------------------------------------------------
74 + * Module use count
75 + */
76 +
77 +/*
78 + * media_entity_get - Get a reference to the parent module
79 + * @entity: The entity
80 + *
81 + * Get a reference to the parent media device module.
82 + *
83 + * The function will return immediately if @entity is NULL.
84 + *
85 + * Return a pointer to the entity on success or NULL on failure.
86 + */
87 +struct media_entity *media_entity_get(struct media_entity *entity)
88 +{
89 +       if (entity == NULL)
90 +               return NULL;
91 +
92 +       if (entity->parent->dev &&
93 +           !try_module_get(entity->parent->dev->driver->owner))
94 +               return NULL;
95 +
96 +       return entity;
97 +}
98 +EXPORT_SYMBOL_GPL(media_entity_get);
99 +
100 +/*
101 + * media_entity_put - Release the reference to the parent module
102 + * @entity: The entity
103 + *
104 + * Release the reference count acquired by media_entity_get().
105 + *
106 + * The function will return immediately if @entity is NULL.
107 + */
108 +void media_entity_put(struct media_entity *entity)
109 +{
110 +       if (entity == NULL)
111 +               return;
113 +       if (entity->parent->dev)
114 +               module_put(entity->parent->dev->driver->owner);
115 +}
116 +EXPORT_SYMBOL_GPL(media_entity_put);
118 +/* -----------------------------------------------------------------------------
119   * Links management
120   */
121  
122 diff --git a/include/media/media-device.h b/include/media/media-device.h
123 index 0b1ecf5..260d59c 100644
124 --- a/include/media/media-device.h
125 +++ b/include/media/media-device.h
126 @@ -25,6 +25,7 @@
127  
128  #include <linux/device.h>
129  #include <linux/list.h>
130 +#include <linux/mutex.h>
131  #include <linux/spinlock.h>
132  
133  #include <media/media-devnode.h>
134 @@ -42,6 +43,7 @@
135   * @entity_id: ID of the next entity to be registered
136   * @entities:  List of registered entities
137   * @lock:      Entities list lock
138 + * @graph_mutex: Entities graph operation lock
139   *
140   * This structure represents an abstract high-level media device. It allows easy
141   * access to entities and provides basic media device-level support. The
142 @@ -69,6 +71,8 @@ struct media_device {
143  
144         /* Protects the entities list */
145         spinlock_t lock;
146 +       /* Serializes graph operations. */
147 +       struct mutex graph_mutex;
148  };
149  
150  /* media_devnode to media_device */
151 diff --git a/include/media/media-entity.h b/include/media/media-entity.h
152 index b82f824..114541a 100644
153 --- a/include/media/media-entity.h
154 +++ b/include/media/media-entity.h
155 @@ -81,6 +81,8 @@ struct media_entity {
156         struct media_pad *pads;         /* Pads array (num_pads elements) */
157         struct media_link *links;       /* Links array (max_links elements)*/
158  
159 +       int use_count;                  /* Use count for the entity. */
161         union {
162                 /* Node specifications */
163                 struct {
164 @@ -129,6 +131,9 @@ void media_entity_cleanup(struct media_entity *entity);
165  int media_entity_create_link(struct media_entity *source, u16 source_pad,
166                 struct media_entity *sink, u16 sink_pad, u32 flags);
167  
168 +struct media_entity *media_entity_get(struct media_entity *entity);
169 +void media_entity_put(struct media_entity *entity);
171  void media_entity_graph_walk_start(struct media_entity_graph *graph,
172                 struct media_entity *entity);
173  struct media_entity *
174 -- 
175 1.6.6.1