1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | #ifndef COMPONENT_H |
3 | #define COMPONENT_H |
4 | |
5 | #include <linux/stddef.h> |
6 | |
7 | |
8 | struct device; |
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 | */ |
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 | */ |
23 | int (*bind)(struct device *comp, struct device *master, |
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 | */ |
32 | void (*unbind)(struct device *comp, struct device *master, |
33 | void *master_data); |
34 | }; |
35 | |
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); |
39 | void component_del(struct device *, const struct component_ops *); |
40 | |
41 | int component_bind_all(struct device *parent, void *data); |
42 | void component_unbind_all(struct device *parent, void *data); |
43 | |
44 | struct aggregate_device; |
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 | */ |
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 | */ |
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 | */ |
82 | void (*unbind)(struct device *master); |
83 | }; |
84 | |
85 | /* A set helper functions for component compare/release */ |
86 | int component_compare_of(struct device *dev, void *data); |
87 | void component_release_of(struct device *dev, void *data); |
88 | int component_compare_dev(struct device *dev, void *data); |
89 | int component_compare_dev_name(struct device *dev, void *data); |
90 | |
91 | void component_master_del(struct device *, |
92 | const struct component_master_ops *); |
93 | |
94 | struct component_match; |
95 | |
96 | int component_master_add_with_match(struct device *, |
97 | const struct component_master_ops *, struct component_match *); |
98 | void component_match_add_release(struct device *parent, |
99 | struct component_match **matchptr, |
100 | void (*release)(struct device *, void *), |
101 | int (*compare)(struct device *, void *), void *compare_data); |
102 | void component_match_add_typed(struct device *parent, |
103 | struct component_match **matchptr, |
104 | int (*compare_typed)(struct device *, int, void *), void *compare_data); |
105 | |
106 | /** |
107 | * component_match_add - add a component match entry |
108 | * @parent: device with the aggregate driver |
109 | * @matchptr: pointer to the list of component matches |
110 | * @compare: compare function to match against all components |
111 | * @compare_data: opaque pointer passed to the @compare function |
112 | * |
113 | * Adds a new component match to the list stored in @matchptr, which the @parent |
114 | * aggregate driver needs to function. The list of component matches pointed to |
115 | * by @matchptr must be initialized to NULL before adding the first match. This |
116 | * only matches against components added with component_add(). |
117 | * |
118 | * The allocated match list in @matchptr is automatically released using devm |
119 | * actions. |
120 | * |
121 | * See also component_match_add_release() and component_match_add_typed(). |
122 | */ |
123 | static inline void component_match_add(struct device *parent, |
124 | struct component_match **matchptr, |
125 | int (*compare)(struct device *, void *), void *compare_data) |
126 | { |
127 | component_match_add_release(parent, matchptr, NULL, compare, |
128 | compare_data); |
129 | } |
130 | |
131 | #endif |
132 | |