Device drivers infrastructure

The Basic Device Driver-Model Structures

struct subsys_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

subsystem 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 can attach to a subsystem and its devices. Unlike drivers, they do not exclusively claim or control devices. Interfaces usually represent a specific functionality of a subsystem/class of devices.

devm_alloc_percpu

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 is automatically freed on driver detach.

Return

Pointer to allocated memory on success, NULL on failure.

enum dl_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.

enum device_removable

Whether the device is removable. The criteria for a device to be classified as removable is determined by its subsystem or bus.

Constants

DEVICE_REMOVABLE_NOT_SUPPORTED

This attribute is not supported for this device (default).

DEVICE_REMOVABLE_UNKNOWN

Device location is Unknown.

DEVICE_FIXED

Device is not removable by the user.

DEVICE_REMOVABLE

Device is removable by the user.

Device data related to device links.

Definition

struct dev_links_info {
  struct list_head suppliers;
  struct list_head consumers;
  struct list_head defer_sync;
  enum dl_dev_state status;
};

Members

suppliers

List of links to supplier devices.

consumers

List of links to consumer devices.

defer_sync

Hook to global list of devices that have deferred sync_state.

status

Driver status information.

struct device

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_ENERGY_MODEL;
  struct em_perf_domain   *em_pd;
#endif;
#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;
  raw_spinlock_t msi_lock;
  struct list_head        msi_list;
#endif;
#ifdef CONFIG_DMA_OPS;
  const struct dma_map_ops *dma_ops;
#endif;
  u64 *dma_mask;
  u64 coherent_dma_mask;
  u64 bus_dma_limit;
  const struct bus_dma_region *dma_range_map;
  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;
#ifdef CONFIG_SWIOTLB;
  struct io_tlb_mem *dma_io_tlb_mem;
#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;
  enum device_removable   removable;
  bool offline_disabled:1;
  bool offline:1;
  bool of_node_reused:1;
  bool state_synced:1;
  bool can_match: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;
#ifdef CONFIG_DMA_OPS_BYPASS;
  bool dma_ops_bypass : 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 host controller. 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-specific information.

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 a peer 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 Device Power Management Basics for details.

pm_domain

Provide callbacks that are executed during system suspend, hibernation, system resume and during runtime PM transitions along with subsystem-level and driver-level callbacks.

em_pd

device’s energy model performance domain

msi_domain

The generic MSI domain this device is using.

pins

For device pin management. See PINCTRL (PIN CONTROL) subsystem for details.

msi_lock

Lock to protect MSI mask cache and mask register

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 all hardware supports 64-bit addresses for consistent allocations such descriptors.

bus_dma_limit

Limit of an upstream bridge or bus which imposes a smaller DMA limit than the device itself supports.

dma_range_map

map for DMA memory ranges relative to that of RAM

dma_parms

A low level driver may set these to teach IOMMU code about segment limitations.

dma_pools

Dma pools (if dma’ble device).

dma_mem

Internal for coherent mem override.

cma_area

Contiguous memory area for dma allocations

dma_io_tlb_mem

Pointer to the swiotlb pool used. Not for driver use.

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 have gone away. This should be set by the allocator of the device (i.e. the bus driver that discovered the device).

iommu_group

IOMMU group the device belongs to.

iommu

Per device generic IOMMU runtime data

removable

Whether the device can be removed from the system. This should be set by the subsystem / bus driver that discovered the device.

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 ancestor device.

state_synced

The hardware state of this device has been synced to match the software state of this device by calling the driver/bus sync_state() callback.

can_match

The device has matched with a driver at least once or it is in a bus (like AMBA) which can’t check for matching drivers until other devices probe successfully.

dma_coherent

this particular device is dma coherent, even if the architecture supports non-coherent devices.

dma_ops_bypass

If set to true then the dma_ops are bypassed for the streaming DMA operations (->map_* / ->unmap_* / ->sync_*), and optionall (if the coherent mask is large enough) also for dma allocations. This flag is managed by the dma ops instance from ->dma_supported.

Example

For devices on custom boards, as typical of embedded

and SOC based hardware, Linux often uses platform_data to point to board-specific structures describing devices and how they are wired. That can include what ports are available, chip variants, which GPIO pins act in what additional roles, and so on. This shrinks the “Board Support Packages” (BSPs) and minimizes board-specific #ifdefs in drivers.

Description

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

Device link representation.

Definition

