1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Componentized device handling. 4 */ 5 #include <linux/component.h> 6 #include <linux/device.h> 7 #include <linux/list.h> 8 #include <linux/mutex.h> 9 #include <linux/of.h> 10 #include <linux/slab.h> 11 #include <linux/debugfs.h> 12 13 /** 14 * DOC: overview 15 * 16 * The component helper allows drivers to collect a pile of sub-devices, 17 * including their bound drivers, into an aggregate driver. Various subsystems 18 * already provide functions to get hold of such components, e.g. 19 * of_clk_get_by_name(). The component helper can be used when such a 20 * subsystem-specific way to find a device is not available: The component 21 * helper fills the niche of aggregate drivers for specific hardware, where 22 * further standardization into a subsystem would not be practical. The common 23 * example is when a logical device (e.g. a DRM display driver) is spread around 24 * the SoC on various components (scanout engines, blending blocks, transcoders 25 * for various outputs and so on). 26 * 27 * The component helper also doesn't solve runtime dependencies, e.g. for system 28 * suspend and resume operations. See also :ref:`device links<device_link>`. 29 * 30 * Components are registered using component_add() and unregistered with 31 * component_del(), usually from the driver's probe and disconnect functions. 32 * 33 * Aggregate drivers first assemble a component match list of what they need 34 * using component_match_add(). This is then registered as an aggregate driver 35 * using component_master_add_with_match(), and unregistered using 36 * component_master_del(). 37 */ 38 39 struct component; 40 41 struct component_match_array { 42 void *data; 43 int (*compare)(struct device *, void *); 44 int (*compare_typed)(struct device *, int, void *); 45 void (*release)(struct device *, void *); 46 struct component *component; 47 bool duplicate; 48 }; 49 50 struct component_match { 51 size_t alloc; 52 size_t num; 53 struct component_match_array *compare; 54 }; 55 56 struct aggregate_device { 57 struct list_head node; 58 bool bound; 59 60 const struct component_master_ops *ops; 61 struct device *parent; 62 struct component_match *match; 63 }; 64 65 struct component { 66 struct list_head node; 67 struct aggregate_device *adev; 68 bool bound; 69 70 const struct component_ops *ops; 71 int subcomponent; 72 struct device *dev; 73 }; 74 75 static DEFINE_MUTEX(component_mutex); 76 static LIST_HEAD(component_list); 77 static LIST_HEAD(aggregate_devices); 78 79 #ifdef CONFIG_DEBUG_FS 80 81 static struct dentry *component_debugfs_dir; 82 83 static int component_devices_show(struct seq_file *s, void *data) 84 { 85 struct aggregate_device *m = s->private; 86 struct component_match *match = m->match; 87 size_t i; 88 89 mutex_lock(&component_mutex); 90 seq_printf(s, "%-40s %20s\n", "aggregate_device name", "status"); 91 seq_puts(s, "-------------------------------------------------------------\n"); 92 seq_printf(s, "%-40s %20s\n\n", 93 dev_name(m->parent), m->bound ? "bound" : "not bound"); 94 95 seq_printf(s, "%-40s %20s\n", "device name", "status"); 96 seq_puts(s, "-------------------------------------------------------------\n"); 97 for (i = 0; i < match->num; i++) { 98 struct component *component = match->compare[i].component; 99 100 seq_printf(s, "%-40s %20s\n", 101 component ? dev_name(component->dev) : "(unknown)", 102 component ? (component->bound ? "bound" : "not bound") : "not registered"); 103 } 104 mutex_unlock(&component_mutex); 105 106 return 0; 107 } 108 109 DEFINE_SHOW_ATTRIBUTE(component_devices); 110 111 static int __init component_debug_init(void) 112 { 113 component_debugfs_dir = debugfs_create_dir("device_component", NULL); 114 115 return 0; 116 } 117 118 core_initcall(component_debug_init); 119 120 static void component_debugfs_add(struct aggregate_device *m) 121 { 122 debugfs_create_file(dev_name(m->parent), 0444, component_debugfs_dir, m, 123 &component_devices_fops); 124 } 125 126 static void component_debugfs_del(struct aggregate_device *m) 127 { 128 debugfs_lookup_and_remove(dev_name(m->parent), component_debugfs_dir); 129 } 130 131 #else 132 133 static void component_debugfs_add(struct aggregate_device *m) 134 { } 135 136 static void component_debugfs_del(struct aggregate_device *m) 137 { } 138 139 #endif 140 141 static struct aggregate_device *__aggregate_find(struct device *parent, 142 const struct component_master_ops *ops) 143 { 144 struct aggregate_device *m; 145 146 list_for_each_entry(m, &aggregate_devices, node) 147 if (m->parent == parent && (!ops || m->ops == ops)) 148 return m; 149 150 return NULL; 151 } 152 153 static struct component *find_component(struct aggregate_device *adev, 154 struct component_match_array *mc) 155 { 156 struct component *c; 157 158 list_for_each_entry(c, &component_list, node) { 159 if (c->adev && c->adev != adev) 160 continue; 161 162 if (mc->compare && mc->compare(c->dev, mc->data)) 163 return c; 164 165 if (mc->compare_typed && 166 mc->compare_typed(c->dev, c->subcomponent, mc->data)) 167 return c; 168 } 169 170 return NULL; 171 } 172 173 static int find_components(struct aggregate_device *adev) 174 { 175 struct component_match *match = adev->match; 176 size_t i; 177 int ret = 0; 178 179 /* 180 * Scan the array of match functions and attach 181 * any components which are found to this adev. 182 */ 183 for (i = 0; i < match->num; i++) { 184 struct component_match_array *mc = &match->compare[i]; 185 struct component *c; 186 187 dev_dbg(adev->parent, "Looking for component %zu\n", i); 188 189 if (match->compare[i].component) 190 continue; 191 192 c = find_component(adev, mc); 193 if (!c) { 194 ret = -ENXIO; 195 break; 196 } 197 198 dev_dbg(adev->parent, "found component %s, duplicate %u\n", 199 dev_name(c->dev), !!c->adev); 200 201 /* Attach this component to the adev */ 202 match->compare[i].duplicate = !!c->adev; 203 match->compare[i].component = c; 204 c->adev = adev; 205 } 206 return ret; 207 } 208 209 /* Detach component from associated aggregate_device */ 210 static void remove_component(struct aggregate_device *adev, struct component *c) 211 { 212 size_t i; 213 214 /* Detach the component from this adev. */ 215 for (i = 0; i < adev->match->num; i++) 216 if (adev->match->compare[i].component == c) 217 adev->match->compare[i].component = NULL; 218 } 219 220 /* 221 * Try to bring up an aggregate device. If component is NULL, we're interested 222 * in this aggregate device, otherwise it's a component which must be present 223 * to try and bring up the aggregate device. 224 * 225 * Returns 1 for successful bringup, 0 if not ready, or -ve errno. 226 */ 227 static int try_to_bring_up_aggregate_device(struct aggregate_device *adev, 228 struct component *component) 229 { 230 int ret; 231 232 dev_dbg(adev->parent, "trying to bring up adev\n"); 233 234 if (find_components(adev)) { 235 dev_dbg(adev->parent, "master has incomplete components\n"); 236 return 0; 237 } 238 239 if (component && component->adev != adev) { 240 dev_dbg(adev->parent, "master is not for this component (%s)\n", 241 dev_name(component->dev)); 242 return 0; 243 } 244 245 if (!devres_open_group(adev->parent, adev, GFP_KERNEL)) 246 return -ENOMEM; 247 248 /* Found all components */ 249 ret = adev->ops->bind(adev->parent); 250 if (ret < 0) { 251 devres_release_group(adev->parent, NULL); 252 if (ret != -EPROBE_DEFER) 253 dev_info(adev->parent, "adev bind failed: %d\n", ret); 254 return ret; 255 } 256 257 devres_close_group(adev->parent, NULL); 258 adev->bound = true; 259 return 1; 260 } 261 262 static int try_to_bring_up_masters(struct component *component) 263 { 264 struct aggregate_device *adev; 265 int ret = 0; 266 267 list_for_each_entry(adev, &aggregate_devices, node) { 268 if (!adev->bound) { 269 ret = try_to_bring_up_aggregate_device(adev, component); 270 if (ret != 0) 271 break; 272 } 273 } 274 275 return ret; 276 } 277 278 static void take_down_aggregate_device(struct aggregate_device *adev) 279 { 280 if (adev->bound) { 281 adev->ops->unbind(adev->parent); 282 devres_release_group(adev->parent, adev); 283 adev->bound = false; 284 } 285 } 286 287 /** 288 * component_compare_of - A common component compare function for of_node 289 * @dev: component device 290 * @data: @compare_data from component_match_add_release() 291 * 292 * A common compare function when compare_data is device of_node. e.g. 293 * component_match_add_release(masterdev, &match, component_release_of, 294 * component_compare_of, component_dev_of_node) 295 */ 296 int component_compare_of(struct device *dev, void *data) 297 { 298 return device_match_of_node(dev, data); 299 } 300 EXPORT_SYMBOL_GPL(component_compare_of); 301 302 /** 303 * component_release_of - A common component release function for of_node 304 * @dev: component device 305 * @data: @compare_data from component_match_add_release() 306 * 307 * About the example, Please see component_compare_of(). 308 */ 309 void component_release_of(struct device *dev, void *data) 310 { 311 of_node_put(data); 312 } 313 EXPORT_SYMBOL_GPL(component_release_of); 314 315 /** 316 * component_compare_dev - A common component compare function for dev 317 * @dev: component device 318 * @data: @compare_data from component_match_add_release() 319 * 320 * A common compare function when compare_data is struce device. e.g. 321 * component_match_add(masterdev, &match, component_compare_dev, component_dev) 322 */ 323 int component_compare_dev(struct device *dev, void *data) 324 { 325 return dev == data; 326 } 327 EXPORT_SYMBOL_GPL(component_compare_dev); 328 329 /** 330 * component_compare_dev_name - A common component compare function for device name 331 * @dev: component device 332 * @data: @compare_data from component_match_add_release() 333 * 334 * A common compare function when compare_data is device name string. e.g. 335 * component_match_add(masterdev, &match, component_compare_dev_name, 336 * "component_dev_name") 337 */ 338 int component_compare_dev_name(struct device *dev, void *data) 339 { 340 return device_match_name(dev, data); 341 } 342 EXPORT_SYMBOL_GPL(component_compare_dev_name); 343 344 static void devm_component_match_release(struct device *parent, void *res) 345 { 346 struct component_match *match = res; 347 unsigned int i; 348 349 for (i = 0; i < match->num; i++) { 350 struct component_match_array *mc = &match->compare[i]; 351 352 if (mc->release) 353 mc->release(parent, mc->data); 354 } 355 356 kfree(match->compare); 357 } 358 359 static int component_match_realloc(struct component_match *match, size_t num) 360 { 361 struct component_match_array *new; 362 363 if (match->alloc == num) 364 return 0; 365 366 new = kmalloc_array(num, sizeof(*new), GFP_KERNEL); 367 if (!new) 368 return -ENOMEM; 369 370 if (match->compare) { 371 memcpy(new, match->compare, sizeof(*new) * 372 min(match->num, num)); 373 kfree(match->compare); 374 } 375 match->compare = new; 376 match->alloc = num; 377 378 return 0; 379 } 380 381 static void __component_match_add(struct device *parent, 382 struct component_match **matchptr, 383 void (*release)(struct device *, void *), 384 int (*compare)(struct device *, void *), 385 int (*compare_typed)(struct device *, int, void *), 386 void *compare_data) 387 { 388 struct component_match *match = *matchptr; 389 390 if (IS_ERR(match)) 391 return; 392 393 if (!match) { 394 match = devres_alloc(devm_component_match_release, 395 sizeof(*match), GFP_KERNEL); 396 if (!match) { 397 *matchptr = ERR_PTR(-ENOMEM); 398 return; 399 } 400 401 devres_add(parent, match); 402 403 *matchptr = match; 404 } 405 406 if (match->num == match->alloc) { 407 size_t new_size = match->alloc + 16; 408 int ret; 409 410 ret = component_match_realloc(match, new_size); 411 if (ret) { 412 *matchptr = ERR_PTR(ret); 413 return; 414 } 415 } 416 417 match->compare[match->num].compare = compare; 418 match->compare[match->num].compare_typed = compare_typed; 419 match->compare[match->num].release = release; 420 match->compare[match->num].data = compare_data; 421 match->compare[match->num].component = NULL; 422 match->num++; 423 } 424 425 /** 426 * component_match_add_release - add a component match entry with release callback 427 * @parent: parent device of the aggregate driver 428 * @matchptr: pointer to the list of component matches 429 * @release: release function for @compare_data 430 * @compare: compare function to match against all components 431 * @compare_data: opaque pointer passed to the @compare function 432 * 433 * Adds a new component match to the list stored in @matchptr, which the 434 * aggregate driver needs to function. The list of component matches pointed to 435 * by @matchptr must be initialized to NULL before adding the first match. This 436 * only matches against components added with component_add(). 437 * 438 * The allocated match list in @matchptr is automatically released using devm 439 * actions, where upon @release will be called to free any references held by 440 * @compare_data, e.g. when @compare_data is a &device_node that must be 441 * released with of_node_put(). 442 * 443 * See also component_match_add() and component_match_add_typed(). 444 */ 445 void component_match_add_release(struct device *parent, 446 struct component_match **matchptr, 447 void (*release)(struct device *, void *), 448 int (*compare)(struct device *, void *), void *compare_data) 449 { 450 __component_match_add(parent, matchptr, release, compare, NULL, 451 compare_data); 452 } 453 EXPORT_SYMBOL(component_match_add_release); 454 455 /** 456 * component_match_add_typed - add a component match entry for a typed component 457 * @parent: parent device of the aggregate driver 458 * @matchptr: pointer to the list of component matches 459 * @compare_typed: compare function to match against all typed components 460 * @compare_data: opaque pointer passed to the @compare function 461 * 462 * Adds a new component match to the list stored in @matchptr, which the 463 * aggregate driver needs to function. The list of component matches pointed to 464 * by @matchptr must be initialized to NULL before adding the first match. This 465 * only matches against components added with component_add_typed(). 466 * 467 * The allocated match list in @matchptr is automatically released using devm 468 * actions. 469 * 470 * See also component_match_add_release() and component_match_add_typed(). 471 */ 472 void component_match_add_typed(struct device *parent, 473 struct component_match **matchptr, 474 int (*compare_typed)(struct device *, int, void *), void *compare_data) 475 { 476 __component_match_add(parent, matchptr, NULL, NULL, compare_typed, 477 compare_data); 478 } 479 EXPORT_SYMBOL(component_match_add_typed); 480 481 static void free_aggregate_device(struct aggregate_device *adev) 482 { 483 struct component_match *match = adev->match; 484 int i; 485 486 component_debugfs_del(adev); 487 list_del(&adev->node); 488 489 if (match) { 490 for (i = 0; i < match->num; i++) { 491 struct component *c = match->compare[i].component; 492 if (c) 493 c->adev = NULL; 494 } 495 } 496 497 kfree(adev); 498 } 499 500 /** 501 * component_master_add_with_match - register an aggregate driver 502 * @parent: parent device of the aggregate driver 503 * @ops: callbacks for the aggregate driver 504 * @match: component match list for the aggregate driver 505 * 506 * Registers a new aggregate driver consisting of the components added to @match 507 * by calling one of the component_match_add() functions. Once all components in 508 * @match are available, it will be assembled by calling 509 * &component_master_ops.bind from @ops. Must be unregistered by calling 510 * component_master_del(). 511 */ 512 int component_master_add_with_match(struct device *parent, 513 const struct component_master_ops *ops, 514 struct component_match *match) 515 { 516 struct aggregate_device *adev; 517 int ret; 518 519 /* Reallocate the match array for its true size */ 520 ret = component_match_realloc(match, match->num); 521 if (ret) 522 return ret; 523 524 adev = kzalloc(sizeof(*adev), GFP_KERNEL); 525 if (!adev) 526 return -ENOMEM; 527 528 adev->parent = parent; 529 adev->ops = ops; 530 adev->match = match; 531 532 component_debugfs_add(adev); 533 /* Add to the list of available aggregate devices. */ 534 mutex_lock(&component_mutex); 535 list_add(&adev->node, &aggregate_devices); 536 537 ret = try_to_bring_up_aggregate_device(adev, NULL); 538 539 if (ret < 0) 540 free_aggregate_device(adev); 541 542 mutex_unlock(&component_mutex); 543 544 return ret < 0 ? ret : 0; 545 } 546 EXPORT_SYMBOL_GPL(component_master_add_with_match); 547 548 /** 549 * component_master_del - unregister an aggregate driver 550 * @parent: parent device of the aggregate driver 551 * @ops: callbacks for the aggregate driver 552 * 553 * Unregisters an aggregate driver registered with 554 * component_master_add_with_match(). If necessary the aggregate driver is first 555 * disassembled by calling &component_master_ops.unbind from @ops. 556 */ 557 void component_master_del(struct device *parent, 558 const struct component_master_ops *ops) 559 { 560 struct aggregate_device *adev; 561 562 mutex_lock(&component_mutex); 563 adev = __aggregate_find(parent, ops); 564 if (adev) { 565 take_down_aggregate_device(adev); 566 free_aggregate_device(adev); 567 } 568 mutex_unlock(&component_mutex); 569 } 570 EXPORT_SYMBOL_GPL(component_master_del); 571 572 static void component_unbind(struct component *component, 573 struct aggregate_device *adev, void *data) 574 { 575 WARN_ON(!component->bound); 576 577 if (component->ops && component->ops->unbind) 578 component->ops->unbind(component->dev, adev->parent, data); 579 component->bound = false; 580 581 /* Release all resources claimed in the binding of this component */ 582 devres_release_group(component->dev, component); 583 } 584 585 /** 586 * component_unbind_all - unbind all components of an aggregate driver 587 * @parent: parent device of the aggregate driver 588 * @data: opaque pointer, passed to all components 589 * 590 * Unbinds all components of the aggregate device by passing @data to their 591 * &component_ops.unbind functions. Should be called from 592 * &component_master_ops.unbind. 593 */ 594 void component_unbind_all(struct device *parent, void *data) 595 { 596 struct aggregate_device *adev; 597 struct component *c; 598 size_t i; 599 600 WARN_ON(!mutex_is_locked(&component_mutex)); 601 602 adev = __aggregate_find(parent, NULL); 603 if (!adev) 604 return; 605 606 /* Unbind components in reverse order */ 607 for (i = adev->match->num; i--; ) 608 if (!adev->match->compare[i].duplicate) { 609 c = adev->match->compare[i].component; 610 component_unbind(c, adev, data); 611 } 612 } 613 EXPORT_SYMBOL_GPL(component_unbind_all); 614 615 static int component_bind(struct component *component, struct aggregate_device *adev, 616 void *data) 617 { 618 int ret; 619 620 /* 621 * Each component initialises inside its own devres group. 622 * This allows us to roll-back a failed component without 623 * affecting anything else. 624 */ 625 if (!devres_open_group(adev->parent, NULL, GFP_KERNEL)) 626 return -ENOMEM; 627 628 /* 629 * Also open a group for the device itself: this allows us 630 * to release the resources claimed against the sub-device 631 * at the appropriate moment. 632 */ 633 if (!devres_open_group(component->dev, component, GFP_KERNEL)) { 634 devres_release_group(adev->parent, NULL); 635 return -ENOMEM; 636 } 637 638 dev_dbg(adev->parent, "binding %s (ops %ps)\n", 639 dev_name(component->dev), component->ops); 640 641 ret = component->ops->bind(component->dev, adev->parent, data); 642 if (!ret) { 643 component->bound = true; 644 645 /* 646 * Close the component device's group so that resources 647 * allocated in the binding are encapsulated for removal 648 * at unbind. Remove the group on the DRM device as we 649 * can clean those resources up independently. 650 */ 651 devres_close_group(component->dev, NULL); 652 devres_remove_group(adev->parent, NULL); 653 654 dev_info(adev->parent, "bound %s (ops %ps)\n", 655 dev_name(component->dev), component->ops); 656 } else { 657 devres_release_group(component->dev, NULL); 658 devres_release_group(adev->parent, NULL); 659 660 if (ret != -EPROBE_DEFER) 661 dev_err(adev->parent, "failed to bind %s (ops %ps): %d\n", 662 dev_name(component->dev), component->ops, ret); 663 } 664 665 return ret; 666 } 667 668 /** 669 * component_bind_all - bind all components of an aggregate driver 670 * @parent: parent device of the aggregate driver 671 * @data: opaque pointer, passed to all components 672 * 673 * Binds all components of the aggregate @dev by passing @data to their 674 * &component_ops.bind functions. Should be called from 675 * &component_master_ops.bind. 676 */ 677 int component_bind_all(struct device *parent, void *data) 678 { 679 struct aggregate_device *adev; 680 struct component *c; 681 size_t i; 682 int ret = 0; 683 684 WARN_ON(!mutex_is_locked(&component_mutex)); 685 686 adev = __aggregate_find(parent, NULL); 687 if (!adev) 688 return -EINVAL; 689 690 /* Bind components in match order */ 691 for (i = 0; i < adev->match->num; i++) 692 if (!adev->match->compare[i].duplicate) { 693 c = adev->match->compare[i].component; 694 ret = component_bind(c, adev, data); 695 if (ret) 696 break; 697 } 698 699 if (ret != 0) { 700 for (; i > 0; i--) 701 if (!adev->match->compare[i - 1].duplicate) { 702 c = adev->match->compare[i - 1].component; 703 component_unbind(c, adev, data); 704 } 705 } 706 707 return ret; 708 } 709 EXPORT_SYMBOL_GPL(component_bind_all); 710 711 static int __component_add(struct device *dev, const struct component_ops *ops, 712 int subcomponent) 713 { 714 struct component *component; 715 int ret; 716 717 component = kzalloc(sizeof(*component), GFP_KERNEL); 718 if (!component) 719 return -ENOMEM; 720 721 component->ops = ops; 722 component->dev = dev; 723 component->subcomponent = subcomponent; 724 725 dev_dbg(dev, "adding component (ops %ps)\n", ops); 726 727 mutex_lock(&component_mutex); 728 list_add_tail(&component->node, &component_list); 729 730 ret = try_to_bring_up_masters(component); 731 if (ret < 0) { 732 if (component->adev) 733 remove_component(component->adev, component); 734 list_del(&component->node); 735 736 kfree(component); 737 } 738 mutex_unlock(&component_mutex); 739 740 return ret < 0 ? ret : 0; 741 } 742 743 /** 744 * component_add_typed - register a component 745 * @dev: component device 746 * @ops: component callbacks 747 * @subcomponent: nonzero identifier for subcomponents 748 * 749 * Register a new component for @dev. Functions in @ops will be call when the 750 * aggregate driver is ready to bind the overall driver by calling 751 * component_bind_all(). See also &struct component_ops. 752 * 753 * @subcomponent must be nonzero and is used to differentiate between multiple 754 * components registered on the same device @dev. These components are match 755 * using component_match_add_typed(). 756 * 757 * The component needs to be unregistered at driver unload/disconnect by 758 * calling component_del(). 759 * 760 * See also component_add(). 761 */ 762 int component_add_typed(struct device *dev, const struct component_ops *ops, 763 int subcomponent) 764 { 765 if (WARN_ON(subcomponent == 0)) 766 return -EINVAL; 767 768 return __component_add(dev, ops, subcomponent); 769 } 770 EXPORT_SYMBOL_GPL(component_add_typed); 771 772 /** 773 * component_add - register a component 774 * @dev: component device 775 * @ops: component callbacks 776 * 777 * Register a new component for @dev. Functions in @ops will be called when the 778 * aggregate driver is ready to bind the overall driver by calling 779 * component_bind_all(). See also &struct component_ops. 780 * 781 * The component needs to be unregistered at driver unload/disconnect by 782 * calling component_del(). 783 * 784 * See also component_add_typed() for a variant that allows multiple different 785 * components on the same device. 786 */ 787 int component_add(struct device *dev, const struct component_ops *ops) 788 { 789 return __component_add(dev, ops, 0); 790 } 791 EXPORT_SYMBOL_GPL(component_add); 792 793 /** 794 * component_del - unregister a component 795 * @dev: component device 796 * @ops: component callbacks 797 * 798 * Unregister a component added with component_add(). If the component is bound 799 * into an aggregate driver, this will force the entire aggregate driver, including 800 * all its components, to be unbound. 801 */ 802 void component_del(struct device *dev, const struct component_ops *ops) 803 { 804 struct component *c, *component = NULL; 805 806 mutex_lock(&component_mutex); 807 list_for_each_entry(c, &component_list, node) 808 if (c->dev == dev && c->ops == ops) { 809 list_del(&c->node); 810 component = c; 811 break; 812 } 813 814 if (component && component->adev) { 815 take_down_aggregate_device(component->adev); 816 remove_component(component->adev, component); 817 } 818 819 mutex_unlock(&component_mutex); 820 821 WARN_ON(!component); 822 kfree(component); 823 } 824 EXPORT_SYMBOL_GPL(component_del); 825