aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/v4l2-core
diff options
context:
space:
mode:
authorSylwester Nawrocki <s.nawrocki@samsung.com>2013-07-22 07:01:33 -0400
committerMauro Carvalho Chehab <m.chehab@samsung.com>2013-07-30 14:54:56 -0400
commitb426b3a660c85faf6e1ca1c92c6d43577022aa3b (patch)
treeac2d0ff8b1a9946901f280f7516308a04c4292e8 /drivers/media/v4l2-core
parente8419d0890efaccb93f9f274d9ba0aae91210e8c (diff)
[media] V4L: Merge struct v4l2_async_subdev_list with struct v4l2_subdev
By integrating the v4l2-async API internals a bit more with the core overall the v4l2-async code becomes a bit simpler and easier to follow. Acked-and-tested-by: Lad, Prabhakar <prabhakar.csengg@gmail.com> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Acked-by: Hans Verkuil <hans.verkuil@cisco.com> Acked-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
Diffstat (limited to 'drivers/media/v4l2-core')
-rw-r--r--drivers/media/v4l2-core/v4l2-async.c67
1 files changed, 29 insertions, 38 deletions
diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c
index ed31a655b9b7..b350ab99652c 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -49,12 +49,10 @@ static LIST_HEAD(notifier_list);
49static DEFINE_MUTEX(list_lock); 49static DEFINE_MUTEX(list_lock);
50 50
51static struct v4l2_async_subdev *v4l2_async_belongs(struct v4l2_async_notifier *notifier, 51static struct v4l2_async_subdev *v4l2_async_belongs(struct v4l2_async_notifier *notifier,
52 struct v4l2_async_subdev_list *asdl) 52 struct v4l2_subdev *sd)
53{ 53{
54 struct v4l2_subdev *sd = v4l2_async_to_subdev(asdl);
55 struct v4l2_async_subdev *asd; 54 struct v4l2_async_subdev *asd;
56 bool (*match)(struct device *, 55 bool (*match)(struct device *, struct v4l2_async_subdev *);
57 struct v4l2_async_subdev *);
58 56
59 list_for_each_entry(asd, &notifier->waiting, list) { 57 list_for_each_entry(asd, &notifier->waiting, list) {
60 /* bus_type has been verified valid before */ 58 /* bus_type has been verified valid before */
@@ -89,16 +87,15 @@ static struct v4l2_async_subdev *v4l2_async_belongs(struct v4l2_async_notifier *
89} 87}
90 88
91static int v4l2_async_test_notify(struct v4l2_async_notifier *notifier, 89static int v4l2_async_test_notify(struct v4l2_async_notifier *notifier,
92 struct v4l2_async_subdev_list *asdl, 90 struct v4l2_subdev *sd,
93 struct v4l2_async_subdev *asd) 91 struct v4l2_async_subdev *asd)
94{ 92{
95 struct v4l2_subdev *sd = v4l2_async_to_subdev(asdl);
96 int ret; 93 int ret;
97 94
98 /* Remove from the waiting list */ 95 /* Remove from the waiting list */
99 list_del(&asd->list); 96 list_del(&asd->list);
100 asdl->asd = asd; 97 sd->asd = asd;
101 asdl->notifier = notifier; 98 sd->notifier = notifier;
102 99
103 if (notifier->bound) { 100 if (notifier->bound) {
104 ret = notifier->bound(notifier, sd, asd); 101 ret = notifier->bound(notifier, sd, asd);
@@ -106,7 +103,7 @@ static int v4l2_async_test_notify(struct v4l2_async_notifier *notifier,
106 return ret; 103 return ret;
107 } 104 }
108 /* Move from the global subdevice list to notifier's done */ 105 /* Move from the global subdevice list to notifier's done */
109 list_move(&asdl->list, &notifier->done); 106 list_move(&sd->async_list, &notifier->done);
110 107
111 ret = v4l2_device_register_subdev(notifier->v4l2_dev, sd); 108 ret = v4l2_device_register_subdev(notifier->v4l2_dev, sd);
112 if (ret < 0) { 109 if (ret < 0) {
@@ -121,21 +118,19 @@ static int v4l2_async_test_notify(struct v4l2_async_notifier *notifier,
121 return 0; 118 return 0;
122} 119}
123 120
124static void v4l2_async_cleanup(struct v4l2_async_subdev_list *asdl) 121static void v4l2_async_cleanup(struct v4l2_subdev *sd)
125{ 122{
126 struct v4l2_subdev *sd = v4l2_async_to_subdev(asdl);
127
128 v4l2_device_unregister_subdev(sd); 123 v4l2_device_unregister_subdev(sd);
129 /* Subdevice driver will reprobe and put asdl back onto the list */ 124 /* Subdevice driver will reprobe and put the subdev back onto the list */
130 list_del_init(&asdl->list); 125 list_del_init(&sd->async_list);
131 asdl->asd = NULL; 126 sd->asd = NULL;
132 sd->dev = NULL; 127 sd->dev = NULL;
133} 128}
134 129
135int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev, 130int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
136 struct v4l2_async_notifier *notifier) 131 struct v4l2_async_notifier *notifier)
137{ 132{
138 struct v4l2_async_subdev_list *asdl, *tmp; 133 struct v4l2_subdev *sd, *tmp;
139 struct v4l2_async_subdev *asd; 134 struct v4l2_async_subdev *asd;
140 int i; 135 int i;
141 136
@@ -169,14 +164,14 @@ int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
169 /* Keep also completed notifiers on the list */ 164 /* Keep also completed notifiers on the list */
170 list_add(&notifier->list, &notifier_list); 165 list_add(&notifier->list, &notifier_list);
171 166
172 list_for_each_entry_safe(asdl, tmp, &subdev_list, list) { 167 list_for_each_entry_safe(sd, tmp, &subdev_list, async_list) {
173 int ret; 168 int ret;
174 169
175 asd = v4l2_async_belongs(notifier, asdl); 170 asd = v4l2_async_belongs(notifier, sd);
176 if (!asd) 171 if (!asd)
177 continue; 172 continue;
178 173
179 ret = v4l2_async_test_notify(notifier, asdl, asd); 174 ret = v4l2_async_test_notify(notifier, sd, asd);
180 if (ret < 0) { 175 if (ret < 0) {
181 mutex_unlock(&list_lock); 176 mutex_unlock(&list_lock);
182 return ret; 177 return ret;
@@ -191,7 +186,7 @@ EXPORT_SYMBOL(v4l2_async_notifier_register);
191 186
192void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier) 187void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)
193{ 188{
194 struct v4l2_async_subdev_list *asdl, *tmp; 189 struct v4l2_subdev *sd, *tmp;
195 unsigned int notif_n_subdev = notifier->num_subdevs; 190 unsigned int notif_n_subdev = notifier->num_subdevs;
196 unsigned int n_subdev = min(notif_n_subdev, V4L2_MAX_SUBDEVS); 191 unsigned int n_subdev = min(notif_n_subdev, V4L2_MAX_SUBDEVS);
197 struct device *dev[n_subdev]; 192 struct device *dev[n_subdev];
@@ -201,18 +196,16 @@ void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)
201 196
202 list_del(&notifier->list); 197 list_del(&notifier->list);
203 198
204 list_for_each_entry_safe(asdl, tmp, &notifier->done, list) { 199 list_for_each_entry_safe(sd, tmp, &notifier->done, list) {
205 struct v4l2_subdev *sd = v4l2_async_to_subdev(asdl);
206
207 dev[i] = get_device(sd->dev); 200 dev[i] = get_device(sd->dev);
208 201
209 v4l2_async_cleanup(asdl); 202 v4l2_async_cleanup(sd);
210 203
211 /* If we handled USB devices, we'd have to lock the parent too */ 204 /* If we handled USB devices, we'd have to lock the parent too */
212 device_release_driver(dev[i++]); 205 device_release_driver(dev[i++]);
213 206
214 if (notifier->unbind) 207 if (notifier->unbind)
215 notifier->unbind(notifier, sd, sd->asdl.asd); 208 notifier->unbind(notifier, sd, sd->asd);
216 } 209 }
217 210
218 mutex_unlock(&list_lock); 211 mutex_unlock(&list_lock);
@@ -241,24 +234,23 @@ EXPORT_SYMBOL(v4l2_async_notifier_unregister);
241 234
242int v4l2_async_register_subdev(struct v4l2_subdev *sd) 235int v4l2_async_register_subdev(struct v4l2_subdev *sd)
243{ 236{
244 struct v4l2_async_subdev_list *asdl = &sd->asdl;
245 struct v4l2_async_notifier *notifier; 237 struct v4l2_async_notifier *notifier;
246 238
247 mutex_lock(&list_lock); 239 mutex_lock(&list_lock);
248 240
249 INIT_LIST_HEAD(&asdl->list); 241 INIT_LIST_HEAD(&sd->async_list);
250 242
251 list_for_each_entry(notifier, &notifier_list, list) { 243 list_for_each_entry(notifier, &notifier_list, list) {
252 struct v4l2_async_subdev *asd = v4l2_async_belongs(notifier, asdl); 244 struct v4l2_async_subdev *asd = v4l2_async_belongs(notifier, sd);
253 if (asd) { 245 if (asd) {
254 int ret = v4l2_async_test_notify(notifier, asdl, asd); 246 int ret = v4l2_async_test_notify(notifier, sd, asd);
255 mutex_unlock(&list_lock); 247 mutex_unlock(&list_lock);
256 return ret; 248 return ret;
257 } 249 }
258 } 250 }
259 251
260 /* None matched, wait for hot-plugging */ 252 /* None matched, wait for hot-plugging */
261 list_add(&asdl->list, &subdev_list); 253 list_add(&sd->async_list, &subdev_list);
262 254
263 mutex_unlock(&list_lock); 255 mutex_unlock(&list_lock);
264 256
@@ -268,23 +260,22 @@ EXPORT_SYMBOL(v4l2_async_register_subdev);
268 260
269void v4l2_async_unregister_subdev(struct v4l2_subdev *sd) 261void v4l2_async_unregister_subdev(struct v4l2_subdev *sd)
270{ 262{
271 struct v4l2_async_subdev_list *asdl = &sd->asdl; 263 struct v4l2_async_notifier *notifier = sd->notifier;
272 struct v4l2_async_notifier *notifier = asdl->notifier;
273 264
274 if (!asdl->asd) { 265 if (!sd->asd) {
275 if (!list_empty(&asdl->list)) 266 if (!list_empty(&sd->async_list))
276 v4l2_async_cleanup(asdl); 267 v4l2_async_cleanup(sd);
277 return; 268 return;
278 } 269 }
279 270
280 mutex_lock(&list_lock); 271 mutex_lock(&list_lock);
281 272
282 list_add(&asdl->asd->list, &notifier->waiting); 273 list_add(&sd->asd->list, &notifier->waiting);
283 274
284 v4l2_async_cleanup(asdl); 275 v4l2_async_cleanup(sd);
285 276
286 if (notifier->unbind) 277 if (notifier->unbind)
287 notifier->unbind(notifier, sd, sd->asdl.asd); 278 notifier->unbind(notifier, sd, sd->asd);
288 279
289 mutex_unlock(&list_lock); 280 mutex_unlock(&list_lock);
290} 281}