struct device_link {
  struct device *supplier;
  struct list_head s_node;
  struct device *consumer;
  struct list_head c_node;
  struct device link_dev;
  enum device_link_state status;
  u32 flags;
  refcount_t rpm_active;
  struct kref kref;
  struct work_struct rm_work;
  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.

link_dev

device used to expose link details in sysfs

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.

rm_work

Work structure used for removing the link.

supplier_preactivated

Supplier has been made active before consumer probe.

bool device_iommu_mapped(struct device *dev)

Returns true when the device DMA is translated by an IOMMU

Parameters

struct device *dev

Device to perform the check on

const char *dev_bus_name(const struct device *dev)

Return a device’s bus/class name, if at all possible

Parameters

const struct device *dev

struct device to get the bus/class name of

Description

Will return the name of the bus/class the device is attached to. If it is not attached to a bus/class, an empty string will be returned.

Device Drivers Base

void driver_init(void)

initialize driver model.

Parameters

void

no arguments

Description

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

int driver_for_each_device(struct device_driver *drv, struct device *start, void *data, int (*fn)(struct device*, void*))

Iterator for devices bound to a driver.

Parameters

struct device_driver *drv

Driver we’re iterating.

struct device *start

Device to begin with

void *data

Data to pass to the callback.

int (*fn)(struct device *, void *)

Function to call for each device.

Description

Iterate over the drv’s list of devices calling fn for each one.

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

device iterator for locating a particular device.

Parameters

struct device_driver *drv

The device’s driver

struct device *start

Device to begin with

const void *data

Data to pass to match function

int (*match)(struct device *dev, const void *data)

Callback function to check device

Description

This is similar to the driver_for_each_device() function above, but it returns a reference to a device that is ‘found’ for later use, as determined by the match callback.

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

int driver_create_file(struct device_driver *drv, const struct driver_attribute *attr)

create sysfs file for driver.

Parameters

struct device_driver *drv

driver.

const struct driver_attribute *attr

driver attribute descriptor.

void driver_remove_file(struct device_driver *drv, const struct driver_attribute *attr)

remove sysfs file for driver.

Parameters

struct device_driver *drv

driver.

const struct driver_attribute *attr

driver attribute descriptor.

int driver_register(struct device_driver *drv)

register driver with bus

Parameters

struct device_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 bus structures.

void driver_unregister(struct device_driver *drv)

remove driver from system.

Parameters

struct device_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

const char *name

name of the driver.

struct bus_type *bus

bus to scan for the driver.

Description

Call kset_find_obj() to iterate over list of drivers on a bus to find driver by name. Return driver if found.

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

Create a link between two devices.

Parameters

struct device *consumer

Consumer end of the link.

struct device *supplier

Supplier end of the link.

u32 flags

Link flags.

Description

The caller is responsible for the proper synchronization of the link creation with runtime PM. First, setting the DL_FLAG_PM_RUNTIME flag will cause the runtime PM framework to take the link into account. Second, if the DL_FLAG_RPM_ACTIVE flag is set in addition to it, the supplier devices will be forced into the active meta state and reference-counted upon the creation of the link. If DL_FLAG_PM_RUNTIME is not set, DL_FLAG_RPM_ACTIVE will be ignored.

If DL_FLAG_STATELESS is set in flags, the caller of this function is expected to release the link returned by it directly with the help of either device_link_del() or device_link_remove().

If that flag is not set, however, the caller of this function is handing the management of the link over to the driver core entirely and its return value can 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 link flags can be used to indicate to the driver core when the link can be safely deleted. Namely, setting one of them in flags indicates to the driver core that the link is not going to be used (by the given caller of this function) after unbinding the consumer or supplier driver, respectively, from its device, 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 (either the consumer or the supplier) is unregistered.

Also, if DL_FLAG_STATELESS, DL_FLAG_AUTOREMOVE_CONSUMER and DL_FLAG_AUTOREMOVE_SUPPLIER are not set in flags (that is, a persistent managed device link is being added), the DL_FLAG_AUTOPROBE_CONSUMER flag can be used to request the driver core to automatically probe for a consumer driver 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 in flags at the same time is invalid and will cause NULL to be returned upfront. However, if a device link between the given consumer and supplier pair exists already when this function is called for them, the existing link will be returned regardless of its current type and status (the link’s flags may be modified then). The caller of this function is then expected to treat the link as though it has just been created, so (in particular) if DL_FLAG_STATELESS was passed in flags, the link needs to be released explicitly when not needed any more (as stated above).

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

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

Delete a stateless link between two devices.

Parameters

struct device_link *link

Device link to delete.

Description

The caller must ensure proper synchronization of this function with runtime PM. 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 removal and calling device_link_del() is then no longer allowed.

Delete a stateless link between two devices.

Parameters

void *consumer

Consumer end of the link.

struct device *supplier

Supplier end of the link.

Description

The caller must ensure proper synchronization of this function with runtime PM.

const char *dev_driver_string(const struct device *dev)

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

Parameters

const struct device *dev

struct device to get the name of

Description

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

int devm_device_add_group(struct device *dev, const struct attribute_group *grp)

given a device, create a managed attribute group

Parameters

struct device *dev

The device to create the group for

const struct attribute_group *grp

The attribute group to create

Description

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

Returns 0 on success or error code on failure.

void devm_device_remove_group(struct device *dev, const struct attribute_group *grp)

remove a managed group from a device

Parameters

struct device *dev

device to remove the group from

const struct attribute_group *grp

group to remove

Description

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

int devm_device_add_groups(struct device *dev, const struct attribute_group **groups)

create a bunch of managed attribute groups

Parameters

struct device *dev

The device to create the group for

const struct attribute_group **groups

The attribute groups to create, NULL terminated

Description

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

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

void devm_device_remove_groups(struct device *dev, const struct attribute_group **groups)

remove a list of managed groups

Parameters

struct device *dev

The device for the groups to be removed from

const struct attribute_group **groups

NULL terminated list of groups to be removed

Description

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

int device_create_file(struct device *dev, const struct device_attribute *attr)

create sysfs attribute file for device.

Parameters

struct device *dev

device.

const struct device_attribute *attr

device attribute descriptor.

void device_remove_file(struct device *dev, const struct device_attribute *attr)

remove sysfs attribute file.

Parameters

struct device *dev

device.

const struct device_attribute *attr

device attribute descriptor.

bool device_remove_file_self(struct device *dev, const struct device_attribute *attr)

remove sysfs attribute file from its own method.

Parameters

struct device *dev

device.

const struct device_attribute *attr

device attribute descriptor.

Description

See kernfs_remove_self() for details.

int device_create_bin_file(struct device *dev, const struct bin_attribute *attr)

create sysfs binary attribute file for device.

Parameters

struct device *dev

device.

const struct bin_attribute *attr

device binary attribute descriptor.

void device_remove_bin_file(struct device *dev, const struct bin_attribute *attr)

remove sysfs binary attribute file

Parameters

struct device *dev

device.

const struct bin_attribute *attr

device binary attribute descriptor.

void device_initialize(struct device *dev)

init device structure.

Parameters

struct device *dev

device.

Description

This prepares the device for use by other layers by initializing its fields. It is the first half of device_register(), if called by that function, though it can also be called separately, so one may use dev’s fields. In particular, get_device()/put_device() may be used for reference counting of dev after calling this function.

All fields in dev must be initialized by the caller to 0, except for those explicitly set to some other value. The simplest approach is to use kzalloc() to allocate the structure containing dev.

NOTE

Use put_device() to give up your reference instead of freeing dev directly once you have called this function.

int dev_set_name(struct device *dev, const char *fmt, ...)

set a device name

Parameters

struct device *dev

device

const char *fmt

format string for the device’s name

...

variable arguments

int device_add(struct device *dev)

add device to device hierarchy.

Parameters

struct device *dev

device.

Description

This is part 2 of device_register(), though may be called separately _iff_ device_initialize() has been called separately.

This adds dev to the kobject hierarchy via kobject_add(), adds it to the global and sibling lists for the device, then adds it to the other relevant subsystems of the driver model.

Do not call this routine or device_register() more than once for any device structure. The driver model core is not designed to work with devices that get unregistered and then spring back to life. (Among other things, it’s very hard to guarantee that all references to the previous incarnation of dev have been dropped.) Allocate and register a fresh new struct device instead.

Rule of thumb is: if device_add() succeeds, you should call device_del() when you want to get rid of it. If device_add() has not succeeded, use only put_device() to drop the reference count.

NOTE

_Never_ directly free dev after calling this function, even if it returned an error! Always use put_device() to give up your reference instead.

int device_register(struct device *dev)

register a device with the system.

Parameters

struct device *dev

pointer to the device structure

Description

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

For more information, see the kerneldoc for device_initialize() and device_add().

NOTE

_Never_ directly free dev after calling this function, even if it returned an error! Always use put_device() to give up the reference initialized in this function instead.

struct device *get_device(struct device *dev)

increment reference count for device.

Parameters

struct device *dev

device.

Description

This simply forwards the call to kobject_get(), though we do take care to provide for the case that we get a NULL pointer passed in.

void put_device(struct device *dev)

decrement reference count.

Parameters

struct device *dev

device in question.

void device_del(struct device *dev)

delete device from system.

Parameters

struct device *dev

device.

Description

This is the first part of the device unregistration sequence. This removes the device from the lists we control from here, has it removed from the other driver model subsystems it was added to in device_add(), and removes it from the kobject hierarchy.

NOTE

this should be called manually _iff_ device_add() was also called manually.

void device_unregister(struct device *dev)

unregister device from system.

Parameters

struct device *dev

device going away.

Description

We do this in two parts, like we do device_register(). First, we remove it from all the subsystems with device_del(), then we decrement the reference count via put_device(). If that is the final reference count, the device will be cleaned up via device_release() above. Otherwise, the structure will stick around until the final reference to the device is dropped.

int device_for_each_child(struct device *parent, void *data, int (*fn)(struct device *dev, void *data))

device child iterator.

Parameters

struct device *parent

parent struct device.

void *data

data for the callback.

int (*fn)(struct device *dev, void *data)

function to be called for each device.

Description

Iterate over parent’s child devices, and call fn for each, passing it data.

We check the return of fn each time. If it returns anything other than 0, we break out and return that value.

int device_for_each_child_reverse(struct device *parent, void *data, int (*fn)(struct device *dev, void *data))

device child iterator in reversed order.

Parameters

struct device *parent

parent struct device.

void *data

data for the callback.

int (*fn)(struct device *dev, void *data)

function to be called for each device.

Description

Iterate over parent’s child devices, and call fn for each, passing it data.

We check the return of fn each time. If it returns anything other than 0, we break out and return that value.

struct device *device_find_child(struct device *parent, void *data, int (*match)(struct device *dev, void *data))

device iterator for locating a particular device.

Parameters

struct device *parent

parent struct device

void *data

Data to pass to match function

int (*match)(struct device *dev, void *data)

Callback function to check device

Description

This is similar to the device_for_each_child() function above, but it returns a reference to a device that is ‘found’ for later use, as determined by the match callback.

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

NOTE

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

struct device *device_find_child_by_name(struct device *parent, const char *name)

device iterator for locating a child device.

Parameters

struct device *parent

parent struct device

const char *name

name of the child device

Description

This is similar to the device_find_child() function above, but it returns a reference to a device that has the name name.

NOTE

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

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

allocate and register a root device

Parameters

const char *name

root device name

struct module *owner

owner module of the root device, usually THIS_MODULE

Description

This function allocates a root device and registers it using device_register(). In order to free the returned device, use root_device_unregister().

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

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

Returns struct device pointer on success, or ERR_PTR() on error.

Note

You probably want to use root_device_register().

void root_device_unregister(struct device *dev)

unregister and free a root device

Parameters

struct device *dev

device going away

Description

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

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

creates a device and registers it with sysfs

Parameters

struct class *class

pointer to the struct class that this device should be registered to

struct device *parent

pointer to the parent struct device of this new device, if any

dev_t devt

the dev_t for the char device to be added

void *drvdata

the data to be added to the device for callbacks

const char *fmt

string for the device’s name

...

variable arguments

Description

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

A “dev” file will be created, showing the dev_t for the device, if the dev_t is not 0,0. If a pointer to a parent struct device is passed in, the newly created struct 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 this pointer.

Returns struct device pointer on success, or ERR_PTR() on error.

Note

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

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

creates a device and registers it with sysfs

Parameters

struct class *class

pointer to the struct class that this device should be registered to

struct device *parent

pointer to the parent struct device of this new device, if any

dev_t devt

the dev_t for the char device to be added

void *drvdata

the data to be added to the device for callbacks

const struct attribute_group **groups

NULL-terminated list of attribute groups to be created

const char *fmt

string for the device’s name

...

variable arguments

Description

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

A “dev” file will be created, showing the dev_t for the device, if the dev_t is not 0,0. If a pointer to a parent struct device is passed in, the newly created struct 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 this pointer.

Returns struct device pointer on success, or ERR_PTR() on error.

Note

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

void device_destroy(struct class *class, dev_t devt)

removes a device that was created with device_create()

Parameters

struct class *class

pointer to the struct class that this device was registered with

dev_t devt

the dev_t of the device that was previously registered

Description

This call unregisters and cleans up a device that was created with a call to device_create().

int device_rename(struct device *dev, const char *new_name)

renames a device

Parameters

struct device *dev

the pointer to the struct device to be renamed

const char *new_name

the new name of the device

Description

It is the responsibility of the caller to provide mutual exclusion between two different calls of device_rename on the same device to ensure that new_name is valid and won’t conflict with other devices.

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

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

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

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

Note

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

int device_move(struct device *dev, struct device *new_parent, enum dpm_order dpm_order)

moves a device to a new parent

Parameters

struct device *dev

the pointer to the struct device to be moved

struct device *new_parent

the new parent of the device (can be NULL)

enum dpm_order dpm_order

how to reorder the dpm_list

int device_change_owner(struct device *dev, kuid_t kuid, kgid_t kgid)

change the owner of an existing device.

Parameters

struct device *dev

device.

kuid_t kuid

new owner’s kuid

kgid_t kgid

new owner’s kgid

Description

This changes the owner of dev and its corresponding sysfs entries to kuid/kgid. This function closely mirrors how dev was added via driver core.

Returns 0 on success or error code on failure.

int dev_err_probe(const struct device *dev, int err, const char *fmt, ...)

probe error check and log helper

Parameters

const struct device *dev

the pointer to the struct device

int err

error value to test

const char *fmt

printf-style format string

...

arguments as specified in the format string

Description

This helper implements common pattern present in probe functions for error checking: print debug or error message depending if the error value is -EPROBE_DEFER and propagate error upwards. In case of -EPROBE_DEFER it sets also defer probe reason, which can be checked later by reading devices_deferred debugfs attribute. It replaces code sequence:

if (err != -EPROBE_DEFER)
        dev_err(dev, ...);
else
        dev_dbg(dev, ...);
return err;

with:

return dev_err_probe(dev, err, ...);

Note that it is deemed acceptable to use this function for error prints during probe even if the err is known to never be -EPROBE_DEFER. The benefit compared to a normal dev_err() is the standardized format of the error code and the fact that the error code is returned.

Returns err.

void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode)

