Device drivers infrastructure

The Basic Device Driver-Model Structures

structsubsys_interface

interfaces to device functions

Definition

struct subsys_interface {  const char *name;  struct bus_type *subsys;  struct list_head node;  int (*add_dev)(struct device *dev, struct subsys_interface *sif);  void (*remove_dev)(struct device *dev, struct subsys_interface *sif);};

Members

name
name of the device function
subsys
subsytem of the devices to attach to
node
the list of functions registered at the subsystem
add_dev
device hookup to device function handler
remove_dev
device hookup to device function handler

Description

Simple interfaces attached to a subsystem. Multiple interfaces canattach to a subsystem and its devices. Unlike drivers, they do notexclusively claim or control devices. Interfaces usually representa specific functionality of a subsystem/class of devices.

devm_alloc_percpu(dev,type)

Resource-managed alloc_percpu

Parameters

dev
Device to allocate per-cpu memory for
type
Type to allocate per-cpu memory for

Description

Managed alloc_percpu. Per-cpu memory allocated with this function isautomatically freed on driver detach.

Return

Pointer to allocated memory on success, NULL on failure.

structdevice_connection

Device Connection Descriptor

Definition

struct device_connection {  struct fwnode_handle    *fwnode;  const char              *endpoint[2];  const char              *id;  struct list_head        list;};

Members

fwnode
The device node of the connected device
endpoint
The names of the two devices connected together
id
Unique identifier for the connection
list
List head, private, for internal use only

NOTE

fwnode is not used together withendpoint.fwnode is used whenplatform firmware defines the connection. When the connection is registeredwithdevice_connection_add()endpoint is used instead.

voiddevice_connections_add(structdevice_connection * cons)

Add multiple device connections at once

Parameters

structdevice_connection*cons
Zero terminated array of device connection descriptors
voiddevice_connections_remove(structdevice_connection * cons)

Remove multiple device connections at once

Parameters

structdevice_connection*cons
Zero terminated array of device connection descriptors
enumdevice_link_state

Device link states.

Constants

DL_STATE_NONE
The presence of the drivers is not being tracked.
DL_STATE_DORMANT
None of the supplier/consumer drivers is present.
DL_STATE_AVAILABLE
The supplier driver is present, but the consumer is not.
DL_STATE_CONSUMER_PROBE
The consumer is probing (supplier driver present).
DL_STATE_ACTIVE
Both the supplier and consumer drivers are present.
DL_STATE_SUPPLIER_UNBIND
The supplier driver is unbinding.
structdevice_link

Device link representation.

Definition

