diff options
Diffstat (limited to 'drivers/base/component.c')
-rw-r--r-- | drivers/base/component.c | 206 |
1 files changed, 195 insertions, 11 deletions
diff --git a/drivers/base/component.c b/drivers/base/component.c index ddcea8739c12..7dbc41cccd58 100644 --- a/drivers/base/component.c +++ b/drivers/base/component.c | |||
@@ -16,11 +16,38 @@ | |||
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 { |
22 | void *data; | 48 | void *data; |
23 | int (*compare)(struct device *, void *); | 49 | int (*compare)(struct device *, void *); |
50 | int (*compare_typed)(struct device *, int, void *); | ||
24 | void (*release)(struct device *, void *); | 51 | void (*release)(struct device *, void *); |
25 | struct component *component; | 52 | struct component *component; |
26 | bool duplicate; | 53 | bool duplicate; |
@@ -48,6 +75,7 @@ struct component { | |||
48 | bool bound; | 75 | bool bound; |
49 | 76 | ||
50 | const struct component_ops *ops; | 77 | const struct component_ops *ops; |
78 | int subcomponent; | ||
51 | struct device *dev; | 79 | struct device *dev; |
52 | }; | 80 | }; |
53 | 81 | ||
@@ -132,7 +160,7 @@ static struct master *__master_find(struct device *dev, | |||
132 | } | 160 | } |
133 | 161 | ||
134 | static struct component *find_component(struct master *master, | 162 | static struct component *find_component(struct master *master, |
135 | int (*compare)(struct device *, void *), void *compare_data) | 163 | struct component_match_array *mc) |
136 | { | 164 | { |
137 | struct component *c; | 165 | struct component *c; |
138 | 166 | ||
@@ -140,7 +168,11 @@ static struct component *find_component(struct master *master, | |||
140 | if (c->master && c->master != master) | 168 | if (c->master && c->master != master) |
141 | continue; | 169 | continue; |
142 | 170 | ||
143 | if (compare(c->dev, compare_data)) | 171 | if (mc->compare && mc->compare(c->dev, mc->data)) |
172 | return c; | ||
173 | |||
174 | if (mc->compare_typed && | ||
175 | mc->compare_typed(c->dev, c->subcomponent, mc->data)) | ||
144 | return c; | 176 | return c; |
145 | } | 177 | } |
146 | 178 | ||
@@ -166,7 +198,7 @@ static int find_components(struct master *master) | |||
166 | if (match->compare[i].component) | 198 | if (match->compare[i].component) |
167 | continue; | 199 | continue; |
168 | 200 | ||
169 | c = find_component(master, mc->compare, mc->data); | 201 | c = find_component(master, mc); |
170 | if (!c) { | 202 | if (!c) { |
171 | ret = -ENXIO; | 203 | ret = -ENXIO; |
172 | break; | 204 | break; |
@@ -301,15 +333,12 @@ static int component_match_realloc(struct device *dev, | |||
301 | return 0; | 333 | return 0; |
302 | } | 334 | } |
303 | 335 | ||
304 | /* | 336 | static void __component_match_add(struct device *master, |
305 | * Add a component to be matched, with a release function. | ||
306 | * | ||
307 | * The match array is first created or extended if necessary. | ||
308 | */ | ||
309 | void component_match_add_release(struct device *master, | ||
310 | struct component_match **matchptr, | 337 | struct component_match **matchptr, |
311 | void (*release)(struct device *, void *), | 338 | void (*release)(struct device *, void *), |
312 | int (*compare)(struct device *, void *), void *compare_data) | 339 | int (*compare)(struct device *, void *), |
340 | int (*compare_typed)(struct device *, int, void *), | ||
341 | void *compare_data) | ||
313 | { | 342 | { |
314 | struct component_match *match = *matchptr; | 343 | struct component_match *match = *matchptr; |
315 | 344 | ||
@@ -341,13 +370,69 @@ void component_match_add_release(struct device *master, | |||
341 | } | 370 | } |
342 | 371 | ||
343 | match->compare[match->num].compare = compare; | 372 | match->compare[match->num].compare = compare; |
373 | match->compare[match->num].compare_typed = compare_typed; | ||
344 | match->compare[match->num].release = release; | 374 | match->compare[match->num].release = release; |
345 | match->compare[match->num].data = compare_data; | 375 | match->compare[match->num].data = compare_data; |
346 | match->compare[match->num].component = NULL; | 376 | match->compare[match->num].component = NULL; |
347 | match->num++; | 377 | match->num++; |
348 | } | 378 | } |
379 | |||
380 | /** | ||
381 | * component_match_add_release - add a component match with release callback | ||
382 | * @master: device with the aggregate driver | ||
383 | * @matchptr: pointer to the list of component matches | ||
384 | * @release: release function for @compare_data | ||
385 | * @compare: compare function to match against all components | ||
386 | * @compare_data: opaque pointer passed to the @compare function | ||
387 | * | ||
388 | * Adds a new component match to the list stored in @matchptr, which the @master | ||
389 | * aggregate driver needs to function. The list of component matches pointed to | ||
390 | * by @matchptr must be initialized to NULL before adding the first match. This | ||
391 | * only matches against components added with component_add(). | ||
392 | * | ||
393 | * The allocated match list in @matchptr is automatically released using devm | ||
394 | * actions, where upon @release will be called to free any references held by | ||
395 | * @compare_data, e.g. when @compare_data is a &device_node that must be | ||
396 | * released with of_node_put(). | ||
397 | * | ||
398 | * See also component_match_add() and component_match_add_typed(). | ||
399 | */ | ||
400 | void component_match_add_release(struct device *master, | ||
401 | struct component_match **matchptr, | ||
402 | void (*release)(struct device *, void *), | ||
403 | int (*compare)(struct device *, void *), void *compare_data) | ||
404 | { | ||
405 | __component_match_add(master, matchptr, release, compare, NULL, | ||
406 | compare_data); | ||
407 | } | ||
349 | EXPORT_SYMBOL(component_match_add_release); | 408 | EXPORT_SYMBOL(component_match_add_release); |
350 | 409 | ||
410 | /** | ||
411 | * component_match_add_typed - add a compent match for a typed component | ||
412 | * @master: device with the aggregate driver | ||
413 | * @matchptr: pointer to the list of component matches | ||
414 | * @compare_typed: compare function to match against all typed components | ||
415 | * @compare_data: opaque pointer passed to the @compare function | ||
416 | * | ||
417 | * Adds a new component match to the list stored in @matchptr, which the @master | ||
418 | * aggregate driver needs to function. The list of component matches pointed to | ||
419 | * by @matchptr must be initialized to NULL before adding the first match. This | ||
420 | * only matches against components added with component_add_typed(). | ||
421 | * | ||
422 | * The allocated match list in @matchptr is automatically released using devm | ||
423 | * actions. | ||
424 | * | ||
425 | * See also component_match_add_release() and component_match_add_typed(). | ||
426 | */ | ||
427 | void component_match_add_typed(struct device *master, | ||
428 | struct component_match **matchptr, | ||
429 | int (*compare_typed)(struct device *, int, void *), void *compare_data) | ||
430 | { | ||
431 | __component_match_add(master, matchptr, NULL, NULL, compare_typed, | ||
432 | compare_data); | ||
433 | } | ||
434 | EXPORT_SYMBOL(component_match_add_typed); | ||
435 | |||
351 | static void free_master(struct master *master) | 436 | static void free_master(struct master *master) |
352 | { | 437 | { |
353 | struct component_match *match = master->match; | 438 | struct component_match *match = master->match; |
@@ -367,6 +452,18 @@ static void free_master(struct master *master) | |||
367 | kfree(master); | 452 | kfree(master); |
368 | } | 453 | } |
369 | 454 | ||
455 | /** | ||
456 | * component_master_add_with_match - register an aggregate driver | ||
457 | * @dev: device with the aggregate driver | ||
458 | * @ops: callbacks for the aggregate driver | ||
459 | * @match: component match list for the aggregate driver | ||
460 | * | ||
461 | * Registers a new aggregate driver consisting of the components added to @match | ||
462 | * by calling one of the component_match_add() functions. Once all components in | ||
463 | * @match are available, it will be assembled by calling | ||
464 | * &component_master_ops.bind from @ops. Must be unregistered by calling | ||
465 | * component_master_del(). | ||
466 | */ | ||
370 | int component_master_add_with_match(struct device *dev, | 467 | int component_master_add_with_match(struct device *dev, |
371 | const struct component_master_ops *ops, | 468 | const struct component_master_ops *ops, |
372 | struct component_match *match) | 469 | struct component_match *match) |
@@ -403,6 +500,15 @@ int component_master_add_with_match(struct device *dev, | |||
403 | } | 500 | } |
404 | EXPORT_SYMBOL_GPL(component_master_add_with_match); | 501 | EXPORT_SYMBOL_GPL(component_master_add_with_match); |
405 | 502 | ||
503 | /** | ||
504 | * component_master_del - unregister an aggregate driver | ||
505 | * @dev: device with the aggregate driver | ||
506 | * @ops: callbacks for the aggregate driver | ||
507 | * | ||
508 | * Unregisters an aggregate driver registered with | ||
509 | * component_master_add_with_match(). If necessary the aggregate driver is first | ||
510 | * disassembled by calling &component_master_ops.unbind from @ops. | ||
511 | */ | ||
406 | void component_master_del(struct device *dev, | 512 | void component_master_del(struct device *dev, |
407 | const struct component_master_ops *ops) | 513 | const struct component_master_ops *ops) |
408 | { | 514 | { |
@@ -430,6 +536,15 @@ static void component_unbind(struct component *component, | |||
430 | devres_release_group(component->dev, component); | 536 | devres_release_group(component->dev, component); |
431 | } | 537 | } |
432 | 538 | ||
539 | /** | ||
540 | * component_unbind_all - unbind all component to an aggregate driver | ||
541 | * @master_dev: device with the aggregate driver | ||
542 | * @data: opaque pointer, passed to all components | ||
543 | * | ||
544 | * Unbinds all components to the aggregate @dev by passing @data to their | ||
545 | * &component_ops.unbind functions. Should be called from | ||
546 | * &component_master_ops.unbind. | ||
547 | */ | ||
433 | void component_unbind_all(struct device *master_dev, void *data) | 548 | void component_unbind_all(struct device *master_dev, void *data) |
434 | { | 549 | { |
435 | struct master *master; | 550 | struct master *master; |
@@ -503,6 +618,15 @@ static int component_bind(struct component *component, struct master *master, | |||
503 | return ret; | 618 | return ret; |
504 | } | 619 | } |
505 | 620 | ||
621 | /** | ||
622 | * component_bind_all - bind all component to an aggregate driver | ||
623 | * @master_dev: device with the aggregate driver | ||
624 | * @data: opaque pointer, passed to all components | ||
625 | * | ||
626 | * Binds all components to the aggregate @dev by passing @data to their | ||
627 | * &component_ops.bind functions. Should be called from | ||
628 | * &component_master_ops.bind. | ||
629 | */ | ||
506 | int component_bind_all(struct device *master_dev, void *data) | 630 | int component_bind_all(struct device *master_dev, void *data) |
507 | { | 631 | { |
508 | struct master *master; | 632 | struct master *master; |
@@ -537,7 +661,8 @@ int component_bind_all(struct device *master_dev, void *data) | |||
537 | } | 661 | } |
538 | EXPORT_SYMBOL_GPL(component_bind_all); | 662 | EXPORT_SYMBOL_GPL(component_bind_all); |
539 | 663 | ||
540 | int component_add(struct device *dev, const struct component_ops *ops) | 664 | static int __component_add(struct device *dev, const struct component_ops *ops, |
665 | int subcomponent) | ||
541 | { | 666 | { |
542 | struct component *component; | 667 | struct component *component; |
543 | int ret; | 668 | int ret; |
@@ -548,6 +673,7 @@ int component_add(struct device *dev, const struct component_ops *ops) | |||
548 | 673 | ||
549 | component->ops = ops; | 674 | component->ops = ops; |
550 | component->dev = dev; | 675 | component->dev = dev; |
676 | component->subcomponent = subcomponent; | ||
551 | 677 | ||
552 | dev_dbg(dev, "adding component (ops %ps)\n", ops); | 678 | dev_dbg(dev, "adding component (ops %ps)\n", ops); |
553 | 679 | ||
@@ -566,8 +692,66 @@ int component_add(struct device *dev, const struct component_ops *ops) | |||
566 | 692 | ||
567 | return ret < 0 ? ret : 0; | 693 | return ret < 0 ? ret : 0; |
568 | } | 694 | } |
695 | |||
696 | /** | ||
697 | * component_add_typed - register a component | ||
698 | * @dev: component device | ||
699 | * @ops: component callbacks | ||
700 | * @subcomponent: nonzero identifier for subcomponents | ||
701 | * | ||
702 | * Register a new component for @dev. Functions in @ops will be call when the | ||
703 | * aggregate driver is ready to bind the overall driver by calling | ||
704 | * component_bind_all(). See also &struct component_ops. | ||
705 | * | ||
706 | * @subcomponent must be nonzero and is used to differentiate between multiple | ||
707 | * components registerd on the same device @dev. These components are match | ||
708 | * using component_match_add_typed(). | ||
709 | * | ||
710 | * The component needs to be unregistered at driver unload/disconnect by | ||
711 | * calling component_del(). | ||
712 | * | ||
713 | * See also component_add(). | ||
714 | */ | ||
715 | int component_add_typed(struct device *dev, const struct component_ops *ops, | ||
716 | int subcomponent) | ||
717 | { | ||
718 | if (WARN_ON(subcomponent == 0)) | ||
719 | return -EINVAL; | ||
720 | |||
721 | return __component_add(dev, ops, subcomponent); | ||
722 | } | ||
723 | EXPORT_SYMBOL_GPL(component_add_typed); | ||
724 | |||
725 | /** | ||
726 | * component_add - register a component | ||
727 | * @dev: component device | ||
728 | * @ops: component callbacks | ||
729 | * | ||
730 | * Register a new component for @dev. Functions in @ops will be called when the | ||
731 | * aggregate driver is ready to bind the overall driver by calling | ||
732 | * component_bind_all(). See also &struct component_ops. | ||
733 | * | ||
734 | * The component needs to be unregistered at driver unload/disconnect by | ||
735 | * calling component_del(). | ||
736 | * | ||
737 | * See also component_add_typed() for a variant that allows multipled different | ||
738 | * components on the same device. | ||
739 | */ | ||
740 | int component_add(struct device *dev, const struct component_ops *ops) | ||
741 | { | ||
742 | return __component_add(dev, ops, 0); | ||
743 | } | ||
569 | EXPORT_SYMBOL_GPL(component_add); | 744 | EXPORT_SYMBOL_GPL(component_add); |
570 | 745 | ||
746 | /** | ||
747 | * component_del - unregister a component | ||
748 | * @dev: component device | ||
749 | * @ops: component callbacks | ||
750 | * | ||
751 | * Unregister a component added with component_add(). If the component is bound | ||
752 | * into an aggregate driver, this will force the entire aggregate driver, including | ||
753 | * all its components, to be unbound. | ||
754 | */ | ||
571 | void component_del(struct device *dev, const struct component_ops *ops) | 755 | void component_del(struct device *dev, const struct component_ops *ops) |
572 | { | 756 | { |
573 | struct component *c, *component = NULL; | 757 | struct component *c, *component = NULL; |