Change the primary firmware node of a given device.

Parameters

struct device *dev

Device to handle.

struct fwnode_handle *fwnode

New primary firmware node of the device.

Description

Set the device’s firmware node pointer to fwnode, but if a secondary firmware node of the device is present, preserve it.

Valid fwnode cases are:
  • primary –> secondary –> -ENODEV

  • primary –> NULL

  • secondary –> -ENODEV

  • NULL

void set_secondary_fwnode(struct device *dev, struct fwnode_handle *fwnode)

Change the secondary firmware node of a given device.

Parameters

struct device *dev

Device to handle.

struct fwnode_handle *fwnode

New secondary firmware node of the device.

Description

If a primary firmware node of the device is present, set its secondary pointer to fwnode. Otherwise, set the device’s firmware node pointer to fwnode.

void device_set_of_node_from_dev(struct device *dev, const struct device *dev2)

reuse device-tree node of another device

Parameters

struct device *dev

device whose device-tree node is being set

const struct device *dev2

device whose device-tree node is being reused

Description

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

void register_syscore_ops(struct syscore_ops *ops)

Register a set of system core operations.

Parameters

struct syscore_ops *ops

System core operations to register.

void unregister_syscore_ops(struct syscore_ops *ops)

Unregister a set of system core operations.

Parameters

