Merge branch 'for-linus-4.11' of git://git.kernel.org/pub/scm/linux/kernel/git/mason...
[linux-2.6-block.git] / drivers / media / v4l2-core / v4l2-async.c
1 /*
2  * V4L2 asynchronous subdevice registration API
3  *
4  * Copyright (C) 2012-2013, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  */
10
11 #include <linux/device.h>
12 #include <linux/err.h>
13 #include <linux/i2c.h>
14 #include <linux/list.h>
15 #include <linux/module.h>
16 #include <linux/mutex.h>
17 #include <linux/platform_device.h>
18 #include <linux/slab.h>
19 #include <linux/types.h>
20
21 #include <media/v4l2-async.h>
22 #include <media/v4l2-device.h>
23 #include <media/v4l2-subdev.h>
24
25 static bool match_i2c(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
26 {
27 #if IS_ENABLED(CONFIG_I2C)
28         struct i2c_client *client = i2c_verify_client(sd->dev);
29         return client &&
30                 asd->match.i2c.adapter_id == client->adapter->nr &&
31                 asd->match.i2c.address == client->addr;
32 #else
33         return false;
34 #endif
35 }
36
37 static bool match_devname(struct v4l2_subdev *sd,
38                           struct v4l2_async_subdev *asd)
39 {
40         return !strcmp(asd->match.device_name.name, dev_name(sd->dev));
41 }
42
43 static bool match_of(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
44 {
45         return !of_node_cmp(of_node_full_name(sd->of_node),
46                             of_node_full_name(asd->match.of.node));
47 }
48
49 static bool match_custom(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
50 {
51         if (!asd->match.custom.match)
52                 /* Match always */
53                 return true;
54
55         return asd->match.custom.match(sd->dev, asd);
56 }
57
58 static LIST_HEAD(subdev_list);
59 static LIST_HEAD(notifier_list);
60 static DEFINE_MUTEX(list_lock);
61
62 static struct v4l2_async_subdev *v4l2_async_belongs(struct v4l2_async_notifier *notifier,
63                                                     struct v4l2_subdev *sd)
64 {
65         bool (*match)(struct v4l2_subdev *, struct v4l2_async_subdev *);
66         struct v4l2_async_subdev *asd;
67
68         list_for_each_entry(asd, &notifier->waiting, list) {
69                 /* bus_type has been verified valid before */
70                 switch (asd->match_type) {
71                 case V4L2_ASYNC_MATCH_CUSTOM:
72                         match = match_custom;
73                         break;
74                 case V4L2_ASYNC_MATCH_DEVNAME:
75                         match = match_devname;
76                         break;
77                 case V4L2_ASYNC_MATCH_I2C:
78                         match = match_i2c;
79                         break;
80                 case V4L2_ASYNC_MATCH_OF:
81                         match = match_of;
82                         break;
83                 default:
84                         /* Cannot happen, unless someone breaks us */
85                         WARN_ON(true);
86                         return NULL;
87                 }
88
89                 /* match cannot be NULL here */
90                 if (match(sd, asd))
91                         return asd;
92         }
93
94         return NULL;
95 }
96
97 static int v4l2_async_test_notify(struct v4l2_async_notifier *notifier,
98                                   struct v4l2_subdev *sd,
99                                   struct v4l2_async_subdev *asd)
100 {
101         int ret;
102
103         if (notifier->bound) {
104                 ret = notifier->bound(notifier, sd, asd);
105                 if (ret < 0)
106                         return ret;
107         }
108
109         ret = v4l2_device_register_subdev(notifier->v4l2_dev, sd);
110         if (ret < 0) {
111                 if (notifier->unbind)
112                         notifier->unbind(notifier, sd, asd);
113                 return ret;
114         }
115
116         /* Remove from the waiting list */
117         list_del(&asd->list);
118         sd->asd = asd;
119         sd->notifier = notifier;
120
121         /* Move from the global subdevice list to notifier's done */
122         list_move(&sd->async_list, &notifier->done);
123
124         if (list_empty(&notifier->waiting) && notifier->complete)
125                 return notifier->complete(notifier);
126
127         return 0;
128 }
129
130 static void v4l2_async_cleanup(struct v4l2_subdev *sd)
131 {
132         v4l2_device_unregister_subdev(sd);
133         /* Subdevice driver will reprobe and put the subdev back onto the list */
134         list_del_init(&sd->async_list);
135         sd->asd = NULL;
136         sd->dev = NULL;
137 }
138
139 int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
140                                  struct v4l2_async_notifier *notifier)
141 {
142         struct v4l2_subdev *sd, *tmp;
143         struct v4l2_async_subdev *asd;
144         int i;
145
146         if (!notifier->num_subdevs || notifier->num_subdevs > V4L2_MAX_SUBDEVS)
147                 return -EINVAL;
148
149         notifier->v4l2_dev = v4l2_dev;
150         INIT_LIST_HEAD(&notifier->waiting);
151         INIT_LIST_HEAD(&notifier->done);
152
153         for (i = 0; i < notifier->num_subdevs; i++) {
154                 asd = notifier->subdevs[i];
155
156                 switch (asd->match_type) {
157                 case V4L2_ASYNC_MATCH_CUSTOM:
158                 case V4L2_ASYNC_MATCH_DEVNAME:
159                 case V4L2_ASYNC_MATCH_I2C:
160                 case V4L2_ASYNC_MATCH_OF:
161                         break;
162                 default:
163                         dev_err(notifier->v4l2_dev ? notifier->v4l2_dev->dev : NULL,
164                                 "Invalid match type %u on %p\n",
165                                 asd->match_type, asd);
166                         return -EINVAL;
167                 }
168                 list_add_tail(&asd->list, &notifier->waiting);
169         }
170
171         mutex_lock(&list_lock);
172
173         list_for_each_entry_safe(sd, tmp, &subdev_list, async_list) {
174                 int ret;
175
176                 asd = v4l2_async_belongs(notifier, sd);
177                 if (!asd)
178                         continue;
179
180                 ret = v4l2_async_test_notify(notifier, sd, asd);
181                 if (ret < 0) {
182                         mutex_unlock(&list_lock);
183                         return ret;
184                 }
185         }
186
187         /* Keep also completed notifiers on the list */
188         list_add(&notifier->list, &notifier_list);
189
190         mutex_unlock(&list_lock);
191
192         return 0;
193 }
194 EXPORT_SYMBOL(v4l2_async_notifier_register);
195
196 void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)
197 {
198         struct v4l2_subdev *sd, *tmp;
199         unsigned int notif_n_subdev = notifier->num_subdevs;
200         unsigned int n_subdev = min(notif_n_subdev, V4L2_MAX_SUBDEVS);
201         struct device **dev;
202         int i = 0;
203
204         if (!notifier->v4l2_dev)
205                 return;
206
207         dev = kmalloc_array(n_subdev, sizeof(*dev), GFP_KERNEL);
208         if (!dev) {
209                 dev_err(notifier->v4l2_dev->dev,
210                         "Failed to allocate device cache!\n");
211         }
212
213         mutex_lock(&list_lock);
214
215         list_del(&notifier->list);
216
217         list_for_each_entry_safe(sd, tmp, &notifier->done, async_list) {
218                 struct device *d;
219
220                 d = get_device(sd->dev);
221
222                 v4l2_async_cleanup(sd);
223
224                 /* If we handled USB devices, we'd have to lock the parent too */
225                 device_release_driver(d);
226
227                 if (notifier->unbind)
228                         notifier->unbind(notifier, sd, sd->asd);
229
230                 /*
231                  * Store device at the device cache, in order to call
232                  * put_device() on the final step
233                  */
234                 if (dev)
235                         dev[i++] = d;
236                 else
237                         put_device(d);
238         }
239
240         mutex_unlock(&list_lock);
241
242         /*
243          * Call device_attach() to reprobe devices
244          *
245          * NOTE: If dev allocation fails, i is 0, and the whole loop won't be
246          * executed.
247          */
248         while (i--) {
249                 struct device *d = dev[i];
250
251                 if (d && device_attach(d) < 0) {
252                         const char *name = "(none)";
253                         int lock = device_trylock(d);
254
255                         if (lock && d->driver)
256                                 name = d->driver->name;
257                         dev_err(d, "Failed to re-probe to %s\n", name);
258                         if (lock)
259                                 device_unlock(d);
260                 }
261                 put_device(d);
262         }
263         kfree(dev);
264
265         notifier->v4l2_dev = NULL;
266
267         /*
268          * Don't care about the waiting list, it is initialised and populated
269          * upon notifier registration.
270          */
271 }
272 EXPORT_SYMBOL(v4l2_async_notifier_unregister);
273
274 int v4l2_async_register_subdev(struct v4l2_subdev *sd)
275 {
276         struct v4l2_async_notifier *notifier;
277
278         /*
279          * No reference taken. The reference is held by the device
280          * (struct v4l2_subdev.dev), and async sub-device does not
281          * exist independently of the device at any point of time.
282          */
283         if (!sd->of_node && sd->dev)
284                 sd->of_node = sd->dev->of_node;
285
286         mutex_lock(&list_lock);
287
288         INIT_LIST_HEAD(&sd->async_list);
289
290         list_for_each_entry(notifier, &notifier_list, list) {
291                 struct v4l2_async_subdev *asd = v4l2_async_belongs(notifier, sd);
292                 if (asd) {
293                         int ret = v4l2_async_test_notify(notifier, sd, asd);
294                         mutex_unlock(&list_lock);
295                         return ret;
296                 }
297         }
298
299         /* None matched, wait for hot-plugging */
300         list_add(&sd->async_list, &subdev_list);
301
302         mutex_unlock(&list_lock);
303
304         return 0;
305 }
306 EXPORT_SYMBOL(v4l2_async_register_subdev);
307
308 void v4l2_async_unregister_subdev(struct v4l2_subdev *sd)
309 {
310         struct v4l2_async_notifier *notifier = sd->notifier;
311
312         if (!sd->asd) {
313                 if (!list_empty(&sd->async_list))
314                         v4l2_async_cleanup(sd);
315                 return;
316         }
317
318         mutex_lock(&list_lock);
319
320         list_add(&sd->asd->list, &notifier->waiting);
321
322         v4l2_async_cleanup(sd);
323
324         if (notifier->unbind)
325                 notifier->unbind(notifier, sd, sd->asd);
326
327         mutex_unlock(&list_lock);
328 }
329 EXPORT_SYMBOL(v4l2_async_unregister_subdev);