Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #ifndef COMPONENT_H
0003 #define COMPONENT_H
0004 
0005 #include <linux/stddef.h>
0006 
0007 
0008 struct device;
0009 
0010 /**
0011  * struct component_ops - callbacks for component drivers
0012  *
0013  * Components are registered with component_add() and unregistered with
0014  * component_del().
0015  */
0016 struct component_ops {
0017     /**
0018      * @bind:
0019      *
0020      * Called through component_bind_all() when the aggregate driver is
0021      * ready to bind the overall driver.
0022      */
0023     int (*bind)(struct device *comp, struct device *master,
0024             void *master_data);
0025     /**
0026      * @unbind:
0027      *
0028      * Called through component_unbind_all() when the aggregate driver is
0029      * ready to bind the overall driver, or when component_bind_all() fails
0030      * part-ways through and needs to unbind some already bound components.
0031      */
0032     void (*unbind)(struct device *comp, struct device *master,
0033                void *master_data);
0034 };
0035 
0036 int component_add(struct device *, const struct component_ops *);
0037 int component_add_typed(struct device *dev, const struct component_ops *ops,
0038     int subcomponent);
0039 void component_del(struct device *, const struct component_ops *);
0040 
0041 int component_bind_all(struct device *parent, void *data);
0042 void component_unbind_all(struct device *parent, void *data);
0043 
0044 struct aggregate_device;
0045 
0046 /**
0047  * struct component_master_ops - callback for the aggregate driver
0048  *
0049  * Aggregate drivers are registered with component_master_add_with_match() and
0050  * unregistered with component_master_del().
0051  */
0052 struct component_master_ops {
0053     /**
0054      * @bind:
0055      *
0056      * Called when all components or the aggregate driver, as specified in
0057      * the match list passed to component_master_add_with_match(), are
0058      * ready. Usually there are 3 steps to bind an aggregate driver:
0059      *
0060      * 1. Allocate a structure for the aggregate driver.
0061      *
0062      * 2. Bind all components to the aggregate driver by calling
0063      *    component_bind_all() with the aggregate driver structure as opaque
0064      *    pointer data.
0065      *
0066      * 3. Register the aggregate driver with the subsystem to publish its
0067      *    interfaces.
0068      *
0069      * Note that the lifetime of the aggregate driver does not align with
0070      * any of the underlying &struct device instances. Therefore devm cannot
0071      * be used and all resources acquired or allocated in this callback must
0072      * be explicitly released in the @unbind callback.
0073      */
0074     int (*bind)(struct device *master);
0075     /**
0076      * @unbind:
0077      *
0078      * Called when either the aggregate driver, using
0079      * component_master_del(), or one of its components, using
0080      * component_del(), is unregistered.
0081      */
0082     void (*unbind)(struct device *master);
0083 };
0084 
0085 /* A set helper functions for component compare/release */
0086 int component_compare_of(struct device *dev, void *data);
0087 void component_release_of(struct device *dev, void *data);
0088 int component_compare_dev(struct device *dev, void *data);
0089 int component_compare_dev_name(struct device *dev, void *data);
0090 
0091 void component_master_del(struct device *,
0092     const struct component_master_ops *);
0093 
0094 struct component_match;
0095 
0096 int component_master_add_with_match(struct device *,
0097     const struct component_master_ops *, struct component_match *);
0098 void component_match_add_release(struct device *parent,
0099     struct component_match **matchptr,
0100     void (*release)(struct device *, void *),
0101     int (*compare)(struct device *, void *), void *compare_data);
0102 void component_match_add_typed(struct device *parent,
0103     struct component_match **matchptr,
0104     int (*compare_typed)(struct device *, int, void *), void *compare_data);
0105 
0106 /**
0107  * component_match_add - add a component match entry
0108  * @parent: device with the aggregate driver
0109  * @matchptr: pointer to the list of component matches
0110  * @compare: compare function to match against all components
0111  * @compare_data: opaque pointer passed to the @compare function
0112  *
0113  * Adds a new component match to the list stored in @matchptr, which the @parent
0114  * aggregate driver needs to function. The list of component matches pointed to
0115  * by @matchptr must be initialized to NULL before adding the first match. This
0116  * only matches against components added with component_add().
0117  *
0118  * The allocated match list in @matchptr is automatically released using devm
0119  * actions.
0120  *
0121  * See also component_match_add_release() and component_match_add_typed().
0122  */
0123 static inline void component_match_add(struct device *parent,
0124     struct component_match **matchptr,
0125     int (*compare)(struct device *, void *), void *compare_data)
0126 {
0127     component_match_add_release(parent, matchptr, NULL, compare,
0128                     compare_data);
0129 }
0130 
0131 #endif