struct syscore_ops *ops

System core operations to unregister.

int syscore_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.

void syscore_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

struct module *owner

pointer to the module that is to “own” this struct class

const char *name

pointer to a string for the name of this class.

struct lock_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 used in calls to device_create().

Returns struct class pointer on success, or ERR_PTR() on error.

Note, the pointer created here is to be destroyed when finished by making a call to class_destroy().

void class_destroy(struct class *cls)

destroys a struct class structure

Parameters

struct class *cls

pointer to the struct class that is to be destroyed

Description

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

void class_dev_iter_init(struct class_dev_iter *iter, struct class *class, struct device *start, const struct device_type *type)

initialize class device iterator

Parameters

struct class_dev_iter *iter

class iterator to initialize

struct class *class

the class we wanna iterate over

struct device *start

the device to start iterating from, if any

const struct device_type *type

device_type of the devices to iterate over, NULL for all

Description

Initialize class iterator iter such that it iterates over devices of class. If start is set, the list iteration will start there, otherwise if it is NULL, the iteration starts at the beginning of the list.

struct device *class_dev_iter_next(struct class_dev_iter *iter)

iterate to the next device

Parameters

struct class_dev_iter *iter

class iterator to proceed

Description

Proceed iter to the next device and return it. Returns NULL if iteration is complete.

The returned device is referenced and won’t be released till iterator is proceed to the next device or exited. The caller is free to do whatever it wants to do with the device including calling back into class code.

void class_dev_iter_exit(struct class_dev_iter *iter)

finish iteration

Parameters

struct class_dev_iter *iter

class iterator to finish

Description

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

int class_for_each_device(struct class *class, struct device *start, void *data, int (*fn)(struct device*, void*))

device iterator

Parameters

struct class *class

the class we’re iterating

struct device *start

the device to start with in the list, if any.

void *data

data for the callback

int (*fn)(struct device *, void *)

function to be called for each device

Description

Iterate over class’s list of devices, and call fn for each, passing it data. If start is set, the list iteration will start there, otherwise if it is NULL, the iteration starts at the beginning of the list.

We check the return of fn each time. If it returns anything other than 0, we break out and return that value.

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

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

device iterator for locating a particular device

Parameters

struct class *class

the class we’re iterating

struct device *start

Device to begin with

const void *data

data for the match function

int (*match)(struct device *, const void *)

function to check device

Description

This is similar to the class_for_each_dev() function above, but it returns a reference to a device that is ‘found’ for later use, as determined by the match callback.

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

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

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

struct class_compat *class_compat_register(const char *name)

register a compatibility class

Parameters

const char *name

the name of the class

Description

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

void class_compat_unregister(struct class_compat *cls)

unregister a compatibility class

Parameters

struct class_compat *cls

the class to unregister

create a compatibility class device link to a bus device

Parameters

struct class_compat *cls

the compatibility class

struct device *dev

the target bus device

struct device *device_link

an optional device to which a “device” link should be created

remove a compatibility class device link to a bus device

