1 // SPDX-License-Identifier: GPL-2.0-only
3 * V4L2 asynchronous subdevice registration API
8 #include <linux/device.h>
10 #include <linux/i2c.h>
11 #include <linux/list.h>
13 #include <linux/module.h>
14 #include <linux/mutex.h>
16 #include <linux/platform_device.h>
17 #include <linux/slab.h>
18 #include <linux/types.h>
20 #include <media/v4l2-async.h>
21 #include <media/v4l2-device.h>
22 #include <media/v4l2-fwnode.h>
23 #include <media/v4l2-subdev.h>
25 static int v4l2_async_notifier_call_bound(struct v4l2_async_notifier *n,
26 struct v4l2_subdev *subdev,
27 struct v4l2_async_subdev *asd)
29 if (!n->ops || !n->ops->bound)
32 return n->ops->bound(n, subdev, asd);
35 static void v4l2_async_notifier_call_unbind(struct v4l2_async_notifier *n,
36 struct v4l2_subdev *subdev,
37 struct v4l2_async_subdev *asd)
39 if (!n->ops || !n->ops->unbind)
42 n->ops->unbind(n, subdev, asd);
45 static int v4l2_async_notifier_call_complete(struct v4l2_async_notifier *n)
47 if (!n->ops || !n->ops->complete)
50 return n->ops->complete(n);
53 static bool match_i2c(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
55 #if IS_ENABLED(CONFIG_I2C)
56 struct i2c_client *client = i2c_verify_client(sd->dev);
59 asd->match.i2c.adapter_id == client->adapter->nr &&
60 asd->match.i2c.address == client->addr;
66 static bool match_devname(struct v4l2_subdev *sd,
67 struct v4l2_async_subdev *asd)
69 return !strcmp(asd->match.device_name, dev_name(sd->dev));
72 static bool match_fwnode(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
74 return sd->fwnode == asd->match.fwnode;
77 static bool match_custom(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
79 if (!asd->match.custom.match)
83 return asd->match.custom.match(sd->dev, asd);
86 static LIST_HEAD(subdev_list);
87 static LIST_HEAD(notifier_list);
88 static DEFINE_MUTEX(list_lock);
90 static struct v4l2_async_subdev *
91 v4l2_async_find_match(struct v4l2_async_notifier *notifier,
92 struct v4l2_subdev *sd)
94 bool (*match)(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd);
95 struct v4l2_async_subdev *asd;
97 list_for_each_entry(asd, ¬ifier->waiting, list) {
98 /* bus_type has been verified valid before */
99 switch (asd->match_type) {
100 case V4L2_ASYNC_MATCH_CUSTOM:
101 match = match_custom;
103 case V4L2_ASYNC_MATCH_DEVNAME:
104 match = match_devname;
106 case V4L2_ASYNC_MATCH_I2C:
109 case V4L2_ASYNC_MATCH_FWNODE:
110 match = match_fwnode;
113 /* Cannot happen, unless someone breaks us */
118 /* match cannot be NULL here */
126 /* Compare two async sub-device descriptors for equivalence */
127 static bool asd_equal(struct v4l2_async_subdev *asd_x,
128 struct v4l2_async_subdev *asd_y)
130 if (asd_x->match_type != asd_y->match_type)
133 switch (asd_x->match_type) {
134 case V4L2_ASYNC_MATCH_DEVNAME:
135 return strcmp(asd_x->match.device_name,
136 asd_y->match.device_name) == 0;
137 case V4L2_ASYNC_MATCH_I2C:
138 return asd_x->match.i2c.adapter_id ==
139 asd_y->match.i2c.adapter_id &&
140 asd_x->match.i2c.address ==
141 asd_y->match.i2c.address;
142 case V4L2_ASYNC_MATCH_FWNODE:
143 return asd_x->match.fwnode == asd_y->match.fwnode;
151 /* Find the sub-device notifier registered by a sub-device driver. */
152 static struct v4l2_async_notifier *
153 v4l2_async_find_subdev_notifier(struct v4l2_subdev *sd)
155 struct v4l2_async_notifier *n;
157 list_for_each_entry(n, ¬ifier_list, list)
164 /* Get v4l2_device related to the notifier if one can be found. */
165 static struct v4l2_device *
166 v4l2_async_notifier_find_v4l2_dev(struct v4l2_async_notifier *notifier)
168 while (notifier->parent)
169 notifier = notifier->parent;
171 return notifier->v4l2_dev;
175 * Return true if all child sub-device notifiers are complete, false otherwise.
178 v4l2_async_notifier_can_complete(struct v4l2_async_notifier *notifier)
180 struct v4l2_subdev *sd;
182 if (!list_empty(¬ifier->waiting))
185 list_for_each_entry(sd, ¬ifier->done, async_list) {
186 struct v4l2_async_notifier *subdev_notifier =
187 v4l2_async_find_subdev_notifier(sd);
189 if (subdev_notifier &&
190 !v4l2_async_notifier_can_complete(subdev_notifier))
198 * Complete the master notifier if possible. This is done when all async
199 * sub-devices have been bound; v4l2_device is also available then.
202 v4l2_async_notifier_try_complete(struct v4l2_async_notifier *notifier)
204 /* Quick check whether there are still more sub-devices here. */
205 if (!list_empty(¬ifier->waiting))
208 /* Check the entire notifier tree; find the root notifier first. */
209 while (notifier->parent)
210 notifier = notifier->parent;
212 /* This is root if it has v4l2_dev. */
213 if (!notifier->v4l2_dev)
216 /* Is everything ready? */
217 if (!v4l2_async_notifier_can_complete(notifier))
220 return v4l2_async_notifier_call_complete(notifier);
224 v4l2_async_notifier_try_all_subdevs(struct v4l2_async_notifier *notifier);
226 static int v4l2_async_match_notify(struct v4l2_async_notifier *notifier,
227 struct v4l2_device *v4l2_dev,
228 struct v4l2_subdev *sd,
229 struct v4l2_async_subdev *asd)
231 struct v4l2_async_notifier *subdev_notifier;
234 ret = v4l2_device_register_subdev(v4l2_dev, sd);
238 ret = v4l2_async_notifier_call_bound(notifier, sd, asd);
240 v4l2_device_unregister_subdev(sd);
244 /* Remove from the waiting list */
245 list_del(&asd->list);
247 sd->notifier = notifier;
249 /* Move from the global subdevice list to notifier's done */
250 list_move(&sd->async_list, ¬ifier->done);
253 * See if the sub-device has a notifier. If not, return here.
255 subdev_notifier = v4l2_async_find_subdev_notifier(sd);
256 if (!subdev_notifier || subdev_notifier->parent)
260 * Proceed with checking for the sub-device notifier's async
261 * sub-devices, and return the result. The error will be handled by the
264 subdev_notifier->parent = notifier;
266 return v4l2_async_notifier_try_all_subdevs(subdev_notifier);
269 /* Test all async sub-devices in a notifier for a match. */
271 v4l2_async_notifier_try_all_subdevs(struct v4l2_async_notifier *notifier)
273 struct v4l2_device *v4l2_dev =
274 v4l2_async_notifier_find_v4l2_dev(notifier);
275 struct v4l2_subdev *sd;
281 list_for_each_entry(sd, &subdev_list, async_list) {
282 struct v4l2_async_subdev *asd;
285 asd = v4l2_async_find_match(notifier, sd);
289 ret = v4l2_async_match_notify(notifier, v4l2_dev, sd, asd);
294 * v4l2_async_match_notify() may lead to registering a
295 * new notifier and thus changing the async subdevs
296 * list. In order to proceed safely from here, restart
297 * parsing the list from the beginning.
305 static void v4l2_async_cleanup(struct v4l2_subdev *sd)
307 v4l2_device_unregister_subdev(sd);
309 * Subdevice driver will reprobe and put the subdev back
312 list_del_init(&sd->async_list);
316 /* Unbind all sub-devices in the notifier tree. */
318 v4l2_async_notifier_unbind_all_subdevs(struct v4l2_async_notifier *notifier)
320 struct v4l2_subdev *sd, *tmp;
322 list_for_each_entry_safe(sd, tmp, ¬ifier->done, async_list) {
323 struct v4l2_async_notifier *subdev_notifier =
324 v4l2_async_find_subdev_notifier(sd);
327 v4l2_async_notifier_unbind_all_subdevs(subdev_notifier);
329 v4l2_async_notifier_call_unbind(notifier, sd, sd->asd);
330 v4l2_async_cleanup(sd);
332 list_move(&sd->async_list, &subdev_list);
335 notifier->parent = NULL;
338 /* See if an async sub-device can be found in a notifier's lists. */
340 __v4l2_async_notifier_has_async_subdev(struct v4l2_async_notifier *notifier,
341 struct v4l2_async_subdev *asd)
343 struct v4l2_async_subdev *asd_y;
344 struct v4l2_subdev *sd;
346 list_for_each_entry(asd_y, ¬ifier->waiting, list)
347 if (asd_equal(asd, asd_y))
350 list_for_each_entry(sd, ¬ifier->done, async_list) {
351 if (WARN_ON(!sd->asd))
354 if (asd_equal(asd, sd->asd))
362 * Find out whether an async sub-device was set up already or
363 * whether it exists in a given notifier before @this_index.
364 * If @this_index < 0, search the notifier's entire @asd_list.
367 v4l2_async_notifier_has_async_subdev(struct v4l2_async_notifier *notifier,
368 struct v4l2_async_subdev *asd,
371 struct v4l2_async_subdev *asd_y;
374 lockdep_assert_held(&list_lock);
376 /* Check that an asd is not being added more than once. */
377 list_for_each_entry(asd_y, ¬ifier->asd_list, asd_list) {
378 if (this_index >= 0 && j++ >= this_index)
380 if (asd_equal(asd, asd_y))
384 /* Check that an asd does not exist in other notifiers. */
385 list_for_each_entry(notifier, ¬ifier_list, list)
386 if (__v4l2_async_notifier_has_async_subdev(notifier, asd))
392 static int v4l2_async_notifier_asd_valid(struct v4l2_async_notifier *notifier,
393 struct v4l2_async_subdev *asd,
397 notifier->v4l2_dev ? notifier->v4l2_dev->dev : NULL;
402 switch (asd->match_type) {
403 case V4L2_ASYNC_MATCH_CUSTOM:
404 case V4L2_ASYNC_MATCH_DEVNAME:
405 case V4L2_ASYNC_MATCH_I2C:
406 case V4L2_ASYNC_MATCH_FWNODE:
407 if (v4l2_async_notifier_has_async_subdev(notifier, asd,
409 dev_dbg(dev, "subdev descriptor already listed in this or other notifiers\n");
414 dev_err(dev, "Invalid match type %u on %p\n",
415 asd->match_type, asd);
422 void v4l2_async_notifier_init(struct v4l2_async_notifier *notifier)
424 INIT_LIST_HEAD(¬ifier->asd_list);
426 EXPORT_SYMBOL(v4l2_async_notifier_init);
428 static int __v4l2_async_notifier_register(struct v4l2_async_notifier *notifier)
430 struct v4l2_async_subdev *asd;
433 INIT_LIST_HEAD(¬ifier->waiting);
434 INIT_LIST_HEAD(¬ifier->done);
436 mutex_lock(&list_lock);
438 list_for_each_entry(asd, ¬ifier->asd_list, asd_list) {
439 ret = v4l2_async_notifier_asd_valid(notifier, asd, i++);
443 list_add_tail(&asd->list, ¬ifier->waiting);
446 ret = v4l2_async_notifier_try_all_subdevs(notifier);
450 ret = v4l2_async_notifier_try_complete(notifier);
454 /* Keep also completed notifiers on the list */
455 list_add(¬ifier->list, ¬ifier_list);
457 mutex_unlock(&list_lock);
463 * On failure, unbind all sub-devices registered through this notifier.
465 v4l2_async_notifier_unbind_all_subdevs(notifier);
468 mutex_unlock(&list_lock);
473 int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
474 struct v4l2_async_notifier *notifier)
478 if (WARN_ON(!v4l2_dev || notifier->sd))
481 notifier->v4l2_dev = v4l2_dev;
483 ret = __v4l2_async_notifier_register(notifier);
485 notifier->v4l2_dev = NULL;
489 EXPORT_SYMBOL(v4l2_async_notifier_register);
491 int v4l2_async_subdev_notifier_register(struct v4l2_subdev *sd,
492 struct v4l2_async_notifier *notifier)
496 if (WARN_ON(!sd || notifier->v4l2_dev))
501 ret = __v4l2_async_notifier_register(notifier);
507 EXPORT_SYMBOL(v4l2_async_subdev_notifier_register);
510 __v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)
512 if (!notifier || (!notifier->v4l2_dev && !notifier->sd))
515 v4l2_async_notifier_unbind_all_subdevs(notifier);
518 notifier->v4l2_dev = NULL;
520 list_del(¬ifier->list);
523 void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)
525 mutex_lock(&list_lock);
527 __v4l2_async_notifier_unregister(notifier);
529 mutex_unlock(&list_lock);
531 EXPORT_SYMBOL(v4l2_async_notifier_unregister);
533 static void __v4l2_async_notifier_cleanup(struct v4l2_async_notifier *notifier)
535 struct v4l2_async_subdev *asd, *tmp;
537 if (!notifier || !notifier->asd_list.next)
540 list_for_each_entry_safe(asd, tmp, ¬ifier->asd_list, asd_list) {
541 switch (asd->match_type) {
542 case V4L2_ASYNC_MATCH_FWNODE:
543 fwnode_handle_put(asd->match.fwnode);
549 list_del(&asd->asd_list);
554 void v4l2_async_notifier_cleanup(struct v4l2_async_notifier *notifier)
556 mutex_lock(&list_lock);
558 __v4l2_async_notifier_cleanup(notifier);
560 mutex_unlock(&list_lock);
562 EXPORT_SYMBOL_GPL(v4l2_async_notifier_cleanup);
564 int v4l2_async_notifier_add_subdev(struct v4l2_async_notifier *notifier,
565 struct v4l2_async_subdev *asd)
569 mutex_lock(&list_lock);
571 ret = v4l2_async_notifier_asd_valid(notifier, asd, -1);
575 list_add_tail(&asd->asd_list, ¬ifier->asd_list);
578 mutex_unlock(&list_lock);
581 EXPORT_SYMBOL_GPL(v4l2_async_notifier_add_subdev);
583 struct v4l2_async_subdev *
584 v4l2_async_notifier_add_fwnode_subdev(struct v4l2_async_notifier *notifier,
585 struct fwnode_handle *fwnode,
586 unsigned int asd_struct_size)
588 struct v4l2_async_subdev *asd;
591 asd = kzalloc(asd_struct_size, GFP_KERNEL);
593 return ERR_PTR(-ENOMEM);
595 asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
596 asd->match.fwnode = fwnode_handle_get(fwnode);
598 ret = v4l2_async_notifier_add_subdev(notifier, asd);
600 fwnode_handle_put(fwnode);
607 EXPORT_SYMBOL_GPL(v4l2_async_notifier_add_fwnode_subdev);
610 v4l2_async_notifier_add_fwnode_remote_subdev(struct v4l2_async_notifier *notif,
611 struct fwnode_handle *endpoint,
612 struct v4l2_async_subdev *asd)
614 struct fwnode_handle *remote;
617 remote = fwnode_graph_get_remote_port_parent(endpoint);
621 asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
622 asd->match.fwnode = remote;
624 ret = v4l2_async_notifier_add_subdev(notif, asd);
626 fwnode_handle_put(remote);
630 EXPORT_SYMBOL_GPL(v4l2_async_notifier_add_fwnode_remote_subdev);
632 struct v4l2_async_subdev *
633 v4l2_async_notifier_add_i2c_subdev(struct v4l2_async_notifier *notifier,
634 int adapter_id, unsigned short address,
635 unsigned int asd_struct_size)
637 struct v4l2_async_subdev *asd;
640 asd = kzalloc(asd_struct_size, GFP_KERNEL);
642 return ERR_PTR(-ENOMEM);
644 asd->match_type = V4L2_ASYNC_MATCH_I2C;
645 asd->match.i2c.adapter_id = adapter_id;
646 asd->match.i2c.address = address;
648 ret = v4l2_async_notifier_add_subdev(notifier, asd);
656 EXPORT_SYMBOL_GPL(v4l2_async_notifier_add_i2c_subdev);
658 struct v4l2_async_subdev *
659 v4l2_async_notifier_add_devname_subdev(struct v4l2_async_notifier *notifier,
660 const char *device_name,
661 unsigned int asd_struct_size)
663 struct v4l2_async_subdev *asd;
666 asd = kzalloc(asd_struct_size, GFP_KERNEL);
668 return ERR_PTR(-ENOMEM);
670 asd->match_type = V4L2_ASYNC_MATCH_DEVNAME;
671 asd->match.device_name = device_name;
673 ret = v4l2_async_notifier_add_subdev(notifier, asd);
681 EXPORT_SYMBOL_GPL(v4l2_async_notifier_add_devname_subdev);
683 int v4l2_async_register_subdev(struct v4l2_subdev *sd)
685 struct v4l2_async_notifier *subdev_notifier;
686 struct v4l2_async_notifier *notifier;
690 * No reference taken. The reference is held by the device
691 * (struct v4l2_subdev.dev), and async sub-device does not
692 * exist independently of the device at any point of time.
694 if (!sd->fwnode && sd->dev)
695 sd->fwnode = dev_fwnode(sd->dev);
697 mutex_lock(&list_lock);
699 INIT_LIST_HEAD(&sd->async_list);
701 list_for_each_entry(notifier, ¬ifier_list, list) {
702 struct v4l2_device *v4l2_dev =
703 v4l2_async_notifier_find_v4l2_dev(notifier);
704 struct v4l2_async_subdev *asd;
709 asd = v4l2_async_find_match(notifier, sd);
713 ret = v4l2_async_match_notify(notifier, v4l2_dev, sd, asd);
717 ret = v4l2_async_notifier_try_complete(notifier);
724 /* None matched, wait for hot-plugging */
725 list_add(&sd->async_list, &subdev_list);
728 mutex_unlock(&list_lock);
734 * Complete failed. Unbind the sub-devices bound through registering
735 * this async sub-device.
737 subdev_notifier = v4l2_async_find_subdev_notifier(sd);
739 v4l2_async_notifier_unbind_all_subdevs(subdev_notifier);
742 v4l2_async_notifier_call_unbind(notifier, sd, sd->asd);
743 v4l2_async_cleanup(sd);
745 mutex_unlock(&list_lock);
749 EXPORT_SYMBOL(v4l2_async_register_subdev);
751 void v4l2_async_unregister_subdev(struct v4l2_subdev *sd)
753 mutex_lock(&list_lock);
755 __v4l2_async_notifier_unregister(sd->subdev_notifier);
756 __v4l2_async_notifier_cleanup(sd->subdev_notifier);
757 kfree(sd->subdev_notifier);
758 sd->subdev_notifier = NULL;
761 struct v4l2_async_notifier *notifier = sd->notifier;
763 list_add(&sd->asd->list, ¬ifier->waiting);
765 v4l2_async_notifier_call_unbind(notifier, sd, sd->asd);
768 v4l2_async_cleanup(sd);
770 mutex_unlock(&list_lock);
772 EXPORT_SYMBOL(v4l2_async_unregister_subdev);