1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
22a41e607SRussell King #ifndef COMPONENT_H
32a41e607SRussell King #define COMPONENT_H
42a41e607SRussell King
5ce657b1cSRussell King #include <linux/stddef.h>
6*a6ba2dadSHeiko Stuebner #include <linux/types.h>
74d69c80eSDaniel Vetter
82a41e607SRussell King struct device;
92a41e607SRussell King
104d69c80eSDaniel Vetter /**
114d69c80eSDaniel Vetter * struct component_ops - callbacks for component drivers
124d69c80eSDaniel Vetter *
134d69c80eSDaniel Vetter * Components are registered with component_add() and unregistered with
144d69c80eSDaniel Vetter * component_del().
154d69c80eSDaniel Vetter */
162a41e607SRussell King struct component_ops {
174d69c80eSDaniel Vetter /**
184d69c80eSDaniel Vetter * @bind:
194d69c80eSDaniel Vetter *
204d69c80eSDaniel Vetter * Called through component_bind_all() when the aggregate driver is
214d69c80eSDaniel Vetter * ready to bind the overall driver.
224d69c80eSDaniel Vetter */
23ce657b1cSRussell King int (*bind)(struct device *comp, struct device *master,
24ce657b1cSRussell King void *master_data);
254d69c80eSDaniel Vetter /**
264d69c80eSDaniel Vetter * @unbind:
274d69c80eSDaniel Vetter *
284d69c80eSDaniel Vetter * Called through component_unbind_all() when the aggregate driver is
294d69c80eSDaniel Vetter * ready to bind the overall driver, or when component_bind_all() fails
304d69c80eSDaniel Vetter * part-ways through and needs to unbind some already bound components.
314d69c80eSDaniel Vetter */
32ce657b1cSRussell King void (*unbind)(struct device *comp, struct device *master,
33ce657b1cSRussell King void *master_data);
342a41e607SRussell King };
352a41e607SRussell King
362a41e607SRussell King int component_add(struct device *, const struct component_ops *);
373521ee99SDaniel Vetter int component_add_typed(struct device *dev, const struct component_ops *ops,
383521ee99SDaniel Vetter int subcomponent);
392a41e607SRussell King void component_del(struct device *, const struct component_ops *);
402a41e607SRussell King
4113e906e5SStephen Boyd int component_bind_all(struct device *parent, void *data);
4213e906e5SStephen Boyd void component_unbind_all(struct device *parent, void *data);
432a41e607SRussell King
4413e906e5SStephen Boyd struct aggregate_device;
452a41e607SRussell King
464d69c80eSDaniel Vetter /**
474d69c80eSDaniel Vetter * struct component_master_ops - callback for the aggregate driver
484d69c80eSDaniel Vetter *
494d69c80eSDaniel Vetter * Aggregate drivers are registered with component_master_add_with_match() and
504d69c80eSDaniel Vetter * unregistered with component_master_del().
514d69c80eSDaniel Vetter */
522a41e607SRussell King struct component_master_ops {
534d69c80eSDaniel Vetter /**
544d69c80eSDaniel Vetter * @bind:
554d69c80eSDaniel Vetter *
564d69c80eSDaniel Vetter * Called when all components or the aggregate driver, as specified in
574d69c80eSDaniel Vetter * the match list passed to component_master_add_with_match(), are
584d69c80eSDaniel Vetter * ready. Usually there are 3 steps to bind an aggregate driver:
594d69c80eSDaniel Vetter *
604d69c80eSDaniel Vetter * 1. Allocate a structure for the aggregate driver.
614d69c80eSDaniel Vetter *
624d69c80eSDaniel Vetter * 2. Bind all components to the aggregate driver by calling
634d69c80eSDaniel Vetter * component_bind_all() with the aggregate driver structure as opaque
644d69c80eSDaniel Vetter * pointer data.
654d69c80eSDaniel Vetter *
664d69c80eSDaniel Vetter * 3. Register the aggregate driver with the subsystem to publish its
674d69c80eSDaniel Vetter * interfaces.
684d69c80eSDaniel Vetter *
694d69c80eSDaniel Vetter * Note that the lifetime of the aggregate driver does not align with
704d69c80eSDaniel Vetter * any of the underlying &struct device instances. Therefore devm cannot
714d69c80eSDaniel Vetter * be used and all resources acquired or allocated in this callback must
724d69c80eSDaniel Vetter * be explicitly released in the @unbind callback.
734d69c80eSDaniel Vetter */
74ce657b1cSRussell King int (*bind)(struct device *master);
754d69c80eSDaniel Vetter /**
764d69c80eSDaniel Vetter * @unbind:
774d69c80eSDaniel Vetter *
784d69c80eSDaniel Vetter * Called when either the aggregate driver, using
794d69c80eSDaniel Vetter * component_master_del(), or one of its components, using
804d69c80eSDaniel Vetter * component_del(), is unregistered.
814d69c80eSDaniel Vetter */
82ce657b1cSRussell King void (*unbind)(struct device *master);
832a41e607SRussell King };
842a41e607SRussell King
852502960fSYong Wu /* A set helper functions for component compare/release */
862502960fSYong Wu int component_compare_of(struct device *dev, void *data);
872502960fSYong Wu void component_release_of(struct device *dev, void *data);
882502960fSYong Wu int component_compare_dev(struct device *dev, void *data);
892502960fSYong Wu int component_compare_dev_name(struct device *dev, void *data);
902502960fSYong Wu
912a41e607SRussell King void component_master_del(struct device *,
922a41e607SRussell King const struct component_master_ops *);
93*a6ba2dadSHeiko Stuebner bool component_master_is_bound(struct device *parent,
94*a6ba2dadSHeiko Stuebner const struct component_master_ops *ops);
952a41e607SRussell King
966955b582SRussell King struct component_match;
976955b582SRussell King
986955b582SRussell King int component_master_add_with_match(struct device *,
996955b582SRussell King const struct component_master_ops *, struct component_match *);
10013e906e5SStephen Boyd void component_match_add_release(struct device *parent,
101ce657b1cSRussell King struct component_match **matchptr,
102ce657b1cSRussell King void (*release)(struct device *, void *),
1036955b582SRussell King int (*compare)(struct device *, void *), void *compare_data);
10413e906e5SStephen Boyd void component_match_add_typed(struct device *parent,
1053521ee99SDaniel Vetter struct component_match **matchptr,
1063521ee99SDaniel Vetter int (*compare_typed)(struct device *, int, void *), void *compare_data);
1076955b582SRussell King
1084d69c80eSDaniel Vetter /**
109e4246b05SDaniel Vetter * component_match_add - add a component match entry
11013e906e5SStephen Boyd * @parent: device with the aggregate driver
1114d69c80eSDaniel Vetter * @matchptr: pointer to the list of component matches
1124d69c80eSDaniel Vetter * @compare: compare function to match against all components
1134d69c80eSDaniel Vetter * @compare_data: opaque pointer passed to the @compare function
1144d69c80eSDaniel Vetter *
11513e906e5SStephen Boyd * Adds a new component match to the list stored in @matchptr, which the @parent
1164d69c80eSDaniel Vetter * aggregate driver needs to function. The list of component matches pointed to
1173521ee99SDaniel Vetter * by @matchptr must be initialized to NULL before adding the first match. This
1183521ee99SDaniel Vetter * only matches against components added with component_add().
1194d69c80eSDaniel Vetter *
1204d69c80eSDaniel Vetter * The allocated match list in @matchptr is automatically released using devm
1214d69c80eSDaniel Vetter * actions.
1224d69c80eSDaniel Vetter *
1233521ee99SDaniel Vetter * See also component_match_add_release() and component_match_add_typed().
1244d69c80eSDaniel Vetter */
component_match_add(struct device * parent,struct component_match ** matchptr,int (* compare)(struct device *,void *),void * compare_data)12513e906e5SStephen Boyd static inline void component_match_add(struct device *parent,
126ce657b1cSRussell King struct component_match **matchptr,
127ce657b1cSRussell King int (*compare)(struct device *, void *), void *compare_data)
128ce657b1cSRussell King {
12913e906e5SStephen Boyd component_match_add_release(parent, matchptr, NULL, compare,
130ce657b1cSRussell King compare_data);
131ce657b1cSRussell King }
132ce657b1cSRussell King
1332a41e607SRussell King #endif
134