diff options
Diffstat (limited to 'include/linux/component.h')
-rw-r--r-- | include/linux/component.h | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/include/linux/component.h b/include/linux/component.h index e71fbbbc74e2..30bcc7e590eb 100644 --- a/include/linux/component.h +++ b/include/linux/component.h | |||
@@ -4,16 +4,38 @@ | |||
4 | 4 | ||
5 | #include <linux/stddef.h> | 5 | #include <linux/stddef.h> |
6 | 6 | ||
7 | |||
7 | struct device; | 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 | struct component_ops { | 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 | int (*bind)(struct device *comp, struct device *master, | 23 | int (*bind)(struct device *comp, struct device *master, |
11 | void *master_data); | 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 | void (*unbind)(struct device *comp, struct device *master, | 32 | void (*unbind)(struct device *comp, struct device *master, |
13 | void *master_data); | 33 | void *master_data); |
14 | }; | 34 | }; |
15 | 35 | ||
16 | int component_add(struct device *, const struct component_ops *); | 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 | void component_del(struct device *, const struct component_ops *); | 39 | void component_del(struct device *, const struct component_ops *); |
18 | 40 | ||
19 | int component_bind_all(struct device *master, void *master_data); | 41 | int component_bind_all(struct device *master, void *master_data); |
@@ -21,8 +43,42 @@ void component_unbind_all(struct device *master, void *master_data); | |||
21 | 43 | ||
22 | struct master; | 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 | struct component_master_ops { | 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 | int (*bind)(struct device *master); | 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 | void (*unbind)(struct device *master); | 82 | void (*unbind)(struct device *master); |
27 | }; | 83 | }; |
28 | 84 | ||
@@ -37,7 +93,27 @@ void component_match_add_release(struct device *master, | |||
37 | struct component_match **matchptr, | 93 | struct component_match **matchptr, |
38 | void (*release)(struct device *, void *), | 94 | void (*release)(struct device *, void *), |
39 | int (*compare)(struct device *, void *), void *compare_data); | 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 compent match | ||
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 | static inline void component_match_add(struct device *master, | 117 | static inline void component_match_add(struct device *master, |
42 | struct component_match **matchptr, | 118 | struct component_match **matchptr, |
43 | int (*compare)(struct device *, void *), void *compare_data) | 119 | int (*compare)(struct device *, void *), void *compare_data) |