struct device_link {  struct device *supplier;  struct list_head s_node;  struct device *consumer;  struct list_head c_node;  enum device_link_state status;  u32 flags;  refcount_t rpm_active;  struct kref kref;#ifdef CONFIG_SRCU;  struct rcu_head rcu_head;#endif;  bool supplier_preactivated;};

Members

supplier
The device on the supplier end of the link.
s_node
Hook to the supplier device’s list of links to consumers.
consumer
The device on the consumer end of the link.
c_node
Hook to the consumer device’s list of links to suppliers.
status
The state of the link (with respect to the presence of drivers).
flags
Link flags.
rpm_active
Whether or not the consumer device is runtime-PM-active.
kref
Count repeated addition of the same link.
rcu_head
An RCU head to use for deferred execution of SRCU callbacks.
supplier_preactivated
Supplier has been made active before consumer probe.
enumdl_dev_state

Device driver presence tracking information.

Constants

DL_DEV_NO_DRIVER
There is no driver attached to the device.
DL_DEV_PROBING
A driver is probing.
DL_DEV_DRIVER_BOUND
The driver has been bound to the device.
DL_DEV_UNBINDING
The driver is unbinding from the device.
structdev_links_info

Device data related to device links.

Definition

struct dev_links_info {  struct list_head suppliers;  struct list_head consumers;  struct list_head needs_suppliers;  struct list_head defer_hook;  bool need_for_probe;  enum dl_dev_state status;};

Members

suppliers
List of links to supplier devices.
consumers
List of links to consumer devices.
needs_suppliers
Hook to global list of devices waiting for suppliers.
defer_hook
Hook to global list of devices that have deferred sync_state ordeferred fw_devlink.
need_for_probe
If needs_suppliers is on a list, this indicates if thesuppliers are needed for probe or not.
status
Driver status information.
structdevice

The basic device structure

Definition

struct device {  struct kobject kobj;  struct device           *parent;  struct device_private   *p;  const char              *init_name;  const struct device_type *type;  struct bus_type *bus;  struct device_driver *driver;  void *platform_data;  void *driver_data;#ifdef CONFIG_PROVE_LOCKING;  struct mutex            lockdep_mutex;#endif;  struct mutex            mutex;  struct dev_links_info   links;  struct dev_pm_info      power;  struct dev_pm_domain    *pm_domain;#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN;  struct irq_domain       *msi_domain;#endif;#ifdef CONFIG_PINCTRL;  struct dev_pin_info     *pins;#endif;#ifdef CONFIG_GENERIC_MSI_IRQ;  struct list_head        msi_list;#endif;  const struct dma_map_ops *dma_ops;  u64 *dma_mask;  u64 coherent_dma_mask;  u64 bus_dma_limit;  unsigned long   dma_pfn_offset;  struct device_dma_parameters *dma_parms;  struct list_head        dma_pools;#ifdef CONFIG_DMA_DECLARE_COHERENT;  struct dma_coherent_mem *dma_mem;#endif;#ifdef CONFIG_DMA_CMA;  struct cma *cma_area;#endif;  struct dev_archdata     archdata;  struct device_node      *of_node;  struct fwnode_handle    *fwnode;#ifdef CONFIG_NUMA;  int numa_node;#endif;  dev_t devt;  u32 id;  spinlock_t devres_lock;  struct list_head        devres_head;  struct class            *class;  const struct attribute_group **groups;  void (*release)(struct device *dev);  struct iommu_group      *iommu_group;  struct dev_iommu        *iommu;  bool offline_disabled:1;  bool offline:1;  bool of_node_reused:1;  bool state_synced:1;#if defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE) ||     defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU) ||     defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU_ALL);  bool dma_coherent:1;#endif;};

Members

kobj
A top-level, abstract class from which other classes are derived.
parent
The device’s “parent” device, the device to which it is attached.In most cases, a parent device is some sort of bus or hostcontroller. If parent is NULL, the device, is a top-level device,which is not usually what you want.
p
Holds the private data of the driver core portions of the device.See the comment of the struct device_private for detail.
init_name
Initial name of the device.
type
The type of device.This identifies the device type and carries type-specificinformation.
bus
Type of bus device is on.
driver
Which driver has allocated this
platform_data
Platform data specific to the device.
driver_data
Private pointer for driver specific info.
lockdep_mutex
An optional debug lock that a subsystem can use as apeer lock to gain localized lockdep coverage of the device_lock.
mutex
Mutex to synchronize calls to its driver.
links
Links to suppliers and consumers of this device.
power
For device power management.See Documentation/driver-api/pm/devices.rst for details.
pm_domain
Provide callbacks that are executed during system suspend,hibernation, system resume and during runtime PM transitionsalong with subsystem-level and driver-level callbacks.
msi_domain
The generic MSI domain this device is using.
pins
For device pin management.See Documentation/driver-api/pinctl.rst for details.
msi_list
Hosts MSI descriptors
dma_ops
DMA mapping operations for this device.
dma_mask
Dma mask (if dma’ble device).
coherent_dma_mask
Like dma_mask, but for alloc_coherent mapping as not allhardware supports 64-bit addresses for consistent allocationssuch descriptors.
bus_dma_limit
Limit of an upstream bridge or bus which imposes a smallerDMA limit than the device itself supports.
dma_pfn_offset
offset of DMA memory range relatively of RAM
dma_parms
A low level driver may set these to teach IOMMU code aboutsegment limitations.
dma_pools
Dma pools (if dma’ble device).
dma_mem
Internal for coherent mem override.
cma_area
Contiguous memory area for dma allocations
archdata
For arch-specific additions.
of_node
Associated device tree node.
fwnode
Associated device node supplied by platform firmware.
numa_node
NUMA node this device is close to.
devt
For creating the sysfs “dev”.
id
device instance
devres_lock
Spinlock to protect the resource of the device.
devres_head
The resources list of the device.
class
The class of the device.
groups
Optional attribute groups.
release
Callback to free the device after all references havegone away. This should be set by the allocator of thedevice (i.e. the bus driver that discovered the device).
iommu_group
IOMMU group the device belongs to.
iommu
Per device generic IOMMU runtime data
offline_disabled
If set, the device is permanently online.
offline
Set after successful invocation of bus type’s .offline().
of_node_reused
Set if the device-tree node is shared with an ancestordevice.
state_synced
The hardware state of this device has been synced to matchthe software state of this device by calling the driver/bussync_state() callback.
dma_coherent
this particular device is dma coherent, even if thearchitecture supports non-coherent devices.

Example

For devices on custom boards, as typical of embedded
and SOC based hardware, Linux often uses platform_data to pointto board-specific structures describing devices and how theyare wired. That can include what ports are available, chipvariants, which GPIO pins act in what additional roles, and soon. This shrinks the “Board Support Packages” (BSPs) andminimizes board-specific #ifdefs in drivers.

Description

At the lowest level, every device in a Linux system is represented by aninstance of struct device. The device structure contains the informationthat the device model core needs to model the system. Most subsystems,however, track additional information about the devices they host. As aresult, it is rare for devices to be represented by bare device structures;instead, that structure, like kobject structures, is usually embedded withina higher-level representation of the device.

booldevice_iommu_mapped(structdevice * dev)

Returns true when the device DMA is translated by an IOMMU

Parameters

structdevice*dev
Device to perform the check on

Device Drivers Base

voiddriver_init(void)

initialize driver model.

Parameters

void
no arguments

Description

Call the driver model init functions to initialize theirsubsystems. Called early from init/main.c.

intdriver_for_each_device(struct device_driver * drv, structdevice * start, void * data, int (*fn)(structdevice *, void *))

Iterator for devices bound to a driver.

Parameters

structdevice_driver*drv
Driver we’re iterating.
structdevice*start
Device to begin with
void*data
Data to pass to the callback.
int(*)(structdevice*,void*)fn
Function to call for each device.

Description

Iterate over thedrv’s list of devices callingfn for each one.

structdevice *driver_find_device(struct device_driver * drv, structdevice * start, const void * data, int (*match)(structdevice *dev, const void *data))

device iterator for locating a particular device.

Parameters

structdevice_driver*drv
The device’s driver
structdevice*start
Device to begin with
constvoid*data
Data to pass to match function
int(*)(structdevice*dev,constvoid*data)match
Callback function to check device

Description

This is similar to thedriver_for_each_device() function above, butit returns a reference to a device that is ‘found’ for later use, asdetermined by thematch callback.

The callback should return 0 if the device doesn’t match and non-zeroif it does. If the callback returns non-zero, this function willreturn to the caller and not iterate over any more devices.

intdriver_create_file(struct device_driver * drv, const struct driver_attribute * attr)

create sysfs file for driver.

Parameters

structdevice_driver*drv
driver.
conststructdriver_attribute*attr
driver attribute descriptor.
voiddriver_remove_file(struct device_driver * drv, const struct driver_attribute * attr)

remove sysfs file for driver.

Parameters

structdevice_driver*drv
driver.
conststructdriver_attribute*attr
driver attribute descriptor.
intdriver_register(struct device_driver * drv)

register driver with bus

Parameters

structdevice_driver*drv
driver to register

Description

We pass off most of the work to the bus_add_driver() call,since most of the things we have to do deal with the busstructures.

voiddriver_unregister(struct device_driver * drv)

remove driver from system.

Parameters

structdevice_driver*drv
driver.

Description

Again, we pass off most of the work to the bus-level call.

struct device_driver *driver_find(const char * name, struct bus_type * bus)

locate driver on a bus by its name.

Parameters

constchar*name
name of the driver.
structbus_type*bus
bus to scan for the driver.

Description

Callkset_find_obj() to iterate over list of drivers ona bus to find driver by name. Return driver if found.

This routine provides no locking to prevent the driver it returnsfrom being unregistered or unloaded while the caller is using it.The caller is responsible for preventing this.

structdevice_link *device_link_add(structdevice * consumer, structdevice * supplier, u32 flags)

Create a link between two devices.

Parameters

structdevice*consumer
Consumer end of the link.
structdevice*supplier
Supplier end of the link.
u32flags
Link flags.

Description

The caller is responsible for the proper synchronization of the link creationwith runtime PM. First, setting the DL_FLAG_PM_RUNTIME flag will cause theruntime PM framework to take the link into account. Second, if theDL_FLAG_RPM_ACTIVE flag is set in addition to it, the supplier devices willbe forced into the active metastate and reference-counted upon the creationof the link. If DL_FLAG_PM_RUNTIME is not set, DL_FLAG_RPM_ACTIVE will beignored.

If DL_FLAG_STATELESS is set inflags, the caller of this function isexpected to release the link returned by it directly with the help of eitherdevice_link_del() ordevice_link_remove().

If that flag is not set, however, the caller of this function is handing themanagement of the link over to the driver core entirely and its return valuecan only be used to check whether or not the link is present. In that case,the DL_FLAG_AUTOREMOVE_CONSUMER and DL_FLAG_AUTOREMOVE_SUPPLIER device linkflags can be used to indicate to the driver core when the link can be safelydeleted. Namely, setting one of them inflags indicates to the driver corethat the link is not going to be used (by the given caller of this function)after unbinding the consumer or supplier driver, respectively, from itsdevice, so the link can be deleted at that point. If none of them is set,the link will be maintained until one of the devices pointed to by it (eitherthe consumer or the supplier) is unregistered.

Also, if DL_FLAG_STATELESS, DL_FLAG_AUTOREMOVE_CONSUMER andDL_FLAG_AUTOREMOVE_SUPPLIER are not set inflags (that is, a persistentmanaged device link is being added), the DL_FLAG_AUTOPROBE_CONSUMER flag canbe used to request the driver core to automaticall probe for a consmerdriver after successfully binding a driver to the supplier device.

The combination of DL_FLAG_STATELESS and one of DL_FLAG_AUTOREMOVE_CONSUMER,DL_FLAG_AUTOREMOVE_SUPPLIER, or DL_FLAG_AUTOPROBE_CONSUMER set inflags atthe same time is invalid and will cause NULL to be returned upfront.However, if a device link between the givenconsumer andsupplier pairexists already when this function is called for them, the existing link willbe returned regardless of its current type and status (the link’s flags maybe modified then). The caller of this function is then expected to treatthe link as though it has just been created, so (in particular) ifDL_FLAG_STATELESS was passed inflags, the link needs to be releasedexplicitly when not needed any more (as stated above).

A side effect of the link creation is re-ordering of dpm_list and thedevices_kset list by moving the consumer device and all devices dependingon it to the ends of these lists (that does not happen to devices that havenot been registered when this function is called).

The supplier device is required to be registered when this function is calledand NULL will be returned if that is not the case. The consumer device neednot be registered, however.

voiddevice_link_del(structdevice_link * link)

Delete a stateless link between two devices.

Parameters

structdevice_link*link
Device link to delete.

Description

The caller must ensure proper synchronization of this function with runtimePM. If the link was added multiple times, it needs to be deleted as often.Care is required for hotplugged devices: Their links are purged on removaland callingdevice_link_del() is then no longer allowed.

voiddevice_link_remove(void * consumer, structdevice * supplier)

Delete a stateless link between two devices.

Parameters

void*consumer
Consumer end of the link.
structdevice*supplier
Supplier end of the link.

Description

The caller must ensure proper synchronization of this function with runtimePM.

const char *dev_driver_string(const structdevice * dev)

Return a device’s driver name, if at all possible

Parameters

conststructdevice*dev
struct device to get the name of

Description

Will return the device’s driver’s name if it is bound to a device. Ifthe device is not bound to a driver, it will return the name of the busit is attached to. If it is not attached to a bus either, an emptystring will be returned.

intdevm_device_add_group(structdevice * dev, const struct attribute_group * grp)

given a device, create a managed attribute group

Parameters

structdevice*dev
The device to create the group for
conststructattribute_group*grp
The attribute group to create

Description

This function creates a group for the first time. It will explicitlywarn and error if any of the attribute files being created already exist.

Returns 0 on success or error code on failure.

voiddevm_device_remove_group(structdevice * dev, const struct attribute_group * grp)

Parameters

structdevice*dev
device to remove the group from
conststructattribute_group*grp
group to remove

Description

This function removes a group of attributes from a device. The attributespreviously have to have been created for this group, otherwise it will fail.

intdevm_device_add_groups(structdevice * dev, const struct attribute_group ** groups)

create a bunch of managed attribute groups

Parameters

structdevice*dev
The device to create the group for
conststructattribute_group**groups
The attribute groups to create, NULL terminated

Description

This function creates a bunch of managed attribute groups. If an erroroccurs when creating a group, all previously created groups will beremoved, unwinding everything back to the original state when thisfunction was called. It will explicitly warn and error if any of theattribute files being created already exist.

Returns 0 on success or error code from sysfs_create_group on failure.

voiddevm_device_remove_groups(structdevice * dev, const struct attribute_group ** groups)

remove a list of managed groups

Parameters

structdevice*dev
The device for the groups to be removed from
conststructattribute_group**groups
NULL terminated list of groups to be removed

Description

If groups is not NULL, remove the specified groups from the device.

intdevice_create_file(structdevice * dev, const struct device_attribute * attr)

create sysfs attribute file for device.

Parameters

structdevice*dev
device.
conststructdevice_attribute*attr
device attribute descriptor.
voiddevice_remove_file(structdevice * dev, const struct device_attribute * attr)

remove sysfs attribute file.

Parameters

structdevice*dev
device.
conststructdevice_attribute*attr
device attribute descriptor.
booldevice_remove_file_self(structdevice * dev, const struct device_attribute * attr)

remove sysfs attribute file from its own method.

Parameters

structdevice*dev
device.
conststructdevice_attribute*attr
device attribute descriptor.

Description

See kernfs_remove_self() for details.

intdevice_create_bin_file(structdevice * dev, const struct bin_attribute * attr)

create sysfs binary attribute file for device.

Parameters

structdevice*dev
device.
conststructbin_attribute*attr
device binary attribute descriptor.
voiddevice_remove_bin_file(structdevice * dev, const struct bin_attribute * attr)

remove sysfs binary attribute file

Parameters

structdevice*dev
device.
conststructbin_attribute*attr
device binary attribute descriptor.
voiddevice_initialize(structdevice * dev)

init device structure.

Parameters

structdevice*dev
device.

Description

This prepares the device for use by other layers by initializingits fields.It is the first half ofdevice_register(), if called bythat function, though it can also be called separately, so onemay usedev’s fields. In particular,get_device()/put_device()may be used for reference counting ofdev after calling thisfunction.

All fields indev must be initialized by the caller to 0, exceptfor those explicitly set to some other value. The simplestapproach is to usekzalloc() to allocate the structure containingdev.

NOTE

Useput_device() to give up your reference instead of freeingdev directly once you have called this function.

intdev_set_name(structdevice * dev, const char * fmt, ...)

set a device name

Parameters

structdevice*dev
device
constchar*fmt
format string for the device’s name
...
variable arguments
intdevice_add(structdevice * dev)

add device to device hierarchy.

Parameters

structdevice*dev
device.

Description

This is part 2 ofdevice_register(), though may be calledseparately _iff_device_initialize() has been called separately.

This addsdev to the kobject hierarchy viakobject_add(), adds itto the global and sibling lists for the device, thenadds it to the other relevant subsystems of the driver model.

Do not call this routine ordevice_register() more than once forany device structure. The driver model core is not designed to workwith devices that get unregistered and then spring back to life.(Among other things, it’s very hard to guarantee that all referencesto the previous incarnation ofdev have been dropped.) Allocateand register a fresh new struct device instead.

Rule of thumb is: ifdevice_add() succeeds, you should calldevice_del() when you want to get rid of it. Ifdevice_add() hasnot succeeded, useonlyput_device() to drop the referencecount.

NOTE

_Never_ directly freedev after calling this function, evenif it returned an error! Always useput_device() to give up yourreference instead.

intdevice_register(structdevice * dev)

register a device with the system.

Parameters

structdevice*dev
pointer to the device structure

Description

This happens in two clean steps - initialize the deviceand add it to the system. The two steps can be calledseparately, but this is the easiest and most common.I.e. you should only call the two helpers separately ifhave a clearly defined need to use and refcount the devicebefore it is added to the hierarchy.

For more information, see the kerneldoc fordevice_initialize()anddevice_add().

NOTE

_Never_ directly freedev after calling this function, evenif it returned an error! Always useput_device() to give up thereference initialized in this function instead.

structdevice *get_device(structdevice * dev)

increment reference count for device.

Parameters

structdevice*dev
device.

Description

This simply forwards the call tokobject_get(), thoughwe do take care to provide for the case that we get a NULLpointer passed in.

voidput_device(structdevice * dev)

decrement reference count.

Parameters

structdevice*dev
device in question.
voiddevice_del(structdevice * dev)

delete device from system.

Parameters

structdevice*dev
device.

Description

This is the first part of the device unregistrationsequence. This removes the device from the lists we controlfrom here, has it removed from the other driver modelsubsystems it was added to indevice_add(), and removes itfrom the kobject hierarchy.

NOTE

this should be called manually _iff_device_add() wasalso called manually.

voiddevice_unregister(structdevice * dev)

unregister device from system.

Parameters

structdevice*dev
device going away.

Description

We do this in two parts, like we dodevice_register(). First,we remove it from all the subsystems withdevice_del(), thenwe decrement the reference count viaput_device(). If thatis the final reference count, the device will be cleaned upvia device_release() above. Otherwise, the structure willstick around until the final reference to the device is dropped.

intdevice_for_each_child(structdevice * parent, void * data, int (*fn)(structdevice *dev, void *data))

device child iterator.

Parameters

structdevice*parent
parent struct device.
void*data
data for the callback.
int(*)(structdevice*dev,void*data)fn
function to be called for each device.

Description

Iterate overparent’s child devices, and callfn for each,passing itdata.

We check the return offn each time. If it returns anythingother than 0, we break out and return that value.

intdevice_for_each_child_reverse(structdevice * parent, void * data, int (*fn)(structdevice *dev, void *data))

device child iterator in reversed order.

Parameters

structdevice*parent
parent struct device.
void*data
data for the callback.
int(*)(structdevice*dev,void*data)fn
function to be called for each device.

Description

Iterate overparent’s child devices, and callfn for each,passing itdata.

We check the return offn each time. If it returns anythingother than 0, we break out and return that value.

structdevice *device_find_child(structdevice * parent, void * data, int (*match)(structdevice *dev, void *data))

device iterator for locating a particular device.

Parameters

structdevice*parent
parent struct device
void*data
Data to pass to match function
int(*)(structdevice*dev,void*data)match
Callback function to check device

Description

This is similar to thedevice_for_each_child() function above, but itreturns a reference to a device that is ‘found’ for later use, asdetermined by thematch callback.

The callback should return 0 if the device doesn’t match and non-zeroif it does. If the callback returns non-zero and a reference to thecurrent device can be obtained, this function will return to the callerand not iterate over any more devices.

NOTE

you will need to drop the reference withput_device() after use.

structdevice *device_find_child_by_name(structdevice * parent, const char * name)

device iterator for locating a child device.

Parameters

structdevice*parent
parent struct device
constchar*name
name of the child device

Description

This is similar to thedevice_find_child() function above, but itreturns a reference to a device that has the namename.

NOTE

you will need to drop the reference withput_device() after use.

structdevice *__root_device_register(const char * name, struct module * owner)

allocate and register a root device

Parameters

constchar*name
root device name
structmodule*owner
owner module of the root device, usually THIS_MODULE

Description

This function allocates a root device and registers itusingdevice_register(). In order to free the returneddevice, useroot_device_unregister().

Root devices are dummy devices which allow other devicesto be grouped under /sys/devices. Use this function toallocate a root device and then use it as the parent ofany device which should appear under /sys/devices/{name}

The /sys/devices/{name} directory will also contain a‘module’ symlink which points to theowner directoryin sysfs.

Returnsstructdevice pointer on success, or ERR_PTR() on error.

Note

You probably want to use root_device_register().

voidroot_device_unregister(structdevice * dev)

unregister and free a root device

Parameters

structdevice*dev
device going away

Description

This function unregisters and cleans up a device that was created byroot_device_register().

structdevice *device_create(struct class * class, structdevice * parent, dev_t devt, void * drvdata, const char * fmt, ...)

creates a device and registers it with sysfs

Parameters

structclass*class
pointer to the struct class that this device should be registered to
structdevice*parent
pointer to the parent struct device of this new device, if any
dev_tdevt
the dev_t for the char device to be added
void*drvdata
the data to be added to the device for callbacks
constchar*fmt
string for the device’s name
...
variable arguments

Description

This function can be used by char device classes. A struct devicewill be created in sysfs, registered to the specified class.

A “dev” file will be created, showing the dev_t for the device, ifthe dev_t is not 0,0.If a pointer to a parent struct device is passed in, the newly createdstruct device will be a child of that device in sysfs.The pointer to the struct device will be returned from the call.Any further sysfs files that might be required can be created using thispointer.

Returnsstructdevice pointer on success, or ERR_PTR() on error.

Note

the struct class passed to this function must have previouslybeen created with a call to class_create().

structdevice *device_create_with_groups(struct class * class, structdevice * parent, dev_t devt, void * drvdata, const struct attribute_group ** groups, const char * fmt, ...)

creates a device and registers it with sysfs

Parameters

structclass*class
pointer to the struct class that this device should be registered to
structdevice*parent
pointer to the parent struct device of this new device, if any
dev_tdevt
the dev_t for the char device to be added
void*drvdata
the data to be added to the device for callbacks
conststructattribute_group**groups
NULL-terminated list of attribute groups to be created
constchar*fmt
string for the device’s name
...
variable arguments

Description

This function can be used by char device classes. A struct devicewill be created in sysfs, registered to the specified class.Additional attributes specified in the groups parameter will alsobe created automatically.

A “dev” file will be created, showing the dev_t for the device, ifthe dev_t is not 0,0.If a pointer to a parent struct device is passed in, the newly createdstruct device will be a child of that device in sysfs.The pointer to the struct device will be returned from the call.Any further sysfs files that might be required can be created using thispointer.

Returnsstructdevice pointer on success, or ERR_PTR() on error.

Note

the struct class passed to this function must have previouslybeen created with a call to class_create().

voiddevice_destroy(struct class * class, dev_t devt)

removes a device that was created withdevice_create()

Parameters

structclass*class
pointer to the struct class that this device was registered with
dev_tdevt
the dev_t of the device that was previously registered

Description

This call unregisters and cleans up a device that was created with acall todevice_create().

intdevice_rename(structdevice * dev, const char * new_name)

renames a device

Parameters

structdevice*dev
the pointer to the struct device to be renamed
constchar*new_name
the new name of the device

Description

It is the responsibility of the caller to provide mutualexclusion between two different calls of device_renameon the same device to ensure that new_name is valid andwon’t conflict with other devices.

Renaming devices is racy at many levels, symlinks and other stuff are notreplaced atomically, and you get a “move” uevent, but it’s not easy toconnect the event to the old and new device. Device nodes are not renamed atall, there isn’t even support for that in the kernel now.

In the meantime, during renaming, your target name might be taken by anotherdriver, creating conflicts. Or the old name is taken directly after yourenamed it – then you get events for the same DEVPATH, before you even seethe “move” event. It’s just a mess, and nothing new should ever rely onkernel device renaming. Besides that, it’s not even implemented now forother things than (driver-core wise very simple) network devices.

We are currently about to change network renaming in udev to completelydisallow renaming of devices in the same namespace as the kernel uses,because we can’t solve the problems properly, that arise with swapping namesof multiple interfaces without races. Means, renaming of eth[0-9]* will onlybe allowed to some other name than eth[0-9]*, for the aforementionedreasons.

Make up a “real” name in the driver before you register anything, or addsome other attributes for userspace to find the device, or use udev to addsymlinks – but never rename kernel devices later, it’s a complete mess. Wedon’t even want to get into that and try to implement the missing pieces inthe core. We really have other pieces to fix in the driver core mess. :)

Note

Don’t call this function. Currently, the networking layer calls thisfunction, but that will change. The following text from Kay Sievers offerssome insight:

intdevice_move(structdevice * dev, structdevice * new_parent, enum dpm_order dpm_order)

moves a device to a new parent

Parameters

structdevice*dev
the pointer to the struct device to be moved
structdevice*new_parent
the new parent of the device (can be NULL)
enumdpm_orderdpm_order
how to reorder the dpm_list
intdevice_change_owner(structdevice * dev, kuid_t kuid, kgid_t kgid)

change the owner of an existing device.

Parameters

structdevice*dev
device.
kuid_tkuid
new owner’s kuid
kgid_tkgid
new owner’s kgid

Description

This changes the owner ofdev and its corresponding sysfs entries tokuid/kgid. This function closely mirrors howdev was added via drivercore.

Returns 0 on success or error code on failure.

voidset_primary_fwnode(structdevice * dev, struct fwnode_handle * fwnode)

Change the primary firmware node of a given device.

Parameters

structdevice*dev
Device to handle.
structfwnode_handle*fwnode
New primary firmware node of the device.

Description

Set the device’s firmware node pointer tofwnode, but if a secondaryfirmware node of the device is present, preserve it.

voidset_secondary_fwnode(structdevice * dev, struct fwnode_handle * fwnode)

Change the secondary firmware node of a given device.

Parameters

structdevice*dev
Device to handle.
structfwnode_handle*fwnode
New secondary firmware node of the device.

Description

If a primary firmware node of the device is present, set its secondarypointer tofwnode. Otherwise, set the device’s firmware node pointer tofwnode.

voiddevice_set_of_node_from_dev(structdevice * dev, const structdevice * dev2)

reuse device-tree node of another device

Parameters

structdevice*dev
device whose device-tree node is being set
conststructdevice*dev2
device whose device-tree node is being reused

Description

Takes another reference to the new device-tree node after first droppingany reference held to the old node.

voidregister_syscore_ops(struct syscore_ops * ops)

Register a set of system core operations.

Parameters

structsyscore_ops*ops
System core operations to register.
voidunregister_syscore_ops(struct syscore_ops * ops)

Unregister a set of system core operations.

Parameters

structsyscore_ops*ops
System core operations to unregister.
intsyscore_suspend(void)

Execute all the registered system core suspend callbacks.

Parameters

void
no arguments

Description

This function is executed with one CPU on-line and disabled interrupts.

voidsyscore_resume(void)

Execute all the registered system core resume callbacks.

Parameters

void
no arguments

Description

This function is executed with one CPU on-line and disabled interrupts.

struct class *__class_create(struct module * owner, const char * name, struct lock_class_key * key)

create a struct class structure

Parameters

structmodule*owner
pointer to the module that is to “own” this struct class
constchar*name
pointer to a string for the name of this class.
structlock_class_key*key
the lock_class_key for this class; used by mutex lock debugging

Description

This is used to create a struct class pointer that can then be usedin calls todevice_create().

Returnsstructclass pointer on success, or ERR_PTR() on error.

Note, the pointer created here is to be destroyed when finished bymaking a call toclass_destroy().

voidclass_destroy(struct class * cls)

destroys a struct class structure

Parameters

structclass*cls
pointer to the struct class that is to be destroyed

Description

Note, the pointer to be destroyed must have been created with a callto class_create().

voidclass_dev_iter_init(struct class_dev_iter * iter, struct class * class, structdevice * start, const struct device_type * type)

initialize class device iterator

Parameters

structclass_dev_iter*iter
class iterator to initialize
structclass*class
the class we wanna iterate over
structdevice*start
the device to start iterating from, if any
conststructdevice_type*type
device_type of the devices to iterate over, NULL for all

Description

Initialize class iteratoriter such that it iterates over devicesofclass. Ifstart is set, the list iteration will start there,otherwise if it is NULL, the iteration starts at the beginning ofthe list.

structdevice *class_dev_iter_next(struct class_dev_iter * iter)

iterate to the next device

Parameters

structclass_dev_iter*iter
class iterator to proceed

Description

Proceediter to the next device and return it. Returns NULL ifiteration is complete.

The returned device is referenced and won’t be released tilliterator is proceed to the next device or exited. The caller isfree to do whatever it wants to do with the device includingcalling back into class code.

voidclass_dev_iter_exit(struct class_dev_iter * iter)

finish iteration

Parameters

structclass_dev_iter*iter
class iterator to finish

Description

Finish an iteration. Always call this function after iteration iscomplete whether the iteration ran till the end or not.

intclass_for_each_device(struct class * class, structdevice * start, void * data, int (*fn)(structdevice *, void *))

device iterator

Parameters

structclass*class
the class we’re iterating
structdevice*start
the device to start with in the list, if any.
void*data
data for the callback
int(*)(structdevice*,void*)fn
function to be called for each device

Description

Iterate overclass’s list of devices, and callfn for each,passing itdata. Ifstart is set, the list iteration will startthere, otherwise if it is NULL, the iteration starts at thebeginning of the list.

We check the return offn each time. If it returns anythingother than 0, we break out and return that value.

fn is allowed to do anything including calling back into classcode. There’s no locking restriction.

structdevice *class_find_device(struct class * class, structdevice * start, const void * data, int (*match)(structdevice *, const void *))

device iterator for locating a particular device

Parameters

structclass*class
the class we’re iterating
structdevice*start
Device to begin with
constvoid*data
data for the match function
int(*)(structdevice*,constvoid*)match
function to check device

Description

This is similar to the class_for_each_dev() function above, but itreturns a reference to a device that is ‘found’ for later use, asdetermined by thematch callback.

The callback should return 0 if the device doesn’t match and non-zeroif it does. If the callback returns non-zero, this function willreturn to the caller and not iterate over any more devices.

Note, you will need to drop the reference withput_device() after use.

match is allowed to do anything including calling back into classcode. There’s no locking restriction.

struct class_compat *class_compat_register(const char * name)

register a compatibility class

Parameters

constchar*name
the name of the class

Description

Compatibility class are meant as a temporary user-space compatibilityworkaround when converting a family of class devices to a bus devices.

voidclass_compat_unregister(struct class_compat * cls)

unregister a compatibility class

Parameters

structclass_compat*cls
the class to unregister
intclass_compat_create_link(struct class_compat * cls, structdevice * dev, structdevice * device_link)

create a compatibility class device link to a bus device

Parameters

structclass_compat*cls
the compatibility class
structdevice*dev
the target bus device
structdevice*device_link
an optional device to which a “device” link should be created
voidclass_compat_remove_link(struct class_compat * cls, structdevice * dev, structdevice * device_link)

remove a compatibility class device link to a bus device

Parameters

structclass_compat*cls
the compatibility class
structdevice*dev
the target bus device
structdevice*device_link
an optional device to which a “device” link was previouslycreated
structnode_access_nodes

Access class device to hold user visible relationships to other nodes.

Definition

struct node_access_nodes {  struct device           dev;  struct list_head        list_node;  unsigned access;#ifdef CONFIG_HMEM_REPORTING;  struct node_hmem_attrs  hmem_attrs;#endif;};

Members

dev
Device for this memory access class
list_node
List element in the node’s access list
access
The access class rank
hmem_attrs
Heterogeneous memory performance attributes
voidnode_set_perf_attrs(unsigned int nid, struct node_hmem_attrs * hmem_attrs, unsigned access)

Set the performance values for given access class

Parameters

unsignedintnid
Node identifier to be set
structnode_hmem_attrs*hmem_attrs
Heterogeneous memory performance attributes
unsignedaccess
The access class the for the given attributes
structnode_cache_info

Internal tracking for memory node caches

Definition

struct node_cache_info {  struct device dev;  struct list_head node;  struct node_cache_attrs cache_attrs;};

Members

dev
Device represeting the cache level
node
List element for tracking in the node
cache_attrs
Attributes for this cache level
voidnode_add_cache(unsigned int nid, struct node_cache_attrs * cache_attrs)

add cache attribute to a memory node

Parameters

unsignedintnid
Node identifier that has new cache attributes
structnode_cache_attrs*cache_attrs
Attributes for the cache being added
voidunregister_node(struct node * node)

unregister a node device

Parameters

structnode*node
node going away

Description

Unregisters a node devicenode. All the devices on the node must beunregistered before calling this function.

intregister_memory_node_under_compute_node(unsigned int mem_nid, unsigned int cpu_nid, unsigned access)

link memory node to its compute node for a given access class.

Parameters

unsignedintmem_nid
Memory node number
unsignedintcpu_nid
Cpu node number
unsignedaccess
Access class to register

Description

For use with platforms that may have separate memory and compute nodes.This function will export node relationships linking which memoryinitiator nodes can access memory targets at a given ranked accessclass.
intrequest_firmware(const struct firmware ** firmware_p, const char * name, structdevice * device)

send firmware request and wait for it

Parameters

conststructfirmware**firmware_p
pointer to firmware image
constchar*name
name of firmware file
structdevice*device

device for which firmware is being loaded

firmware_p will be used to return a firmware image by the nameofname for devicedevice.

Should be called from user context where sleeping is allowed.

name will be used as $FIRMWARE in the uevent environment andshould be distinctive enough not to be confused with any otherfirmware image for this or any other device.

Caller must hold the reference count ofdevice.

The function can be called safely inside device’s suspend andresume callback.

intfirmware_request_nowarn(const struct firmware ** firmware, const char * name, structdevice * device)

request for an optional fw module

Parameters

conststructfirmware**firmware
pointer to firmware image
constchar*name
name of firmware file
structdevice*device
device for which firmware is being loaded

Description

This function is similar in behaviour torequest_firmware(), exceptit doesn’t produce warning messages when the file is not found.The sysfs fallback mechanism is enabled if direct filesystem lookup fails,however, however failures to find the firmware file with it are stillsuppressed. It is therefore up to the driver to check for the return valueof this call and to decide when to inform the users of errors.

intrequest_firmware_direct(const struct firmware ** firmware_p, const char * name, structdevice * device)

load firmware directly without usermode helper

Parameters

conststructfirmware**firmware_p
pointer to firmware image
constchar*name
name of firmware file
structdevice*device
device for which firmware is being loaded

Description

This function works pretty much likerequest_firmware(), but this doesn’tfall back to usermode helper even if the firmware couldn’t be loadeddirectly from fs. Hence it’s useful for loading optional firmwares, whicharen’t always present, without extra long timeouts of udev.

intfirmware_request_platform(const struct firmware ** firmware, const char * name, structdevice * device)

request firmware with platform-fw fallback

Parameters

conststructfirmware**firmware
pointer to firmware image
constchar*name
name of firmware file
structdevice*device
device for which firmware is being loaded

Description

This function is similar in behaviour to request_firmware, except that ifdirect filesystem lookup fails, it will fallback to looking for a copy of therequested firmware embedded in the platform’s main (e.g. UEFI) firmware.

intfirmware_request_cache(structdevice * device, const char * name)

cache firmware for suspend so resume can use it

Parameters

structdevice*device
device for which firmware should be cached for
constchar*name
name of firmware file

Description

There are some devices with an optimization that enables the device to notrequire loading firmware on system reboot. This optimization may stillrequire the firmware present on resume from suspend. This routine can beused to ensure the firmware is present on resume from suspend in thesesituations. This helper is not compatible with drivers which userequest_firmware_into_buf() orrequest_firmware_nowait() with no uevent set.

intrequest_firmware_into_buf(const struct firmware ** firmware_p, const char * name, structdevice * device, void * buf, size_t size)

load firmware into a previously allocated buffer

Parameters

conststructfirmware**firmware_p
pointer to firmware image
constchar*name
name of firmware file
structdevice*device
device for which firmware is being loaded and DMA region allocated
void*buf
address of buffer to load firmware into
size_tsize
size of buffer

Description

This function works pretty much likerequest_firmware(), but it doesn’tallocate a buffer to hold the firmware data. Instead, the firmwareis loaded directly into the buffer pointed to bybuf and thefirmware_pdata member is pointed atbuf.

This function doesn’t cache firmware either.

voidrelease_firmware(const struct firmware * fw)

release the resource associated with a firmware image

Parameters

conststructfirmware*fw
firmware resource to release
intrequest_firmware_nowait(struct module * module, bool uevent, const char * name, structdevice * device, gfp_t gfp, void * context, void (*cont)(const struct firmware *fw, void *context))

asynchronous version of request_firmware

Parameters

structmodule*module
module requesting the firmware
booluevent
sends uevent to copy the firmware image if this flagis non-zero else the firmware copy must be done manually.
constchar*name
name of firmware file
structdevice*device
device for which firmware is being loaded
gfp_tgfp
allocation flags
void*context
will be passed over tocont, andfw may beNULL if firmware request fails.
void(*)(conststructfirmware*fw,void*context)cont

function will be called asynchronously when the firmwarerequest is over.

Caller must hold the reference count ofdevice.

Asynchronous variant of request_firmware() for user contexts:
  • sleep for as small periods as possible since it mayincrease kernel boot time of built-in device driversrequesting firmware in their ->probe() methods, ifgfp is GFP_KERNEL.
  • can’t sleep at all ifgfp is GFP_ATOMIC.
inttransport_class_register(struct transport_class * tclass)

register an initial transport class

Parameters

structtransport_class*tclass
a pointer to the transport class structure to be initialised

Description

The transport class contains an embedded class which is used toidentify it. The caller should initialise this structure withzeros and then generic class must have been initialised with theactual transport class unique name. There’s a macroDECLARE_TRANSPORT_CLASS() to do this (declared classes still mustbe registered).

Returns 0 on success or error on failure.

voidtransport_class_unregister(struct transport_class * tclass)

unregister a previously registered class

Parameters

structtransport_class*tclass
The transport class to unregister

Description

Must be called prior to deallocating the memory for the transportclass.

intanon_transport_class_register(struct anon_transport_class * atc)

register an anonymous class

Parameters

structanon_transport_class*atc
The anon transport class to register

Description

The anonymous transport class contains both a transport class and acontainer. The idea of an anonymous class is that it neveractually has any device attributes associated with it (and thussaves on container storage). So it can only be used for triggeringevents. Use prezero and then use DECLARE_ANON_TRANSPORT_CLASS() toinitialise the anon transport class storage.

voidanon_transport_class_unregister(struct anon_transport_class * atc)

unregister an anon class

Parameters

structanon_transport_class*atc
Pointer to the anon transport class to unregister

Description

Must be called prior to deallocating the memory for the anontransport class.

voidtransport_setup_device(structdevice * dev)

declare a new dev for transport class association but don’t make it visible yet.

Parameters

structdevice*dev
the generic device representing the entity being added

Description

Usually, dev represents some component in the HBA system (eitherthe HBA itself or a device remote across the HBA bus). Thisroutine is simply a trigger point to see if any set of transportclasses wishes to associate with the added device. This allocatesstorage for the class device and initialises it, but does not yetadd it to the system or add attributes to it (you do this withtransport_add_device). If you have no need for a separate setupand add operations, use transport_register_device (seetransport_class.h).

inttransport_add_device(structdevice * dev)

declare a new dev for transport class association

Parameters

structdevice*dev
the generic device representing the entity being added

Description

Usually, dev represents some component in the HBA system (eitherthe HBA itself or a device remote across the HBA bus). Thisroutine is simply a trigger point used to add the device to thesystem and register attributes for it.

voidtransport_configure_device(structdevice * dev)

configure an already set up device

Parameters

structdevice*dev
generic device representing device to be configured

Description

The idea of configure is simply to provide a point within the setupprocess to allow the transport class to extract information from adevice after it has been setup. This is used in SCSI because wehave to have a setup device to begin using the HBA, but after wesend the initial inquiry, we use configure to extract the deviceparameters. The device need not have been added to be configured.

voidtransport_remove_device(structdevice * dev)

remove the visibility of a device

Parameters

structdevice*dev
generic device to remove

Description

This call removes the visibility of the device (to the user fromsysfs), but does not destroy it. To eliminate a device entirelyyou must also call transport_destroy_device. If you don’t need todo remove and destroy as separate operations, usetransport_unregister_device() (see transport_class.h) which willperform both calls for you.

voidtransport_destroy_device(structdevice * dev)

destroy a removed device

Parameters

structdevice*dev
device to eliminate from the transport class.

Description

This call triggers the elimination of storage associated with thetransport classdev. Note: all it really does is relinquish areference to the classdev. The memory will not be freed until thelast reference goes to zero. Note also that the classdev retains areference count on dev, so dev too will remain for as long as thetransport class device remains around.

intdevice_bind_driver(structdevice * dev)

bind a driver to one device.

Parameters

structdevice*dev
device.

Description

Allow manual attachment of a driver to a device.Caller must have already setdev->driver.

Note that this does not modify the bus reference countnor take the bus’s rwsem. Please verify those are accountedfor before calling this. (It is ok to call with no other effortfrom a driver’s probe() method.)

This function must be called with the device lock held.

voidwait_for_device_probe(void)

Parameters

void
no arguments

Description

Wait for device probing to be completed.

intdevice_attach(structdevice * dev)

try to attach device to a driver.

Parameters

structdevice*dev
device.

Description

Walk the list of drivers that the bus has and calldriver_probe_device() for each pair. If a compatiblepair is found, break out and return.

Returns 1 if the device was bound to a driver;0 if no matching driver was found;-ENODEV if the device is not registered.

When called for a USB interface,dev->parent lock must be held.

intdriver_attach(struct device_driver * drv)

try to bind driver to devices.

Parameters

structdevice_driver*drv
driver.

Description

Walk the list of devices that the bus has on it and try tomatch the driver with each one. If driver_probe_device()returns 0 and thedev->driver is set, we’ve found acompatible pair.

voiddevice_release_driver(structdevice * dev)

manually detach device from driver.

Parameters

structdevice*dev
device.

Description

Manually detach device from driver.When called for a USB interface,dev->parent lock must be held.

If this function is to be called withdev->parent lock held, ensure thatthe device’s consumers are unbound in advance or that their locks can beacquired under thedev->parent lock.

struct platform_device *platform_device_register_resndata(structdevice * parent, const char * name, int id, const struct resource * res, unsigned int num, const void * data, size_t size)

add a platform-level device with resources and platform-specific data

Parameters

structdevice*parent
parent device for the device we’re adding
constchar*name
base name of the device we’re adding
intid
instance id
conststructresource*res
set of resources that needs to be allocated for the device
unsignedintnum
number of resources
constvoid*data
platform specific data for this platform device
size_tsize
size of platform specific data

Description

Returnsstructplatform_device pointer on success, or ERR_PTR() on error.

struct platform_device *platform_device_register_simple(const char * name, int id, const struct resource * res, unsigned int num)

add a platform-level device and its resources

Parameters

constchar*name
base name of the device we’re adding
intid
instance id
conststructresource*res
set of resources that needs to be allocated for the device
unsignedintnum
number of resources

Description

This function creates a simple platform device that requires minimalresource and memory management. Canned release function freeing memoryallocated for the device allows drivers using such devices to beunloaded without waiting for the last reference to the device to bedropped.

This interface is primarily intended for use with legacy drivers whichprobe hardware directly. Because such drivers create sysfs device nodesthemselves, rather than letting system infrastructure handle such deviceenumeration tasks, they don’t fully conform to the Linux driver model.In particular, when such drivers are built as modules, they can’t be“hotplugged”.

Returnsstructplatform_device pointer on success, or ERR_PTR() on error.

struct platform_device *platform_device_register_data(structdevice * parent, const char * name, int id, const void * data, size_t size)

add a platform-level device with platform-specific data

Parameters

structdevice*parent
parent device for the device we’re adding
constchar*name
base name of the device we’re adding
intid
instance id
constvoid*data
platform specific data for this platform device
size_tsize
size of platform specific data

Description

This function creates a simple platform device that requires minimalresource and memory management. Canned release function freeing memoryallocated for the device allows drivers using such devices to beunloaded without waiting for the last reference to the device to bedropped.

Returnsstructplatform_device pointer on success, or ERR_PTR() on error.

struct resource *platform_get_resource(struct platform_device * dev, unsigned int type, unsigned int num)

get a resource for a device

Parameters

structplatform_device*dev
platform device
unsignedinttype
resource type
unsignedintnum
resource index
void __iomem *devm_platform_get_and_ioremap_resource(struct platform_device * pdev, unsigned int index, struct resource ** res)

call devm_ioremap_resource() for a platform device and get resource

Parameters

structplatform_device*pdev
platform device to use both for memory resource lookup as well asresource management
unsignedintindex
resource index
structresource**res
optional output parameter to store a pointer to the obtained resource.
void __iomem *devm_platform_ioremap_resource(struct platform_device * pdev, unsigned int index)

call devm_ioremap_resource() for a platform device

Parameters

structplatform_device*pdev
platform device to use both for memory resource lookup as well asresource management
unsignedintindex
resource index
void __iomem *devm_platform_ioremap_resource_byname(struct platform_device * pdev, const char * name)

call devm_ioremap_resource for a platform device, retrieve the resource by name

Parameters

structplatform_device*pdev
platform device to use both for memory resource lookup as well asresource management
constchar*name
name of the resource
intplatform_get_irq_optional(struct platform_device * dev, unsigned int num)

get an optional IRQ for a device

Parameters

structplatform_device*dev
platform device
unsignedintnum
IRQ number index

Description

Gets an IRQ for a platform device. Device drivers should check the returnvalue for errors so as to not pass a negative integer value to therequest_irq() APIs. This is the same asplatform_get_irq(), except that itdoes not print an error message if an IRQ can not be obtained.

For example:

int irq = platform_get_irq_optional(pdev, 0);if (irq < 0)        return irq;

Return

non-zero IRQ number on success, negative error number on failure.

intplatform_get_irq(struct platform_device * dev, unsigned int num)

get an IRQ for a device

Parameters

structplatform_device*dev
platform device
unsignedintnum
IRQ number index

Description

Gets an IRQ for a platform device and prints an error message if finding theIRQ fails. Device drivers should check the return value for errors so as tonot pass a negative integer value to therequest_irq() APIs.

For example:

int irq = platform_get_irq(pdev, 0);if (irq < 0)        return irq;

Return

non-zero IRQ number on success, negative error number on failure.

intplatform_irq_count(struct platform_device * dev)

Count the number of IRQs a platform device uses

Parameters

structplatform_device*dev
platform device

Return

Number of IRQs a platform device uses or EPROBE_DEFER

struct resource *platform_get_resource_byname(struct platform_device * dev, unsigned int type, const char * name)

get a resource for a device by name

Parameters

structplatform_device*dev
platform device
unsignedinttype
resource type
constchar*name
resource name
intplatform_get_irq_byname(struct platform_device * dev, const char * name)

get an IRQ for a device by name

Parameters

structplatform_device*dev
platform device
constchar*name
IRQ name

Description

Get an IRQ likeplatform_get_irq(), but then by name rather then by index.

Return

non-zero IRQ number on success, negative error number on failure.

intplatform_get_irq_byname_optional(struct platform_device * dev, const char * name)

get an optional IRQ for a device by name

Parameters

structplatform_device*dev
platform device
constchar*name
IRQ name

Description

Get an optional IRQ by name likeplatform_get_irq_byname(). Except that itdoes not print an error message if an IRQ can not be obtained.

Return

non-zero IRQ number on success, negative error number on failure.

intplatform_add_devices(struct platform_device ** devs, int num)

add a numbers of platform devices

Parameters

structplatform_device**devs
array of platform devices to add
intnum
number of platform devices in array
voidplatform_device_put(struct platform_device * pdev)

destroy a platform device

Parameters

structplatform_device*pdev
platform device to free

Description

Free all memory associated with a platform device. This function must_only_ be externally called in error cases. All other usage is a bug.

struct platform_device *platform_device_alloc(const char * name, int id)

create a platform device

Parameters

constchar*name
base name of the device we’re adding
intid
instance id

Description

Create a platform device object which can have other objects attachedto it, and which will have attached objects freed when it is released.

intplatform_device_add_resources(struct platform_device * pdev, const struct resource * res, unsigned int num)

add resources to a platform device

Parameters

structplatform_device*pdev
platform device allocated by platform_device_alloc to add resources to
conststructresource*res
set of resources that needs to be allocated for the device
unsignedintnum
number of resources

Description

Add a copy of the resources to the platform device. The memoryassociated with the resources will be freed when the platform device isreleased.

intplatform_device_add_data(struct platform_device * pdev, const void * data, size_t size)

add platform-specific data to a platform device

Parameters

structplatform_device*pdev
platform device allocated by platform_device_alloc to add resources to
constvoid*data
platform specific data for this platform device
size_tsize
size of platform specific data

Description

Add a copy of platform specific data to the platform device’splatform_data pointer. The memory associated with the platform datawill be freed when the platform device is released.

intplatform_device_add_properties(struct platform_device * pdev, const struct property_entry * properties)

add built-in properties to a platform device

Parameters

structplatform_device*pdev
platform device to add properties to
conststructproperty_entry*properties
null terminated array of properties to add

Description

The function will take deep copy ofproperties and attach the copy to theplatform device. The memory associated with properties will be freed when theplatform device is released.

intplatform_device_add(struct platform_device * pdev)

add a platform device to device hierarchy

Parameters

structplatform_device*pdev
platform device we’re adding

Description

This is part 2 ofplatform_device_register(), though may be calledseparately _iff_ pdev was allocated byplatform_device_alloc().

voidplatform_device_del(struct platform_device * pdev)

remove a platform-level device

Parameters

structplatform_device*pdev
platform device we’re removing

Description

Note that this function will also release all memory- and port-basedresources owned by the device (dev->resource). This function must_only_ be externally called in error cases. All other usage is a bug.

intplatform_device_register(struct platform_device * pdev)

add a platform-level device

Parameters

structplatform_device*pdev
platform device we’re adding
voidplatform_device_unregister(struct platform_device * pdev)

unregister a platform-level device

Parameters

structplatform_device*pdev
platform device we’re unregistering

Description

Unregistration is done in 2 steps. First we release all resourcesand remove it from the subsystem, then we drop reference count bycallingplatform_device_put().

struct platform_device *platform_device_register_full(const struct platform_device_info * pdevinfo)

add a platform-level device with resources and platform-specific data

Parameters

conststructplatform_device_info*pdevinfo
data used to create device

Description

Returnsstructplatform_device pointer on success, or ERR_PTR() on error.

int__platform_driver_register(struct platform_driver * drv, struct module * owner)

register a driver for platform-level devices

Parameters

structplatform_driver*drv
platform driver structure
structmodule*owner
owning module/driver
voidplatform_driver_unregister(struct platform_driver * drv)

unregister a driver for platform-level devices

Parameters

structplatform_driver*drv
platform driver structure
int__platform_driver_probe(struct platform_driver * drv, int (*probe)(struct platform_device *), struct module * module)

register driver for non-hotpluggable device

Parameters

structplatform_driver*drv
platform driver structure
int(*)(structplatform_device*)probe
the driver probe routine, probably from an __init section
structmodule*module
module which will be the owner of the driver

Description

Use this instead of platform_driver_register() when you know the deviceis not hotpluggable and has already been registered, and you want toremove its run-once probe() infrastructure from memory after the driverhas bound to the device.

One typical use for this would be with drivers for controllers integratedinto system-on-chip processors, where the controller devices have beenconfigured as part of board setup.

Note that this is incompatible with deferred probing.

Returns zero if the driver registered and bound to a device, else returnsa negative error code and with the driver not registered.

struct platform_device *__platform_create_bundle(struct platform_driver * driver, int (*probe)(struct platform_device *), struct resource * res, unsigned int n_res, const void * data, size_t size, struct module * module)

register driver and create corresponding device

Parameters

structplatform_driver*driver
platform driver structure
int(*)(structplatform_device*)probe
the driver probe routine, probably from an __init section
structresource*res
set of resources that needs to be allocated for the device
unsignedintn_res
number of resources
constvoid*data
platform specific data for this platform device
size_tsize
size of platform specific data
structmodule*module
module which will be the owner of the driver

Description

Use this in legacy-style modules that probe hardware directly andregister a single platform device and corresponding platform driver.

Returnsstructplatform_device pointer on success, or ERR_PTR() on error.

int__platform_register_drivers(struct platform_driver *const * drivers, unsigned int count, struct module * owner)

register an array of platform drivers

Parameters

structplatform_driver*const*drivers
an array of drivers to register
unsignedintcount
the number of drivers to register
structmodule*owner
module owning the drivers

Description

Registers platform drivers specified by an array. On failure to register adriver, all previously registered drivers will be unregistered. Callers ofthis API should useplatform_unregister_drivers() to unregister drivers inthe reverse order.

Return

0 on success or a negative error code on failure.

voidplatform_unregister_drivers(struct platform_driver *const * drivers, unsigned int count)

unregister an array of platform drivers

Parameters

structplatform_driver*const*drivers
an array of drivers to unregister
unsignedintcount
the number of drivers to unregister

Description

Unregisters platform drivers specified by an array. This is typically usedto complement an earlier call to platform_register_drivers(). Drivers areunregistered in the reverse order in which they were registered.

structdevice *platform_find_device_by_driver(structdevice * start, const struct device_driver * drv)

Find a platform device with a given driver.

Parameters

structdevice*start
The device to start the search from.
conststructdevice_driver*drv
The device driver to look for.
intbus_for_each_dev(struct bus_type * bus, structdevice * start, void * data, int (*fn)(structdevice *, void *))

device iterator.

Parameters

structbus_type*bus
bus type.
structdevice*start
device to start iterating from.
void*data
data for the callback.
int(*)(structdevice*,void*)fn
function to be called for each device.

Description

Iterate overbus’s list of devices, and callfn for each,passing itdata. Ifstart is not NULL, we use that device tobegin iterating from.

We check the return offn each time. If it returns anythingother than 0, we break out and return that value.

NOTE

The device that returns a non-zero value is not retainedin any way, nor is its refcount incremented. If the caller needsto retain this data, it should do so, and increment the referencecount in the supplied callback.

structdevice *bus_find_device(struct bus_type * bus, structdevice * start, const void * data, int (*match)(structdevice *dev, const void *data))

device iterator for locating a particular device.

Parameters

structbus_type*bus
bus type
structdevice*start
Device to begin with
constvoid*data
Data to pass to match function
int(*)(structdevice*dev,constvoid*data)match
Callback function to check device

Description

This is similar to thebus_for_each_dev() function above, but itreturns a reference to a device that is ‘found’ for later use, asdetermined by thematch callback.

The callback should return 0 if the device doesn’t match and non-zeroif it does. If the callback returns non-zero, this function willreturn to the caller and not iterate over any more devices.

structdevice *subsys_find_device_by_id(struct bus_type * subsys, unsigned int id, structdevice * hint)

find a device with a specific enumeration number

Parameters

structbus_type*subsys
subsystem
unsignedintid
index ‘id’ in struct device
structdevice*hint
device to check first

Description

Check the hint’s next object and if it is a match return it directly,otherwise, fall back to a full list search. Either way a reference forthe returned object is taken.

intbus_for_each_drv(struct bus_type * bus, struct device_driver * start, void * data, int (*fn)(struct device_driver *, void *))

driver iterator

Parameters

structbus_type*bus
bus we’re dealing with.
structdevice_driver*start
driver to start iterating on.
void*data
data to pass to the callback.
int(*)(structdevice_driver*,void*)fn
function to call for each driver.

Description

This is nearly identical to the device iterator above.We iterate over each driver that belongs tobus, and callfn for each. Iffn returns anything but 0, we break outand return it. Ifstart is not NULL, we use it as the headof the list.

NOTE

we don’t return the driver that returns a non-zerovalue, nor do we leave the reference count incremented for thatdriver. If the caller needs to know that info, it must set itin the callback. It must also be sure to increment the refcountso it doesn’t disappear before returning to the caller.

intbus_rescan_devices(struct bus_type * bus)

rescan devices on the bus for possible drivers

Parameters

structbus_type*bus
the bus to scan.

Description

This function will look for devices on the bus with no driverattached and rescan it against existing drivers to see if it matchesany by callingdevice_attach() for the unbound devices.

intdevice_reprobe(structdevice * dev)

remove driver for a device and probe for a new driver

Parameters

structdevice*dev
the device to reprobe

Description

This function detaches the attached driver (if any) for the givendevice and restarts the driver probing process. It is intendedto use if probing criteria changed during a devices lifetime anddriver attachment should change accordingly.

intbus_register(struct bus_type * bus)

register a driver-core subsystem

Parameters

structbus_type*bus
bus to register

Description

Once we have that, we register the bus with the kobjectinfrastructure, then register the children subsystems it has:the devices and drivers that belong to the subsystem.

voidbus_unregister(struct bus_type * bus)

remove a bus from the system

Parameters

structbus_type*bus
bus.

Description

Unregister the child subsystems and the bus itself.Finally, we call bus_put() to release the refcount

voidsubsys_dev_iter_init(struct subsys_dev_iter * iter, struct bus_type * subsys, structdevice * start, const struct device_type * type)

initialize subsys device iterator

Parameters

structsubsys_dev_iter*iter
subsys iterator to initialize
structbus_type*subsys
the subsys we wanna iterate over
structdevice*start
the device to start iterating from, if any
conststructdevice_type*type
device_type of the devices to iterate over, NULL for all

Description

Initialize subsys iteratoriter such that it iterates over devicesofsubsys. Ifstart is set, the list iteration will start there,otherwise if it is NULL, the iteration starts at the beginning ofthe list.

structdevice *subsys_dev_iter_next(struct subsys_dev_iter * iter)

iterate to the next device

Parameters

structsubsys_dev_iter*iter
subsys iterator to proceed

Description

Proceediter to the next device and return it. Returns NULL ifiteration is complete.

The returned device is referenced and won’t be released tilliterator is proceed to the next device or exited. The caller isfree to do whatever it wants to do with the device includingcalling back into subsys code.

voidsubsys_dev_iter_exit(struct subsys_dev_iter * iter)

finish iteration

Parameters

structsubsys_dev_iter*iter
subsys iterator to finish

Description

Finish an iteration. Always call this function after iteration iscomplete whether the iteration ran till the end or not.

intsubsys_system_register(struct bus_type * subsys, const struct attribute_group ** groups)

register a subsystem at /sys/devices/system/

Parameters

structbus_type*subsys
system subsystem
conststructattribute_group**groups
default attributes for the root device

Description

All ‘system’ subsystems have a /sys/devices/system/<name> root devicewith the name of the subsystem. The root device can carry subsystem-wide attributes. All registered devices are below this single rootdevice and are named after the subsystem with a simple enumerationnumber appended. The registered devices are not explicitly named;only ‘id’ in the device needs to be set.

Do not use this interface for anything new, it exists for compatibilitywith bad ideas only. New subsystems should use plain subsystems; andadd the subsystem-wide attributes should be added to the subsystemdirectory itself and not some create fake root-device placed in/sys/devices/system/<name>.

intsubsys_virtual_register(struct bus_type * subsys, const struct attribute_group ** groups)

register a subsystem at /sys/devices/virtual/

Parameters

structbus_type*subsys
virtual subsystem
conststructattribute_group**groups
default attributes for the root device

Description

All ‘virtual’ subsystems have a /sys/devices/system/<name> root devicewith the name of the subystem. The root device can carry subsystem-wideattributes. All registered devices are below this single root device.There’s no restriction on device naming. This is for kernel softwareconstructs which need sysfs interface.

Device Drivers DMA Management

voiddmam_free_coherent(structdevice * dev, size_t size, void * vaddr, dma_addr_t dma_handle)

Managed dma_free_coherent()

Parameters

structdevice*dev
Device to free coherent memory for
size_tsize
Size of allocation
void*vaddr
Virtual address of the memory to free
dma_addr_tdma_handle
DMA handle of the memory to free

Description

Managed dma_free_coherent().

void *dmam_alloc_attrs(structdevice * dev, size_t size, dma_addr_t * dma_handle, gfp_t gfp, unsigned long attrs)

Managed dma_alloc_attrs()

Parameters

structdevice*dev
Device to allocate non_coherent memory for
size_tsize
Size of allocation
dma_addr_t*dma_handle
Out argument for allocated DMA handle
gfp_tgfp
Allocation flags
unsignedlongattrs
Flags in the DMA_ATTR_* namespace.

Description

Managed dma_alloc_attrs(). Memory allocated using this function will beautomatically released on driver detach.

Return

Pointer to allocated memory on success, NULL on failure.

booldma_can_mmap(structdevice * dev)

check if a given device supports dma_mmap_*

Parameters

structdevice*dev
device to check

Description

Returnstrue ifdev supports dma_mmap_coherent() anddma_mmap_attrs() tomap DMA allocations to userspace.

intdma_mmap_attrs(structdevice * dev, struct vm_area_struct * vma, void * cpu_addr, dma_addr_t dma_addr, size_t size, unsigned long attrs)

map a coherent DMA allocation into user space

Parameters

structdevice*dev
valid struct device pointer, or NULL for ISA and EISA-like devices
structvm_area_struct*vma
vm_area_struct describing requested user mapping
void*cpu_addr
kernel CPU-view address returned from dma_alloc_attrs
dma_addr_tdma_addr
device-view address returned from dma_alloc_attrs
size_tsize
size of memory originally requested in dma_alloc_attrs
unsignedlongattrs
attributes of mapping properties requested in dma_alloc_attrs

Description

Map a coherent DMA buffer previously allocated by dma_alloc_attrs into userspace. The coherent DMA buffer must not be freed by the driver until theuser space mapping has been released.

Device drivers PnP support

intpnp_register_protocol(struct pnp_protocol * protocol)

adds a pnp protocol to the pnp layer

Parameters

structpnp_protocol*protocol

pointer to the corresponding pnp_protocol structure

Ex protocols: ISAPNP, PNPBIOS, etc

voidpnp_unregister_protocol(struct pnp_protocol * protocol)

removes a pnp protocol from the pnp layer

Parameters

structpnp_protocol*protocol
pointer to the corresponding pnp_protocol structure
struct pnp_dev *pnp_request_card_device(struct pnp_card_link * clink, const char * id, struct pnp_dev * from)

Searches for a PnP device under the specified card

Parameters

structpnp_card_link*clink
pointer to the card link, cannot be NULL
constchar*id
pointer to a PnP ID structure that explains the rules for finding the device
structpnp_dev*from
Starting place to search from. If NULL it will start from the beginning.
voidpnp_release_card_device(struct pnp_dev * dev)

call this when the driver no longer needs the device

Parameters

structpnp_dev*dev
pointer to the PnP device structure
intpnp_register_card_driver(struct pnp_card_driver * drv)

registers a PnP card driver with the PnP Layer

Parameters

structpnp_card_driver*drv
pointer to the driver to register
voidpnp_unregister_card_driver(struct pnp_card_driver * drv)

unregisters a PnP card driver from the PnP Layer

Parameters

structpnp_card_driver*drv
pointer to the driver to unregister
struct pnp_id *pnp_add_id(struct pnp_dev * dev, const char * id)

adds an EISA id to the specified device

Parameters

structpnp_dev*dev
pointer to the desired device
constchar*id
pointer to an EISA id string
intpnp_start_dev(struct pnp_dev * dev)

low-level start of the PnP device

Parameters

structpnp_dev*dev
pointer to the desired device

Description

assumes that resources have already been allocated

intpnp_stop_dev(struct pnp_dev * dev)

low-level disable of the PnP device

Parameters

structpnp_dev*dev
pointer to the desired device

Description

does not free resources

intpnp_activate_dev(struct pnp_dev * dev)

activates a PnP device for use

Parameters

structpnp_dev*dev
pointer to the desired device

Description

does not validate or set resources so be careful.

intpnp_disable_dev(struct pnp_dev * dev)

disables device

Parameters

structpnp_dev*dev
pointer to the desired device

Description

inform the correct pnp protocol so that resources can be used by other devices

intpnp_is_active(struct pnp_dev * dev)

Determines if a device is active based on its current resources

Parameters

structpnp_dev*dev
pointer to the desired PnP device

Userspace IO devices

voiduio_event_notify(structuio_info * info)

trigger an interrupt event

Parameters

structuio_info*info
UIO device capabilities
int__uio_register_device(struct module * owner, structdevice * parent, structuio_info * info)

register a new userspace IO device

Parameters

structmodule*owner
module that creates the new device
structdevice*parent
parent device
structuio_info*info
UIO device capabilities

Description

returns zero on success or a negative error code.

int__devm_uio_register_device(struct module * owner, structdevice * parent, structuio_info * info)

Resource managed uio_register_device()

Parameters

structmodule*owner
module that creates the new device
structdevice*parent
parent device
structuio_info*info
UIO device capabilities

Description

returns zero on success or a negative error code.

voiduio_unregister_device(structuio_info * info)

unregister a industrial IO device

Parameters

structuio_info*info
UIO device capabilities
structuio_mem

description of a UIO memory region

Definition

struct uio_mem {  const char              *name;  phys_addr_t addr;  unsigned long           offs;  resource_size_t size;  int memtype;  void __iomem            *internal_addr;  struct uio_map          *map;};

Members

name
name of the memory region for identification
addr
address of the device’s memory rounded to pagesize (phys_addr is used since addr can belogical, virtual, or physical & phys_addr_tshould always be large enough to handle any ofthe address types)
offs
offset of device memory within the page
size
size of IO (multiple of page size)
memtype
type of memory addr points to
internal_addr
ioremap-ped version of addr, for driver internal use
map
for use by the UIO core only.
structuio_port

description of a UIO port region

Definition

struct uio_port {  const char              *name;  unsigned long           start;  unsigned long           size;  int porttype;  struct uio_portio       *portio;};

Members

name
name of the port region for identification
start
start of port region
size
size of port region
porttype
type of port (see UIO_PORT_* below)
portio
for use by the UIO core only.
structuio_info

UIO device capabilities

Definition

struct uio_info {  struct uio_device       *uio_dev;  const char              *name;  const char              *version;  struct uio_mem          mem[MAX_UIO_MAPS];  struct uio_port         port[MAX_UIO_PORT_REGIONS];  long irq;  unsigned long           irq_flags;  void *priv;  irqreturn_t (*handler)(int irq, struct uio_info *dev_info);  int (*mmap)(struct uio_info *info, struct vm_area_struct *vma);  int (*open)(struct uio_info *info, struct inode *inode);  int (*release)(struct uio_info *info, struct inode *inode);  int (*irqcontrol)(struct uio_info *info, s32 irq_on);};

Members

uio_dev
the UIO device this info belongs to
name
device name
version
device driver version
mem
list of mappable memory regions, size==0 for end of list
port
list of port regions, size==0 for end of list
irq
interrupt number or UIO_IRQ_CUSTOM
irq_flags
flags forrequest_irq()
priv
optional private data
handler
the device’s irq handler
mmap
mmap operation for this uio device
open
open operation for this uio device
release
release operation for this uio device
irqcontrol
disable/enable irqs when 0/1 is written to /dev/uioX