diff options
Diffstat (limited to 'drivers/base/component.c')
-rw-r--r-- | drivers/base/component.c | 106 |
1 files changed, 103 insertions, 3 deletions
diff --git a/drivers/base/component.c b/drivers/base/component.c index ddcea8739c12..1624c2a892a5 100644 --- a/drivers/base/component.c +++ b/drivers/base/component.c | |||
@@ -16,6 +16,32 @@ | |||
16 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
17 | #include <linux/debugfs.h> | 17 | #include <linux/debugfs.h> |
18 | 18 | ||
19 | /** | ||
20 | * DOC: overview | ||
21 | * | ||
22 | * The component helper allows drivers to collect a pile of sub-devices, | ||
23 | * including their bound drivers, into an aggregate driver. Various subsystems | ||
24 | * already provide functions to get hold of such components, e.g. | ||
25 | * of_clk_get_by_name(). The component helper can be used when such a | ||
26 | * subsystem-specific way to find a device is not available: The component | ||
27 | * helper fills the niche of aggregate drivers for specific hardware, where | ||
28 | * further standardization into a subsystem would not be practical. The common | ||
29 | * example is when a logical device (e.g. a DRM display driver) is spread around | ||
30 | * the SoC on various component (scanout engines, blending blocks, transcoders | ||
31 | * for various outputs and so on). | ||
32 | * | ||
33 | * The component helper also doesn't solve runtime dependencies, e.g. for system | ||
34 | * suspend and resume operations. See also :ref:`device links<device_link>`. | ||
35 | * | ||
36 | * Components are registered using component_add() and unregistered with | ||
37 | * component_del(), usually from the driver's probe and disconnect functions. | ||
38 | * | ||
39 | * Aggregate drivers first assemble a component match list of what they need | ||
40 | * using component_match_add(). This is then registered as an aggregate driver | ||
41 | * using component_master_add_with_match(), and unregistered using | ||
42 | * component_master_del(). | ||
43 | */ | ||
44 | |||
19 | struct component; | 45 | struct component; |
20 | 46 | ||
21 | struct component_match_array { | 47 | struct component_match_array { |
@@ -301,10 +327,24 @@ static int component_match_realloc(struct device *dev, | |||
301 | return 0; | 327 | return 0; |
302 | } | 328 | } |
303 | 329 | ||
304 | /* | 330 | /** |
305 | * Add a component to be matched, with a release function. | 331 | * component_match_add_release - add a component match with release callback |
332 | * @master: device with the aggregate driver | ||
333 | * @matchptr: pointer to the list of component matches | ||
334 | * @release: release function for @compare_data | ||
335 | * @compare: compare function to match against all components | ||
336 | * @compare_data: opaque pointer passed to the @compare function | ||
337 | * | ||
338 | * Adds a new component match to the list stored in @matchptr, which the @master | ||
339 | * aggregate driver needs to function. The list of component matches pointed to | ||
340 | * by @matchptr must be initialized to NULL before adding the first match. | ||
341 | * | ||
342 | * The allocated match list in @matchptr is automatically released using devm | ||
343 | * actions, where upon @release will be called to free any references held by | ||
344 | * @compare_data, e.g. when @compare_data is a &device_node that must be | ||
345 | * released with of_node_put(). | ||
306 | * | 346 | * |
307 | * The match array is first created or extended if necessary. | 347 | * See also component_match_add(). |
308 | */ | 348 | */ |
309 | void component_match_add_release(struct device *master, | 349 | void component_match_add_release(struct device *master, |
310 | struct component_match **matchptr, | 350 | struct component_match **matchptr, |
@@ -367,6 +407,18 @@ static void free_master(struct master *master) | |||
367 | kfree(master); | 407 | kfree(master); |
368 | } | 408 | } |
369 | 409 | ||
410 | /** | ||
411 | * component_master_add_with_match - register an aggregate driver | ||
412 | * @dev: device with the aggregate driver | ||
413 | * @ops: callbacks for the aggregate driver | ||
414 | * @match: component match list for the aggregate driver | ||
415 | * | ||
416 | * Registers a new aggregate driver consisting of the components added to @match | ||
417 | * by calling one of the component_match_add() functions. Once all components in | ||
418 | * @match are available, it will be assembled by calling | ||
419 | * &component_master_ops.bind from @ops. Must be unregistered by calling | ||
420 | * component_master_del(). | ||
421 | */ | ||
370 | int component_master_add_with_match(struct device *dev, | 422 | int component_master_add_with_match(struct device *dev, |
371 | const struct component_master_ops *ops, | 423 | const struct component_master_ops *ops, |
372 | struct component_match *match) | 424 | struct component_match *match) |
@@ -403,6 +455,15 @@ int component_master_add_with_match(struct device *dev, | |||
403 | } | 455 | } |
404 | EXPORT_SYMBOL_GPL(component_master_add_with_match); | 456 | EXPORT_SYMBOL_GPL(component_master_add_with_match); |
405 | 457 | ||
458 | /** | ||
459 | * component_master_del - unregister an aggregate driver | ||
460 | * @dev: device with the aggregate driver | ||
461 | * @ops: callbacks for the aggregate driver | ||
462 | * | ||
463 | * Unregisters an aggregate driver registered with | ||
464 | * component_master_add_with_match(). If necessary the aggregate driver is first | ||
465 | * disassembled by calling &component_master_ops.unbind from @ops. | ||
466 | */ | ||
406 | void component_master_del(struct device *dev, | 467 | void component_master_del(struct device *dev, |
407 | const struct component_master_ops *ops) | 468 | const struct component_master_ops *ops) |
408 | { | 469 | { |
@@ -430,6 +491,15 @@ static void component_unbind(struct component *component, | |||
430 | devres_release_group(component->dev, component); | 491 | devres_release_group(component->dev, component); |
431 | } | 492 | } |
432 | 493 | ||
494 | /** | ||
495 | * component_unbind_all - unbind all component to an aggregate driver | ||
496 | * @master_dev: device with the aggregate driver | ||
497 | * @data: opaque pointer, passed to all components | ||
498 | * | ||
499 | * Unbinds all components to the aggregate @dev by passing @data to their | ||
500 | * &component_ops.unbind functions. Should be called from | ||
501 | * &component_master_ops.unbind. | ||
502 | */ | ||
433 | void component_unbind_all(struct device *master_dev, void *data) | 503 | void component_unbind_all(struct device *master_dev, void *data) |
434 | { | 504 | { |
435 | struct master *master; | 505 | struct master *master; |
@@ -503,6 +573,15 @@ static int component_bind(struct component *component, struct master *master, | |||
503 | return ret; | 573 | return ret; |
504 | } | 574 | } |
505 | 575 | ||
576 | /** | ||
577 | * component_bind_all - bind all component to an aggregate driver | ||
578 | * @master_dev: device with the aggregate driver | ||
579 | * @data: opaque pointer, passed to all components | ||
580 | * | ||
581 | * Binds all components to the aggregate @dev by passing @data to their | ||
582 | * &component_ops.bind functions. Should be called from | ||
583 | * &component_master_ops.bind. | ||
584 | */ | ||
506 | int component_bind_all(struct device *master_dev, void *data) | 585 | int component_bind_all(struct device *master_dev, void *data) |
507 | { | 586 | { |
508 | struct master *master; | 587 | struct master *master; |
@@ -537,6 +616,18 @@ int component_bind_all(struct device *master_dev, void *data) | |||
537 | } | 616 | } |
538 | EXPORT_SYMBOL_GPL(component_bind_all); | 617 | EXPORT_SYMBOL_GPL(component_bind_all); |
539 | 618 | ||
619 | /** | ||
620 | * component_add - register a component | ||
621 | * @dev: component device | ||
622 | * @ops: component callbacks | ||
623 | * | ||
624 | * Register a new component for @dev. Functions in @ops will be called when the | ||
625 | * aggregate driver is ready to bind the overall driver by calling | ||
626 | * component_bind_all(). See also &struct component_ops. | ||
627 | * | ||
628 | * The component needs to be unregistered at driver unload/disconnect by calling | ||
629 | * component_del(). | ||
630 | */ | ||
540 | int component_add(struct device *dev, const struct component_ops *ops) | 631 | int component_add(struct device *dev, const struct component_ops *ops) |
541 | { | 632 | { |
542 | struct component *component; | 633 | struct component *component; |
@@ -568,6 +659,15 @@ int component_add(struct device *dev, const struct component_ops *ops) | |||
568 | } | 659 | } |
569 | EXPORT_SYMBOL_GPL(component_add); | 660 | EXPORT_SYMBOL_GPL(component_add); |
570 | 661 | ||
662 | /** | ||
663 | * component_del - unregister a component | ||
664 | * @dev: component device | ||
665 | * @ops: component callbacks | ||
666 | * | ||
667 | * Unregister a component added with component_add(). If the component is bound | ||
668 | * into an aggregate driver, this will force the entire aggregate driver, including | ||
669 | * all its components, to be unbound. | ||
670 | */ | ||
571 | void component_del(struct device *dev, const struct component_ops *ops) | 671 | void component_del(struct device *dev, const struct component_ops *ops) |
572 | { | 672 | { |
573 | struct component *c, *component = NULL; | 673 | struct component *c, *component = NULL; |