Component Helper for Aggregate Drivers¶
The component helper allows drivers to collect a pile of sub-devices,including their bound drivers, into an aggregate driver. Various subsystemsalready provide functions to get hold of such components, e.g.of_clk_get_by_name(). The component helper can be used when such asubsystem-specific way to find a device is not available: The componenthelper fills the niche of aggregate drivers for specific hardware, wherefurther standardization into a subsystem would not be practical. The commonexample is when a logical device (e.g. a DRM display driver) is spread aroundthe SoC on various components (scanout engines, blending blocks, transcodersfor various outputs and so on).
The component helper also doesn’t solve runtime dependencies, e.g. for systemsuspend and resume operations. See alsodevice links.
Components are registered usingcomponent_add() and unregistered withcomponent_del(), usually from the driver’s probe and disconnect functions.
Aggregate drivers first assemble a component match list of what they needusingcomponent_match_add(). This is then registered as an aggregate driverusingcomponent_master_add_with_match(), and unregistered usingcomponent_master_del().
API¶
- struct
component_ops¶ callbacks for component drivers
Definition
struct component_ops { int (*bind)(struct device *comp, struct device *master, void *master_data); void (*unbind)(struct device *comp, struct device *master, void *master_data);};Members
bind- Called through
component_bind_all()when the aggregate driver isready to bind the overall driver. unbind- Called through
component_unbind_all()when the aggregate driver isready to bind the overall driver, or whencomponent_bind_all()failspart-ways through and needs to unbind some already bound components.
Description
Components are registered withcomponent_add() and unregistered withcomponent_del().
- struct
component_master_ops¶ callback for the aggregate driver
Definition
struct component_master_ops { int (*bind)(struct device *master); void (*unbind)(struct device *master);};Members
bindCalled when all components or the aggregate driver, as specified inthe match list passed to
component_master_add_with_match(), areready. Usually there are 3 steps to bind an aggregate driver:- Allocate a structure for the aggregate driver.
- Bind all components to the aggregate driver by calling
component_bind_all()with the aggregate driver structure as opaquepointer data. - Register the aggregate driver with the subsystem to publish itsinterfaces.
Note that the lifetime of the aggregate driver does not align withany of the underlying
structdeviceinstances. Therefore devm cannotbe used and all resources acquired or allocated in this callback mustbe explicitly released in theunbind callback.unbind- Called when either the aggregate driver, using
component_master_del(), or one of its components, usingcomponent_del(), is unregistered.
Description
Aggregate drivers are registered withcomponent_master_add_with_match() andunregistered withcomponent_master_del().
- void
component_match_add(structdevice * master, struct component_match ** matchptr, int (*compare)(structdevice *, void *), void * compare_data)¶ add a component match entry
Parameters
structdevice*master- device with the aggregate driver
structcomponent_match**matchptr- pointer to the list of component matches
int(*)(structdevice*,void*)compare- compare function to match against all components
void*compare_data- opaque pointer passed to thecompare function
Description
Adds a new component match to the list stored inmatchptr, which themasteraggregate driver needs to function. The list of component matches pointed tobymatchptr must be initialized to NULL before adding the first match. Thisonly matches against components added withcomponent_add().
The allocated match list inmatchptr is automatically released using devmactions.
See alsocomponent_match_add_release() andcomponent_match_add_typed().
- void
component_match_add_release(structdevice * master, struct component_match ** matchptr, void (*release)(structdevice *, void *), int (*compare) (structdevice *, void *), void * compare_data)¶ add a component match entry with release callback
Parameters
structdevice*master- device with the aggregate driver
structcomponent_match**matchptr- pointer to the list of component matches
void(*)(structdevice*,void*)release- release function forcompare_data
int(*)(structdevice*,void*)compare- compare function to match against all components
void*compare_data- opaque pointer passed to thecompare function
Description
Adds a new component match to the list stored inmatchptr, which themasteraggregate driver needs to function. The list of component matches pointed tobymatchptr must be initialized to NULL before adding the first match. Thisonly matches against components added withcomponent_add().
The allocated match list inmatchptr is automatically released using devmactions, where uponrelease will be called to free any references held bycompare_data, e.g. whencompare_data is adevice_node that must bereleased with of_node_put().
See alsocomponent_match_add() andcomponent_match_add_typed().
- void
component_match_add_typed(structdevice * master, struct component_match ** matchptr, int (*compare_typed)(structdevice *, int, void *), void * compare_data)¶ add a component match entry for a typed component
Parameters
structdevice*master- device with the aggregate driver
structcomponent_match**matchptr- pointer to the list of component matches
int(*)(structdevice*,int,void*)compare_typed- compare function to match against all typed components
void*compare_data- opaque pointer passed to thecompare function
Description
Adds a new component match to the list stored inmatchptr, which themasteraggregate driver needs to function. The list of component matches pointed tobymatchptr must be initialized to NULL before adding the first match. Thisonly matches against components added withcomponent_add_typed().
The allocated match list inmatchptr is automatically released using devmactions.
See alsocomponent_match_add_release() andcomponent_match_add_typed().
- int
component_master_add_with_match(structdevice * dev, const structcomponent_master_ops * ops, struct component_match * match)¶ register an aggregate driver
Parameters
structdevice*dev- device with the aggregate driver
conststructcomponent_master_ops*ops- callbacks for the aggregate driver
structcomponent_match*match- component match list for the aggregate driver
Description
Registers a new aggregate driver consisting of the components added tomatchby calling one of thecomponent_match_add() functions. Once all components inmatch are available, it will be assembled by callingcomponent_master_ops.bind fromops. Must be unregistered by callingcomponent_master_del().
- void
component_master_del(structdevice * dev, const structcomponent_master_ops * ops)¶ unregister an aggregate driver
Parameters
structdevice*dev- device with the aggregate driver
conststructcomponent_master_ops*ops- callbacks for the aggregate driver
Description
Unregisters an aggregate driver registered withcomponent_master_add_with_match(). If necessary the aggregate driver is firstdisassembled by callingcomponent_master_ops.unbind fromops.
- void
component_unbind_all(structdevice * master_dev, void * data)¶ unbind all components of an aggregate driver
Parameters
structdevice*master_dev- device with the aggregate driver
void*data- opaque pointer, passed to all components
Description
Unbinds all components of the aggregatedev by passingdata to theircomponent_ops.unbind functions. Should be called fromcomponent_master_ops.unbind.
- int
component_bind_all(structdevice * master_dev, void * data)¶ bind all components of an aggregate driver
Parameters
structdevice*master_dev- device with the aggregate driver
void*data- opaque pointer, passed to all components
Description
Binds all components of the aggregatedev by passingdata to theircomponent_ops.bind functions. Should be called fromcomponent_master_ops.bind.
- int
component_add_typed(structdevice * dev, const structcomponent_ops * ops, int subcomponent)¶ register a component
Parameters
structdevice*dev- component device
conststructcomponent_ops*ops- component callbacks
intsubcomponent- nonzero identifier for subcomponents
Description
Register a new component fordev. Functions inops will be call when theaggregate driver is ready to bind the overall driver by callingcomponent_bind_all(). See alsostructcomponent_ops.
subcomponent must be nonzero and is used to differentiate between multiplecomponents registerd on the same devicedev. These components are matchusingcomponent_match_add_typed().
The component needs to be unregistered at driver unload/disconnect bycallingcomponent_del().
See alsocomponent_add().
- int
component_add(structdevice * dev, const structcomponent_ops * ops)¶ register a component
Parameters
structdevice*dev- component device
conststructcomponent_ops*ops- component callbacks
Description
Register a new component fordev. Functions inops will be called when theaggregate driver is ready to bind the overall driver by callingcomponent_bind_all(). See alsostructcomponent_ops.
The component needs to be unregistered at driver unload/disconnect bycallingcomponent_del().
See alsocomponent_add_typed() for a variant that allows multipled differentcomponents on the same device.
- void
component_del(structdevice * dev, const structcomponent_ops * ops)¶ unregister a component
Parameters
structdevice*dev- component device
conststructcomponent_ops*ops- component callbacks
Description
Unregister a component added withcomponent_add(). If the component is boundinto an aggregate driver, this will force the entire aggregate driver, includingall its components, to be unbound.