Parameters

struct class_compat *cls

the compatibility class

struct device *dev

the target bus device

struct device *device_link

an optional device to which a “device” link was previously created

struct node_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 int            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

void node_set_perf_attrs(unsigned int nid, struct node_hmem_attrs *hmem_attrs, unsigned int access)

Set the performance values for given access class

Parameters

unsigned int nid

Node identifier to be set

struct node_hmem_attrs *hmem_attrs

Heterogeneous memory performance attributes

unsigned int access

The access class the for the given attributes

struct node_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

void node_add_cache(unsigned int nid, struct node_cache_attrs *cache_attrs)

add cache attribute to a memory node

Parameters

unsigned int nid

Node identifier that has new cache attributes

struct node_cache_attrs *cache_attrs

Attributes for the cache being added

void unregister_node(struct node *node)

unregister a node device

Parameters

struct node *node

node going away

Description

Unregisters a node device node. All the devices on the node must be unregistered before calling this function.

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

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

Parameters

unsigned int mem_nid

Memory node number

unsigned int cpu_nid

Cpu node number

unsigned int access

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 memory initiator nodes can access memory targets at a given ranked access class.

int transport_class_register(struct transport_class *tclass)

register an initial transport class

Parameters

struct transport_class *tclass

a pointer to the transport class structure to be initialised

Description

The transport class contains an embedded class which is used to identify it. The caller should initialise this structure with zeros and then generic class must have been initialised with the actual transport class unique name. There’s a macro DECLARE_TRANSPORT_CLASS() to do this (declared classes still must be registered).

Returns 0 on success or error on failure.

void transport_class_unregister(struct transport_class *tclass)

unregister a previously registered class

Parameters

struct transport_class *tclass

The transport class to unregister

Description

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

int anon_transport_class_register(struct anon_transport_class *atc)

register an anonymous class

Parameters

struct anon_transport_class *atc

The anon transport class to register

Description

The anonymous transport class contains both a transport class and a container. The idea of an anonymous class is that it never actually has any device attributes associated with it (and thus saves on container storage). So it can only be used for triggering events. Use prezero and then use DECLARE_ANON_TRANSPORT_CLASS() to initialise the anon transport class storage.

void anon_transport_class_unregister(struct anon_transport_class *atc)

unregister an anon class

Parameters

struct anon_transport_class *atc

Pointer to the anon transport class to unregister

Description

Must be called prior to deallocating the memory for the anon transport class.

void transport_setup_device(struct device *dev)

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

Parameters

struct device *dev

the generic device representing the entity being added

Description

Usually, dev represents some component in the HBA system (either the HBA itself or a device remote across the HBA bus). This routine is simply a trigger point to see if any set of transport classes wishes to associate with the added device. This allocates storage for the class device and initialises it, but does not yet add it to the system or add attributes to it (you do this with transport_add_device). If you have no need for a separate setup and add operations, use transport_register_device (see transport_class.h).

int transport_add_device(struct device *dev)

declare a new dev for transport class association

Parameters

struct device *dev

the generic device representing the entity being added

Description

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

void transport_configure_device(struct device *dev)

configure an already set up device

Parameters

struct device *dev

generic device representing device to be configured

Description

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

void transport_remove_device(struct device *dev)

remove the visibility of a device

Parameters

struct device *dev

generic device to remove

Description

This call removes the visibility of the device (to the user from sysfs), but does not destroy it. To eliminate a device entirely you must also call transport_destroy_device. If you don’t need to do remove and destroy as separate operations, use transport_unregister_device() (see transport_class.h) which will perform both calls for you.

void transport_destroy_device(struct device *dev)

destroy a removed device

Parameters

struct device *dev

device to eliminate from the transport class.

Description

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

int device_bind_driver(struct device *dev)

bind a driver to one device.

Parameters

struct device *dev

device.

Description

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

Note that this does not modify the bus reference count. Please verify that is accounted for before calling this. (It is ok to call with no other effort from a driver’s probe() method.)

This function must be called with the device lock held.

Callers should prefer to use device_driver_attach() instead.

void wait_for_device_probe(void)

Parameters

void

no arguments

Description

Wait for device probing to be completed.

int device_attach(struct device *dev)

try to attach device to a driver.

Parameters

struct device *dev

device.

Description

Walk the list of drivers that the bus has and call driver_probe_device() for each pair. If a compatible pair 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.

int device_driver_attach(struct device_driver *drv, struct device *dev)

attach a specific driver to a specific device

Parameters

struct device_driver *drv

Driver to attach

struct device *dev

Device to attach it to

Description

Manually attach driver to a device. Will acquire both dev lock and dev->parent lock if needed. Returns 0 on success, -ERR on failure.

int driver_attach(struct device_driver *drv)

try to bind driver to devices.

Parameters

struct device_driver *drv

driver.

Description

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

void device_release_driver(struct device *dev)

manually detach device from driver.

Parameters

struct device *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 with dev->parent lock held, ensure that the device’s consumers are unbound in advance or that their locks can be acquired under the dev->parent lock.

