// SPDX-License-Identifier: GPL-2.0
/*
* device . h - generic , centralized driver model
*
* Copyright ( c ) 2001 - 2003 Patrick Mochel < mochel @ osdl . org >
* Copyright ( c ) 2004 - 2009 Greg Kroah - Hartman < gregkh @ suse . de >
* Copyright ( c ) 2008 - 2009 Novell Inc .
*
* See Documentation / driver - api / driver - model / for more information .
*/
#ifndef _DEVICE_H_
#define _DEVICE_H_
#include <linux/dev_printk.h>
#include <linux/energy_model.h>
#include <linux/ioport.h>
#include <linux/kobject.h>
#include <linux/klist.h>
#include <linux/list.h>
#include <linux/lockdep.h>
#include <linux/compiler.h>
#include <linux/types.h>
#include <linux/mutex.h>
#include <linux/pm.h>
#include <linux/atomic.h>
#include <linux/uidgid.h>
#include <linux/gfp.h>
#include <linux/device/bus.h>
#include <linux/device/class .h>
#include <linux/device/devres.h>
#include <linux/device/driver.h>
#include <linux/cleanup.h>
#include <asm /device.h>
struct device;
struct device_private;
struct device_driver;
struct driver_private;
struct module;
struct class ;
struct subsys_private;
struct device_node;
struct fwnode_handle;
struct iommu_group;
struct dev_pin_info;
struct dev_iommu;
struct msi_device_data;
/**
* struct subsys_interface - interfaces to device functions
* @ name : name of the device function
* @ subsys : subsystem of the devices to attach to
* @ node : the list of functions registered at the subsystem
* @ add_dev : device hookup to device function handler
* @ remove_dev : device hookup to device function handler
*
* 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 subsys_interface {
const char *name;
const 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);
};
int subsys_interface_register(struct subsys_interface *sif);
void subsys_interface_unregister(struct subsys_interface *sif);
int subsys_system_register(const struct bus_type *subsys,
const struct attribute_group **groups);
int subsys_virtual_register(const struct bus_type *subsys,
const struct attribute_group **groups);
/*
* The type of device , " struct device " is embedded in . A class
* or bus can contain devices of different types
* like " partitions " and " disks " , " mouse " and " event " .
* This identifies the device type and carries type - specific
* information , equivalent to the kobj_type of a kobject .
* If " name " is specified , the uevent will contain it in
* the DEVTYPE variable .
*/
struct device_type {
const char *name;
const struct attribute_group **groups;
int (*uevent)(const struct device *dev, struct kobj_uevent_env *env);
char *(*devnode)(const struct device *dev, umode_t *mode,
kuid_t *uid, kgid_t *gid);
void (*release)(struct device *dev);
const struct dev_pm_ops *pm;
};
/**
* struct device_attribute - Interface for exporting device attributes .
* @ attr : sysfs attribute definition .
* @ show : Show handler .
* @ store : Store handler .
*/
struct device_attribute {
struct attribute attr;
ssize_t (*show)(struct device *dev, struct device_attribute *attr,
char *buf);
ssize_t (*store)(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count);
};
/**
* struct dev_ext_attribute - Exported device attribute with extra context .
* @ attr : Exported device attribute .
* @ var : Pointer to context .
*/
struct dev_ext_attribute {
struct device_attribute attr;
void *var;
};
ssize_t device_show_ulong(struct device *dev, struct device_attribute *attr,
char *buf);
ssize_t device_store_ulong(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count);
ssize_t device_show_int(struct device *dev, struct device_attribute *attr,
char *buf);
ssize_t device_store_int(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count);
ssize_t device_show_bool(struct device *dev, struct device_attribute *attr,
char *buf);
ssize_t device_store_bool(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count);
ssize_t device_show_string(struct device *dev, struct device_attribute *attr,
char *buf);
/**
* DEVICE_ATTR - Define a device attribute .
* @ _ name : Attribute name .
* @ _ mode : File mode .
* @ _ show : Show handler . Optional , but mandatory if attribute is readable .
* @ _ store : Store handler . Optional , but mandatory if attribute is writable .
*
* Convenience macro for defining a struct device_attribute .
*
* For example , ` ` DEVICE_ATTR ( foo , 0644 , foo_show , foo_store ) ; ` ` expands to :
*
* . . code - block : : c
*
* struct device_attribute dev_attr_foo = {
* . attr = { . name = " foo " , . mode = 0644 } ,
* . show = foo_show ,
* . store = foo_store ,
* } ;
*/
#define DEVICE_ATTR(_name, _mode, _show, _store) \
struct device_attribute dev_attr_## _name = __ATTR(_name, _mode, _show, _store)
/**
* DEVICE_ATTR_PREALLOC - Define a preallocated device attribute .
* @ _ name : Attribute name .
* @ _ mode : File mode .
* @ _ show : Show handler . Optional , but mandatory if attribute is readable .
* @ _ store : Store handler . Optional , but mandatory if attribute is writable .
*
* Like DEVICE_ATTR ( ) , but ` ` SYSFS_PREALLOC ` ` is set on @ _ mode .
*/
#define DEVICE_ATTR_PREALLOC(_name, _mode, _show, _store) \
struct device_attribute dev_attr_## _name = \
__ATTR_PREALLOC(_name, _mode, _show, _store)
/**
* DEVICE_ATTR_RW - Define a read - write device attribute .
* @ _ name : Attribute name .
*
* Like DEVICE_ATTR ( ) , but @ _ mode is 0644 , @ _ show is < _ name > _ show ,
* and @ _ store is < _ name > _ store .
*/
#define DEVICE_ATTR_RW(_name) \
struct device_attribute dev_attr_## _name = __ATTR_RW(_name)
/**
* DEVICE_ATTR_ADMIN_RW - Define an admin - only read - write device attribute .
* @ _ name : Attribute name .
*
* Like DEVICE_ATTR_RW ( ) , but @ _ mode is 0600 .
*/
#define DEVICE_ATTR_ADMIN_RW(_name) \
struct device_attribute dev_attr_## _name = __ATTR_RW_MODE(_name, 0600 )
/**
* DEVICE_ATTR_RO - Define a readable device attribute .
* @ _ name : Attribute name .
*
* Like DEVICE_ATTR ( ) , but @ _ mode is 0444 and @ _ show is < _ name > _ show .
*/
#define DEVICE_ATTR_RO(_name) \
struct device_attribute dev_attr_## _name = __ATTR_RO(_name)
/**
* DEVICE_ATTR_ADMIN_RO - Define an admin - only readable device attribute .
* @ _ name : Attribute name .
*
* Like DEVICE_ATTR_RO ( ) , but @ _ mode is 0400 .
*/
#define DEVICE_ATTR_ADMIN_RO(_name) \
struct device_attribute dev_attr_## _name = __ATTR_RO_MODE(_name, 0400 )
/**
* DEVICE_ATTR_WO - Define an admin - only writable device attribute .
* @ _ name : Attribute name .
*
* Like DEVICE_ATTR ( ) , but @ _ mode is 0200 and @ _ store is < _ name > _ store .
*/
#define DEVICE_ATTR_WO(_name) \
struct device_attribute dev_attr_## _name = __ATTR_WO(_name)
/**
* DEVICE_ULONG_ATTR - Define a device attribute backed by an unsigned long .
* @ _ name : Attribute name .
* @ _ mode : File mode .
* @ _ var : Identifier of unsigned long .
*
* Like DEVICE_ATTR ( ) , but @ _ show and @ _ store are automatically provided
* such that reads and writes to the attribute from userspace affect @ _ var .
*/
#define DEVICE_ULONG_ATTR(_name, _mode, _var) \
struct dev_ext_attribute dev_attr_## _name = \
{ __ATTR(_name, _mode, device_show_ulong, device_store_ulong), &(_var) }
/**
* DEVICE_INT_ATTR - Define a device attribute backed by an int .
* @ _ name : Attribute name .
* @ _ mode : File mode .
* @ _ var : Identifier of int .
*
* Like DEVICE_ULONG_ATTR ( ) , but @ _ var is an int .
*/
#define DEVICE_INT_ATTR(_name, _mode, _var) \
struct dev_ext_attribute dev_attr_## _name = \
{ __ATTR(_name, _mode, device_show_int, device_store_int), &(_var) }
/**
* DEVICE_BOOL_ATTR - Define a device attribute backed by a bool .
* @ _ name : Attribute name .
* @ _ mode : File mode .
* @ _ var : Identifier of bool .
*
* Like DEVICE_ULONG_ATTR ( ) , but @ _ var is a bool .
*/
#define DEVICE_BOOL_ATTR(_name, _mode, _var) \
struct dev_ext_attribute dev_attr_## _name = \
{ __ATTR(_name, _mode, device_show_bool, device_store_bool), &(_var) }
/**
* DEVICE_STRING_ATTR_RO - Define a device attribute backed by a r / o string .
* @ _ name : Attribute name .
* @ _ mode : File mode .
* @ _ var : Identifier of string .
*
* Like DEVICE_ULONG_ATTR ( ) , but @ _ var is a string . Because the length of the
* string allocation is unknown , the attribute must be read - only .
*/
#define DEVICE_STRING_ATTR_RO(_name, _mode, _var) \
struct dev_ext_attribute dev_attr_## _name = \
{ __ATTR(_name, (_mode) & ~0222 , device_show_string, NULL), (_var) }
#define DEVICE_ATTR_IGNORE_LOCKDEP(_name, _mode, _show, _store) \
struct device_attribute dev_attr_## _name = \
__ATTR_IGNORE_LOCKDEP(_name, _mode, _show, _store)
int device_create_file(struct device *device,
const struct device_attribute *entry);
void device_remove_file(struct device *dev,
const struct device_attribute *attr);
bool device_remove_file_self(struct device *dev,
const struct device_attribute *attr);
int __must_check device_create_bin_file(struct device *dev,
const struct bin_attribute *attr);
void device_remove_bin_file(struct device *dev,
const struct bin_attribute *attr);
/**
* devm_alloc_percpu - Resource - managed alloc_percpu
* @ dev : Device to allocate per - cpu memory for
* @ type : Type to allocate per - cpu memory for
*
* Managed alloc_percpu . Per - cpu memory allocated with this function is
* automatically freed on driver detach .
*
* RETURNS :
* Pointer to allocated memory on success , NULL on failure .
*/
#define devm_alloc_percpu(dev, type) \
((typeof(type) __percpu *)__devm_alloc_percpu((dev), sizeof (type), \
__alignof__(type)))
void __percpu *__devm_alloc_percpu(struct device *dev, size_t size,
size_t align);
void devm_free_percpu(struct device *dev, void __percpu *pdata);
struct device_dma_parameters {
/*
* a low level driver may set these to teach IOMMU code about
* sg limitations .
*/
unsigned int max_segment_size;
unsigned int min_align_mask;
unsigned long segment_boundary_mask;
};
/**
* enum device_link_state - Device link states .
* @ DL_STATE_NONE : The presence of the drivers is not being tracked .
* @ DL_STATE_DORMANT : None of the supplier / consumer drivers is present .
* @ DL_STATE_AVAILABLE : The supplier driver is present , but the consumer is not .
* @ DL_STATE_CONSUMER_PROBE : The consumer is probing ( supplier driver present ) .
* @ DL_STATE_ACTIVE : Both the supplier and consumer drivers are present .
* @ DL_STATE_SUPPLIER_UNBIND : The supplier driver is unbinding .
*/
enum device_link_state {
DL_STATE_NONE = -1 ,
DL_STATE_DORMANT = 0 ,
DL_STATE_AVAILABLE,
DL_STATE_CONSUMER_PROBE,
DL_STATE_ACTIVE,
DL_STATE_SUPPLIER_UNBIND,
};
/*
* Device link flags .
*
* STATELESS : The core will not remove this link automatically .
* AUTOREMOVE_CONSUMER : Remove the link automatically on consumer driver unbind .
* PM_RUNTIME : If set , the runtime PM framework will use this link .
* RPM_ACTIVE : Run pm_runtime_get_sync ( ) on the supplier during link creation .
* AUTOREMOVE_SUPPLIER : Remove the link automatically on supplier driver unbind .
* AUTOPROBE_CONSUMER : Probe consumer driver automatically after supplier binds .
* MANAGED : The core tracks presence of supplier / consumer drivers ( internal ) .
* SYNC_STATE_ONLY : Link only affects sync_state ( ) behavior .
* INFERRED : Inferred from data ( eg : firmware ) and not from driver actions .
*/
#define DL_FLAG_STATELESS BIT(0 )
#define DL_FLAG_AUTOREMOVE_CONSUMER BIT(1 )
#define DL_FLAG_PM_RUNTIME BIT(2 )
#define DL_FLAG_RPM_ACTIVE BIT(3 )
#define DL_FLAG_AUTOREMOVE_SUPPLIER BIT(4 )
#define DL_FLAG_AUTOPROBE_CONSUMER BIT(5 )
#define DL_FLAG_MANAGED BIT(6 )
#define DL_FLAG_SYNC_STATE_ONLY BIT(7 )
#define DL_FLAG_INFERRED BIT(8 )
#define DL_FLAG_CYCLE BIT(9 )
/**
* enum dl_dev_state - Device driver presence tracking information .
* @ DL_DEV_NO_DRIVER : There is no driver attached to the device .
* @ DL_DEV_PROBING : A driver is probing .
* @ DL_DEV_DRIVER_BOUND : The driver has been bound to the device .
* @ DL_DEV_UNBINDING : The driver is unbinding from the device .
*/
enum dl_dev_state {
DL_DEV_NO_DRIVER = 0 ,
DL_DEV_PROBING,
DL_DEV_DRIVER_BOUND,
DL_DEV_UNBINDING,
};
/**
* enum device_removable - Whether the device is removable . The criteria for a
* device to be classified as removable is determined by its subsystem or bus .
* @ DEVICE_REMOVABLE_NOT_SUPPORTED : This attribute is not supported for this
* device ( default ) .
* @ DEVICE_REMOVABLE_UNKNOWN : Device location is Unknown .
* @ DEVICE_FIXED : Device is not removable by the user .
* @ DEVICE_REMOVABLE : Device is removable by the user .
*/
enum device_removable {
DEVICE_REMOVABLE_NOT_SUPPORTED = 0 , /* must be 0 */
DEVICE_REMOVABLE_UNKNOWN,
DEVICE_FIXED,
DEVICE_REMOVABLE,
};
/**
* struct dev_links_info - Device data related to device links .
* @ suppliers : List of links to supplier devices .
* @ consumers : List of links to consumer devices .
* @ defer_sync : Hook to global list of devices that have deferred sync_state .
* @ status : Driver status information .
*/
struct dev_links_info {
struct list_head suppliers;
struct list_head consumers;
struct list_head defer_sync;
enum dl_dev_state status;
};
/**
* struct dev_msi_info - Device data related to MSI
* @ domain : The MSI interrupt domain associated to the device
* @ data : Pointer to MSI device data
*/
struct dev_msi_info {
#ifdef CONFIG_GENERIC_MSI_IRQ
struct irq_domain *domain;
struct msi_device_data *data;
#endif
};
/**
* enum device_physical_location_panel - Describes which panel surface of the
* system ' s housing the device connection point resides on .
* @ DEVICE_PANEL_TOP : Device connection point is on the top panel .
* @ DEVICE_PANEL_BOTTOM : Device connection point is on the bottom panel .
* @ DEVICE_PANEL_LEFT : Device connection point is on the left panel .
* @ DEVICE_PANEL_RIGHT : Device connection point is on the right panel .
* @ DEVICE_PANEL_FRONT : Device connection point is on the front panel .
* @ DEVICE_PANEL_BACK : Device connection point is on the back panel .
* @ DEVICE_PANEL_UNKNOWN : The panel with device connection point is unknown .
*/
enum device_physical_location_panel {
DEVICE_PANEL_TOP,
DEVICE_PANEL_BOTTOM,
DEVICE_PANEL_LEFT,
DEVICE_PANEL_RIGHT,
DEVICE_PANEL_FRONT,
DEVICE_PANEL_BACK,
DEVICE_PANEL_UNKNOWN,
};
/**
* enum device_physical_location_vertical_position - Describes vertical
* position of the device connection point on the panel surface .
* @ DEVICE_VERT_POS_UPPER : Device connection point is at upper part of panel .
* @ DEVICE_VERT_POS_CENTER : Device connection point is at center part of panel .
* @ DEVICE_VERT_POS_LOWER : Device connection point is at lower part of panel .
*/
enum device_physical_location_vertical_position {
DEVICE_VERT_POS_UPPER,
DEVICE_VERT_POS_CENTER,
DEVICE_VERT_POS_LOWER,
};
/**
* enum device_physical_location_horizontal_position - Describes horizontal
* position of the device connection point on the panel surface .
* @ DEVICE_HORI_POS_LEFT : Device connection point is at left part of panel .
* @ DEVICE_HORI_POS_CENTER : Device connection point is at center part of panel .
* @ DEVICE_HORI_POS_RIGHT : Device connection point is at right part of panel .
*/
enum device_physical_location_horizontal_position {
DEVICE_HORI_POS_LEFT,
DEVICE_HORI_POS_CENTER,
DEVICE_HORI_POS_RIGHT,
};
/**
* struct device_physical_location - Device data related to physical location
* of the device connection point .
* @ panel : Panel surface of the system ' s housing that the device connection
* point resides on .
* @ vertical_position : Vertical position of the device connection point within
* the panel .
* @ horizontal_position : Horizontal position of the device connection point
* within the panel .
* @ dock : Set if the device connection point resides in a docking station or
* port replicator .
* @ lid : Set if this device connection point resides on the lid of laptop
* system .
*/
struct device_physical_location {
enum device_physical_location_panel panel;
enum device_physical_location_vertical_position vertical_position;
enum device_physical_location_horizontal_position horizontal_position;
bool dock;
bool lid;
};
/**
* struct device - The basic device structure
* @ 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 .
* 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 .
* @ driver_data : Private pointer for driver specific info .
* @ links : Links to suppliers and consumers of this device .
* @ power : For device power management .
* See Documentation / driver - api / pm / devices . rst for details .
* @ pm_domain : Provide callbacks that are executed during system suspend ,
* hibernation , system resume and during runtime PM transitions
* along with subsystem - level and driver - level callbacks .
* @ em_pd : device ' s energy model performance domain
* @ pins : For device pin management .
* See Documentation / driver - api / pin - control . rst for details .
* @ msi : MSI related data
* @ numa_node : NUMA node this device is close to .
* @ dma_ops : DMA mapping operations for this device .
* @ dma_mask : Dma mask ( if dma ' ble device ) .
* @ coherent_dma_mask : Like dma_mask , but for alloc_coherent mapping as not all
* hardware supports 64 - bit addresses for consistent allocations
* such descriptors .
* @ bus_dma_limit : Limit of an upstream bridge or bus which imposes a smaller
* DMA limit than the device itself supports .
* @ dma_range_map : map for DMA memory ranges relative to that of RAM
* @ dma_parms : A low level driver may set these to teach IOMMU code about
* segment limitations .
* @ dma_pools : Dma pools ( if dma ' ble device ) .
* @ dma_mem : Internal for coherent mem override .
* @ cma_area : Contiguous memory area for dma allocations
* @ dma_io_tlb_mem : Software IO TLB allocator . Not for driver use .
* @ dma_io_tlb_pools : List of transient swiotlb memory pools .
* @ dma_io_tlb_lock : Protects changes to the list of active pools .
* @ dma_uses_io_tlb : % true if device has used the software IO TLB .
* @ 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 .
* @ class : The class of the device .
* @ groups : Optional attribute groups .
* @ release : Callback to free the device after all references have
* gone away . This should be set by the allocator of the
* device ( i . e . the bus driver that discovered the device ) .
* @ iommu_group : IOMMU group the device belongs to .
* @ iommu : Per device generic IOMMU runtime data
* @ physical_location : Describes physical location of the device connection
* point in the system housing .
* @ removable : Whether the device can be removed from the system . This
* should be set by the subsystem / bus driver that discovered
* the device .
*
* @ offline_disabled : If set , the device is permanently online .
* @ offline : Set after successful invocation of bus type ' s . offline ( ) .
* @ of_node_reused : Set if the device - tree node is shared with an ancestor
* device .
* @ state_synced : The hardware state of this device has been synced to match
* the software state of this device by calling the driver / bus
* sync_state ( ) callback .
* @ can_match : The device has matched with a driver at least once or it is in
* a bus ( like AMBA ) which can ' t check for matching drivers until
* other devices probe successfully .
* @ dma_coherent : this particular device is dma coherent , even if the
* architecture supports non - coherent devices .
* @ dma_ops_bypass : If set to % true then the dma_ops are bypassed for the
* streaming DMA operations ( - > map_ * / - > unmap_ * / - > sync_ * ) ,
* and optionall ( if the coherent mask is large enough ) also
* for dma allocations . This flag is managed by the dma ops
* instance from - > dma_supported .
* @ dma_skip_sync : DMA sync operations can be skipped for coherent buffers .
* @ dma_iommu : Device is using default IOMMU implementation for DMA and
* doesn ' t rely on dma_ops structure .
*
* 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 .
*/
struct device {
struct kobject kobj;
struct device *parent;
struct device_private *p;
const char *init_name; /* initial name of the device */
const struct device_type *type;
const struct bus_type *bus; /* type of bus device is on */
struct device_driver *driver; /* which driver has allocated this
device */
void *platform_data; /* Platform specific data, device
core doesn't touch it */
void *driver_data; /* Driver data, set and get with
dev_set_drvdata/dev_get_drvdata */
struct mutex mutex; /* mutex to synchronize calls to
* its driver .
*/
struct dev_links_info links;
struct dev_pm_info power;
struct dev_pm_domain *pm_domain;
#ifdef CONFIG_ENERGY_MODEL
struct em_perf_domain *em_pd;
#endif
#ifdef CONFIG_PINCTRL
struct dev_pin_info *pins;
#endif
struct dev_msi_info msi;
#ifdef CONFIG_ARCH_HAS_DMA_OPS
const struct dma_map_ops *dma_ops;
#endif
u64 *dma_mask; /* dma mask (if dma'able device) */
u64 coherent_dma_mask;/* Like dma_mask, but for
alloc_coherent mappings as
not all hardware supports
64 bit addresses for consistent
allocations such descriptors. */
u64 bus_dma_limit; /* upstream dma constraint */
const struct bus_dma_region *dma_range_map;
struct device_dma_parameters *dma_parms;
struct list_head dma_pools; /* dma pools (if dma'ble) */
#ifdef CONFIG_DMA_DECLARE_COHERENT
struct dma_coherent_mem *dma_mem; /* internal for coherent mem
override */
#endif
#ifdef CONFIG_DMA_CMA
struct cma *cma_area; /* contiguous memory area for dma
allocations */
#endif
#ifdef CONFIG_SWIOTLB
struct io_tlb_mem *dma_io_tlb_mem;
#endif
#ifdef CONFIG_SWIOTLB_DYNAMIC
struct list_head dma_io_tlb_pools;
spinlock_t dma_io_tlb_lock;
bool dma_uses_io_tlb;
#endif
/* arch specific additions */
struct dev_archdata archdata;
struct device_node *of_node; /* associated device tree node */
struct fwnode_handle *fwnode; /* firmware device node */
#ifdef CONFIG_NUMA
int numa_node; /* NUMA node this device is close to */
#endif
dev_t devt; /* dev_t, creates the sysfs "dev" */
u32 id; /* device instance */
spinlock_t devres_lock;
struct list_head devres_head;
const struct class *class ;
const struct attribute_group **groups; /* optional groups */
void (*release)(struct device *dev);
struct iommu_group *iommu_group;
struct dev_iommu *iommu;
struct device_physical_location *physical_location;
enum device_removable removable;
bool offline_disabled:1 ;
bool offline:1 ;
bool of_node_reused:1 ;
bool state_synced:1 ;
bool can_match:1 ;
#if defined (CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE) || \
defined (CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU) || \
defined (CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU_ALL)
bool dma_coherent:1 ;
#endif
#ifdef CONFIG_DMA_OPS_BYPASS
bool dma_ops_bypass : 1 ;
#endif
#ifdef CONFIG_DMA_NEED_SYNC
bool dma_skip_sync:1 ;
#endif
#ifdef CONFIG_IOMMU_DMA
bool dma_iommu:1 ;
#endif
};
/**
* struct device_link - Device link representation .
* @ supplier : The device on the supplier end of the link .
* @ s_node : Hook to the supplier device ' s list of links to consumers .
* @ consumer : The device on the consumer end of the link .
* @ c_node : Hook to the consumer device ' s list of links to suppliers .
* @ link_dev : device used to expose link details in sysfs
* @ status : The state of the link ( with respect to the presence of drivers ) .
* @ flags : Link flags .
* @ rpm_active : Whether or not the consumer device is runtime - PM - active .
* @ kref : Count repeated addition of the same link .
* @ rm_work : Work structure used for removing the link .
* @ supplier_preactivated : Supplier has been made active before consumer probe .
*/
struct device_link {
struct device *supplier;
struct list_head s_node;
struct device *consumer;
struct list_head c_node;
struct device link_dev;
enum device_link_state status;
u32 flags;
refcount_t rpm_active;
struct kref kref;
struct work_struct rm_work;
bool supplier_preactivated; /* Owned by consumer probe. */
};
#define kobj_to_dev(__kobj) container_of_const(__kobj, struct device, kobj)
/**
* device_iommu_mapped - Returns true when the device DMA is translated
* by an IOMMU
* @ dev : Device to perform the check on
*/
static inline bool device_iommu_mapped(struct device *dev)
{
return (dev->iommu_group != NULL);
}
/* Get the wakeup routines, which depend on struct device */
#include <linux/pm_wakeup.h>
/**
* dev_name - Return a device ' s name .
* @ dev : Device with name to get .
* Return : The kobject name of the device , or its initial name if unavailable .
*/
static inline const char *dev_name(const struct device *dev)
{
/* Use the init name until the kobject becomes available */
if (dev->init_name)
return dev->init_name;
return kobject_name(&dev->kobj);
}
/**
* dev_bus_name - Return a device ' s bus / class name , if at all possible
* @ dev : struct device to get the bus / class name of
*
* Will return the name of the bus / class the device is attached to . If it is
* not attached to a bus / class , an empty string will be returned .
*/
static inline const char *dev_bus_name(const struct device *dev)
{
return dev->bus ? dev->bus->name : (dev->class ? dev->class ->name : "" );
}
__printf(2 , 3 ) int dev_set_name(struct device *dev, const char *name, ...);
#ifdef CONFIG_NUMA
static inline int dev_to_node(struct device *dev)
{
return dev->numa_node;
}
static inline void set_dev_node(struct device *dev, int node)
{
dev->numa_node = node;
}
#else
static inline int dev_to_node(struct device *dev)
{
return NUMA_NO_NODE;
}
static inline void set_dev_node(struct device *dev, int node)
{
}
#endif
static inline struct irq_domain *dev_get_msi_domain(const struct device *dev)
{
#ifdef CONFIG_GENERIC_MSI_IRQ
return dev->msi.domain;
#else
return NULL;
#endif
}
static inline void dev_set_msi_domain(struct device *dev, struct irq_domain *d)
{
#ifdef CONFIG_GENERIC_MSI_IRQ
dev->msi.domain = d;
#endif
}
static inline void *dev_get_drvdata(const struct device *dev)
{
return dev->driver_data;
}
static inline void dev_set_drvdata(struct device *dev, void *data)
{
dev->driver_data = data;
}
static inline struct pm_subsys_data *dev_to_psd(struct device *dev)
{
return dev ? dev->power.subsys_data : NULL;
}
static inline unsigned int dev_get_uevent_suppress(const struct device *dev)
{
return dev->kobj.uevent_suppress;
}
static inline void dev_set_uevent_suppress(struct device *dev, int val)
{
dev->kobj.uevent_suppress = val;
}
static inline int device_is_registered(struct device *dev)
{
return dev->kobj.state_in_sysfs;
}
static inline void device_enable_async_suspend(struct device *dev)
{
if (!dev->power.is_prepared)
dev->power.async_suspend = true ;
}
static inline void device_disable_async_suspend(struct device *dev)
{
if (!dev->power.is_prepared)
dev->power.async_suspend = false ;
}
static inline bool device_async_suspend_enabled(struct device *dev)
{
return !!dev->power.async_suspend;
}
static inline bool device_pm_not_required(struct device *dev)
{
return dev->power.no_pm;
}
static inline void device_set_pm_not_required(struct device *dev)
{
dev->power.no_pm = true ;
#ifdef CONFIG_PM
dev->power.no_callbacks = true ;
#endif
}
static inline void dev_pm_syscore_device(struct device *dev, bool val)
{
#ifdef CONFIG_PM_SLEEP
dev->power.syscore = val;
#endif
}
static inline void dev_pm_set_driver_flags(struct device *dev, u32 flags)
{
dev->power.driver_flags = flags;
}
static inline bool dev_pm_test_driver_flags(struct device *dev, u32 flags)
{
return !!(dev->power.driver_flags & flags);
}
static inline bool dev_pm_smart_suspend(struct device *dev)
{
#ifdef CONFIG_PM_SLEEP
return dev->power.smart_suspend;
#else
return false ;
#endif
}
/*
* dev_pm_set_strict_midlayer - Update the device ' s power . strict_midlayer flag
* @ dev : Target device .
* @ val : New flag value .
*
* When set , power . strict_midlayer means that the middle layer power management
* code ( typically , a bus type or a PM domain ) does not expect its runtime PM
* suspend callback to be invoked at all during system - wide PM transitions and
* it does not expect its runtime PM resume callback to be invoked at any point
* when runtime PM is disabled for the device during system - wide PM transitions .
*/
static inline void dev_pm_set_strict_midlayer(struct device *dev, bool val)
{
#ifdef CONFIG_PM_SLEEP
dev->power.strict_midlayer = val;
#endif
}
static inline bool dev_pm_strict_midlayer_is_set(struct device *dev)
{
#ifdef CONFIG_PM_SLEEP
return dev->power.strict_midlayer;
#else
return false ;
#endif
}
static inline void device_lock(struct device *dev)
{
mutex_lock(&dev->mutex);
}
static inline int device_lock_interruptible(struct device *dev)
{
return mutex_lock_interruptible(&dev->mutex);
}
static inline int device_trylock(struct device *dev)
{
return mutex_trylock(&dev->mutex);
}
static inline void device_unlock(struct device *dev)
{
mutex_unlock(&dev->mutex);
}
DEFINE_GUARD(device, struct device *, device_lock(_T), device_unlock(_T))
static inline void device_lock_assert(struct device *dev)
{
lockdep_assert_held(&dev->mutex);
}
static inline bool dev_has_sync_state(struct device *dev)
{
if (!dev)
return false ;
if (dev->driver && dev->driver->sync_state)
return true ;
if (dev->bus && dev->bus->sync_state)
return true ;
return false ;
}
static inline int dev_set_drv_sync_state(struct device *dev,
void (*fn)(struct device *dev))
{
if (!dev || !dev->driver)
return 0 ;
if (dev->driver->sync_state && dev->driver->sync_state != fn)
return -EBUSY;
if (!dev->driver->sync_state)
dev->driver->sync_state = fn;
return 0 ;
}
static inline void dev_set_removable(struct device *dev,
enum device_removable removable)
{
dev->removable = removable;
}
static inline bool dev_is_removable(struct device *dev)
{
return dev->removable == DEVICE_REMOVABLE;
}
static inline bool dev_removable_is_valid(struct device *dev)
{
return dev->removable != DEVICE_REMOVABLE_NOT_SUPPORTED;
}
/*
* High level routines for use by the bus drivers
*/
int __must_check device_register(struct device *dev);
void device_unregister(struct device *dev);
void device_initialize(struct device *dev);
int __must_check device_add(struct device *dev);
void device_del(struct device *dev);
DEFINE_FREE(device_del, struct device *, if (_T) device_del(_T))
int device_for_each_child(struct device *parent, void *data,
device_iter_t fn);
int device_for_each_child_reverse(struct device *parent, void *data,
device_iter_t fn);
int device_for_each_child_reverse_from(struct device *parent,
struct device *from, void *data,
device_iter_t fn);
struct device *device_find_child(struct device *parent, const void *data,
device_match_t match);
/**
* device_find_child_by_name - device iterator for locating a child device .
* @ parent : parent struct device
* @ name : name of the child device
*
* This is similar to the device_find_child ( ) function above , but it
* returns a reference to a device that has the name @ name .
*
* NOTE : you will need to drop the reference with put_device ( ) after use .
*/
static inline struct device *device_find_child_by_name(struct device *parent,
const char *name)
{
return device_find_child(parent, name, device_match_name);
}
/**
* device_find_any_child - device iterator for locating a child device , if any .
* @ parent : parent struct device
*
* This is similar to the device_find_child ( ) function above , but it
* returns a reference to a child device , if any .
*
* NOTE : you will need to drop the reference with put_device ( ) after use .
*/
static inline struct device *device_find_any_child(struct device *parent)
{
return device_find_child(parent, NULL, device_match_any);
}
int device_rename(struct device *dev, const char *new_name);
int device_move(struct device *dev, struct device *new_parent,
enum dpm_order dpm_order);
int device_change_owner(struct device *dev, kuid_t kuid, kgid_t kgid);
static inline bool device_supports_offline(struct device *dev)
{
return dev->bus && dev->bus->offline && dev->bus->online;
}
#define __device_lock_set_class(dev, name, key) \
do { \
struct device *__d2 __maybe_unused = dev; \
lock_set_class(&__d2->mutex.dep_map, name, key, 0 , _THIS_IP_); \
} while (0 )
/**
* device_lock_set_class - Specify a temporary lock class while a device
* is attached to a driver
* @ dev : device to modify
* @ key : lock class key data
*
* This must be called with the device_lock ( ) already held , for example
* from driver - > probe ( ) . Take care to only override the default
* lockdep_no_validate class .
*/
#ifdef CONFIG_LOCKDEP
#define device_lock_set_class(dev, key) \
do { \
struct device *__d = dev; \
dev_WARN_ONCE(__d, !lockdep_match_class(&__d->mutex, \
&__lockdep_no_validate__), \
"overriding existing custom lock class\n" ); \
__device_lock_set_class(__d, #key , key); \
} while (0 )
#else
#define device_lock_set_class(dev, key) __device_lock_set_class(dev, #key , key)
#endif
/**
* device_lock_reset_class - Return a device to the default lockdep novalidate state
* @ dev : device to modify
*
* This must be called with the device_lock ( ) already held , for example
* from driver - > remove ( ) .
*/
#define device_lock_reset_class(dev) \
do { \
struct device *__d __maybe_unused = dev; \
lock_set_novalidate_class(&__d->mutex.dep_map, "&dev->mutex" , \
_THIS_IP_); \
} while (0 )
void lock_device_hotplug(void );
void unlock_device_hotplug(void );
int lock_device_hotplug_sysfs(void );
int device_offline(struct device *dev);
int device_online(struct device *dev);
void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode);
void set_secondary_fwnode(struct device *dev, struct fwnode_handle *fwnode);
void device_set_node(struct device *dev, struct fwnode_handle *fwnode);
int device_add_of_node(struct device *dev, struct device_node *of_node);
void device_remove_of_node(struct device *dev);
void device_set_of_node_from_dev(struct device *dev, const struct device *dev2);
struct device *get_dev_from_fwnode(struct fwnode_handle *fwnode);
static inline struct device_node *dev_of_node(struct device *dev)
{
if (!IS_ENABLED(CONFIG_OF) || !dev)
return NULL;
return dev->of_node;
}
static inline int dev_num_vf(struct device *dev)
{
if (dev->bus && dev->bus->num_vf)
return dev->bus->num_vf(dev);
return 0 ;
}
/*
* Root device objects for grouping under / sys / devices
*/
struct device *__root_device_register(const char *name, struct module *owner);
/* This is a macro to avoid include problems with THIS_MODULE */
#define root_device_register(name) \
__root_device_register(name, THIS_MODULE)
void root_device_unregister(struct device *root);
static inline void *dev_get_platdata(const struct device *dev)
{
return dev->platform_data;
}
/*
* Manual binding of a device to driver . See drivers / base / bus . c
* for information on use .
*/
int __must_check device_driver_attach(const struct device_driver *drv,
struct device *dev);
int __must_check device_bind_driver(struct device *dev);
void device_release_driver(struct device *dev);
int __must_check device_attach(struct device *dev);
int __must_check driver_attach(const struct device_driver *drv);
void device_initial_probe(struct device *dev);
int __must_check device_reprobe(struct device *dev);
bool device_is_bound(struct device *dev);
/*
* Easy functions for dynamically creating devices on the fly
*/
__printf(5 , 6 ) struct device *
device_create(const struct class *cls, struct device *parent, dev_t devt,
void *drvdata, const char *fmt, ...);
__printf(6 , 7 ) struct device *
device_create_with_groups(const struct class *cls, struct device *parent, dev_t devt,
void *drvdata, const struct attribute_group **groups,
const char *fmt, ...);
void device_destroy(const struct class *cls, dev_t devt);
int __must_check device_add_groups(struct device *dev,
const struct attribute_group **groups);
void device_remove_groups(struct device *dev,
const struct attribute_group **groups);
static inline int __must_check device_add_group(struct device *dev,
const struct attribute_group *grp)
{
const struct attribute_group *groups[] = { grp, NULL };
return device_add_groups(dev, groups);
}
static inline void device_remove_group(struct device *dev,
const struct attribute_group *grp)
{
const struct attribute_group *groups[] = { grp, NULL };
device_remove_groups(dev, groups);
}
int __must_check devm_device_add_group(struct device *dev,
const struct attribute_group *grp);
/*
* get_device - atomically increment the reference count for the device .
*
*/
struct device *get_device(struct device *dev);
void put_device(struct device *dev);
DEFINE_FREE(put_device, struct device *, if (_T) put_device(_T))
bool kill_device(struct device *dev);
#ifdef CONFIG_DEVTMPFS
int devtmpfs_mount(void );
#else
static inline int devtmpfs_mount(void ) { return 0 ; }
#endif
/* drivers/base/power/shutdown.c */
void device_shutdown(void );
/* debugging and troubleshooting/diagnostic helpers. */
const char *dev_driver_string(const struct device *dev);
/* Device links interface. */
struct device_link *device_link_add(struct device *consumer,
struct device *supplier, u32 flags);
void device_link_del(struct device_link *link);
void device_link_remove(void *consumer, struct device *supplier);
void device_links_supplier_sync_state_pause(void );
void device_links_supplier_sync_state_resume(void );
void device_link_wait_removal(void );
static inline bool device_link_test(const struct device_link *link, u32 flags)
{
return !!(link->flags & flags);
}
/* Create alias, so I can be autoloaded. */
#define MODULE_ALIAS_CHARDEV(major,minor) \
MODULE_ALIAS("char-major-" __stringify(major) "-" __stringify(minor))
#define MODULE_ALIAS_CHARDEV_MAJOR(major) \
MODULE_ALIAS("char-major-" __stringify(major) "-*" )
#endif /* _DEVICE_H_ */
Messung V0.5 in Prozent C=95 H=98 G=96
¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.43Angebot
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-09-27)
¤
*Eine klare Vorstellung vom Zielzustand