Commit | Line | Data |
---|---|---|
b2441318 | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2a41e607 RK |
2 | #ifndef COMPONENT_H |
3 | #define COMPONENT_H | |
4 | ||
ce657b1c RK |
5 | #include <linux/stddef.h> |
6 | ||
4d69c80e | 7 | |
2a41e607 RK |
8 | struct device; |
9 | ||
4d69c80e DV |
10 | /** |
11 | * struct component_ops - callbacks for component drivers | |
12 | * | |
13 | * Components are registered with component_add() and unregistered with | |
14 | * component_del(). | |
15 | */ | |
2a41e607 | 16 | struct component_ops { |
4d69c80e DV |
17 | /** |
18 | * @bind: | |
19 | * | |
20 | * Called through component_bind_all() when the aggregate driver is | |
21 | * ready to bind the overall driver. | |
22 | */ | |
ce657b1c RK |
23 | int (*bind)(struct device *comp, struct device *master, |
24 | void *master_data); | |
4d69c80e DV |
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 | */ | |
ce657b1c RK |
32 | void (*unbind)(struct device *comp, struct device *master, |
33 | void *master_data); | |
2a41e607 RK |
34 | }; |
35 | ||
36 | int component_add(struct device *, const struct component_ops *); | |
3521ee99 DV |
37 | int component_add_typed(struct device *dev, const struct component_ops *ops, |
38 | int subcomponent); | |
2a41e607 RK |
39 | void component_del(struct device *, const struct component_ops *); |
40 | ||
ce657b1c RK |
41 | int component_bind_all(struct device *master, void *master_data); |
42 | void component_unbind_all(struct device *master, void *master_data); | |
2a41e607 RK |
43 | |
44 | struct master; | |
45 | ||
4d69c80e DV |
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 | */ | |
2a41e607 | 52 | struct component_master_ops { |
4d69c80e DV |
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 | */ | |
ce657b1c | 74 | int (*bind)(struct device *master); |
4d69c80e DV |
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 | */ | |
ce657b1c | 82 | void (*unbind)(struct device *master); |
2a41e607 RK |
83 | }; |
84 | ||
2a41e607 RK |
85 | void component_master_del(struct device *, |
86 | const struct component_master_ops *); | |
87 | ||
6955b582 RK |
88 | struct component_match; |
89 | ||
90 | int component_master_add_with_match(struct device *, | |
91 | const struct component_master_ops *, struct component_match *); | |
ce657b1c RK |
92 | void component_match_add_release(struct device *master, |
93 | struct component_match **matchptr, | |
94 | void (*release)(struct device *, void *), | |
6955b582 | 95 | int (*compare)(struct device *, void *), void *compare_data); |
3521ee99 DV |
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); | |
6955b582 | 99 | |
4d69c80e | 100 | /** |
e4246b05 | 101 | * component_match_add - add a component match entry |
4d69c80e DV |
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 | |
3521ee99 DV |
109 | * by @matchptr must be initialized to NULL before adding the first match. This |
110 | * only matches against components added with component_add(). | |
4d69c80e DV |
111 | * |
112 | * The allocated match list in @matchptr is automatically released using devm | |
113 | * actions. | |
114 | * | |
3521ee99 | 115 | * See also component_match_add_release() and component_match_add_typed(). |
4d69c80e | 116 | */ |
ce657b1c RK |
117 | static inline void component_match_add(struct device *master, |
118 | struct component_match **matchptr, | |
119 | int (*compare)(struct device *, void *), void *compare_data) | |
120 | { | |
121 | component_match_add_release(master, matchptr, NULL, compare, | |
122 | compare_data); | |
123 | } | |
124 | ||
2a41e607 | 125 | #endif |