struct platform_device *platform_device_register_resndata(struct device *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

struct device *parent

parent device for the device we’re adding

const char *name

base name of the device we’re adding

int id

instance id

const struct resource *res

set of resources that needs to be allocated for the device

unsigned int num

number of resources

const void *data

platform specific data for this platform device

size_t size

size of platform specific data

Description

Returns struct platform_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

const char *name

base name of the device we’re adding

int id

instance id

const struct resource *res

set of resources that needs to be allocated for the device

unsigned int num

number of resources

Description

This function creates a simple platform device that requires minimal resource and memory management. Canned release function freeing memory allocated for the device allows drivers using such devices to be unloaded without waiting for the last reference to the device to be dropped.

This interface is primarily intended for use with legacy drivers which probe hardware directly. Because such drivers create sysfs device nodes themselves, rather than letting system infrastructure handle such device enumeration 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”.

Returns struct platform_device pointer on success, or ERR_PTR() on error.

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

add a platform-level device with platform-specific data

Parameters

struct device *parent

parent device for the device we’re adding

const char *name

base name of the device we’re adding

int id

instance id

const void *data

platform specific data for this platform device

size_t size

size of platform specific data

Description

This function creates a simple platform device that requires minimal resource and memory management. Canned release function freeing memory allocated for the device allows drivers using such devices to be unloaded without waiting for the last reference to the device to be dropped.

Returns struct platform_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

struct platform_device *dev

platform device

unsigned int type

resource type

unsigned int num

resource index

Return

a pointer to the resource or NULL on failure.

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

struct platform_device *pdev

platform device to use both for memory resource lookup as well as resource management

unsigned int index

resource index

struct resource **res

optional output parameter to store a pointer to the obtained resource.

Return

a pointer to the remapped memory or an ERR_PTR() encoded error code on failure.

void __iomem *devm_platform_ioremap_resource(struct platform_device *pdev, unsigned int index)

call devm_ioremap_resource() for a platform device

Parameters

struct platform_device *pdev

platform device to use both for memory resource lookup as well as resource management

unsigned int index

resource index

Return

a pointer to the remapped memory or an ERR_PTR() encoded error code on failure.

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

struct platform_device *pdev

platform device to use both for memory resource lookup as well as resource management

const char *name

name of the resource

Return

a pointer to the remapped memory or an ERR_PTR() encoded error code on failure.

int platform_get_irq_optional(struct platform_device *dev, unsigned int num)

get an optional IRQ for a device

Parameters

struct platform_device *dev

platform device

unsigned int num

IRQ number index

Description

Gets an IRQ for a platform device. Device drivers should check the return value for errors so as to not pass a negative integer value to the request_irq() APIs. This is the same as platform_get_irq(), except that it does 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.

int platform_get_irq(struct platform_device *dev, unsigned int num)

get an IRQ for a device

Parameters

struct platform_device *dev

platform device

unsigned int num

IRQ number index

Description

Gets an IRQ for a platform device and prints an error message if finding the IRQ fails. Device drivers should check the return value for errors so as to not pass a negative integer value to the request_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.

int platform_irq_count(struct platform_device *dev)

Count the number of IRQs a platform device uses

Parameters

struct platform_device *dev

platform device

Return

Number of IRQs a platform device uses or EPROBE_DEFER

int devm_platform_get_irqs_affinity(struct platform_device *dev, struct irq_affinity *affd, unsigned int minvec, unsigned int maxvec, int **irqs)

devm method to get a set of IRQs for a device using an interrupt affinity descriptor

Parameters

struct platform_device *dev

platform device pointer

struct irq_affinity *affd

affinity descriptor

unsigned int minvec

minimum count of interrupt vectors

unsigned int maxvec

maximum count of interrupt vectors

int **irqs

pointer holder for IRQ numbers

Description

Gets a set of IRQs for a platform device, and updates IRQ afffinty according to the passed affinity descriptor

Return

Number of vectors on success, negative error number on failure.

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

struct platform_device *dev

platform device

unsigned int type

resource type

const char *name

resource name

int platform_get_irq_byname(struct platform_device *dev, const char *name)

get an IRQ for a device by name

Parameters

struct platform_device *dev

platform device

const char *name

IRQ name

Description

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

Return

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

int platform_get_irq_byname_optional(struct platform_device *dev, const char *name)

get an optional IRQ for a device by name

Parameters

struct platform_device *dev

platform device

const char *name

IRQ name

Description

Get an optional IRQ by name like platform_get_irq_byname(). Except that it does not print an error message if an IRQ can not be obtained.

Return

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

int platform_add_devices(struct platform_device **devs, int num)

add a numbers of platform devices

Parameters

struct platform_device **devs

array of platform devices to add

int num

number of platform devices in array

void platform_device_put(struct platform_device *pdev)

destroy a platform device

Parameters

struct platform_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

const char *name

base name of the device we’re adding

int id

instance id

Description

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

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

add resources to a platform device

Parameters

struct platform_device *pdev

platform device allocated by platform_device_alloc to add resources to

const struct resource *res

set of resources that needs to be allocated for the device

unsigned int num

number of resources

Description

Add a copy of the resources to the platform device. The memory associated with the resources will be freed when the platform device is released.

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

add platform-specific data to a platform device

Parameters

struct platform_device *pdev

platform device allocated by platform_device_alloc to add resources to

const void *data

platform specific data for this platform device

size_t size

size of platform specific data

Description

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

int platform_device_add(struct platform_device *pdev)

add a platform device to device hierarchy

Parameters

struct platform_device *pdev

platform device we’re adding

Description

This is part 2 of platform_device_register(), though may be called separately _iff_ pdev was allocated by platform_device_alloc().

void platform_device_del(struct platform_device *pdev)

remove a platform-level device

Parameters

struct platform_device *pdev

platform device we’re removing

Description

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

int platform_device_register(struct platform_device *pdev)

add a platform-level device

Parameters

struct platform_device *pdev

platform device we’re adding

void platform_device_unregister(struct platform_device *pdev)

unregister a platform-level device

Parameters

struct platform_device *pdev

platform device we’re unregistering

Description

Unregistration is done in 2 steps. First we release all resources and remove it from the subsystem, then we drop reference count by calling platform_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

const struct platform_device_info *pdevinfo

data used to create device

Description

Returns struct platform_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

struct platform_driver *drv

platform driver structure

struct module *owner

owning module/driver

void platform_driver_unregister(struct platform_driver *drv)

unregister a driver for platform-level devices

Parameters

struct platform_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

struct platform_driver *drv

platform driver structure

int (*probe)(struct platform_device *)

the driver probe routine, probably from an __init section

struct module *module

module which will be the owner of the driver

Description

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

One typical use for this would be with drivers for controllers integrated into system-on-chip processors, where the controller devices have been configured 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 returns a 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

struct platform_driver *driver

platform driver structure

int (*probe)(struct platform_device *)

the driver probe routine, probably from an __init section

struct resource *res

set of resources that needs to be allocated for the device

unsigned int n_res

number of resources

const void *data

platform specific data for this platform device

size_t size

size of platform specific data

struct module *module

module which will be the owner of the driver

Description

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

Returns struct platform_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

struct platform_driver * const *drivers

an array of drivers to register

unsigned int count

the number of drivers to register

struct module *owner

module owning the drivers

Description

Registers platform drivers specified by an array. On failure to register a driver, all previously registered drivers will be unregistered. Callers of this API should use platform_unregister_drivers() to unregister drivers in the reverse order.

Return

0 on success or a negative error code on failure.

void platform_unregister_drivers(struct platform_driver *const *drivers, unsigned int count)

unregister an array of platform drivers

Parameters

struct platform_driver * const *drivers

an array of drivers to unregister

unsigned int count

the number of drivers to unregister

Description

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

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

Find a platform device with a given driver.

Parameters

struct device *start

The device to start the search from.

const struct device_driver *drv

The device driver to look for.

int bus_for_each_dev(struct bus_type *bus, struct device *start, void *data, int (*fn)(struct device*, void*))

device iterator.

Parameters

struct bus_type *bus

bus type.

struct device *start

device to start iterating from.

void *data

data for the callback.

int (*fn)(struct device *, void *)

function to be called for each device.

Description

Iterate over bus’s list of devices, and call fn for each, passing it data. If start is not NULL, we use that device to begin iterating from.

We check the return of fn each time. If it returns anything other than 0, we break out and return that value.

NOTE

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

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

device iterator for locating a particular device.

Parameters

struct bus_type *bus

bus type

struct device *start

Device to begin with

const void *data

Data to pass to match function

int (*match)(struct device *dev, const void *data)

Callback function to check device

Description

This is similar to the bus_for_each_dev() function above, but it returns a reference to a device that is ‘found’ for later use, as determined by the match callback.

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

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

find a device with a specific enumeration number

Parameters

struct bus_type *subsys

subsystem

unsigned int id

index ‘id’ in struct device

struct device *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 for the returned object is taken.

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

driver iterator

Parameters

struct bus_type *bus

bus we’re dealing with.

struct device_driver *start

driver to start iterating on.

void *data

data to pass to the callback.

int (*fn)(struct device_driver *, void *)

function to call for each driver.

Description

This is nearly identical to the device iterator above. We iterate over each driver that belongs to bus, and call fn for each. If fn returns anything but 0, we break out and return it. If start is not NULL, we use it as the head of the list.

NOTE

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

int bus_rescan_devices(struct bus_type *bus)

rescan devices on the bus for possible drivers

Parameters

struct bus_type *bus

the bus to scan.

Description

This function will look for devices on the bus with no driver attached and rescan it against existing drivers to see if it matches any by calling device_attach() for the unbound devices.

int device_reprobe(struct device *dev)

remove driver for a device and probe for a new driver

Parameters

struct device *dev

the device to reprobe

Description

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

int bus_register(struct bus_type *bus)

register a driver-core subsystem

Parameters

struct bus_type *bus

bus to register

Description

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

void bus_unregister(struct bus_type *bus)

remove a bus from the system

Parameters

struct bus_type *bus

bus.

Description

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

void subsys_dev_iter_init(struct subsys_dev_iter *iter, struct bus_type *subsys, struct device *start, const struct device_type *type)

initialize subsys device iterator

Parameters

struct subsys_dev_iter *iter

subsys iterator to initialize

struct bus_type *subsys

the subsys we wanna iterate over

struct device *start

the device to start iterating from, if any

const struct device_type *type

device_type of the devices to iterate over, NULL for all

Description

Initialize subsys iterator iter such that it iterates over devices of subsys. If start is set, the list iteration will start there, otherwise if it is NULL, the iteration starts at the beginning of the list.

struct device *subsys_dev_iter_next(struct subsys_dev_iter *iter)

iterate to the next device

Parameters

struct subsys_dev_iter *iter

subsys iterator to proceed

Description

Proceed iter to the next device and return it. Returns NULL if iteration is complete.

The returned device is referenced and won’t be released till iterator is proceed to the next device or exited. The caller is free to do whatever it wants to do with the device including calling back into subsys code.

void subsys_dev_iter_exit(struct subsys_dev_iter *iter)

finish iteration

Parameters

struct subsys_dev_iter *iter

subsys iterator to finish

Description

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

int subsys_system_register(struct bus_type *subsys, const struct attribute_group **groups)

register a subsystem at /sys/devices/system/

Parameters

struct bus_type *subsys

system subsystem

const struct attribute_group **groups

default attributes for the root device

Description

All ‘system’ subsystems have a /sys/devices/system/<name> root device with the name of the subsystem. The root device can carry subsystem- wide attributes. All registered devices are below this single root device and are named after the subsystem with a simple enumeration number 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 compatibility with bad ideas only. New subsystems should use plain subsystems; and add the subsystem-wide attributes should be added to the subsystem directory itself and not some create fake root-device placed in /sys/devices/system/<name>.

int subsys_virtual_register(struct bus_type *subsys, const struct attribute_group **groups)

register a subsystem at /sys/devices/virtual/

Parameters

struct bus_type *subsys

virtual subsystem

const struct attribute_group **groups

default attributes for the root device

Description

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

Device Drivers DMA Management

void dmam_free_coherent(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle)

Managed dma_free_coherent()

Parameters

struct device *dev

Device to free coherent memory for

size_t size

Size of allocation

void *vaddr

Virtual address of the memory to free

dma_addr_t dma_handle

DMA handle of the memory to free

Description

Managed dma_free_coherent().

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

Managed dma_alloc_attrs()

Parameters

struct device *dev

Device to allocate non_coherent memory for

size_t size

Size of allocation

dma_addr_t *dma_handle

Out argument for allocated DMA handle

gfp_t gfp

Allocation flags

unsigned long attrs

Flags in the DMA_ATTR_* namespace.

Description

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

Return

Pointer to allocated memory on success, NULL on failure.

unsigned int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction dir, unsigned long attrs)

