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