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