Line data Source code
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 0 : list_for_each_entry(m, &aggregate_devices, node)
147 0 : if (m->parent == parent && (!ops || m->ops == ops))
148 : return m;
149 :
150 : return NULL;
151 : }
152 :
153 0 : static struct component *find_component(struct aggregate_device *adev,
154 : struct component_match_array *mc)
155 : {
156 : struct component *c;
157 :
158 0 : list_for_each_entry(c, &component_list, node) {
159 0 : if (c->adev && c->adev != adev)
160 0 : continue;
161 :
162 0 : if (mc->compare && mc->compare(c->dev, mc->data))
163 : return c;
164 :
165 0 : if (mc->compare_typed &&
166 0 : mc->compare_typed(c->dev, c->subcomponent, mc->data))
167 : return c;
168 : }
169 :
170 : return NULL;
171 : }
172 :
173 0 : static int find_components(struct aggregate_device *adev)
174 : {
175 0 : struct component_match *match = adev->match;
176 : size_t i;
177 0 : 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 0 : for (i = 0; i < match->num; i++) {
184 0 : 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 0 : if (match->compare[i].component)
190 0 : continue;
191 :
192 0 : c = find_component(adev, mc);
193 0 : 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 0 : match->compare[i].duplicate = !!c->adev;
203 0 : match->compare[i].component = c;
204 0 : c->adev = adev;
205 : }
206 0 : 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 0 : for (i = 0; i < adev->match->num; i++)
216 0 : if (adev->match->compare[i].component == c)
217 0 : 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 0 : 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 0 : if (find_components(adev)) {
235 : dev_dbg(adev->parent, "master has incomplete components\n");
236 : return 0;
237 : }
238 :
239 0 : 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 0 : if (!devres_open_group(adev->parent, adev, GFP_KERNEL))
246 : return -ENOMEM;
247 :
248 : /* Found all components */
249 0 : ret = adev->ops->bind(adev->parent);
250 0 : if (ret < 0) {
251 0 : devres_release_group(adev->parent, NULL);
252 0 : if (ret != -EPROBE_DEFER)
253 0 : dev_info(adev->parent, "adev bind failed: %d\n", ret);
254 : return ret;
255 : }
256 :
257 0 : devres_close_group(adev->parent, NULL);
258 0 : adev->bound = true;
259 0 : return 1;
260 : }
261 :
262 0 : static int try_to_bring_up_masters(struct component *component)
263 : {
264 : struct aggregate_device *adev;
265 0 : int ret = 0;
266 :
267 0 : list_for_each_entry(adev, &aggregate_devices, node) {
268 0 : if (!adev->bound) {
269 0 : ret = try_to_bring_up_aggregate_device(adev, component);
270 0 : if (ret != 0)
271 : break;
272 : }
273 : }
274 :
275 0 : return ret;
276 : }
277 :
278 0 : static void take_down_aggregate_device(struct aggregate_device *adev)
279 : {
280 0 : if (adev->bound) {
281 0 : adev->ops->unbind(adev->parent);
282 0 : devres_release_group(adev->parent, adev);
283 0 : adev->bound = false;
284 : }
285 0 : }
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 0 : int component_compare_of(struct device *dev, void *data)
297 : {
298 0 : 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 0 : void component_release_of(struct device *dev, void *data)
310 : {
311 0 : of_node_put(data);
312 0 : }
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 0 : int component_compare_dev(struct device *dev, void *data)
324 : {
325 0 : 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 0 : int component_compare_dev_name(struct device *dev, void *data)
339 : {
340 0 : return device_match_name(dev, data);
341 : }
342 : EXPORT_SYMBOL_GPL(component_compare_dev_name);
343 :
344 0 : static void devm_component_match_release(struct device *parent, void *res)
345 : {
346 0 : struct component_match *match = res;
347 : unsigned int i;
348 :
349 0 : for (i = 0; i < match->num; i++) {
350 0 : struct component_match_array *mc = &match->compare[i];
351 :
352 0 : if (mc->release)
353 0 : mc->release(parent, mc->data);
354 : }
355 :
356 0 : kfree(match->compare);
357 0 : }
358 :
359 0 : static int component_match_realloc(struct component_match *match, size_t num)
360 : {
361 : struct component_match_array *new;
362 :
363 0 : if (match->alloc == num)
364 : return 0;
365 :
366 0 : new = kmalloc_array(num, sizeof(*new), GFP_KERNEL);
367 0 : if (!new)
368 : return -ENOMEM;
369 :
370 0 : if (match->compare) {
371 0 : memcpy(new, match->compare, sizeof(*new) *
372 0 : min(match->num, num));
373 0 : kfree(match->compare);
374 : }
375 0 : match->compare = new;
376 0 : match->alloc = num;
377 :
378 0 : return 0;
379 : }
380 :
381 0 : 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 0 : struct component_match *match = *matchptr;
389 :
390 0 : if (IS_ERR(match))
391 : return;
392 :
393 0 : if (!match) {
394 0 : match = devres_alloc(devm_component_match_release,
395 : sizeof(*match), GFP_KERNEL);
396 0 : if (!match) {
397 0 : *matchptr = ERR_PTR(-ENOMEM);
398 0 : return;
399 : }
400 :
401 0 : devres_add(parent, match);
402 :
403 0 : *matchptr = match;
404 : }
405 :
406 0 : if (match->num == match->alloc) {
407 0 : size_t new_size = match->alloc + 16;
408 : int ret;
409 :
410 0 : ret = component_match_realloc(match, new_size);
411 0 : if (ret) {
412 0 : *matchptr = ERR_PTR(ret);
413 0 : return;
414 : }
415 : }
416 :
417 0 : match->compare[match->num].compare = compare;
418 0 : match->compare[match->num].compare_typed = compare_typed;
419 0 : match->compare[match->num].release = release;
420 0 : match->compare[match->num].data = compare_data;
421 0 : match->compare[match->num].component = NULL;
422 0 : 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 0 : 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 0 : __component_match_add(parent, matchptr, release, compare, NULL,
451 : compare_data);
452 0 : }
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 0 : 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 0 : __component_match_add(parent, matchptr, NULL, NULL, compare_typed,
477 : compare_data);
478 0 : }
479 : EXPORT_SYMBOL(component_match_add_typed);
480 :
481 0 : static void free_aggregate_device(struct aggregate_device *adev)
482 : {
483 0 : struct component_match *match = adev->match;
484 : int i;
485 :
486 0 : component_debugfs_del(adev);
487 0 : list_del(&adev->node);
488 :
489 0 : if (match) {
490 0 : for (i = 0; i < match->num; i++) {
491 0 : struct component *c = match->compare[i].component;
492 0 : if (c)
493 0 : c->adev = NULL;
494 : }
495 : }
496 :
497 0 : kfree(adev);
498 0 : }
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 0 : 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 0 : ret = component_match_realloc(match, match->num);
521 0 : if (ret)
522 : return ret;
523 :
524 0 : adev = kzalloc(sizeof(*adev), GFP_KERNEL);
525 0 : if (!adev)
526 : return -ENOMEM;
527 :
528 0 : adev->parent = parent;
529 0 : adev->ops = ops;
530 0 : adev->match = match;
531 :
532 : component_debugfs_add(adev);
533 : /* Add to the list of available aggregate devices. */
534 0 : mutex_lock(&component_mutex);
535 0 : list_add(&adev->node, &aggregate_devices);
536 :
537 0 : ret = try_to_bring_up_aggregate_device(adev, NULL);
538 :
539 0 : if (ret < 0)
540 0 : free_aggregate_device(adev);
541 :
542 0 : mutex_unlock(&component_mutex);
543 :
544 0 : 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 0 : void component_master_del(struct device *parent,
558 : const struct component_master_ops *ops)
559 : {
560 : struct aggregate_device *adev;
561 :
562 0 : mutex_lock(&component_mutex);
563 0 : adev = __aggregate_find(parent, ops);
564 0 : if (adev) {
565 0 : take_down_aggregate_device(adev);
566 0 : free_aggregate_device(adev);
567 : }
568 0 : mutex_unlock(&component_mutex);
569 0 : }
570 : EXPORT_SYMBOL_GPL(component_master_del);
571 :
572 0 : static void component_unbind(struct component *component,
573 : struct aggregate_device *adev, void *data)
574 : {
575 0 : WARN_ON(!component->bound);
576 :
577 0 : if (component->ops && component->ops->unbind)
578 0 : component->ops->unbind(component->dev, adev->parent, data);
579 0 : component->bound = false;
580 :
581 : /* Release all resources claimed in the binding of this component */
582 0 : devres_release_group(component->dev, component);
583 0 : }
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 0 : 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 0 : WARN_ON(!mutex_is_locked(&component_mutex));
601 :
602 0 : adev = __aggregate_find(parent, NULL);
603 0 : if (!adev)
604 : return;
605 :
606 : /* Unbind components in reverse order */
607 0 : for (i = adev->match->num; i--; )
608 0 : if (!adev->match->compare[i].duplicate) {
609 0 : c = adev->match->compare[i].component;
610 0 : component_unbind(c, adev, data);
611 : }
612 : }
613 : EXPORT_SYMBOL_GPL(component_unbind_all);
614 :
615 0 : 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 0 : 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 0 : if (!devres_open_group(component->dev, component, GFP_KERNEL)) {
634 0 : 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 0 : ret = component->ops->bind(component->dev, adev->parent, data);
642 0 : if (!ret) {
643 0 : 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 0 : devres_close_group(component->dev, NULL);
652 0 : devres_remove_group(adev->parent, NULL);
653 :
654 0 : dev_info(adev->parent, "bound %s (ops %ps)\n",
655 : dev_name(component->dev), component->ops);
656 : } else {
657 0 : devres_release_group(component->dev, NULL);
658 0 : devres_release_group(adev->parent, NULL);
659 :
660 0 : if (ret != -EPROBE_DEFER)
661 0 : 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 0 : int component_bind_all(struct device *parent, void *data)
678 : {
679 : struct aggregate_device *adev;
680 : struct component *c;
681 : size_t i;
682 0 : int ret = 0;
683 :
684 0 : WARN_ON(!mutex_is_locked(&component_mutex));
685 :
686 0 : adev = __aggregate_find(parent, NULL);
687 0 : if (!adev)
688 : return -EINVAL;
689 :
690 : /* Bind components in match order */
691 0 : for (i = 0; i < adev->match->num; i++)
692 0 : if (!adev->match->compare[i].duplicate) {
693 0 : c = adev->match->compare[i].component;
694 0 : ret = component_bind(c, adev, data);
695 0 : if (ret)
696 : break;
697 : }
698 :
699 0 : if (ret != 0) {
700 0 : for (; i > 0; i--)
701 0 : if (!adev->match->compare[i - 1].duplicate) {
702 0 : c = adev->match->compare[i - 1].component;
703 0 : component_unbind(c, adev, data);
704 : }
705 : }
706 :
707 : return ret;
708 : }
709 : EXPORT_SYMBOL_GPL(component_bind_all);
710 :
711 0 : 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 0 : component = kzalloc(sizeof(*component), GFP_KERNEL);
718 0 : if (!component)
719 : return -ENOMEM;
720 :
721 0 : component->ops = ops;
722 0 : component->dev = dev;
723 0 : component->subcomponent = subcomponent;
724 :
725 : dev_dbg(dev, "adding component (ops %ps)\n", ops);
726 :
727 0 : mutex_lock(&component_mutex);
728 0 : list_add_tail(&component->node, &component_list);
729 :
730 0 : ret = try_to_bring_up_masters(component);
731 0 : if (ret < 0) {
732 0 : if (component->adev)
733 : remove_component(component->adev, component);
734 0 : list_del(&component->node);
735 :
736 0 : kfree(component);
737 : }
738 0 : mutex_unlock(&component_mutex);
739 :
740 0 : 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 registerd 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 0 : int component_add_typed(struct device *dev, const struct component_ops *ops,
763 : int subcomponent)
764 : {
765 0 : if (WARN_ON(subcomponent == 0))
766 : return -EINVAL;
767 :
768 0 : 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 multipled different
785 : * components on the same device.
786 : */
787 0 : int component_add(struct device *dev, const struct component_ops *ops)
788 : {
789 0 : 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 0 : void component_del(struct device *dev, const struct component_ops *ops)
803 : {
804 0 : struct component *c, *component = NULL;
805 :
806 0 : mutex_lock(&component_mutex);
807 0 : list_for_each_entry(c, &component_list, node)
808 0 : if (c->dev == dev && c->ops == ops) {
809 0 : list_del(&c->node);
810 0 : component = c;
811 0 : break;
812 : }
813 :
814 0 : if (component && component->adev) {
815 0 : take_down_aggregate_device(component->adev);
816 0 : remove_component(component->adev, component);
817 : }
818 :
819 0 : mutex_unlock(&component_mutex);
820 :
821 0 : WARN_ON(!component);
822 0 : kfree(component);
823 0 : }
824 : EXPORT_SYMBOL_GPL(component_del);
|