Map the given buffer for DMA

Parameters

struct device *dev

The device for which to perform the DMA operation

struct scatterlist *sg

The sg_table object describing the buffer

int nents

Number of entries to map

enum dma_data_direction dir

DMA direction

unsigned long attrs

Optional DMA attributes for the map operation

Description

Maps a buffer described by a scatterlist passed in the sg argument with nents segments for the dir DMA operation by the dev device.

Returns the number of mapped entries (which can be less than nents) on success. Zero is returned for any error.

dma_unmap_sg_attrs() should be used to unmap the buffer with the original sg and original nents (not the value returned by this funciton).

int dma_map_sgtable(struct device *dev, struct sg_table *sgt, enum dma_data_direction dir, unsigned long attrs)

Map the given buffer for DMA

Parameters

struct device *dev

The device for which to perform the DMA operation

struct sg_table *sgt

The sg_table object describing the buffer

enum dma_data_direction dir

DMA direction

unsigned long attrs

Optional DMA attributes for the map operation

Description

Maps a buffer described by a scatterlist stored in the given sg_table object for the dir DMA operation by the dev device. After success, the ownership for the buffer is transferred to the DMA domain. One has to call dma_sync_sgtable_for_cpu() or dma_unmap_sgtable() to move the ownership of the buffer back to the CPU domain before touching the buffer by the CPU.

