diff options
author | Sylwester Nawrocki <s.nawrocki@samsung.com> | 2013-07-22 07:01:33 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <m.chehab@samsung.com> | 2013-07-30 14:54:56 -0400 |
commit | b426b3a660c85faf6e1ca1c92c6d43577022aa3b (patch) | |
tree | ac2d0ff8b1a9946901f280f7516308a04c4292e8 /drivers/media/v4l2-core | |
parent | e8419d0890efaccb93f9f274d9ba0aae91210e8c (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.c | 67 |
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); | |||
49 | static DEFINE_MUTEX(list_lock); | 49 | static DEFINE_MUTEX(list_lock); |
50 | 50 | ||
51 | static struct v4l2_async_subdev *v4l2_async_belongs(struct v4l2_async_notifier *notifier, | 51 | static 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, ¬ifier->waiting, list) { | 57 | list_for_each_entry(asd, ¬ifier->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 | ||
91 | static int v4l2_async_test_notify(struct v4l2_async_notifier *notifier, | 89 | static 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, ¬ifier->done); | 106 | list_move(&sd->async_list, ¬ifier->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 | ||
124 | static void v4l2_async_cleanup(struct v4l2_async_subdev_list *asdl) | 121 | static 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 | ||
135 | int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev, | 130 | int 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(¬ifier->list, ¬ifier_list); | 165 | list_add(¬ifier->list, ¬ifier_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 | ||
192 | void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier) | 187 | void 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(¬ifier->list); | 197 | list_del(¬ifier->list); |
203 | 198 | ||
204 | list_for_each_entry_safe(asdl, tmp, ¬ifier->done, list) { | 199 | list_for_each_entry_safe(sd, tmp, ¬ifier->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 | ||
242 | int v4l2_async_register_subdev(struct v4l2_subdev *sd) | 235 | int 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, ¬ifier_list, list) { | 243 | list_for_each_entry(notifier, ¬ifier_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 | ||
269 | void v4l2_async_unregister_subdev(struct v4l2_subdev *sd) | 261 | void 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, ¬ifier->waiting); | 273 | list_add(&sd->asd->list, ¬ifier->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 | } |