Device drivers infrastructure¶
The Basic Device Driver-Model Structures¶
-
struct
bus_type
¶ The bus type of the device
Definition
struct bus_type {
const char * name;
const char * dev_name;
struct device * dev_root;
struct device_attribute * dev_attrs;
const struct attribute_group ** bus_groups;
const struct attribute_group ** dev_groups;
const struct attribute_group ** drv_groups;
int (* match) (struct device *dev, struct device_driver *drv);
int (* uevent) (struct device *dev, struct kobj_uevent_env *env);
int (* probe) (struct device *dev);
int (* remove) (struct device *dev);
void (* shutdown) (struct device *dev);
int (* online) (struct device *dev);
int (* offline) (struct device *dev);
int (* suspend) (struct device *dev, pm_message_t state);
int (* resume) (struct device *dev);
const struct dev_pm_ops * pm;
const struct iommu_ops * iommu_ops;
struct subsys_private * p;
struct lock_class_key lock_key;
};
Members
name
- The name of the bus.
dev_name
- Used for subsystems to enumerate devices like (“foo``u``”, dev->id).
dev_root
- Default device to use as the parent.
dev_attrs
- Default attributes of the devices on the bus.
bus_groups
- Default attributes of the bus.
dev_groups
- Default attributes of the devices on the bus.
drv_groups
- Default attributes of the device drivers on the bus.
match
- Called, perhaps multiple times, whenever a new device or driver is added for this bus. It should return a positive value if the given device can be handled by the given driver and zero otherwise. It may also return error code if determining that the driver supports the device is not possible. In case of -EPROBE_DEFER it will queue the device for deferred probing.
uevent
- Called when a device is added, removed, or a few other things that generate uevents to add the environment variables.
probe
- Called when a new device or driver add to this bus, and callback the specific driver’s probe to initial the matched device.
remove
- Called when a device removed from this bus.
shutdown
- Called at shut-down time to quiesce the device.
online
- Called to put the device back online (after offlining it).
offline
- Called to put the device offline for hot-removal. May fail.
suspend
- Called when a device on this bus wants to go to sleep mode.
resume
- Called to bring a device on this bus out of sleep mode.
pm
- Power management operations of this bus, callback the specific device driver’s pm-ops.
iommu_ops
- IOMMU specific operations for this bus, used to attach IOMMU driver implementations to a bus and allow the driver to do bus-specific setup
p
- The private data of the driver core, only the driver core can touch this.
lock_key
- Lock class key for use by the lock validator
Description
A bus is a channel between the processor and one or more devices. For the purposes of the device model, all devices are connected via a bus, even if it is an internal, virtual, “platform” bus. Buses can plug into each other. A USB controller is usually a PCI device, for example. The device model represents the actual connections between buses and the devices they control. A bus is represented by the bus_type structure. It contains the name, the default attributes, the bus’ methods, PM operations, and the driver core’s private data.
-
enum
probe_type
¶ device driver probe type to try Device drivers may opt in for special handling of their respective probe routines. This tells the core what to expect and prefer.
Constants
PROBE_DEFAULT_STRATEGY
- Used by drivers that work equally well whether probed synchronously or asynchronously.
PROBE_PREFER_ASYNCHRONOUS
- Drivers for “slow” devices which probing order is not essential for booting the system may opt into executing their probes asynchronously.
PROBE_FORCE_SYNCHRONOUS
- Use this to annotate drivers that need their probe routines to run synchronously with driver and device registration (with the exception of -EPROBE_DEFER handling - re-probing always ends up being done asynchronously).
Description
Note that the end goal is to switch the kernel to use asynchronous
probing by default, so annotating drivers with
PROBE_PREFER_ASYNCHRONOUS
is a temporary measure that allows us
to speed up boot process while we are validating the rest of the
drivers.
-
struct
device_driver
¶ The basic device driver structure
Definition
struct device_driver {
const char * name;
struct bus_type * bus;
struct module * owner;
const char * mod_name;
bool suppress_bind_attrs;
enum probe_type probe_type;
const struct of_device_id * of_match_table;
const struct acpi_device_id * acpi_match_table;
int (* probe) (struct device *dev);
int (* remove) (struct device *dev);
void (* shutdown) (struct device *dev);
int (* suspend) (struct device *dev, pm_message_t state);
int (* resume) (struct device *dev);
const struct attribute_group ** groups;
const struct dev_pm_ops * pm;
struct driver_private * p;
};
Members
name
- Name of the device driver.
bus
- The bus which the device of this driver belongs to.
owner
- The module owner.
mod_name
- Used for built-in modules.
suppress_bind_attrs
- Disables bind/unbind via sysfs.
probe_type
- Type of the probe (synchronous or asynchronous) to use.
of_match_table
- The open firmware table.
acpi_match_table
- The ACPI match table.
probe
- Called to query the existence of a specific device, whether this driver can work with it, and bind the driver to a specific device.
remove
- Called when the device is removed from the system to unbind a device from this driver.
shutdown
- Called at shut-down time to quiesce the device.
suspend
- Called to put the device to sleep mode. Usually to a low power state.
resume
- Called to bring a device from sleep mode.
groups
- Default attributes that get created by the driver core automatically.
pm
- Power management operations of the device which matched this driver.
p
- Driver core’s private data, no one other than the driver core can touch this.
Description
The device driver-model tracks all of the drivers known to the system. The main reason for this tracking is to enable the driver core to match up drivers with new devices. Once drivers are known objects within the system, however, a number of other things become possible. Device drivers can export information and configuration variables that are independent of any specific device.
-
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
- 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 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.
-
struct
class
¶ device classes
Definition
struct class {
const char * name;
struct module * owner;
struct class_attribute * class_attrs;
const struct attribute_group ** dev_groups;
struct kobject * dev_kobj;
int (* dev_uevent) (struct device *dev, struct kobj_uevent_env *env);
char *(* devnode) (struct device *dev, umode_t *mode);
void (* class_release) (struct class *class);
void (* dev_release) (struct device *dev);
int (* suspend) (struct device *dev, pm_message_t state);
int (* resume) (struct device *dev);
const struct kobj_ns_type_operations * ns_type;
const void *(* namespace) (struct device *dev);
const struct dev_pm_ops * pm;
struct subsys_private * p;
};
Members
name
- Name of the class.
owner
- The module owner.
class_attrs
- Default attributes of this class.
dev_groups
- Default attributes of the devices that belong to the class.
dev_kobj
- The kobject that represents this class and links it into the hierarchy.
dev_uevent
- Called when a device is added, removed from this class, or a few other things that generate uevents to add the environment variables.
devnode
- Callback to provide the devtmpfs.
class_release
- Called to release this class.
dev_release
- Called to release the device.
suspend
- Used to put the device to sleep mode, usually to a low power state.
resume
- Used to bring the device from the sleep mode.
ns_type
- Callbacks so sysfs can detemine namespaces.
namespace
- Namespace of the device belongs to this class.
pm
- The default device power management operations of this class.
p
- The private data of the driver core, no one other than the driver core can touch this.
Description
A class is a higher-level view of a device that abstracts out low-level implementation details. Drivers may see a SCSI disk or an ATA disk, but, at the class level, they are all simply disks. Classes allow user space to work with devices based on what they do, rather than how they are connected or how they work.
-
struct
device
¶ The basic device structure
Definition
struct device {
struct device * parent;
struct device_private * p;
struct kobject kobj;
const char * init_name;
const struct device_type * type;
struct mutex mutex;
struct bus_type * bus;
struct device_driver * driver;
void * platform_data;
void * driver_data;
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
#ifdef CONFIG_NUMA
int numa_node;
#endif
u64 * dma_mask;
u64 coherent_dma_mask;
unsigned long dma_pfn_offset;
struct device_dma_parameters * dma_parms;
struct list_head dma_pools;
struct dma_coherent_mem * dma_mem;
#ifdef CONFIG_DMA_CMA
struct cma * cma_area;
#endif
struct dev_archdata archdata;
struct device_node * of_node;
struct fwnode_handle * fwnode;
dev_t devt;
u32 id;
spinlock_t devres_lock;
struct list_head devres_head;
struct klist_node knode_class;
struct class * class;
const struct attribute_group ** groups;
void (* release) (struct device *dev);
struct iommu_group * iommu_group;
struct iommu_fwspec * iommu_fwspec;
bool offline_disabled:1;
bool offline:1;
};
Members
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.
kobj
- A top-level, abstract class from which other classes are derived.
init_name
- Initial name of the device.
type
- The type of device. This identifies the device type and carries type-specific information.
mutex
- Mutex to synchronize calls to its driver.
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.
power
- For device power management. See Documentation/power/devices.txt 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.
msi_domain
- The generic MSI domain this device is using.
pins
- For device pin management. See Documentation/pinctrl.txt for details.
msi_list
- Hosts MSI descriptors
numa_node
- NUMA node this device is close to.
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.
dma_pfn_offset
- offset of DMA memory range relatively 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
archdata
- For arch-specific additions.
of_node
- Associated device tree node.
fwnode
- Associated device node supplied by platform firmware.
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.
knode_class
- The node used to add the device to the class list.
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_fwspec
- IOMMU-specific properties supplied by firmware.
offline_disabled
- If set, the device is permanently online.
offline
- Set after successful invocation of bus type’s .:c:func:offline().
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.
-
module_driver
(__driver, __register, __unregister, ...)¶ Helper macro for drivers that don’t do anything special in module init/exit. This eliminates a lot of boilerplate. Each module may only use this macro once, and calling it replaces
module_init()
andmodule_exit()
.
Parameters
__driver
- driver name
__register
- register function for this driver type
__unregister
- unregister function for this driver type
...
- Additional arguments to be passed to __register and __unregister.
Description
Use this macro to construct bus specific macros for registering drivers, and do not use it on its own.
-
builtin_driver
(__driver, __register, ...)¶ Helper macro for drivers that don’t do anything special in init and have no exit. This eliminates some boilerplate. Each driver may only use this macro once, and calling it replaces device_initcall (or in some cases, the legacy __initcall). This is meant to be a direct parallel of
module_driver()
above but without the __exit stuff that is not used for builtin cases.
Parameters
__driver
- driver name
__register
- register function for this driver type
...
- Additional arguments to be passed to __register
Description
Use this macro to construct bus specific macros for registering drivers, and do not use it on its own.
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 (*)(struct device *, void *) fn
- 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, void * data, int (*match) (struct device *dev, 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
void * data
- Data to pass to match function
int (*)(struct device *dev, void *data) match
- 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.
-
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
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.
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.
Parameters
struct device * dev
- device
const char * fmt
- format string for the device’s name
...
- variable arguments
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.
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.
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.
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.
Parameters
struct device * dev
- device in question.
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.
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 (*)(struct device *dev, void *data) fn
- 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 (*)(struct device *dev, void *data) fn
- 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 (*)(struct device *dev, void *data) match
- 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 *
__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()
.
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_vargs
(struct class * class, struct device * parent, dev_t devt, void * drvdata, const char * fmt, va_list args)¶ 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
va_list args
- va_list for the device’s name
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
(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()
.
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.
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:
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. :)
-
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 by NULL)
enum dpm_order dpm_order
- how to reorder the dpm_list
-
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.
-
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()
.
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.
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 (*)(struct device *, void *) fn
- 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 (*)(struct device *, const void *) match
- 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
-
int
class_compat_create_link
(struct class_compat * cls, struct device * dev, struct device * device_link)¶ 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
-
void
class_compat_remove_link
(struct class_compat * cls, struct device * dev, struct device * device_link)¶ 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
-
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
request_firmware
(const struct firmware ** firmware_p, const char * name, struct device * device)¶ send firmware request and wait for it
Parameters
const struct firmware ** firmware_p
- pointer to firmware image
const char * name
- name of firmware file
struct device * device
- device for which firmware is being loaded
Description
firmware_p will be used to return a firmware image by the name of name for device device.
Should be called from user context where sleeping is allowed.
name will be used as $FIRMWARE in the uevent environment and should be distinctive enough not to be confused with any other firmware image for this or any other device.
Caller must hold the reference count of device.
The function can be called safely inside device’s suspend and resume callback.
-
int
request_firmware_direct
(const struct firmware ** firmware_p, const char * name, struct device * device)¶ load firmware directly without usermode helper
Parameters
const struct firmware ** firmware_p
- pointer to firmware image
const char * name
- name of firmware file
struct device * device
- device for which firmware is being loaded
Description
This function works pretty much like request_firmware()
, but this doesn’t
fall back to usermode helper even if the firmware couldn’t be loaded
directly from fs. Hence it’s useful for loading optional firmwares, which
aren’t always present, without extra long timeouts of udev.
-
int
request_firmware_into_buf
(const struct firmware ** firmware_p, const char * name, struct device * device, void * buf, size_t size)¶ load firmware into a previously allocated buffer
Parameters
const struct firmware ** firmware_p
- pointer to firmware image
const char * name
- name of firmware file
struct device * device
- device for which firmware is being loaded and DMA region allocated
void * buf
- address of buffer to load firmware into
size_t size
- size of buffer
Description
This function works pretty much like request_firmware()
, but it doesn’t
allocate a buffer to hold the firmware data. Instead, the firmware
is loaded directly into the buffer pointed to by buf and the firmware_p
data member is pointed at buf.
This function doesn’t cache firmware either.
-
void
release_firmware
(const struct firmware * fw)¶ release the resource associated with a firmware image
Parameters
const struct firmware * fw
- firmware resource to release
-
int
request_firmware_nowait
(struct module * module, bool uevent, const char * name, struct device * device, gfp_t gfp, void * context, void (*cont) (const struct firmware *fw, void *context)¶ asynchronous version of request_firmware
Parameters
struct module * module
- module requesting the firmware
bool uevent
- sends uevent to copy the firmware image if this flag is non-zero else the firmware copy must be done manually.
const char * name
- name of firmware file
struct device * device
- device for which firmware is being loaded
gfp_t gfp
- allocation flags
void * context
- will be passed over to cont, and
fw may be
NULL
if firmware request fails. void (*)(const struct firmware *fw, void *context) cont
- function will be called asynchronously when the firmware request is over.
Description
Caller must hold the reference count of device.
- Asynchronous variant of
request_firmware()
for user contexts:
- sleep for as small periods as possible since it may
increase kernel boot time of built-in device drivers requesting firmware in their ->:c:func:probe() methods, if gfp is GFP_KERNEL.
- can’t sleep at all if gfp is GFP_ATOMIC.
-
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).
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.
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.
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.
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.
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
nor take the bus’s rwsem. Please verify those are 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.
-
void
wait_for_device_probe
(void)¶
Parameters
void
- no arguments
Description
Wait for device probing to be completed.
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
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.
Parameters
struct device * dev
- device.
Description
Manually detach device from driver. When called for a USB interface, dev->parent lock must be held.
-
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
-
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
-
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
-
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
-
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_properties
(struct platform_device * pdev, struct property_entry * properties)¶ add built-in properties to a platform device
Parameters
struct platform_device * pdev
- platform device to add properties to
struct property_entry * properties
- null terminated array of properties to add
Description
The function will take deep copy of properties and attach the copy to the platform device. The memory associated with properties 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 (*)(struct platform_device *) probe
- 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 (*)(struct platform_device *) probe
- 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
Unegisters 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.
-
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 (*)(struct device *, void *) fn
- 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, void * data, int (*match) (struct device *dev, void *data)¶ device iterator for locating a particular device.
Parameters
struct bus_type * bus
- bus type
struct device * start
- Device to begin with
void * data
- Data to pass to match function
int (*)(struct device *dev, void *data) match
- 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 *
bus_find_device_by_name
(struct bus_type * bus, struct device * start, const char * name)¶ device iterator for locating a particular device of a specific name
Parameters
struct bus_type * bus
- bus type
struct device * start
- Device to begin with
const char * name
- name of the device to match
Description
This is similar to the bus_find_device()
function above, but it handles
searching by a name automatically, no need to write another strcmp matching
function.
-
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 (*)(struct device_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 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.
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.
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.
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.
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.
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.
Buffer Sharing and Synchronization¶
The dma-buf subsystem provides the framework for sharing buffers for hardware (DMA) access across multiple device drivers and subsystems, and for synchronizing asynchronous hardware access.
This is used, for example, by drm “prime” multi-GPU support, but is of course not limited to GPU use cases.
The three main components of this are: (1) dma-buf, representing a sg_table and exposed to userspace as a file descriptor to allow passing between devices, (2) fence, which provides a mechanism to signal when one device as finished access, and (3) reservation, which manages the shared or exclusive fence(s) associated with the buffer.
dma-buf¶
-
struct dma_buf *
dma_buf_export
(const struct dma_buf_export_info * exp_info)¶ Creates a new dma_buf, and associates an anon file with this buffer, so it can be exported. Also connect the allocator specific data and ops to the buffer. Additionally, provide a name string for exporter; useful in debugging.
Parameters
const struct dma_buf_export_info * exp_info
- [in] holds all the export related information provided by the exporter. see struct dma_buf_export_info for further details.
Description
Returns, on success, a newly created dma_buf object, which wraps the supplied private data and operations for dma_buf_ops. On either missing ops, or error in allocating struct dma_buf, will return negative error.
Parameters
struct dma_buf * dmabuf
- [in] pointer to dma_buf for which fd is required.
int flags
- [in] flags to give to fd
Description
On success, returns an associated ‘fd’. Else, returns error.
Parameters
int fd
- [in] fd associated with the dma_buf to be returned
Description
On success, returns the dma_buf structure associated with an fd; uses file’s refcounting done by fget to increase refcount. returns ERR_PTR otherwise.
Parameters
struct dma_buf * dmabuf
- [in] buffer to reduce refcount of
Description
Uses file’s refcounting done implicitly by fput()
-
struct dma_buf_attachment *
dma_buf_attach
(struct dma_buf * dmabuf, struct device * dev)¶ Add the device to dma_buf’s attachments list; optionally, calls
attach()
of dma_buf_ops to allow device-specific attach functionality
Parameters
struct dma_buf * dmabuf
- [in] buffer to attach device to.
struct device * dev
- [in] device to be attached.
Description
Returns struct dma_buf_attachment * for this attachment; returns ERR_PTR on error.
-
void
dma_buf_detach
(struct dma_buf * dmabuf, struct dma_buf_attachment * attach)¶ Remove the given attachment from dmabuf’s attachments list; optionally calls
detach()
of dma_buf_ops for device-specific detach
Parameters
struct dma_buf * dmabuf
- [in] buffer to detach from.
struct dma_buf_attachment * attach
- [in] attachment to be detached; is free’d after this call.
-
struct sg_table *
dma_buf_map_attachment
(struct dma_buf_attachment * attach, enum dma_data_direction direction)¶ Returns the scatterlist table of the attachment; mapped into _device_ address space. Is a wrapper for
map_dma_buf()
of the dma_buf_ops.
Parameters
struct dma_buf_attachment * attach
- [in] attachment whose scatterlist is to be returned
enum dma_data_direction direction
- [in] direction of DMA transfer
Description
Returns sg_table containing the scatterlist to be returned; returns ERR_PTR on error.
-
void
dma_buf_unmap_attachment
(struct dma_buf_attachment * attach, struct sg_table * sg_table, enum dma_data_direction direction)¶ unmaps and decreases usecount of the buffer;might deallocate the scatterlist associated. Is a wrapper for
unmap_dma_buf()
of dma_buf_ops.
Parameters
struct dma_buf_attachment * attach
- [in] attachment to unmap buffer from
struct sg_table * sg_table
- [in] scatterlist info of the buffer to unmap
enum dma_data_direction direction
- [in] direction of DMA transfer
-
int
dma_buf_begin_cpu_access
(struct dma_buf * dmabuf, enum dma_data_direction direction)¶ Must be called before accessing a dma_buf from the cpu in the kernel context. Calls begin_cpu_access to allow exporter-specific preparations. Coherency is only guaranteed in the specified range for the specified access direction.
Parameters
struct dma_buf * dmabuf
- [in] buffer to prepare cpu access for.
enum dma_data_direction direction
- [in] length of range for cpu access.
Description
Can return negative error values, returns 0 on success.
-
int
dma_buf_end_cpu_access
(struct dma_buf * dmabuf, enum dma_data_direction direction)¶ Must be called after accessing a dma_buf from the cpu in the kernel context. Calls end_cpu_access to allow exporter-specific actions. Coherency is only guaranteed in the specified range for the specified access direction.
Parameters
struct dma_buf * dmabuf
- [in] buffer to complete cpu access for.
enum dma_data_direction direction
- [in] length of range for cpu access.
Description
Can return negative error values, returns 0 on success.
-
void *
dma_buf_kmap_atomic
(struct dma_buf * dmabuf, unsigned long page_num)¶ Map a page of the buffer object into kernel address space. The same restrictions as for kmap_atomic and friends apply.
Parameters
struct dma_buf * dmabuf
- [in] buffer to map page from.
unsigned long page_num
- [in] page in PAGE_SIZE units to map.
Description
This call must always succeed, any necessary preparations that might fail need to be done in begin_cpu_access.
-
void
dma_buf_kunmap_atomic
(struct dma_buf * dmabuf, unsigned long page_num, void * vaddr)¶ Unmap a page obtained by dma_buf_kmap_atomic.
Parameters
struct dma_buf * dmabuf
- [in] buffer to unmap page from.
unsigned long page_num
- [in] page in PAGE_SIZE units to unmap.
void * vaddr
- [in] kernel space pointer obtained from dma_buf_kmap_atomic.
Description
This call must always succeed.
-
void *
dma_buf_kmap
(struct dma_buf * dmabuf, unsigned long page_num)¶ Map a page of the buffer object into kernel address space. The same restrictions as for kmap and friends apply.
Parameters
struct dma_buf * dmabuf
- [in] buffer to map page from.
unsigned long page_num
- [in] page in PAGE_SIZE units to map.
Description
This call must always succeed, any necessary preparations that might fail need to be done in begin_cpu_access.
-
void
dma_buf_kunmap
(struct dma_buf * dmabuf, unsigned long page_num, void * vaddr)¶ Unmap a page obtained by dma_buf_kmap.
Parameters
struct dma_buf * dmabuf
- [in] buffer to unmap page from.
unsigned long page_num
- [in] page in PAGE_SIZE units to unmap.
void * vaddr
- [in] kernel space pointer obtained from dma_buf_kmap.
Description
This call must always succeed.
-
int
dma_buf_mmap
(struct dma_buf * dmabuf, struct vm_area_struct * vma, unsigned long pgoff)¶ Setup up a userspace mmap with the given vma
Parameters
struct dma_buf * dmabuf
- [in] buffer that should back the vma
struct vm_area_struct * vma
- [in] vma for the mmap
unsigned long pgoff
- [in] offset in pages where this mmap should start within the dma-buf buffer.
Description
This function adjusts the passed in vma so that it points at the file of the dma_buf operation. It also adjusts the starting pgoff and does bounds checking on the size of the vma. Then it calls the exporters mmap function to set up the mapping.
Can return negative error values, returns 0 on success.
-
void *
dma_buf_vmap
(struct dma_buf * dmabuf)¶ Create virtual mapping for the buffer object into kernel address space. Same restrictions as for vmap and friends apply.
Parameters
struct dma_buf * dmabuf
- [in] buffer to vmap
Description
This call may fail due to lack of virtual mapping address space. These calls are optional in drivers. The intended use for them is for mapping objects linear in kernel space for high use objects. Please attempt to use kmap/kunmap before thinking about these interfaces.
Returns NULL on error.
Parameters
struct dma_buf * dmabuf
- [in] buffer to vunmap
void * vaddr
- [in] vmap to vunmap
-
struct
dma_buf_ops
¶ operations possible on struct dma_buf
Definition
struct dma_buf_ops {
int (* attach) (struct dma_buf *, struct device *,struct dma_buf_attachment *);
void (* detach) (struct dma_buf *, struct dma_buf_attachment *);
struct sg_table * (* map_dma_buf) (struct dma_buf_attachment *,enum dma_data_direction);
void (* unmap_dma_buf) (struct dma_buf_attachment *,struct sg_table *,enum dma_data_direction);
void (* release) (struct dma_buf *);
int (* begin_cpu_access) (struct dma_buf *, enum dma_data_direction);
int (* end_cpu_access) (struct dma_buf *, enum dma_data_direction);
void *(* kmap_atomic) (struct dma_buf *, unsigned long);
void (* kunmap_atomic) (struct dma_buf *, unsigned long, void *);
void *(* kmap) (struct dma_buf *, unsigned long);
void (* kunmap) (struct dma_buf *, unsigned long, void *);
int (* mmap) (struct dma_buf *, struct vm_area_struct *vma);
void *(* vmap) (struct dma_buf *);
void (* vunmap) (struct dma_buf *, void *vaddr);
};
Members
attach
- [optional] allows different devices to ‘attach’ themselves to the given buffer. It might return -EBUSY to signal that backing storage is already allocated and incompatible with the requirements of requesting device.
detach
- [optional] detach a given device from this buffer.
map_dma_buf
- returns list of scatter pages allocated, increases usecount of the buffer. Requires atleast one attach to be called before. Returned sg list should already be mapped into _device_ address space. This call may sleep. May also return -EINTR. Should return -EINVAL if attach hasn’t been called yet.
unmap_dma_buf
- decreases usecount of buffer, might deallocate scatter pages.
release
- release this buffer; to be called after the last dma_buf_put.
begin_cpu_access
- [optional] called before cpu access to invalidate cpu caches and allocate backing storage (if not yet done) respectively pin the object into memory.
end_cpu_access
- [optional] called after cpu access to flush caches.
kmap_atomic
- maps a page from the buffer into kernel address space, users may not block until the subsequent unmap call. This callback must not sleep.
kunmap_atomic
- [optional] unmaps a atomically mapped page from the buffer. This Callback must not sleep.
kmap
- maps a page from the buffer into kernel address space.
kunmap
- [optional] unmaps a page from the buffer.
mmap
- used to expose the backing storage to userspace. Note that the mapping needs to be coherent - if the exporter doesn’t directly support this, it needs to fake coherency by shooting down any ptes when transitioning away from the cpu domain.
vmap
- [optional] creates a virtual mapping for the buffer into kernel address space. Same restrictions as for vmap and friends apply.
vunmap
- [optional] unmaps a vmap from the buffer
-
struct
dma_buf
¶ shared buffer object
Definition
struct dma_buf {
size_t size;
struct file * file;
struct list_head attachments;
const struct dma_buf_ops * ops;
struct mutex lock;
unsigned vmapping_counter;
void * vmap_ptr;
const char * exp_name;
struct module * owner;
struct list_head list_node;
void * priv;
struct reservation_object * resv;
wait_queue_head_t poll;
struct dma_buf_poll_cb_t cb_excl;
struct dma_buf_poll_cb_t cb_shared;
};
Members
size
- size of the buffer
file
- file pointer used for sharing buffers across, and for refcounting.
attachments
- list of dma_buf_attachment that denotes all devices attached.
ops
- dma_buf_ops associated with this buffer object.
lock
- used internally to serialize list manipulation, attach/detach and vmap/unmap
vmapping_counter
- used internally to refcnt the vmaps
vmap_ptr
- the current vmap ptr if vmapping_counter > 0
exp_name
- name of the exporter; useful for debugging.
owner
- pointer to exporter module; used for refcounting when exporter is a kernel module.
list_node
- node for dma_buf accounting and debugging.
priv
- exporter specific private data for this buffer object.
resv
- reservation object linked to this dma-buf
poll
- for userspace poll support
cb_excl
- for userspace poll support
cb_shared
- for userspace poll support
-
struct
dma_buf_attachment
¶ holds device-buffer attachment data
Definition
struct dma_buf_attachment {
struct dma_buf * dmabuf;
struct device * dev;
struct list_head node;
void * priv;
};
Members
dmabuf
- buffer for this attachment.
dev
- device attached to the buffer.
node
- list of dma_buf_attachment.
priv
- exporter specific attachment data.
Description
This structure holds the attachment information between the dma_buf buffer and its user device(s). The list contains one attachment struct per device attached to the buffer.
-
struct
dma_buf_export_info
¶ holds information needed to export a dma_buf
Definition
struct dma_buf_export_info {
const char * exp_name;
struct module * owner;
const struct dma_buf_ops * ops;
size_t size;
int flags;
struct reservation_object * resv;
void * priv;
};
Members
exp_name
- name of the exporter - useful for debugging.
owner
- pointer to exporter module - used for refcounting kernel module
ops
- Attach allocator-defined dma buf ops to the new buffer
size
- Size of the buffer
flags
- mode flags for the file
resv
- reservation-object, NULL to allocate default one
priv
- Attach private data of allocator to this buffer
Description
This structure holds the information required to export the buffer. Used
with dma_buf_export()
only.
-
DEFINE_DMA_BUF_EXPORT_INFO
(name)¶
Parameters
name
- export-info name
Parameters
struct dma_buf * dmabuf
- [in] pointer to dma_buf
Description
Increments the reference count on the dma-buf, needed in case of drivers that either need to create additional references to the dmabuf on the kernel side. For example, an exporter that needs to keep a dmabuf ptr so that subsequent exports don’t create a new dmabuf.
reservation¶
The reservation object provides a mechanism to manage shared and exclusive fences associated with a buffer. A reservation object can have attached one exclusive fence (normally associated with write operations) or N shared fences (read operations). The RCU mechanism is used to protect read access to fences from locked write-side updates.
Reserve space to add a shared fence to a reservation_object.
Parameters
struct reservation_object * obj
- reservation object
Description
Should be called before reservation_object_add_shared_fence()
. Must
be called with obj->lock held.
RETURNS Zero for success, or -errno
Add a fence to a shared slot
Parameters
struct reservation_object * obj
- the reservation object
struct fence * fence
- the shared fence to add
Description
Add a fence to a shared slot, obj->lock must be held, and
reservation_object_reserve_shared()
has been called.
-
void
reservation_object_add_excl_fence
(struct reservation_object * obj, struct fence * fence)¶ Add an exclusive fence.
Parameters
struct reservation_object * obj
- the reservation object
struct fence * fence
- the shared fence to add
Description
Add a fence to the exclusive slot. The obj->lock must be held.
-
int
reservation_object_get_fences_rcu
(struct reservation_object * obj, struct fence ** pfence_excl, unsigned * pshared_count, struct fence *** pshared)¶ Get an object’s shared and exclusive fences without update side lock held
Parameters
struct reservation_object * obj
- the reservation object
struct fence ** pfence_excl
- the returned exclusive fence (or NULL)
unsigned * pshared_count
- the number of shared fences returned
struct fence *** pshared
- the array of shared fence ptrs returned (array is krealloc’d to the required size, and must be freed by caller)
Description
RETURNS Zero or -errno
-
long
reservation_object_wait_timeout_rcu
(struct reservation_object * obj, bool wait_all, bool intr, unsigned long timeout)¶ Wait on reservation’s objects shared and/or exclusive fences.
Parameters
struct reservation_object * obj
- the reservation object
bool wait_all
- if true, wait on all fences, else wait on just exclusive fence
bool intr
- if true, do interruptible wait
unsigned long timeout
- timeout value in jiffies or zero to return immediately
Description
RETURNS Returns -ERESTARTSYS if interrupted, 0 if the wait timed out, or greater than zer on success.
-
bool
reservation_object_test_signaled_rcu
(struct reservation_object * obj, bool test_all)¶ Test if a reservation object’s fences have been signaled.
Parameters
struct reservation_object * obj
- the reservation object
bool test_all
- if true, test all fences, otherwise only test the exclusive fence
Description
RETURNS true if all fences signaled, else false
-
struct
reservation_object_list
¶ a list of shared fences
Definition
struct reservation_object_list {
struct rcu_head rcu;
u32 shared_count;
u32 shared_max;
struct fence __rcu * shared[];
};
Members
rcu
- for internal use
shared_count
- table of shared fences
shared_max
- for growing shared fence table
shared[]
- shared fence table
-
struct
reservation_object
¶ a reservation object manages fences for a buffer
Definition
struct reservation_object {
struct ww_mutex lock;
seqcount_t seq;
struct fence __rcu * fence_excl;
struct reservation_object_list __rcu * fence;
struct reservation_object_list * staged;
};
Members
lock
- update side lock
seq
- sequence count for managing RCU read-side synchronization
fence_excl
- the exclusive fence, if there is one currently
fence
- list of current shared fences
staged
- staged copy of shared fences for RCU updates
-
void
reservation_object_init
(struct reservation_object * obj)¶ initialize a reservation object
Parameters
struct reservation_object * obj
- the reservation object
-
void
reservation_object_fini
(struct reservation_object * obj)¶ destroys a reservation object
Parameters
struct reservation_object * obj
- the reservation object
-
struct reservation_object_list *
reservation_object_get_list
(struct reservation_object * obj)¶ get the reservation object’s shared fence list, with update-side lock held
Parameters
struct reservation_object * obj
- the reservation object
Description
Returns the shared fence list. Does NOT take references to the fence. The obj->lock must be held.
-
struct fence *
reservation_object_get_excl
(struct reservation_object * obj)¶ get the reservation object’s exclusive fence, with update-side lock held
Parameters
struct reservation_object * obj
- the reservation object
Description
Returns the exclusive fence (if any). Does NOT take a reference. The obj->lock must be held.
RETURNS The exclusive fence or NULL
-
struct fence *
reservation_object_get_excl_rcu
(struct reservation_object * obj)¶ get the reservation object’s exclusive fence, without lock held.
Parameters
struct reservation_object * obj
- the reservation object
Description
If there is an exclusive fence, this atomically increments it’s reference count and returns it.
RETURNS The exclusive fence or NULL if none
fence¶
-
u64
fence_context_alloc
(unsigned num)¶ allocate an array of fence contexts
Parameters
unsigned num
- [in] amount of contexts to allocate
Description
This function will return the first index of the number of fences allocated. The fence context is used for setting fence->context to a unique number.
Parameters
struct fence * fence
- the fence to signal
Description
Signal completion for software callbacks on a fence, this will unblock
fence_wait()
calls and run all the callbacks added with
fence_add_callback()
. Can be called multiple times, but since a fence
can only go from unsignaled to signaled state, it will only be effective
the first time.
Unlike fence_signal, this function must be called with fence->lock held.
Parameters
struct fence * fence
- the fence to signal
Description
Signal completion for software callbacks on a fence, this will unblock
fence_wait()
calls and run all the callbacks added with
fence_add_callback()
. Can be called multiple times, but since a fence
can only go from unsignaled to signaled state, it will only be effective
the first time.
-
signed long
fence_wait_timeout
(struct fence * fence, bool intr, signed long timeout)¶ sleep until the fence gets signaled or until timeout elapses
Parameters
struct fence * fence
- [in] the fence to wait on
bool intr
- [in] if true, do an interruptible wait
signed long timeout
- [in] timeout value in jiffies, or MAX_SCHEDULE_TIMEOUT
Description
Returns -ERESTARTSYS if interrupted, 0 if the wait timed out, or the remaining timeout in jiffies on success. Other error values may be returned on custom implementations.
Performs a synchronous wait on this fence. It is assumed the caller directly or indirectly (buf-mgr between reservation and committing) holds a reference to the fence, otherwise the fence might be freed before return, resulting in undefined behavior.
Parameters
struct fence * fence
- [in] the fence to enable
Description
this will request for sw signaling to be enabled, to make the fence complete as soon as possible
-
int
fence_add_callback
(struct fence * fence, struct fence_cb * cb, fence_func_t func)¶ add a callback to be called when the fence is signaled
Parameters
struct fence * fence
- [in] the fence to wait on
struct fence_cb * cb
- [in] the callback to register
fence_func_t func
- [in] the function to call
Description
cb will be initialized by fence_add_callback, no initialization by the caller is required. Any number of callbacks can be registered to a fence, but a callback can only be registered to one fence at a time.
Note that the callback can be called from an atomic context. If fence is already signaled, this function will return -ENOENT (and not call the callback)
Add a software callback to the fence. Same restrictions apply to refcount as it does to fence_wait, however the caller doesn’t need to keep a refcount to fence afterwards: when software access is enabled, the creator of the fence is required to keep the fence alive until after it signals with fence_signal. The callback itself can be called from irq context.
-
bool
fence_remove_callback
(struct fence * fence, struct fence_cb * cb)¶ remove a callback from the signaling list
Parameters
struct fence * fence
- [in] the fence to wait on
struct fence_cb * cb
- [in] the callback to remove
Description
Remove a previously queued callback from the fence. This function returns true if the callback is successfully removed, or false if the fence has already been signaled.
WARNING: Cancelling a callback should only be done if you really know what you’re doing, since deadlocks and race conditions could occur all too easily. For this reason, it should only ever be done on hardware lockup recovery, with a reference held to the fence.
-
signed long
fence_default_wait
(struct fence * fence, bool intr, signed long timeout)¶ default sleep until the fence gets signaled or until timeout elapses
Parameters
struct fence * fence
- [in] the fence to wait on
bool intr
- [in] if true, do an interruptible wait
signed long timeout
- [in] timeout value in jiffies, or MAX_SCHEDULE_TIMEOUT
Description
Returns -ERESTARTSYS if interrupted, 0 if the wait timed out, or the remaining timeout in jiffies on success.
-
signed long
fence_wait_any_timeout
(struct fence ** fences, uint32_t count, bool intr, signed long timeout)¶ sleep until any fence gets signaled or until timeout elapses
Parameters
struct fence ** fences
- [in] array of fences to wait on
uint32_t count
- [in] number of fences to wait on
bool intr
- [in] if true, do an interruptible wait
signed long timeout
- [in] timeout value in jiffies, or MAX_SCHEDULE_TIMEOUT
Description
Returns -EINVAL on custom fence wait implementation, -ERESTARTSYS if interrupted, 0 if the wait timed out, or the remaining timeout in jiffies on success.
Synchronous waits for the first fence in the array to be signaled. The caller needs to hold a reference to all fences in the array, otherwise a fence might be freed before return, resulting in undefined behavior.
-
void
fence_init
(struct fence * fence, const struct fence_ops * ops, spinlock_t * lock, u64 context, unsigned seqno)¶ Initialize a custom fence.
Parameters
struct fence * fence
- [in] the fence to initialize
const struct fence_ops * ops
- [in] the fence_ops for operations on this fence
spinlock_t * lock
- [in] the irqsafe spinlock to use for locking this fence
u64 context
- [in] the execution context this fence is run on
unsigned seqno
- [in] a linear increasing sequence number for this context
Description
Initializes an allocated fence, the caller doesn’t have to keep its refcount after committing with this fence, but it will need to hold a refcount again if fence_ops.enable_signaling gets called. This can be used for other implementing other types of fence.
context and seqno are used for easy comparison between fences, allowing to check which fence is later by simply using fence_later.
-
struct
fence
¶ software synchronization primitive
Definition
struct fence {
struct kref refcount;
const struct fence_ops * ops;
struct rcu_head rcu;
struct list_head cb_list;
spinlock_t * lock;
u64 context;
unsigned seqno;
unsigned long flags;
ktime_t timestamp;
int status;
};
Members
refcount
- refcount for this fence
ops
- fence_ops associated with this fence
rcu
- used for releasing fence with kfree_rcu
cb_list
- list of all callbacks to call
lock
- spin_lock_irqsave used for locking
context
- execution context this fence belongs to, returned by
fence_context_alloc()
seqno
- the sequence number of this fence inside the execution context, can be compared to decide which fence would be signaled later.
flags
- A mask of FENCE_FLAG_* defined below
timestamp
- Timestamp when the fence was signaled.
status
- Optional, only valid if < 0, must be set before calling fence_signal, indicates that the fence has completed with an error.
Description
the flags member must be manipulated and read using the appropriate atomic ops (bit_*), so taking the spinlock will not be needed most of the time.
FENCE_FLAG_SIGNALED_BIT - fence is already signaled FENCE_FLAG_ENABLE_SIGNAL_BIT - enable_signaling might have been called* FENCE_FLAG_USER_BITS - start of the unused bits, can be used by the implementer of the fence for its own purposes. Can be used in different ways by different fence implementers, so do not rely on this.
Since atomic bitops are used, this is not guaranteed to be the case. Particularly, if the bit was set, but fence_signal was called right before this bit was set, it would have been able to set the FENCE_FLAG_SIGNALED_BIT, before enable_signaling was called. Adding a check for FENCE_FLAG_SIGNALED_BIT after setting FENCE_FLAG_ENABLE_SIGNAL_BIT closes this race, and makes sure that after fence_signal was called, any enable_signaling call will have either been completed, or never called at all.
-
struct
fence_cb
¶ callback for fence_add_callback
Definition
struct fence_cb {
struct list_head node;
fence_func_t func;
};
Members
node
- used by fence_add_callback to append this struct to fence::cb_list
func
- fence_func_t to call
Description
This struct will be initialized by fence_add_callback, additional data can be passed along by embedding fence_cb in another struct.
-
struct
fence_ops
¶ operations implemented for fence
Definition
struct fence_ops {
const char * (* get_driver_name) (struct fence *fence);
const char * (* get_timeline_name) (struct fence *fence);
bool (* enable_signaling) (struct fence *fence);
bool (* signaled) (struct fence *fence);
signed long (* wait) (struct fence *fence, bool intr, signed long timeout);
void (* release) (struct fence *fence);
int (* fill_driver_data) (struct fence *fence, void *data, int size);
void (* fence_value_str) (struct fence *fence, char *str, int size);
void (* timeline_value_str) (struct fence *fence, char *str, int size);
};
Members
get_driver_name
- returns the driver name.
get_timeline_name
- return the name of the context this fence belongs to.
enable_signaling
- enable software signaling of fence.
signaled
- [optional] peek whether the fence is signaled, can be null.
wait
- custom wait implementation, or fence_default_wait.
release
- [optional] called on destruction of fence, can be null
fill_driver_data
- [optional] callback to fill in free-form debug info Returns amount of bytes filled, or -errno.
fence_value_str
- [optional] fills in the value of the fence as a string
timeline_value_str
- [optional] fills in the current value of the timeline as a string
Description
Notes on enable_signaling:
For fence implementations that have the capability for hw->hw
signaling, they can implement this op to enable the necessary
irqs, or insert commands into cmdstream, etc. This is called
in the first wait()
or add_callback()
path to let the fence
implementation know that there is another driver waiting on
the signal (ie. hw->sw case).
This function can be called called from atomic context, but not from irq context, so normal spinlocks can be used.
A return value of false indicates the fence already passed, or some failure occurred that made it impossible to enable signaling. True indicates successful enabling.
fence->status may be set in enable_signaling, but only when false is returned.
Calling fence_signal before enable_signaling is called allows for a tiny race window in which enable_signaling is called during, before, or after fence_signal. To fight this, it is recommended that before enable_signaling returns true an extra reference is taken on the fence, to be released when the fence is signaled. This will mean fence_signal will still be called twice, but the second time will be a noop since it was already signaled.
Notes on signaled: May set fence->status if returning true.
Notes on wait: Must not be NULL, set to fence_default_wait for default implementation. the fence_default_wait implementation should work for any fence, as long as enable_signaling works correctly.
Must return -ERESTARTSYS if the wait is intr = true and the wait was interrupted, and remaining jiffies if fence has signaled, or 0 if wait timed out. Can also return other error values on custom implementations, which should be treated as if the fence is signaled. For example a hardware lockup could be reported like that.
Notes on release: Can be NULL, this function allows additional commands to run on destruction of the fence. Can be called from irq context. If pointer is set to NULL, kfree will get called instead.
Parameters
struct fence * fence
- [in] fence to increase refcount of
Description
Returns the same fence, with refcount increased by 1.
-
struct fence *
fence_get_rcu
(struct fence * fence)¶ get a fence from a reservation_object_list with rcu read lock
Parameters
struct fence * fence
- [in] fence to increase refcount of
Description
Function returns NULL if no refcount could be obtained, or the fence.
Parameters
struct fence * fence
- [in] fence to reduce refcount of
-
bool
fence_is_signaled_locked
(struct fence * fence)¶ Return an indication if the fence is signaled yet.
Parameters
struct fence * fence
- [in] the fence to check
Description
Returns true if the fence was already signaled, false if not. Since this function doesn’t enable signaling, it is not guaranteed to ever return true if fence_add_callback, fence_wait or fence_enable_sw_signaling haven’t been called before.
This function requires fence->lock to be held.
Parameters
struct fence * fence
- [in] the fence to check
Description
Returns true if the fence was already signaled, false if not. Since this function doesn’t enable signaling, it is not guaranteed to ever return true if fence_add_callback, fence_wait or fence_enable_sw_signaling haven’t been called before.
It’s recommended for seqno fences to call fence_signal when the operation is complete, it makes it possible to prevent issues from wraparound between time of issue and time of use by checking the return value of this function before calling hardware-specific wait instructions.
-
bool
fence_is_later
(struct fence * f1, struct fence * f2)¶ return if f1 is chronologically later than f2
Parameters
struct fence * f1
- [in] the first fence from the same context
struct fence * f2
- [in] the second fence from the same context
Description
Returns true if f1 is chronologically later than f2. Both fences must be from the same context, since a seqno is not re-used across contexts.
-
struct fence *
fence_later
(struct fence * f1, struct fence * f2)¶ return the chronologically later fence
Parameters
struct fence * f1
- [in] the first fence from the same context
struct fence * f2
- [in] the second fence from the same context
Description
Returns NULL if both fences are signaled, otherwise the fence that would be signaled last. Both fences must be from the same context, since a seqno is not re-used across contexts.
Parameters
struct fence * fence
- [in] the fence to wait on
bool intr
- [in] if true, do an interruptible wait
Description
This function will return -ERESTARTSYS if interrupted by a signal, or 0 if the fence was signaled. Other error values may be returned on custom implementations.
Performs a synchronous wait on this fence. It is assumed the caller directly or indirectly holds a reference to the fence, otherwise the fence might be freed before return, resulting in undefined behavior.
Parameters
struct fence * fence
- fence to cast to a seqno_fence
Description
Returns NULL if the fence is not a seqno_fence, or the seqno_fence otherwise.
-
void
seqno_fence_init
(struct seqno_fence * fence, spinlock_t * lock, struct dma_buf * sync_buf, uint32_t context, uint32_t seqno_ofs, uint32_t seqno, enum seqno_fence_condition cond, const struct fence_ops * ops)¶ initialize a seqno fence
Parameters
struct seqno_fence * fence
- seqno_fence to initialize
spinlock_t * lock
- pointer to spinlock to use for fence
struct dma_buf * sync_buf
- buffer containing the memory location to signal on
uint32_t context
- the execution context this fence is a part of
uint32_t seqno_ofs
- the offset within sync_buf
uint32_t seqno
- the sequence # to signal on
enum seqno_fence_condition cond
- fence wait condition
const struct fence_ops * ops
- the fence_ops for operations on this seqno fence
Description
This function initializes a struct seqno_fence with passed parameters, and takes a reference on sync_buf which is released on fence destruction.
A seqno_fence is a dma_fence which can complete in software when enable_signaling is called, but it also completes when (s32)((sync_buf)[seqno_ofs] - seqno) >= 0 is true
The seqno_fence will take a refcount on the sync_buf until it’s destroyed, but actual lifetime of sync_buf may be longer if one of the callers take a reference to it.
Certain hardware have instructions to insert this type of wait condition in the command stream, so no intervention from software would be needed. This type of fence can be destroyed before completed, however a reference on the sync_buf dma-buf can be taken. It is encouraged to re-use the same dma-buf for sync_buf, since mapping or unmapping the sync_buf to the device’s vm can be expensive.
It is recommended for creators of seqno_fence to call fence_signal before destruction. This will prevent possible issues from wraparound at time of issue vs time of check, since users can check fence_is_signaled before submitting instructions for the hardware to wait on the fence. However, when ops.enable_signaling is not called, it doesn’t have to be done as soon as possible, just before there’s any real danger of seqno wraparound.
-
struct fence_array *
fence_array_create
(int num_fences, struct fence ** fences, u64 context, unsigned seqno, bool signal_on_any)¶ Create a custom fence array
Parameters
int num_fences
- [in] number of fences to add in the array
struct fence ** fences
- [in] array containing the fences
u64 context
- [in] fence context to use
unsigned seqno
- [in] sequence number to use
bool signal_on_any
- [in] signal on any fence in the array
Description
Allocate a fence_array object and initialize the base fence with fence_init()
.
In case of error it returns NULL.
The caller should allocate the fences array with num_fences size
and fill it with the fences it wants to add to the object. Ownership of this
array is taken and fence_put()
is used on each fence on release.
If signal_on_any is true the fence array signals if any fence in the array signals, otherwise it signals when all fences in the array signal.
-
struct
fence_array_cb
¶ callback helper for fence array
Definition
struct fence_array_cb {
struct fence_cb cb;
struct fence_array * array;
};
Members
cb
- fence callback structure for signaling
array
- reference to the parent fence array object
-
struct
fence_array
¶ fence to represent an array of fences
Definition
struct fence_array {
struct fence base;
spinlock_t lock;
unsigned num_fences;
atomic_t num_pending;
struct fence ** fences;
};
Members
base
- fence base class
lock
- spinlock for fence handling
num_fences
- number of fences in the array
num_pending
- fences in the array still pending
fences
- array of the fences
Parameters
struct fence * fence
- undescribed
Description
Return true if it is a fence_array and false otherwise.
-
struct fence_array *
to_fence_array
(struct fence * fence)¶ cast a fence to a fence_array
Parameters
struct fence * fence
- fence to cast to a fence_array
Description
Returns NULL if the fence is not a fence_array, or the fence_array otherwise.
-
int
reservation_object_reserve_shared
(struct reservation_object * obj) Reserve space to add a shared fence to a reservation_object.
Parameters
struct reservation_object * obj
- reservation object
Description
Should be called before reservation_object_add_shared_fence()
. Must
be called with obj->lock held.
RETURNS Zero for success, or -errno
-
void
reservation_object_add_shared_fence
(struct reservation_object * obj, struct fence * fence) Add a fence to a shared slot
Parameters
struct reservation_object * obj
- the reservation object
struct fence * fence
- the shared fence to add
Description
Add a fence to a shared slot, obj->lock must be held, and
reservation_object_reserve_shared()
has been called.
-
void
reservation_object_add_excl_fence
(struct reservation_object * obj, struct fence * fence) Add an exclusive fence.
Parameters
struct reservation_object * obj
- the reservation object
struct fence * fence
- the shared fence to add
Description
Add a fence to the exclusive slot. The obj->lock must be held.
-
int
reservation_object_get_fences_rcu
(struct reservation_object * obj, struct fence ** pfence_excl, unsigned * pshared_count, struct fence *** pshared) Get an object’s shared and exclusive fences without update side lock held
Parameters
struct reservation_object * obj
- the reservation object
struct fence ** pfence_excl
- the returned exclusive fence (or NULL)
unsigned * pshared_count
- the number of shared fences returned
struct fence *** pshared
- the array of shared fence ptrs returned (array is krealloc’d to the required size, and must be freed by caller)
Description
RETURNS Zero or -errno
-
long
reservation_object_wait_timeout_rcu
(struct reservation_object * obj, bool wait_all, bool intr, unsigned long timeout) Wait on reservation’s objects shared and/or exclusive fences.
Parameters
struct reservation_object * obj
- the reservation object
bool wait_all
- if true, wait on all fences, else wait on just exclusive fence
bool intr
- if true, do interruptible wait
unsigned long timeout
- timeout value in jiffies or zero to return immediately
Description
RETURNS Returns -ERESTARTSYS if interrupted, 0 if the wait timed out, or greater than zer on success.
-
bool
reservation_object_test_signaled_rcu
(struct reservation_object * obj, bool test_all) Test if a reservation object’s fences have been signaled.
Parameters
struct reservation_object * obj
- the reservation object
bool test_all
- if true, test all fences, otherwise only test the exclusive fence
Description
RETURNS true if all fences signaled, else false
-
struct
reservation_object_list
a list of shared fences
Definition
struct reservation_object_list {
struct rcu_head rcu;
u32 shared_count;
u32 shared_max;
struct fence __rcu * shared[];
};
Members
rcu
- for internal use
shared_count
- table of shared fences
shared_max
- for growing shared fence table
shared[]
- shared fence table
-
struct
reservation_object
a reservation object manages fences for a buffer
Definition
struct reservation_object {
struct ww_mutex lock;
seqcount_t seq;
struct fence __rcu * fence_excl;
struct reservation_object_list __rcu * fence;
struct reservation_object_list * staged;
};
Members
lock
- update side lock
seq
- sequence count for managing RCU read-side synchronization
fence_excl
- the exclusive fence, if there is one currently
fence
- list of current shared fences
staged
- staged copy of shared fences for RCU updates
-
void
reservation_object_init
(struct reservation_object * obj) initialize a reservation object
Parameters
struct reservation_object * obj
- the reservation object
-
void
reservation_object_fini
(struct reservation_object * obj) destroys a reservation object
Parameters
struct reservation_object * obj
- the reservation object
-
struct reservation_object_list *
reservation_object_get_list
(struct reservation_object * obj) get the reservation object’s shared fence list, with update-side lock held
Parameters
struct reservation_object * obj
- the reservation object
Description
Returns the shared fence list. Does NOT take references to the fence. The obj->lock must be held.
-
struct fence *
reservation_object_get_excl
(struct reservation_object * obj) get the reservation object’s exclusive fence, with update-side lock held
Parameters
struct reservation_object * obj
- the reservation object
Description
Returns the exclusive fence (if any). Does NOT take a reference. The obj->lock must be held.
RETURNS The exclusive fence or NULL
-
struct fence *
reservation_object_get_excl_rcu
(struct reservation_object * obj) get the reservation object’s exclusive fence, without lock held.
Parameters
struct reservation_object * obj
- the reservation object
Description
If there is an exclusive fence, this atomically increments it’s reference count and returns it.
RETURNS The exclusive fence or NULL if none
Parameters
struct fence * fence
- fence to add to the sync_fence
Description
Creates a sync_file containg fence. Once this is called, the sync_file takes ownership of fence. The sync_file can be released with fput(sync_file->file). Returns the sync_file or NULL in case of error.
Parameters
int fd
- sync_file fd to get the fence from
Description
Ensures fd references a valid sync_file and returns a fence that represents all fence in the sync_file. On error NULL is returned.
-
struct
sync_file
¶ sync file to export to the userspace
Definition
struct sync_file {
struct file * file;
struct kref kref;
char name[32];
#ifdef CONFIG_DEBUG_FS
struct list_head sync_file_list;
#endif
wait_queue_head_t wq;
struct fence * fence;
struct fence_cb cb;
};
Members
file
- file representing this fence
kref
- reference count on fence.
name[32]
- name of sync_file. Useful for debugging
sync_file_list
- membership in global file list
wq
- wait queue for fence signaling
fence
- fence with the fences in the sync_file
cb
- fence callback information
Device Drivers DMA Management¶
-
int
dma_alloc_from_coherent
(struct device * dev, ssize_t size, dma_addr_t * dma_handle, void ** ret)¶ try to allocate memory from the per-device coherent area
Parameters
struct device * dev
- device from which we allocate memory
ssize_t size
- size of requested memory area
dma_addr_t * dma_handle
- This will be filled with the correct dma handle
void ** ret
- This pointer will be filled with the virtual address to allocated area.
Description
This function should be only called from per-arch dma_alloc_coherent()
to support allocation from per-device coherent memory pools.
Returns 0 if dma_alloc_coherent should continue with allocating from generic memory areas, or !0 if dma_alloc_coherent should return ret.
-
int
dma_release_from_coherent
(struct device * dev, int order, void * vaddr)¶ try to free the memory allocated from per-device coherent memory pool
Parameters
struct device * dev
- device from which the memory was allocated
int order
- the order of pages allocated
void * vaddr
- virtual address of allocated pages
Description
This checks whether the memory was allocated from the per-device coherent memory pool and if so, releases that memory.
Returns 1 if we correctly released the memory, or 0 if
dma_release_coherent()
should proceed with releasing memory from
generic pools.
-
int
dma_mmap_from_coherent
(struct device * dev, struct vm_area_struct * vma, void * vaddr, size_t size, int * ret)¶ try to mmap the memory allocated from per-device coherent memory pool to userspace
Parameters
struct device * dev
- device from which the memory was allocated
struct vm_area_struct * vma
- vm_area for the userspace memory
void * vaddr
- cpu address returned by dma_alloc_from_coherent
size_t size
- size of the memory buffer allocated by dma_alloc_from_coherent
int * ret
- result from
remap_pfn_range()
Description
This checks whether the memory was allocated from the per-device coherent memory pool and if so, maps that memory to the provided vma.
Returns 1 if we correctly mapped the memory, or 0 if the caller should proceed with mapping memory from generic pools.
-
void *
dmam_alloc_coherent
(struct device * dev, size_t size, dma_addr_t * dma_handle, gfp_t gfp)¶ Managed
dma_alloc_coherent()
Parameters
struct device * dev
- Device to allocate 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
Description
Managed dma_alloc_coherent()
. Memory allocated using this function
will be automatically released on driver detach.
Return
Pointer to allocated memory on success, NULL on failure.
-
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_noncoherent
(struct device * dev, size_t size, dma_addr_t * dma_handle, gfp_t gfp)¶ Managed
dma_alloc_non_coherent()
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
Description
Managed dma_alloc_non_coherent()
. Memory allocated using this
function will be automatically released on driver detach.
Return
Pointer to allocated memory on success, NULL on failure.
-
void
dmam_free_noncoherent
(struct device * dev, size_t size, void * vaddr, dma_addr_t dma_handle)¶ Managed
dma_free_noncoherent()
Parameters
struct device * dev
- Device to free noncoherent 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_noncoherent()
.
-
int
dmam_declare_coherent_memory
(struct device * dev, phys_addr_t phys_addr, dma_addr_t device_addr, size_t size, int flags)¶ Managed
dma_declare_coherent_memory()
Parameters
struct device * dev
- Device to declare coherent memory for
phys_addr_t phys_addr
- Physical address of coherent memory to be declared
dma_addr_t device_addr
- Device address of coherent memory to be declared
size_t size
- Size of coherent memory to be declared
int flags
- Flags
Description
Managed dma_declare_coherent_memory()
.
Return
0 on success, -errno on failure.
Parameters
struct device * dev
- Device to release declared coherent memory for
Description
Managed dmam_release_declared_memory()
.
Device Drivers Power Management¶
-
void
dpm_resume_start
(pm_message_t state)¶ Execute “noirq” and “early” device callbacks.
Parameters
pm_message_t state
- PM transition of the system being carried out.
-
void
dpm_resume_end
(pm_message_t state)¶ Execute “resume” callbacks and complete system transition.
Parameters
pm_message_t state
- PM transition of the system being carried out.
Description
Execute “resume” callbacks for all devices and complete the PM transition of the system.
-
int
dpm_suspend_end
(pm_message_t state)¶ Execute “late” and “noirq” device suspend callbacks.
Parameters
pm_message_t state
- PM transition of the system being carried out.
-
int
dpm_suspend_start
(pm_message_t state)¶ Prepare devices for PM transition and suspend them.
Parameters
pm_message_t state
- PM transition of the system being carried out.
Description
Prepare all non-sysdev devices for system PM transition and execute “suspend” callbacks for them.
-
int
device_pm_wait_for_dev
(struct device * subordinate, struct device * dev)¶ Wait for suspend/resume of a device to complete.
Parameters
struct device * subordinate
- Device that needs to wait for dev.
struct device * dev
- Device to wait for.
Parameters
void * data
- data for the callback.
void (*)(struct device *, void *) fn
- function to be called for each device.
Description
Iterate over devices in dpm_list, and call fn for each device, passing it data.
Device Drivers ACPI Support¶
-
int
acpi_bus_scan
(acpi_handle handle)¶ Add ACPI device node objects in a given namespace scope.
Parameters
acpi_handle handle
- Root of the namespace scope to scan.
Description
Scan a given ACPI tree (probably recently hot-plugged) and create and add found devices.
If no devices were found, -ENODEV is returned, but it does not mean that there has been a real error. There just have been no suitable ACPI objects in the table trunk from which the kernel could create a device and add an appropriate driver.
Must be called under acpi_scan_lock.
-
void
acpi_bus_trim
(struct acpi_device * adev)¶ Detach scan handlers and drivers from ACPI device objects.
Parameters
struct acpi_device * adev
- Root of the ACPI namespace scope to walk.
Description
Must be called under acpi_scan_lock.
-
void
acpi_scan_drop_device
(acpi_handle handle, void * context)¶ Drop an ACPI device object.
Parameters
acpi_handle handle
- Handle of an ACPI namespace node, not used.
void * context
- Address of the ACPI device object to drop.
Description
This is invoked by acpi_ns_delete_node()
during the removal of the ACPI
namespace node the device object pointed to by context is attached to.
The unregistration is carried out asynchronously to avoid running
acpi_device_del()
under the ACPICA’s namespace mutex and the list is used to
ensure the correct ordering (the device objects must be unregistered in the
same order in which the corresponding namespace nodes are deleted).
-
bool
acpi_dma_supported
(struct acpi_device * adev)¶ Check DMA support for the specified device.
Parameters
struct acpi_device * adev
- The pointer to acpi device
Description
Return false if DMA is not supported. Otherwise, return true
-
enum dev_dma_attr
acpi_get_dma_attr
(struct acpi_device * adev)¶ Check the supported DMA attr for the specified device.
Parameters
struct acpi_device * adev
- The pointer to acpi device
Description
Return enum dev_dma_attr.
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
Description
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¶
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.
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;
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 (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)
size
- size of IO
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[MAX_UIO_MAPS]
- list of mappable memory regions, size==0 for end of list
port[MAX_UIO_PORT_REGIONS]
- 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