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