.. | .. |
---|
4 | 4 | |
---|
5 | 5 | #include <linux/stddef.h> |
---|
6 | 6 | |
---|
| 7 | + |
---|
7 | 8 | struct device; |
---|
8 | 9 | |
---|
| 10 | +/** |
---|
| 11 | + * struct component_ops - callbacks for component drivers |
---|
| 12 | + * |
---|
| 13 | + * Components are registered with component_add() and unregistered with |
---|
| 14 | + * component_del(). |
---|
| 15 | + */ |
---|
9 | 16 | struct component_ops { |
---|
| 17 | + /** |
---|
| 18 | + * @bind: |
---|
| 19 | + * |
---|
| 20 | + * Called through component_bind_all() when the aggregate driver is |
---|
| 21 | + * ready to bind the overall driver. |
---|
| 22 | + */ |
---|
10 | 23 | int (*bind)(struct device *comp, struct device *master, |
---|
11 | 24 | void *master_data); |
---|
| 25 | + /** |
---|
| 26 | + * @unbind: |
---|
| 27 | + * |
---|
| 28 | + * Called through component_unbind_all() when the aggregate driver is |
---|
| 29 | + * ready to bind the overall driver, or when component_bind_all() fails |
---|
| 30 | + * part-ways through and needs to unbind some already bound components. |
---|
| 31 | + */ |
---|
12 | 32 | void (*unbind)(struct device *comp, struct device *master, |
---|
13 | 33 | void *master_data); |
---|
14 | 34 | }; |
---|
15 | 35 | |
---|
16 | 36 | int component_add(struct device *, const struct component_ops *); |
---|
| 37 | +int component_add_typed(struct device *dev, const struct component_ops *ops, |
---|
| 38 | + int subcomponent); |
---|
17 | 39 | void component_del(struct device *, const struct component_ops *); |
---|
18 | 40 | |
---|
19 | 41 | int component_bind_all(struct device *master, void *master_data); |
---|
.. | .. |
---|
21 | 43 | |
---|
22 | 44 | struct master; |
---|
23 | 45 | |
---|
| 46 | +/** |
---|
| 47 | + * struct component_master_ops - callback for the aggregate driver |
---|
| 48 | + * |
---|
| 49 | + * Aggregate drivers are registered with component_master_add_with_match() and |
---|
| 50 | + * unregistered with component_master_del(). |
---|
| 51 | + */ |
---|
24 | 52 | struct component_master_ops { |
---|
| 53 | + /** |
---|
| 54 | + * @bind: |
---|
| 55 | + * |
---|
| 56 | + * Called when all components or the aggregate driver, as specified in |
---|
| 57 | + * the match list passed to component_master_add_with_match(), are |
---|
| 58 | + * ready. Usually there are 3 steps to bind an aggregate driver: |
---|
| 59 | + * |
---|
| 60 | + * 1. Allocate a structure for the aggregate driver. |
---|
| 61 | + * |
---|
| 62 | + * 2. Bind all components to the aggregate driver by calling |
---|
| 63 | + * component_bind_all() with the aggregate driver structure as opaque |
---|
| 64 | + * pointer data. |
---|
| 65 | + * |
---|
| 66 | + * 3. Register the aggregate driver with the subsystem to publish its |
---|
| 67 | + * interfaces. |
---|
| 68 | + * |
---|
| 69 | + * Note that the lifetime of the aggregate driver does not align with |
---|
| 70 | + * any of the underlying &struct device instances. Therefore devm cannot |
---|
| 71 | + * be used and all resources acquired or allocated in this callback must |
---|
| 72 | + * be explicitly released in the @unbind callback. |
---|
| 73 | + */ |
---|
25 | 74 | int (*bind)(struct device *master); |
---|
| 75 | + /** |
---|
| 76 | + * @unbind: |
---|
| 77 | + * |
---|
| 78 | + * Called when either the aggregate driver, using |
---|
| 79 | + * component_master_del(), or one of its components, using |
---|
| 80 | + * component_del(), is unregistered. |
---|
| 81 | + */ |
---|
26 | 82 | void (*unbind)(struct device *master); |
---|
27 | 83 | }; |
---|
28 | 84 | |
---|
.. | .. |
---|
37 | 93 | struct component_match **matchptr, |
---|
38 | 94 | void (*release)(struct device *, void *), |
---|
39 | 95 | int (*compare)(struct device *, void *), void *compare_data); |
---|
| 96 | +void component_match_add_typed(struct device *master, |
---|
| 97 | + struct component_match **matchptr, |
---|
| 98 | + int (*compare_typed)(struct device *, int, void *), void *compare_data); |
---|
40 | 99 | |
---|
| 100 | +/** |
---|
| 101 | + * component_match_add - add a component match entry |
---|
| 102 | + * @master: device with the aggregate driver |
---|
| 103 | + * @matchptr: pointer to the list of component matches |
---|
| 104 | + * @compare: compare function to match against all components |
---|
| 105 | + * @compare_data: opaque pointer passed to the @compare function |
---|
| 106 | + * |
---|
| 107 | + * Adds a new component match to the list stored in @matchptr, which the @master |
---|
| 108 | + * aggregate driver needs to function. The list of component matches pointed to |
---|
| 109 | + * by @matchptr must be initialized to NULL before adding the first match. This |
---|
| 110 | + * only matches against components added with component_add(). |
---|
| 111 | + * |
---|
| 112 | + * The allocated match list in @matchptr is automatically released using devm |
---|
| 113 | + * actions. |
---|
| 114 | + * |
---|
| 115 | + * See also component_match_add_release() and component_match_add_typed(). |
---|
| 116 | + */ |
---|
41 | 117 | static inline void component_match_add(struct device *master, |
---|
42 | 118 | struct component_match **matchptr, |
---|
43 | 119 | int (*compare)(struct device *, void *), void *compare_data) |
---|