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

structcomponent_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 throughcomponent_bind_all() when the aggregate driver isready to bind the overall driver.

unbind

Called throughcomponent_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().

structcomponent_master_ops

callback for the aggregate driver

Definition:

struct component_master_ops {    int (*bind)(struct device *master);    void (*unbind)(struct device *master);};

Members

bind

Called when all components or the aggregate driver, as specified inthe match list passed tocomponent_master_add_with_match(), areready. Usually there are 3 steps to bind an aggregate driver:

  1. Allocate a structure for the aggregate driver.

  2. Bind all components to the aggregate driver by callingcomponent_bind_all() with the aggregate driver structure as opaquepointer data.

  3. Register the aggregate driver with the subsystem to publish itsinterfaces.

Note that the lifetime of the aggregate driver does not align withany of the underlyingstructdevice instances. 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, usingcomponent_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().

voidcomponent_match_add(structdevice*parent,structcomponent_match**matchptr,int(*compare)(structdevice*,void*),void*compare_data)

add a component match entry

Parameters

structdevice*parent

device with the aggregate driver

structcomponent_match**matchptr

pointer to the list of component matches

int(*compare)(structdevice*,void*)

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 theparentaggregate 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().

intcomponent_compare_of(structdevice*dev,void*data)

A common component compare function for of_node

Parameters

structdevice*dev

component device

void*data

compare_data fromcomponent_match_add_release()

Description

A common compare function when compare_data is device of_node. e.g.component_match_add_release(masterdev,match, component_release_of,component_compare_of, component_dev_of_node)

voidcomponent_release_of(structdevice*dev,void*data)

A common component release function for of_node

Parameters

structdevice*dev

component device

void*data

compare_data fromcomponent_match_add_release()

Description

About the example, Please seecomponent_compare_of().

intcomponent_compare_dev(structdevice*dev,void*data)

A common component compare function for dev

Parameters

structdevice*dev

component device

void*data

compare_data fromcomponent_match_add_release()

Description

A common compare function when compare_data is struce device. e.g.component_match_add(masterdev,match, component_compare_dev, component_dev)

intcomponent_compare_dev_name(structdevice*dev,void*data)

A common component compare function for device name

Parameters

structdevice*dev

component device

void*data

compare_data fromcomponent_match_add_release()

Description

A common compare function when compare_data is device name string. e.g.component_match_add(masterdev,match, component_compare_dev_name,“component_dev_name”)

voidcomponent_match_add_release(structdevice*parent,structcomponent_match**matchptr,void(*release)(structdevice*,void*),int(*compare)(structdevice*,void*),void*compare_data)

add a component match entry with release callback

Parameters

structdevice*parent

parent device of the aggregate driver

structcomponent_match**matchptr

pointer to the list of component matches

void(*release)(structdevice*,void*)

release function forcompare_data

int(*compare)(structdevice*,void*)

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 theaggregate 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 withof_node_put().

See alsocomponent_match_add() andcomponent_match_add_typed().

voidcomponent_match_add_typed(structdevice*parent,structcomponent_match**matchptr,int(*compare_typed)(structdevice*,int,void*),void*compare_data)

add a component match entry for a typed component

Parameters

structdevice*parent

parent device of the aggregate driver

structcomponent_match**matchptr

pointer to the list of component matches

int(*compare_typed)(structdevice*,int,void*)

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 theaggregate 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().

intcomponent_master_add_with_match(structdevice*parent,conststructcomponent_master_ops*ops,structcomponent_match*match)

register an aggregate driver

Parameters

structdevice*parent

parent device of 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().

voidcomponent_master_del(structdevice*parent,conststructcomponent_master_ops*ops)

unregister an aggregate driver

Parameters

structdevice*parent

parent device of 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.

voidcomponent_unbind_all(structdevice*parent,void*data)

unbind all components of an aggregate driver

Parameters

structdevice*parent

parent device of the aggregate driver

void*data

opaque pointer, passed to all components

Description

Unbinds all components of the aggregate device by passingdata to theircomponent_ops.unbind functions. Should be called fromcomponent_master_ops.unbind.

intcomponent_bind_all(structdevice*parent,void*data)

bind all components of an aggregate driver

Parameters

structdevice*parent

parent device of 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.

intcomponent_add_typed(structdevice*dev,conststructcomponent_ops*ops,intsubcomponent)

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 registered 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().

intcomponent_add(structdevice*dev,conststructcomponent_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 multiple differentcomponents on the same device.

voidcomponent_del(structdevice*dev,conststructcomponent_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.