xref: /linux/drivers/media/v4l2-core/v4l2-async.c (revision bf4afc53b77aeaa48b5409da5c8da6bb4eff7f43)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * V4L2 asynchronous subdevice registration API
4  *
5  * Copyright (C) 2012-2013, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
6  */
7 
8 #include <linux/debugfs.h>
9 #include <linux/device.h>
10 #include <linux/err.h>
11 #include <linux/i2c.h>
12 #include <linux/list.h>
13 #include <linux/mm.h>
14 #include <linux/module.h>
15 #include <linux/mutex.h>
16 #include <linux/of.h>
17 #include <linux/platform_device.h>
18 #include <linux/seq_file.h>
19 #include <linux/slab.h>
20 #include <linux/types.h>
21 
22 #include <media/v4l2-async.h>
23 #include <media/v4l2-device.h>
24 #include <media/v4l2-fwnode.h>
25 #include <media/v4l2-subdev.h>
26 
27 #include "v4l2-subdev-priv.h"
28 
v4l2_async_nf_call_bound(struct v4l2_async_notifier * n,struct v4l2_subdev * subdev,struct v4l2_async_connection * asc)29 static int v4l2_async_nf_call_bound(struct v4l2_async_notifier *n,
30 				    struct v4l2_subdev *subdev,
31 				    struct v4l2_async_connection *asc)
32 {
33 	if (!n->ops || !n->ops->bound)
34 		return 0;
35 
36 	return n->ops->bound(n, subdev, asc);
37 }
38 
v4l2_async_nf_call_unbind(struct v4l2_async_notifier * n,struct v4l2_subdev * subdev,struct v4l2_async_connection * asc)39 static void v4l2_async_nf_call_unbind(struct v4l2_async_notifier *n,
40 				      struct v4l2_subdev *subdev,
41 				      struct v4l2_async_connection *asc)
42 {
43 	if (!n->ops || !n->ops->unbind)
44 		return;
45 
46 	n->ops->unbind(n, subdev, asc);
47 }
48 
v4l2_async_nf_call_complete(struct v4l2_async_notifier * n)49 static int v4l2_async_nf_call_complete(struct v4l2_async_notifier *n)
50 {
51 	if (!n->ops || !n->ops->complete)
52 		return 0;
53 
54 	return n->ops->complete(n);
55 }
56 
v4l2_async_nf_call_destroy(struct v4l2_async_notifier * n,struct v4l2_async_connection * asc)57 static void v4l2_async_nf_call_destroy(struct v4l2_async_notifier *n,
58 				       struct v4l2_async_connection *asc)
59 {
60 	if (!n->ops || !n->ops->destroy)
61 		return;
62 
63 	n->ops->destroy(asc);
64 }
65 
match_i2c(struct v4l2_async_notifier * notifier,struct v4l2_subdev * sd,struct v4l2_async_match_desc * match)66 static bool match_i2c(struct v4l2_async_notifier *notifier,
67 		      struct v4l2_subdev *sd,
68 		      struct v4l2_async_match_desc *match)
69 {
70 #if IS_ENABLED(CONFIG_I2C)
71 	struct i2c_client *client = i2c_verify_client(sd->dev);
72 
73 	return client &&
74 		match->i2c.adapter_id == client->adapter->nr &&
75 		match->i2c.address == client->addr;
76 #else
77 	return false;
78 #endif
79 }
80 
notifier_dev(struct v4l2_async_notifier * notifier)81 static struct device *notifier_dev(struct v4l2_async_notifier *notifier)
82 {
83 	if (notifier->sd)
84 		return notifier->sd->dev;
85 
86 	if (notifier->v4l2_dev)
87 		return notifier->v4l2_dev->dev;
88 
89 	return NULL;
90 }
91 
92 static bool
match_fwnode_one(struct v4l2_async_notifier * notifier,struct v4l2_subdev * sd,struct fwnode_handle * sd_fwnode,struct v4l2_async_match_desc * match)93 match_fwnode_one(struct v4l2_async_notifier *notifier,
94 		 struct v4l2_subdev *sd, struct fwnode_handle *sd_fwnode,
95 		 struct v4l2_async_match_desc *match)
96 {
97 	struct fwnode_handle *asd_dev_fwnode;
98 	bool ret;
99 
100 	dev_dbg(notifier_dev(notifier),
101 		"v4l2-async: fwnode match: need %pfw, trying %pfw\n",
102 		sd_fwnode, match->fwnode);
103 
104 	if (sd_fwnode == match->fwnode) {
105 		dev_dbg(notifier_dev(notifier),
106 			"v4l2-async: direct match found\n");
107 		return true;
108 	}
109 
110 	if (!fwnode_graph_is_endpoint(match->fwnode)) {
111 		dev_dbg(notifier_dev(notifier),
112 			"v4l2-async: direct match not found\n");
113 		return false;
114 	}
115 
116 	asd_dev_fwnode = fwnode_graph_get_port_parent(match->fwnode);
117 
118 	ret = sd_fwnode == asd_dev_fwnode;
119 
120 	fwnode_handle_put(asd_dev_fwnode);
121 
122 	dev_dbg(notifier_dev(notifier),
123 		"v4l2-async: device--endpoint match %sfound\n",
124 		ret ? "" : "not ");
125 
126 	return ret;
127 }
128 
match_fwnode(struct v4l2_async_notifier * notifier,struct v4l2_subdev * sd,struct v4l2_async_match_desc * match)129 static bool match_fwnode(struct v4l2_async_notifier *notifier,
130 			 struct v4l2_subdev *sd,
131 			 struct v4l2_async_match_desc *match)
132 {
133 	dev_dbg(notifier_dev(notifier),
134 		"v4l2-async: matching for notifier %pfw, sd fwnode %pfw\n",
135 		dev_fwnode(notifier_dev(notifier)), sd->fwnode);
136 
137 	if (!list_empty(&sd->async_subdev_endpoint_list)) {
138 		struct v4l2_async_subdev_endpoint *ase;
139 
140 		dev_dbg(sd->dev,
141 			"v4l2-async: endpoint fwnode list available, looking for %pfw\n",
142 			match->fwnode);
143 
144 		list_for_each_entry(ase, &sd->async_subdev_endpoint_list,
145 				    async_subdev_endpoint_entry) {
146 			bool matched = ase->endpoint == match->fwnode;
147 
148 			dev_dbg(sd->dev,
149 				"v4l2-async: endpoint-endpoint match %sfound with %pfw\n",
150 				matched ? "" : "not ", ase->endpoint);
151 
152 			if (matched)
153 				return true;
154 		}
155 
156 		dev_dbg(sd->dev, "async: no endpoint matched\n");
157 
158 		return false;
159 	}
160 
161 	if (match_fwnode_one(notifier, sd, sd->fwnode, match))
162 		return true;
163 
164 	/* Also check the secondary fwnode. */
165 	if (IS_ERR_OR_NULL(sd->fwnode->secondary))
166 		return false;
167 
168 	dev_dbg(notifier_dev(notifier),
169 		"v4l2-async: trying secondary fwnode match\n");
170 
171 	return match_fwnode_one(notifier, sd, sd->fwnode->secondary, match);
172 }
173 
174 static LIST_HEAD(subdev_list);
175 static LIST_HEAD(notifier_list);
176 static DEFINE_MUTEX(list_lock);
177 
178 static struct v4l2_async_connection *
v4l2_async_find_match(struct v4l2_async_notifier * notifier,struct v4l2_subdev * sd)179 v4l2_async_find_match(struct v4l2_async_notifier *notifier,
180 		      struct v4l2_subdev *sd)
181 {
182 	bool (*match)(struct v4l2_async_notifier *notifier,
183 		      struct v4l2_subdev *sd,
184 		      struct v4l2_async_match_desc *match);
185 	struct v4l2_async_connection *asc;
186 
187 	list_for_each_entry(asc, &notifier->waiting_list, asc_entry) {
188 		/* bus_type has been verified valid before */
189 		switch (asc->match.type) {
190 		case V4L2_ASYNC_MATCH_TYPE_I2C:
191 			match = match_i2c;
192 			break;
193 		case V4L2_ASYNC_MATCH_TYPE_FWNODE:
194 			match = match_fwnode;
195 			break;
196 		default:
197 			/* Cannot happen, unless someone breaks us */
198 			WARN_ON(true);
199 			return NULL;
200 		}
201 
202 		/* match cannot be NULL here */
203 		if (match(notifier, sd, &asc->match))
204 			return asc;
205 	}
206 
207 	return NULL;
208 }
209 
210 /* Compare two async match descriptors for equivalence */
v4l2_async_match_equal(struct v4l2_async_match_desc * match1,struct v4l2_async_match_desc * match2)211 static bool v4l2_async_match_equal(struct v4l2_async_match_desc *match1,
212 				   struct v4l2_async_match_desc *match2)
213 {
214 	if (match1->type != match2->type)
215 		return false;
216 
217 	switch (match1->type) {
218 	case V4L2_ASYNC_MATCH_TYPE_I2C:
219 		return match1->i2c.adapter_id == match2->i2c.adapter_id &&
220 			match1->i2c.address == match2->i2c.address;
221 	case V4L2_ASYNC_MATCH_TYPE_FWNODE:
222 		return match1->fwnode == match2->fwnode;
223 	default:
224 		break;
225 	}
226 
227 	return false;
228 }
229 
230 /* Find the sub-device notifier registered by a sub-device driver. */
231 static struct v4l2_async_notifier *
v4l2_async_find_subdev_notifier(struct v4l2_subdev * sd)232 v4l2_async_find_subdev_notifier(struct v4l2_subdev *sd)
233 {
234 	struct v4l2_async_notifier *n;
235 
236 	list_for_each_entry(n, &notifier_list, notifier_entry)
237 		if (n->sd == sd)
238 			return n;
239 
240 	return NULL;
241 }
242 
243 /* Get v4l2_device related to the notifier if one can be found. */
244 static struct v4l2_device *
v4l2_async_nf_find_v4l2_dev(struct v4l2_async_notifier * notifier)245 v4l2_async_nf_find_v4l2_dev(struct v4l2_async_notifier *notifier)
246 {
247 	while (notifier->parent)
248 		notifier = notifier->parent;
249 
250 	return notifier->v4l2_dev;
251 }
252 
253 /*
254  * Return true if all child sub-device notifiers are complete, false otherwise.
255  */
256 static bool
v4l2_async_nf_can_complete(struct v4l2_async_notifier * notifier)257 v4l2_async_nf_can_complete(struct v4l2_async_notifier *notifier)
258 {
259 	struct v4l2_async_connection *asc;
260 
261 	if (!list_empty(&notifier->waiting_list))
262 		return false;
263 
264 	list_for_each_entry(asc, &notifier->done_list, asc_entry) {
265 		struct v4l2_async_notifier *subdev_notifier =
266 			v4l2_async_find_subdev_notifier(asc->sd);
267 
268 		if (subdev_notifier &&
269 		    !v4l2_async_nf_can_complete(subdev_notifier))
270 			return false;
271 	}
272 
273 	return true;
274 }
275 
276 /*
277  * Complete the master notifier if possible. This is done when all async
278  * sub-devices have been bound; v4l2_device is also available then.
279  */
280 static int
v4l2_async_nf_try_complete(struct v4l2_async_notifier * notifier)281 v4l2_async_nf_try_complete(struct v4l2_async_notifier *notifier)
282 {
283 	struct v4l2_async_notifier *__notifier = notifier;
284 
285 	/* Quick check whether there are still more sub-devices here. */
286 	if (!list_empty(&notifier->waiting_list))
287 		return 0;
288 
289 	if (notifier->sd)
290 		dev_dbg(notifier_dev(notifier),
291 			"v4l2-async: trying to complete\n");
292 
293 	/* Check the entire notifier tree; find the root notifier first. */
294 	while (notifier->parent)
295 		notifier = notifier->parent;
296 
297 	/* This is root if it has v4l2_dev. */
298 	if (!notifier->v4l2_dev) {
299 		dev_dbg(notifier_dev(__notifier),
300 			"v4l2-async: V4L2 device not available\n");
301 		return 0;
302 	}
303 
304 	/* Is everything ready? */
305 	if (!v4l2_async_nf_can_complete(notifier))
306 		return 0;
307 
308 	dev_dbg(notifier_dev(__notifier), "v4l2-async: complete\n");
309 
310 	return v4l2_async_nf_call_complete(notifier);
311 }
312 
313 static int
314 v4l2_async_nf_try_all_subdevs(struct v4l2_async_notifier *notifier);
315 
v4l2_async_create_ancillary_links(struct v4l2_async_notifier * n,struct v4l2_subdev * sd)316 static int v4l2_async_create_ancillary_links(struct v4l2_async_notifier *n,
317 					     struct v4l2_subdev *sd)
318 {
319 #if IS_ENABLED(CONFIG_MEDIA_CONTROLLER)
320 	struct media_link *link;
321 
322 	if (sd->entity.function != MEDIA_ENT_F_LENS &&
323 	    sd->entity.function != MEDIA_ENT_F_FLASH)
324 		return 0;
325 
326 	if (!n->sd) {
327 		dev_warn(notifier_dev(n),
328 			 "not a sub-device notifier, not creating an ancillary link for %s!\n",
329 			 dev_name(sd->dev));
330 		return 0;
331 	}
332 
333 	link = media_create_ancillary_link(&n->sd->entity, &sd->entity);
334 
335 	return IS_ERR(link) ? PTR_ERR(link) : 0;
336 #else
337 	return 0;
338 #endif
339 }
340 
v4l2_async_match_notify(struct v4l2_async_notifier * notifier,struct v4l2_device * v4l2_dev,struct v4l2_subdev * sd,struct v4l2_async_connection * asc)341 static int v4l2_async_match_notify(struct v4l2_async_notifier *notifier,
342 				   struct v4l2_device *v4l2_dev,
343 				   struct v4l2_subdev *sd,
344 				   struct v4l2_async_connection *asc)
345 {
346 	bool registered = false;
347 	int ret;
348 
349 	if (list_empty(&sd->asc_list)) {
350 		ret = __v4l2_device_register_subdev(v4l2_dev, sd, sd->owner);
351 		if (ret < 0)
352 			return ret;
353 		registered = true;
354 	}
355 
356 	ret = v4l2_async_nf_call_bound(notifier, sd, asc);
357 	if (ret < 0) {
358 		if (asc->match.type == V4L2_ASYNC_MATCH_TYPE_FWNODE)
359 			dev_dbg(notifier_dev(notifier),
360 				"failed binding %pfw (%d)\n",
361 				asc->match.fwnode, ret);
362 		goto err_unregister_subdev;
363 	}
364 
365 	if (registered) {
366 		/*
367 		 * Depending of the function of the entities involved, we may
368 		 * want to create links between them (for example between a
369 		 * sensor and its lens or between a sensor's source pad and the
370 		 * connected device's sink pad).
371 		 */
372 		ret = v4l2_async_create_ancillary_links(notifier, sd);
373 		if (ret) {
374 			if (asc->match.type == V4L2_ASYNC_MATCH_TYPE_FWNODE)
375 				dev_dbg(notifier_dev(notifier),
376 					"failed creating links for %pfw (%d)\n",
377 					asc->match.fwnode, ret);
378 			goto err_call_unbind;
379 		}
380 	}
381 
382 	list_add(&asc->asc_subdev_entry, &sd->asc_list);
383 	asc->sd = sd;
384 
385 	/* Move from the waiting list to notifier's done */
386 	list_move(&asc->asc_entry, &notifier->done_list);
387 
388 	dev_dbg(notifier_dev(notifier), "v4l2-async: %s bound (ret %d)\n",
389 		dev_name(sd->dev), ret);
390 
391 	return 0;
392 
393 err_call_unbind:
394 	v4l2_async_nf_call_unbind(notifier, sd, asc);
395 	list_del(&asc->asc_subdev_entry);
396 
397 err_unregister_subdev:
398 	if (registered)
399 		v4l2_device_unregister_subdev(sd);
400 
401 	return ret;
402 }
403 
404 static int
v4l2_async_nf_try_subdev_notifier(struct v4l2_async_notifier * notifier,struct v4l2_subdev * sd)405 v4l2_async_nf_try_subdev_notifier(struct v4l2_async_notifier *notifier,
406 				  struct v4l2_subdev *sd)
407 {
408 	struct v4l2_async_notifier *subdev_notifier;
409 
410 	/*
411 	 * See if the sub-device has a notifier. If not, return here.
412 	 */
413 	subdev_notifier = v4l2_async_find_subdev_notifier(sd);
414 	if (!subdev_notifier || subdev_notifier->parent)
415 		return 0;
416 
417 	/*
418 	 * Proceed with checking for the sub-device notifier's async
419 	 * sub-devices, and return the result. The error will be handled by the
420 	 * caller.
421 	 */
422 	subdev_notifier->parent = notifier;
423 
424 	return v4l2_async_nf_try_all_subdevs(subdev_notifier);
425 }
426 
427 /* Test all async sub-devices in a notifier for a match. */
428 static int
v4l2_async_nf_try_all_subdevs(struct v4l2_async_notifier * notifier)429 v4l2_async_nf_try_all_subdevs(struct v4l2_async_notifier *notifier)
430 {
431 	struct v4l2_device *v4l2_dev =
432 		v4l2_async_nf_find_v4l2_dev(notifier);
433 	struct v4l2_subdev *sd;
434 
435 	if (!v4l2_dev)
436 		return 0;
437 
438 	dev_dbg(notifier_dev(notifier), "v4l2-async: trying all sub-devices\n");
439 
440 again:
441 	list_for_each_entry(sd, &subdev_list, async_list) {
442 		struct v4l2_async_connection *asc;
443 		int ret;
444 
445 		asc = v4l2_async_find_match(notifier, sd);
446 		if (!asc)
447 			continue;
448 
449 		dev_dbg(notifier_dev(notifier),
450 			"v4l2-async: match found, subdev %s\n", sd->name);
451 
452 		ret = v4l2_async_match_notify(notifier, v4l2_dev, sd, asc);
453 		if (ret < 0)
454 			return ret;
455 
456 		ret = v4l2_async_nf_try_subdev_notifier(notifier, sd);
457 		if (ret < 0)
458 			return ret;
459 
460 		/*
461 		 * v4l2_async_match_notify() may lead to registering a
462 		 * new notifier and thus changing the async subdevs
463 		 * list. In order to proceed safely from here, restart
464 		 * parsing the list from the beginning.
465 		 */
466 		goto again;
467 	}
468 
469 	return 0;
470 }
471 
v4l2_async_unbind_subdev_one(struct v4l2_async_notifier * notifier,struct v4l2_async_connection * asc)472 static void v4l2_async_unbind_subdev_one(struct v4l2_async_notifier *notifier,
473 					 struct v4l2_async_connection *asc)
474 {
475 	list_move_tail(&asc->asc_entry, &notifier->waiting_list);
476 	if (list_is_singular(&asc->asc_subdev_entry)) {
477 		v4l2_async_nf_call_unbind(notifier, asc->sd, asc);
478 		v4l2_device_unregister_subdev(asc->sd);
479 		asc->sd = NULL;
480 	}
481 	list_del(&asc->asc_subdev_entry);
482 }
483 
484 /* Unbind all sub-devices in the notifier tree. */
485 static void
v4l2_async_nf_unbind_all_subdevs(struct v4l2_async_notifier * notifier)486 v4l2_async_nf_unbind_all_subdevs(struct v4l2_async_notifier *notifier)
487 {
488 	struct v4l2_async_connection *asc, *asc_tmp;
489 
490 	list_for_each_entry_safe(asc, asc_tmp, &notifier->done_list,
491 				 asc_entry) {
492 		struct v4l2_async_notifier *subdev_notifier =
493 			v4l2_async_find_subdev_notifier(asc->sd);
494 
495 		if (subdev_notifier)
496 			v4l2_async_nf_unbind_all_subdevs(subdev_notifier);
497 
498 		v4l2_async_unbind_subdev_one(notifier, asc);
499 	}
500 
501 	notifier->parent = NULL;
502 }
503 
504 /* See if an async sub-device can be found in a notifier's lists. */
505 static bool
v4l2_async_nf_has_async_match_entry(struct v4l2_async_notifier * notifier,struct v4l2_async_match_desc * match)506 v4l2_async_nf_has_async_match_entry(struct v4l2_async_notifier *notifier,
507 				    struct v4l2_async_match_desc *match)
508 {
509 	struct v4l2_async_connection *asc;
510 
511 	list_for_each_entry(asc, &notifier->waiting_list, asc_entry)
512 		if (v4l2_async_match_equal(&asc->match, match))
513 			return true;
514 
515 	list_for_each_entry(asc, &notifier->done_list, asc_entry)
516 		if (v4l2_async_match_equal(&asc->match, match))
517 			return true;
518 
519 	return false;
520 }
521 
522 /*
523  * Find out whether an async sub-device was set up already or whether it exists
524  * in a given notifier.
525  */
526 static bool
v4l2_async_nf_has_async_match(struct v4l2_async_notifier * notifier,struct v4l2_async_match_desc * match)527 v4l2_async_nf_has_async_match(struct v4l2_async_notifier *notifier,
528 			      struct v4l2_async_match_desc *match)
529 {
530 	struct list_head *heads[] = {
531 		&notifier->waiting_list,
532 		&notifier->done_list,
533 	};
534 	unsigned int i;
535 
536 	lockdep_assert_held(&list_lock);
537 
538 	/* Check that an asd is not being added more than once. */
539 	for (i = 0; i < ARRAY_SIZE(heads); i++) {
540 		struct v4l2_async_connection *asc;
541 
542 		list_for_each_entry(asc, heads[i], asc_entry) {
543 			if (&asc->match == match)
544 				continue;
545 			if (v4l2_async_match_equal(&asc->match, match))
546 				return true;
547 		}
548 	}
549 
550 	/* Check that an asc does not exist in other notifiers. */
551 	list_for_each_entry(notifier, &notifier_list, notifier_entry)
552 		if (v4l2_async_nf_has_async_match_entry(notifier, match))
553 			return true;
554 
555 	return false;
556 }
557 
v4l2_async_nf_match_valid(struct v4l2_async_notifier * notifier,struct v4l2_async_match_desc * match)558 static int v4l2_async_nf_match_valid(struct v4l2_async_notifier *notifier,
559 				     struct v4l2_async_match_desc *match)
560 {
561 	struct device *dev = notifier_dev(notifier);
562 
563 	switch (match->type) {
564 	case V4L2_ASYNC_MATCH_TYPE_I2C:
565 	case V4L2_ASYNC_MATCH_TYPE_FWNODE:
566 		if (v4l2_async_nf_has_async_match(notifier, match)) {
567 			dev_dbg(dev, "v4l2-async: match descriptor already listed in a notifier\n");
568 			return -EEXIST;
569 		}
570 		break;
571 	default:
572 		dev_err(dev, "v4l2-async: Invalid match type %u on %p\n",
573 			match->type, match);
574 		return -EINVAL;
575 	}
576 
577 	return 0;
578 }
579 
v4l2_async_nf_init(struct v4l2_async_notifier * notifier,struct v4l2_device * v4l2_dev)580 void v4l2_async_nf_init(struct v4l2_async_notifier *notifier,
581 			struct v4l2_device *v4l2_dev)
582 {
583 	INIT_LIST_HEAD(&notifier->waiting_list);
584 	INIT_LIST_HEAD(&notifier->done_list);
585 	INIT_LIST_HEAD(&notifier->notifier_entry);
586 	notifier->v4l2_dev = v4l2_dev;
587 }
588 EXPORT_SYMBOL(v4l2_async_nf_init);
589 
v4l2_async_subdev_nf_init(struct v4l2_async_notifier * notifier,struct v4l2_subdev * sd)590 void v4l2_async_subdev_nf_init(struct v4l2_async_notifier *notifier,
591 			       struct v4l2_subdev *sd)
592 {
593 	INIT_LIST_HEAD(&notifier->waiting_list);
594 	INIT_LIST_HEAD(&notifier->done_list);
595 	INIT_LIST_HEAD(&notifier->notifier_entry);
596 	notifier->sd = sd;
597 }
598 EXPORT_SYMBOL_GPL(v4l2_async_subdev_nf_init);
599 
__v4l2_async_nf_register(struct v4l2_async_notifier * notifier)600 static int __v4l2_async_nf_register(struct v4l2_async_notifier *notifier)
601 {
602 	struct v4l2_async_connection *asc;
603 	int ret;
604 
605 	mutex_lock(&list_lock);
606 
607 	list_for_each_entry(asc, &notifier->waiting_list, asc_entry) {
608 		ret = v4l2_async_nf_match_valid(notifier, &asc->match);
609 		if (ret)
610 			goto err_unlock;
611 	}
612 
613 	ret = v4l2_async_nf_try_all_subdevs(notifier);
614 	if (ret < 0)
615 		goto err_unbind;
616 
617 	ret = v4l2_async_nf_try_complete(notifier);
618 	if (ret < 0)
619 		goto err_unbind;
620 
621 	/* Keep also completed notifiers on the list */
622 	list_add(&notifier->notifier_entry, &notifier_list);
623 
624 	mutex_unlock(&list_lock);
625 
626 	return 0;
627 
628 err_unbind:
629 	/*
630 	 * On failure, unbind all sub-devices registered through this notifier.
631 	 */
632 	v4l2_async_nf_unbind_all_subdevs(notifier);
633 
634 err_unlock:
635 	mutex_unlock(&list_lock);
636 
637 	return ret;
638 }
639 
v4l2_async_nf_register(struct v4l2_async_notifier * notifier)640 int v4l2_async_nf_register(struct v4l2_async_notifier *notifier)
641 {
642 	if (WARN_ON(!notifier->v4l2_dev == !notifier->sd))
643 		return -EINVAL;
644 
645 	return __v4l2_async_nf_register(notifier);
646 }
647 EXPORT_SYMBOL(v4l2_async_nf_register);
648 
649 static void
__v4l2_async_nf_unregister(struct v4l2_async_notifier * notifier)650 __v4l2_async_nf_unregister(struct v4l2_async_notifier *notifier)
651 {
652 	if (!notifier || (!notifier->v4l2_dev && !notifier->sd))
653 		return;
654 
655 	v4l2_async_nf_unbind_all_subdevs(notifier);
656 
657 	list_del_init(&notifier->notifier_entry);
658 }
659 
v4l2_async_nf_unregister(struct v4l2_async_notifier * notifier)660 void v4l2_async_nf_unregister(struct v4l2_async_notifier *notifier)
661 {
662 	mutex_lock(&list_lock);
663 
664 	__v4l2_async_nf_unregister(notifier);
665 
666 	mutex_unlock(&list_lock);
667 }
668 EXPORT_SYMBOL(v4l2_async_nf_unregister);
669 
__v4l2_async_nf_cleanup(struct v4l2_async_notifier * notifier)670 static void __v4l2_async_nf_cleanup(struct v4l2_async_notifier *notifier)
671 {
672 	struct v4l2_async_connection *asc, *tmp;
673 
674 	if (!notifier || !notifier->waiting_list.next)
675 		return;
676 
677 	WARN_ON(!list_empty(&notifier->done_list));
678 
679 	list_for_each_entry_safe(asc, tmp, &notifier->waiting_list, asc_entry) {
680 		list_del(&asc->asc_entry);
681 		v4l2_async_nf_call_destroy(notifier, asc);
682 
683 		if (asc->match.type == V4L2_ASYNC_MATCH_TYPE_FWNODE)
684 			fwnode_handle_put(asc->match.fwnode);
685 
686 		kfree(asc);
687 	}
688 
689 	notifier->sd = NULL;
690 	notifier->v4l2_dev = NULL;
691 }
692 
v4l2_async_nf_cleanup(struct v4l2_async_notifier * notifier)693 void v4l2_async_nf_cleanup(struct v4l2_async_notifier *notifier)
694 {
695 	mutex_lock(&list_lock);
696 
697 	__v4l2_async_nf_cleanup(notifier);
698 
699 	mutex_unlock(&list_lock);
700 }
701 EXPORT_SYMBOL_GPL(v4l2_async_nf_cleanup);
702 
__v4l2_async_nf_add_connection(struct v4l2_async_notifier * notifier,struct v4l2_async_connection * asc)703 static void __v4l2_async_nf_add_connection(struct v4l2_async_notifier *notifier,
704 					   struct v4l2_async_connection *asc)
705 {
706 	mutex_lock(&list_lock);
707 
708 	list_add_tail(&asc->asc_entry, &notifier->waiting_list);
709 
710 	mutex_unlock(&list_lock);
711 }
712 
713 struct v4l2_async_connection *
__v4l2_async_nf_add_fwnode(struct v4l2_async_notifier * notifier,struct fwnode_handle * fwnode,unsigned int asc_struct_size)714 __v4l2_async_nf_add_fwnode(struct v4l2_async_notifier *notifier,
715 			   struct fwnode_handle *fwnode,
716 			   unsigned int asc_struct_size)
717 {
718 	struct v4l2_async_connection *asc;
719 
720 	asc = kzalloc(asc_struct_size, GFP_KERNEL);
721 	if (!asc)
722 		return ERR_PTR(-ENOMEM);
723 
724 	asc->notifier = notifier;
725 	asc->match.type = V4L2_ASYNC_MATCH_TYPE_FWNODE;
726 	asc->match.fwnode = fwnode_handle_get(fwnode);
727 
728 	__v4l2_async_nf_add_connection(notifier, asc);
729 
730 	return asc;
731 }
732 EXPORT_SYMBOL_GPL(__v4l2_async_nf_add_fwnode);
733 
734 struct v4l2_async_connection *
__v4l2_async_nf_add_fwnode_remote(struct v4l2_async_notifier * notif,struct fwnode_handle * endpoint,unsigned int asc_struct_size)735 __v4l2_async_nf_add_fwnode_remote(struct v4l2_async_notifier *notif,
736 				  struct fwnode_handle *endpoint,
737 				  unsigned int asc_struct_size)
738 {
739 	struct v4l2_async_connection *asc;
740 	struct fwnode_handle *remote;
741 
742 	remote = fwnode_graph_get_remote_endpoint(endpoint);
743 	if (!remote)
744 		return ERR_PTR(-ENOTCONN);
745 
746 	asc = __v4l2_async_nf_add_fwnode(notif, remote, asc_struct_size);
747 	/*
748 	 * Calling __v4l2_async_nf_add_fwnode grabs a refcount,
749 	 * so drop the one we got in fwnode_graph_get_remote_port_parent.
750 	 */
751 	fwnode_handle_put(remote);
752 	return asc;
753 }
754 EXPORT_SYMBOL_GPL(__v4l2_async_nf_add_fwnode_remote);
755 
756 struct v4l2_async_connection *
__v4l2_async_nf_add_i2c(struct v4l2_async_notifier * notifier,int adapter_id,unsigned short address,unsigned int asc_struct_size)757 __v4l2_async_nf_add_i2c(struct v4l2_async_notifier *notifier, int adapter_id,
758 			unsigned short address, unsigned int asc_struct_size)
759 {
760 	struct v4l2_async_connection *asc;
761 
762 	asc = kzalloc(asc_struct_size, GFP_KERNEL);
763 	if (!asc)
764 		return ERR_PTR(-ENOMEM);
765 
766 	asc->notifier = notifier;
767 	asc->match.type = V4L2_ASYNC_MATCH_TYPE_I2C;
768 	asc->match.i2c.adapter_id = adapter_id;
769 	asc->match.i2c.address = address;
770 
771 	__v4l2_async_nf_add_connection(notifier, asc);
772 
773 	return asc;
774 }
775 EXPORT_SYMBOL_GPL(__v4l2_async_nf_add_i2c);
776 
v4l2_async_subdev_endpoint_add(struct v4l2_subdev * sd,struct fwnode_handle * fwnode)777 int v4l2_async_subdev_endpoint_add(struct v4l2_subdev *sd,
778 				   struct fwnode_handle *fwnode)
779 {
780 	struct v4l2_async_subdev_endpoint *ase;
781 
782 	ase = kmalloc_obj(*ase);
783 	if (!ase)
784 		return -ENOMEM;
785 
786 	ase->endpoint = fwnode;
787 	list_add(&ase->async_subdev_endpoint_entry,
788 		 &sd->async_subdev_endpoint_list);
789 
790 	return 0;
791 }
792 EXPORT_SYMBOL_GPL(v4l2_async_subdev_endpoint_add);
793 
794 struct v4l2_async_connection *
v4l2_async_connection_unique(struct v4l2_subdev * sd)795 v4l2_async_connection_unique(struct v4l2_subdev *sd)
796 {
797 	if (!list_is_singular(&sd->asc_list))
798 		return NULL;
799 
800 	return list_first_entry(&sd->asc_list,
801 				struct v4l2_async_connection, asc_subdev_entry);
802 }
803 EXPORT_SYMBOL_GPL(v4l2_async_connection_unique);
804 
__v4l2_async_register_subdev(struct v4l2_subdev * sd,struct module * module)805 int __v4l2_async_register_subdev(struct v4l2_subdev *sd, struct module *module)
806 {
807 	struct v4l2_async_notifier *subdev_notifier;
808 	struct v4l2_async_notifier *notifier;
809 	struct v4l2_async_connection *asc;
810 	int ret;
811 
812 	INIT_LIST_HEAD(&sd->asc_list);
813 
814 	/*
815 	 * No reference taken. The reference is held by the device (struct
816 	 * v4l2_subdev.dev), and async sub-device does not exist independently
817 	 * of the device at any point of time.
818 	 *
819 	 * The async sub-device shall always be registered for its device node,
820 	 * not the endpoint node.
821 	 */
822 	if (!sd->fwnode && sd->dev) {
823 		sd->fwnode = dev_fwnode(sd->dev);
824 	} else if (fwnode_graph_is_endpoint(sd->fwnode)) {
825 		dev_warn(sd->dev, "sub-device fwnode is an endpoint!\n");
826 		return -EINVAL;
827 	}
828 
829 	sd->owner = module;
830 
831 	mutex_lock(&list_lock);
832 
833 	list_for_each_entry(notifier, &notifier_list, notifier_entry) {
834 		struct v4l2_device *v4l2_dev =
835 			v4l2_async_nf_find_v4l2_dev(notifier);
836 
837 		if (!v4l2_dev)
838 			continue;
839 
840 		while ((asc = v4l2_async_find_match(notifier, sd))) {
841 			ret = v4l2_async_match_notify(notifier, v4l2_dev, sd,
842 						      asc);
843 			if (ret)
844 				goto err_unlock;
845 
846 			ret = v4l2_async_nf_try_subdev_notifier(notifier, sd);
847 			if (ret)
848 				goto err_unbind_one;
849 
850 			ret = v4l2_async_nf_try_complete(notifier);
851 			if (ret)
852 				goto err_unbind;
853 		}
854 	}
855 
856 	/* None matched, wait for hot-plugging */
857 	list_add(&sd->async_list, &subdev_list);
858 
859 	mutex_unlock(&list_lock);
860 
861 	return 0;
862 
863 err_unbind:
864 	/*
865 	 * Complete failed. Unbind the sub-devices bound through registering
866 	 * this async sub-device.
867 	 */
868 	subdev_notifier = v4l2_async_find_subdev_notifier(sd);
869 	if (subdev_notifier)
870 		v4l2_async_nf_unbind_all_subdevs(subdev_notifier);
871 
872 err_unbind_one:
873 	v4l2_async_unbind_subdev_one(notifier, asc);
874 
875 err_unlock:
876 	mutex_unlock(&list_lock);
877 
878 	sd->owner = NULL;
879 
880 	return ret;
881 }
882 EXPORT_SYMBOL(__v4l2_async_register_subdev);
883 
v4l2_async_unregister_subdev(struct v4l2_subdev * sd)884 void v4l2_async_unregister_subdev(struct v4l2_subdev *sd)
885 {
886 	struct v4l2_async_connection *asc, *asc_tmp;
887 
888 	if (!sd->async_list.next)
889 		return;
890 
891 	v4l2_subdev_put_privacy_led(sd);
892 
893 	mutex_lock(&list_lock);
894 
895 	__v4l2_async_nf_unregister(sd->subdev_notifier);
896 	__v4l2_async_nf_cleanup(sd->subdev_notifier);
897 	kfree(sd->subdev_notifier);
898 	sd->subdev_notifier = NULL;
899 
900 	if (sd->asc_list.next) {
901 		list_for_each_entry_safe(asc, asc_tmp, &sd->asc_list,
902 					 asc_subdev_entry) {
903 			v4l2_async_unbind_subdev_one(asc->notifier, asc);
904 		}
905 	}
906 
907 	list_del(&sd->async_list);
908 	sd->async_list.next = NULL;
909 
910 	mutex_unlock(&list_lock);
911 }
912 EXPORT_SYMBOL(v4l2_async_unregister_subdev);
913 
print_waiting_match(struct seq_file * s,struct v4l2_async_match_desc * match)914 static void print_waiting_match(struct seq_file *s,
915 				struct v4l2_async_match_desc *match)
916 {
917 	switch (match->type) {
918 	case V4L2_ASYNC_MATCH_TYPE_I2C:
919 		seq_printf(s, " [i2c] dev=%d-%04x\n", match->i2c.adapter_id,
920 			   match->i2c.address);
921 		break;
922 	case V4L2_ASYNC_MATCH_TYPE_FWNODE: {
923 		struct fwnode_handle *devnode, *fwnode = match->fwnode;
924 
925 		devnode = fwnode_graph_is_endpoint(fwnode) ?
926 			  fwnode_graph_get_port_parent(fwnode) :
927 			  fwnode_handle_get(fwnode);
928 
929 		seq_printf(s, " [fwnode] dev=%s, node=%pfw\n",
930 			   devnode->dev ? dev_name(devnode->dev) : "nil",
931 			   fwnode);
932 
933 		fwnode_handle_put(devnode);
934 		break;
935 	}
936 	}
937 }
938 
939 static const char *
v4l2_async_nf_name(struct v4l2_async_notifier * notifier)940 v4l2_async_nf_name(struct v4l2_async_notifier *notifier)
941 {
942 	if (notifier->v4l2_dev)
943 		return notifier->v4l2_dev->name;
944 	else if (notifier->sd)
945 		return notifier->sd->name;
946 	else
947 		return "nil";
948 }
949 
pending_subdevs_show(struct seq_file * s,void * data)950 static int pending_subdevs_show(struct seq_file *s, void *data)
951 {
952 	struct v4l2_async_notifier *notif;
953 	struct v4l2_async_connection *asc;
954 
955 	mutex_lock(&list_lock);
956 
957 	list_for_each_entry(notif, &notifier_list, notifier_entry) {
958 		seq_printf(s, "%s:\n", v4l2_async_nf_name(notif));
959 		list_for_each_entry(asc, &notif->waiting_list, asc_entry)
960 			print_waiting_match(s, &asc->match);
961 	}
962 
963 	mutex_unlock(&list_lock);
964 
965 	return 0;
966 }
967 DEFINE_SHOW_ATTRIBUTE(pending_subdevs);
968 
969 static struct dentry *v4l2_async_debugfs_dir;
970 
v4l2_async_init(void)971 static int __init v4l2_async_init(void)
972 {
973 	v4l2_async_debugfs_dir = debugfs_create_dir("v4l2-async", NULL);
974 	debugfs_create_file("pending_async_subdevices", 0444,
975 			    v4l2_async_debugfs_dir, NULL,
976 			    &pending_subdevs_fops);
977 
978 	return 0;
979 }
980 
v4l2_async_exit(void)981 static void __exit v4l2_async_exit(void)
982 {
983 	debugfs_remove_recursive(v4l2_async_debugfs_dir);
984 }
985 
986 subsys_initcall(v4l2_async_init);
987 module_exit(v4l2_async_exit);
988 
989 MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
990 MODULE_AUTHOR("Sakari Ailus <sakari.ailus@linux.intel.com>");
991 MODULE_AUTHOR("Ezequiel Garcia <ezequiel@collabora.com>");
992 MODULE_DESCRIPTION("V4L2 asynchronous subdevice registration API");
993 MODULE_LICENSE("GPL");
994