Returns 0 on success or a negative error code on error. The following error codes are supported with the given meaning:

-EINVAL

An invalid argument, unaligned access or other error in usage. Will not succeed if retried.

-ENOMEM

Insufficient resources (like memory or IOVA space) to complete the mapping. Should succeed if retried later.

-EIO

Legacy error code with an unknown meaning. eg. this is returned if a lower level call returned DMA_MAPPING_ERROR.

bool dma_can_mmap(struct device *dev)

check if a given device supports dma_mmap_*

Parameters

struct device *dev

device to check

Description

Returns true if dev supports dma_mmap_coherent() and dma_mmap_attrs() to map DMA allocations to userspace.

int dma_mmap_attrs(struct device *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

struct device *dev

valid struct device pointer, or NULL for ISA and EISA-like devices

struct vm_area_struct *vma

vm_area_struct describing requested user mapping

void *cpu_addr

kernel CPU-view address returned from dma_alloc_attrs

dma_addr_t dma_addr

device-view address returned from dma_alloc_attrs

size_t size

size of memory originally requested in dma_alloc_attrs

unsigned long attrs

attributes of mapping properties requested in dma_alloc_attrs

Description

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

Device drivers PnP support

int pnp_register_protocol(struct pnp_protocol *protocol)

adds a pnp protocol to the pnp layer

Parameters

struct pnp_protocol *protocol

pointer to the corresponding pnp_protocol structure

Ex protocols: ISAPNP, PNPBIOS, etc

void pnp_unregister_protocol(struct pnp_protocol *protocol)

removes a pnp protocol from the pnp layer

Parameters

struct pnp_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

struct pnp_card_link *clink

pointer to the card link, cannot be NULL

const char *id

pointer to a PnP ID structure that explains the rules for finding the device

struct pnp_dev *from

Starting place to search from. If NULL it will start from the beginning.

void pnp_release_card_device(struct pnp_dev *dev)

call this when the driver no longer needs the device

Parameters

struct pnp_dev *dev

pointer to the PnP device structure

int pnp_register_card_driver(struct pnp_card_driver *drv)

registers a PnP card driver with the PnP Layer

Parameters

struct pnp_card_driver *drv

pointer to the driver to register

void pnp_unregister_card_driver(struct pnp_card_driver *drv)

unregisters a PnP card driver from the PnP Layer

Parameters

struct pnp_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

struct pnp_dev *dev

pointer to the desired device

const char *id

pointer to an EISA id string

int pnp_start_dev(struct pnp_dev *dev)

low-level start of the PnP device

Parameters

struct pnp_dev *dev

pointer to the desired device

Description

assumes that resources have already been allocated

int pnp_stop_dev(struct pnp_dev *dev)

low-level disable of the PnP device

Parameters

struct pnp_dev *dev

pointer to the desired device

Description

does not free resources

int pnp_activate_dev(struct pnp_dev *dev)

activates a PnP device for use

Parameters

struct pnp_dev *dev

pointer to the desired device

Description

does not validate or set resources so be careful.

int pnp_disable_dev(struct pnp_dev *dev)

disables device

Parameters

struct pnp_dev *dev

pointer to the desired device

Description

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

int pnp_is_active(struct pnp_dev *dev)

Determines if a device is active based on its current resources

Parameters

struct pnp_dev *dev

pointer to the desired PnP device

Userspace IO devices

void uio_event_notify(struct uio_info *info)

trigger an interrupt event

Parameters

struct uio_info *info

UIO device capabilities

int __uio_register_device(struct module *owner, struct device *parent, struct uio_info *info)

register a new userspace IO device

Parameters

struct module *owner

module that creates the new device

struct device *parent

parent device

struct uio_info *info

UIO device capabilities

Description

returns zero on success or a negative error code.

int __devm_uio_register_device(struct module *owner, struct device *parent, struct uio_info *info)

Resource managed uio_register_device()

Parameters

struct module *owner

module that creates the new device

struct device *parent

parent device

struct uio_info *info

UIO device capabilities

Description

returns zero on success or a negative error code.

void uio_unregister_device(struct uio_info *info)

unregister a industrial IO device

Parameters

struct uio_info *info

UIO device capabilities

struct uio_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 page size (phys_addr is used since addr can be logical, virtual, or physical & phys_addr_t should always be large enough to handle any of the 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.

struct uio_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.

struct uio_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 for request_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

uio_register_device

uio_register_device (parent, info)

register a new userspace IO device

Parameters

parent

parent device

info

UIO device capabilities

Description

returns zero on success or a negative error code.

devm_uio_register_device

devm_uio_register_device (parent, info)

Resource managed uio_register_device()

Parameters

parent

parent device

info

UIO device capabilities

Description

returns zero on success or a negative error code.