设备驱动程序基础设施¶
基本设备驱动程序模型结构¶
-
struct subsys_interface¶
设备功能的接口
定义:
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);
};
成员
name
设备功能的名称
subsys
要附加到的设备的子系统
node
在子系统注册的函数列表
add_dev
设备连接到设备功能处理程序
remove_dev
设备连接到设备功能处理程序
描述
附加到子系统的简单接口。多个接口可以附加到子系统及其设备。与驱动程序不同,它们不独占声明或控制设备。接口通常表示子系统/设备类别的特定功能。
-
struct device_attribute¶
用于导出设备属性的接口。
定义:
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);
};
成员
attr
sysfs 属性定义。
show
显示处理程序。
store
存储处理程序。
-
struct dev_ext_attribute¶
带有额外上下文的导出的设备属性。
定义:
struct dev_ext_attribute {
struct device_attribute attr;
void *var;
};
成员
attr
导出的设备属性。
var
指向上下文的指针。
-
DEVICE_ATTR¶
DEVICE_ATTR (_name, _mode, _show, _store)
定义一个设备属性。
参数
_name
属性名称。
_mode
文件模式。
_show
显示处理程序。可选,但如果属性是可读的则必须。
_store
存储处理程序。可选,但如果属性是可写的则必须。
描述
用于定义 struct device_attribute
的便捷宏。
例如,DEVICE_ATTR(foo, 0644, foo_show, foo_store);
展开为
struct device_attribute dev_attr_foo = {
.attr = { .name = "foo", .mode = 0644 },
.show = foo_show,
.store = foo_store,
};
-
DEVICE_ATTR_PREALLOC¶
DEVICE_ATTR_PREALLOC (_name, _mode, _show, _store)
定义一个预先分配的设备属性。
参数
_name
属性名称。
_mode
文件模式。
_show
显示处理程序。可选,但如果属性是可读的则必须。
_store
存储处理程序。可选,但如果属性是可写的则必须。
描述
与 DEVICE_ATTR()
类似,但在 _mode 上设置 SYSFS_PREALLOC
。
-
DEVICE_ATTR_RW¶
DEVICE_ATTR_RW (_name)
定义一个读写设备属性。
-
DEVICE_ATTR_ADMIN_RW¶
DEVICE_ATTR_ADMIN_RW (_name)
定义一个仅管理员可读写的设备属性。
-
DEVICE_ATTR_RO¶
DEVICE_ATTR_RO (_name)
定义一个可读的设备属性。
-
DEVICE_ATTR_ADMIN_RO¶
DEVICE_ATTR_ADMIN_RO (_name)
定义一个仅管理员可读的设备属性。
-
DEVICE_ATTR_WO¶
DEVICE_ATTR_WO (_name)
定义一个仅管理员可写的设备属性。
-
DEVICE_ULONG_ATTR¶
DEVICE_ULONG_ATTR (_name, _mode, _var)
定义一个由无符号长整型支持的设备属性。
参数
_name
属性名称。
_mode
文件模式。
_var
无符号长整型的标识符。
描述
与 DEVICE_ATTR()
类似,但会自动提供 _show 和 _store,以便从用户空间读取和写入属性会影响 _var。
-
DEVICE_INT_ATTR¶
DEVICE_INT_ATTR (_name, _mode, _var)
定义一个由 int 支持的设备属性。
-
DEVICE_BOOL_ATTR¶
DEVICE_BOOL_ATTR (_name, _mode, _var)
定义一个由布尔值支持的设备属性。
-
DEVICE_STRING_ATTR_RO¶
DEVICE_STRING_ATTR_RO (_name, _mode, _var)
定义一个由 r/o 字符串支持的设备属性。
参数
_name
属性名称。
_mode
文件模式。
_var
字符串的标识符。
描述
与 DEVICE_ULONG_ATTR()
类似,但 _var 是一个字符串。由于字符串分配的长度未知,因此该属性必须是只读的。
-
devm_alloc_percpu¶
devm_alloc_percpu (dev, type)
资源托管的 alloc_percpu
参数
dev
为其分配每个 CPU 内存的设备
type
为其分配每个 CPU 内存的类型
描述
托管的 alloc_percpu。使用此函数分配的每个 CPU 内存会在驱动程序分离时自动释放。
返回
成功时指向已分配内存的指针,失败时为 NULL。
-
enum dl_dev_state¶
设备驱动程序存在跟踪信息。
常量
DL_DEV_NO_DRIVER
没有驱动程序附加到设备。
DL_DEV_PROBING
驱动程序正在探测。
DL_DEV_DRIVER_BOUND
驱动程序已绑定到设备。
DL_DEV_UNBINDING
驱动程序正在从设备解除绑定。
-
enum device_removable¶
设备是否可移动。设备被分类为可移动的标准由其子系统或总线确定。
常量
DEVICE_REMOVABLE_NOT_SUPPORTED
此设备不支持此属性(默认)。
DEVICE_REMOVABLE_UNKNOWN
设备位置未知。
DEVICE_FIXED
用户不可移动设备。
DEVICE_REMOVABLE
用户可移动设备。
-
struct dev_links_info¶
与设备链接相关的设备数据。
定义:
struct dev_links_info {
struct list_head suppliers;
struct list_head consumers;
struct list_head defer_sync;
enum dl_dev_state status;
};
成员
suppliers
到供应商设备的链接列表。
consumers
到消费者设备的链接列表。
defer_sync
挂接到具有延迟 sync_state 的设备的全局列表。
status
驱动程序状态信息。
-
struct dev_msi_info¶
与 MSI 相关的设备数据
定义:
struct dev_msi_info {
#ifdef CONFIG_GENERIC_MSI_IRQ;
struct irq_domain *domain;
struct msi_device_data *data;
#endif;
};
成员
domain
与设备关联的 MSI 中断域
data
指向 MSI 设备数据的指针
-
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¶
描述设备连接点在面板表面上的垂直位置。
常量
DEVICE_VERT_POS_UPPER
设备连接点在面板的上部。
DEVICE_VERT_POS_CENTER
设备连接点在面板的中心部分。
DEVICE_VERT_POS_LOWER
设备连接点在面板的下部。
-
enum device_physical_location_horizontal_position¶
描述设备连接点在面板表面上的水平位置。
常量
DEVICE_HORI_POS_LEFT
设备连接点在面板的左侧。
DEVICE_HORI_POS_CENTER
设备连接点在面板的中心部分。
DEVICE_HORI_POS_RIGHT
设备连接点在面板的右侧。
-
struct device_physical_location¶
与设备连接点的物理位置相关的设备数据。
定义:
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;
};
成员
panel
设备连接点所在的系统外壳的面板表面。
vertical_position
设备连接点在面板内的垂直位置。
horizontal_position
设备连接点在面板内的水平位置。
dock
如果设备连接点位于扩展坞或端口复制器中,则设置此项。
lid
如果此设备连接点位于笔记本电脑系统的盖子上,则设置此项。
-
struct device¶
基本的设备结构
定义:
struct device {
struct kobject kobj;
struct device *parent;
struct device_private *p;
const char *init_name;
const struct device_type *type;
const struct bus_type *bus;
struct device_driver *driver;
void *platform_data;
void *driver_data;
struct mutex mutex;
struct dev_links_info links;
struct dev_pm_info power;
struct dev_pm_domain *pm_domain;
#ifdef CONFIG_ENERGY_MODEL;
struct em_perf_domain *em_pd;
#endif;
#ifdef CONFIG_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;
u64 coherent_dma_mask;
u64 bus_dma_limit;
const struct bus_dma_region *dma_range_map;
struct device_dma_parameters *dma_parms;
struct list_head dma_pools;
#ifdef CONFIG_DMA_DECLARE_COHERENT;
struct dma_coherent_mem *dma_mem;
#endif;
#ifdef CONFIG_DMA_CMA;
struct cma *cma_area;
#endif;
#ifdef CONFIG_SWIOTLB;
struct io_tlb_mem *dma_io_tlb_mem;
#endif;
#ifdef CONFIG_SWIOTLB_DYNAMIC;
struct list_head dma_io_tlb_pools;
spinlock_t dma_io_tlb_lock;
bool dma_uses_io_tlb;
#endif;
struct dev_archdata archdata;
struct device_node *of_node;
struct fwnode_handle *fwnode;
#ifdef CONFIG_NUMA;
int numa_node;
#endif;
dev_t devt;
u32 id;
spinlock_t devres_lock;
struct list_head devres_head;
const struct class *class;
const struct attribute_group **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;
};
成员
kobj
一个顶级的抽象类,其他类由此派生。
parent
该设备的“父”设备,即它所连接的设备。在大多数情况下,父设备是某种总线或主机控制器。如果 parent 为 NULL,则该设备是顶层设备,这通常不是你想要的。
p
保存设备驱动程序核心部分的私有数据。有关详细信息,请参阅 struct device_private 的注释。
init_name
设备的初始名称。
type
设备类型。这标识了设备类型并携带特定于类型的信息。
bus
设备所在的总线类型。
driver
哪个驱动程序分配了这个
platform_data
特定于设备的平台数据。
driver_data
驱动程序特定信息的私有指针。
mutex
用于同步对其驱动程序的调用的互斥锁。
links
指向此设备的供应商和消费者的链接。
power
用于设备电源管理。有关详细信息,请参阅 设备电源管理基础。
pm_domain
提供在系统挂起、休眠、系统恢复以及运行时 PM 转换期间执行的回调,以及子系统级和驱动程序级回调。
em_pd
设备的能量模型性能域
pins
用于设备引脚管理。有关详细信息,请参阅 PINCTRL(引脚控制)子系统。
msi
MSI 相关数据
dma_ops
此设备的 DMA 映射操作。
dma_mask
DMA 掩码(如果设备支持 DMA)。
coherent_dma_mask
类似于 dma_mask,但用于 alloc_coherent 映射,因为并非所有硬件都支持 64 位地址用于一致分配的描述符。
bus_dma_limit
上游桥或总线的限制,该限制施加的 DMA 限制小于设备本身支持的限制。
dma_range_map
用于相对于 RAM 的 DMA 内存范围的映射
dma_parms
低级别驱动程序可以设置这些来告知 IOMMU 代码有关段限制的信息。
dma_pools
DMA 池(如果设备支持 DMA)。
dma_mem
内部用于一致内存覆盖。
cma_area
用于 DMA 分配的连续内存区域
dma_io_tlb_mem
软件 IO TLB 分配器。不供驱动程序使用。
dma_io_tlb_pools
瞬态 swiotlb 内存池的列表。
dma_io_tlb_lock
保护对活动池列表的更改。
dma_uses_io_tlb
如果设备使用了软件 IO TLB,则为
true
。archdata
用于特定于架构的添加。
of_node
关联的设备树节点。
fwnode
平台固件提供的关联设备节点。
numa_node
此设备所靠近的 NUMA 节点。
devt
用于创建 sysfs “dev”。
id
设备实例
devres_lock
用于保护设备资源的自旋锁。
devres_head
设备的资源列表。
class
设备类别。
groups
可选的属性组。
release
在所有引用消失后释放设备的回调。这应由设备分配器(即发现该设备的总线驱动程序)设置。
iommu_group
设备所属的 IOMMU 组。
iommu
每个设备的通用 IOMMU 运行时数据
physical_location
描述设备连接点在系统外壳中的物理位置。
removable
设备是否可以从系统中移除。这应由发现该设备的子系统/总线驱动程序设置。
offline_disabled
如果设置,则设备永久在线。
offline
在成功调用总线类型的 .offline() 之后设置。
of_node_reused
如果设备树节点与祖先设备共享,则设置此项。
state_synced
此设备的硬件状态已通过调用驱动程序/总线 sync_state() 回调同步,以匹配此设备的软件状态。
can_match
该设备至少与一个驱动程序匹配过,或者它位于一个总线(如 AMBA)中,该总线在其他设备成功探测之前无法检查匹配的驱动程序。
dma_coherent
此特定设备是 DMA 一致的,即使该架构支持非一致的设备。
dma_ops_bypass
如果设置为
true
,则对于流式 DMA 操作(->map_* / ->unmap_* / ->sync_*)会绕过 dma_ops,并且对于 DMA 分配(如果一致掩码足够大)也会绕过。此标志由来自 ->dma_supported 的 dma ops 实例管理。dma_skip_sync
可以跳过一致缓冲区的 DMA 同步操作。
dma_iommu
设备正在使用默认的 IOMMU 实现进行 DMA,而不依赖于 dma_ops 结构。
示例
- 对于自定义板上的设备,如嵌入式设备中的典型设备
和基于 SOC 的硬件,Linux 通常使用 platform_data 来指向描述设备及其连接方式的特定于板的结构。这可以包括哪些端口可用、芯片变体、哪些 GPIO 引脚在哪些其他角色中起作用等等。这缩小了“板支持包”(BSP)并最大限度地减少了驱动程序中特定于板的 #ifdef。
描述
在最低级别,Linux 系统中的每个设备都由 struct device
的实例表示。设备结构包含设备模型核心对系统建模所需的信息。但是,大多数子系统会跟踪有关其托管设备的其他信息。因此,很少有设备仅由裸设备结构表示;相反,像 kobject 结构一样,该结构通常嵌入在设备的高级表示中。
-
struct device_link¶
设备链接表示。
定义:
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;
};
成员
supplier
链接的供应商端的设备。
s_node
挂钩到供应商设备的消费者链接列表。
consumer
链接的消费者端的设备。
c_node
挂钩到消费者设备的供应商链接列表。
link_dev
用于在 sysfs 中公开链接详细信息的设备
status
链接的状态(关于驱动程序的存在)。
flags
链接标志。
rpm_active
消费者设备是否处于运行时 PM 活动状态。
kref
计算重复添加的同一链接。
rm_work
用于删除链接的工作结构。
supplier_preactivated
供应商在消费者探测之前已激活。
参数
struct device *dev
要执行检查的设备
参数
const struct device *dev
要获取名称的设备。
返回
设备的 kobject 名称,如果不可用,则为其初始名称。
-
device_lock_set_class¶
device_lock_set_class (dev, key)
当设备连接到驱动程序时,指定一个临时的锁类
参数
dev
要修改的设备
键
锁类键数据
描述
必须在已经持有 device_lock() 的情况下调用,例如从驱动程序的 ->probe() 中调用。请注意仅覆盖默认的 lockdep_no_validate 类。
-
device_lock_reset_class¶
device_lock_reset_class (dev)
将设备恢复到默认的 lockdep novalidate 状态
参数
dev
要修改的设备
描述
必须在已经持有 device_lock() 的情况下调用,例如从驱动程序的 ->remove() 中调用。
-
struct bus_type¶
设备的总线类型
定义:
struct bus_type {
const char *name;
const char *dev_name;
const struct attribute_group **bus_groups;
const struct attribute_group **dev_groups;
const struct attribute_group **drv_groups;
int (*match)(struct device *dev, const struct device_driver *drv);
int (*uevent)(const struct device *dev, struct kobj_uevent_env *env);
int (*probe)(struct device *dev);
void (*sync_state)(struct device *dev);
void (*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);
int (*num_vf)(struct device *dev);
int (*dma_configure)(struct device *dev);
void (*dma_cleanup)(struct device *dev);
const struct dev_pm_ops *pm;
bool need_parent_lock;
};
成员
name
总线的名称。
dev_name
用于子系统枚举设备,如 (“foo``u``”, dev->id)。
bus_groups
总线的默认属性。
dev_groups
总线上设备的默认属性。
drv_groups
总线上设备驱动程序的默认属性。
match
当为此总线添加新设备或驱动程序时可能会多次调用。如果给定的设备可以由给定的驱动程序处理,则应返回一个正值,否则返回零。如果无法确定驱动程序是否支持该设备,它也可能返回错误代码。如果返回 -EPROBE_DEFER,则会将设备排队以进行延迟探测。
uevent
当添加、删除设备或发生其他生成 uevent 的事件时调用,以添加环境变量。
probe
当为此总线添加新设备或驱动程序时调用,并回调特定驱动程序的探测以初始化匹配的设备。
sync_state
在所有链接到此设备(在 late_initcall 时存在)的状态跟踪消费者成功绑定到驱动程序之后,调用以将设备状态同步到软件状态。如果设备没有消费者,则此函数将在 late_initcall_sync 级别调用。如果设备有从不绑定到驱动程序的消费者,则此函数永远不会被调用,直到它们绑定为止。
remove
当从总线移除设备时调用。
shutdown
在关闭时调用以使设备静止。
online
调用以将设备重新置于在线状态(在离线后)。
offline
调用以使设备离线以进行热移除。可能会失败。
suspend
当该总线上的设备想要进入睡眠模式时调用。
resume
调用以将该总线上的设备从睡眠模式唤醒。
num_vf
调用以查找该总线上的设备支持多少个虚拟函数。
dma_configure
调用以设置该总线上的设备的 DMA 配置。
dma_cleanup
调用以清理该总线上的设备的 DMA 配置。
pm
此总线的电源管理操作,回调特定设备驱动程序的 pm-ops。
need_parent_lock
当探测或移除此总线上的设备时,设备核心应锁定该设备的父设备。
描述
总线是处理器和一个或多个设备之间的通道。就设备模型而言,所有设备都通过总线连接,即使它是内部的、虚拟的“平台”总线。总线可以相互插入。例如,USB 控制器通常是 PCI 设备。设备模型表示总线和它们控制的设备之间的实际连接。总线由 bus_type 结构表示。它包含名称、默认属性、总线的方法、PM 操作以及驱动程序核心的私有数据。
-
enum bus_notifier_event¶
已发生的总线通知器事件
常量
BUS_NOTIFY_ADD_DEVICE
设备已添加到此总线
BUS_NOTIFY_DEL_DEVICE
设备即将从此总线移除
BUS_NOTIFY_REMOVED_DEVICE
设备已成功从此总线移除
BUS_NOTIFY_BIND_DRIVER
驱动程序即将绑定到此总线上此设备
BUS_NOTIFY_BOUND_DRIVER
驱动程序已成功绑定到此总线上此设备
BUS_NOTIFY_UNBIND_DRIVER
驱动程序即将从此总线上此设备解除绑定
BUS_NOTIFY_UNBOUND_DRIVER
驱动程序已成功从此总线上此设备解除绑定
BUS_NOTIFY_DRIVER_NOT_BOUND
驱动程序未能绑定到此总线上此设备
描述
这些是当特定事件发生时传递给总线通知器的值。
请注意,总线通知器很可能会在驱动程序核心已经持有设备锁的情况下被调用,因此请在任何通知器回调中谨慎处理设备结构。
所有总线通知器都以目标 struct device
* 作为参数调用。
-
struct class¶
设备类
定义:
struct class {
const char *name;
const struct attribute_group **class_groups;
const struct attribute_group **dev_groups;
int (*dev_uevent)(const struct device *dev, struct kobj_uevent_env *env);
char *(*devnode)(const struct device *dev, umode_t *mode);
void (*class_release)(const struct class *class);
void (*dev_release)(struct device *dev);
int (*shutdown_pre)(struct device *dev);
const struct kobj_ns_type_operations *ns_type;
const void *(*namespace)(const struct device *dev);
void (*get_ownership)(const struct device *dev, kuid_t *uid, kgid_t *gid);
const struct dev_pm_ops *pm;
};
成员
name
类的名称。
class_groups
此类的默认属性。
dev_groups
属于该类的设备的默认属性。
dev_uevent
当设备添加、从此类移除或发生其他生成 uevent 的事件时调用,以添加环境变量。
devnode
回调以提供 devtmpfs。
class_release
调用以释放此类。
dev_release
调用以释放设备。
shutdown_pre
在驱动程序关闭之前在关闭时调用。
ns_type
回调,以便 sysfs 可以确定命名空间。
namespace
属于此类的设备的命名空间。
get_ownership
允许类指定属于该类的设备的 sysfs 目录的 uid/gid。通常与设备的命名空间相关。
pm
此类的默认设备电源管理操作。
描述
类是设备的更高层次的视图,它抽象出低级实现细节。驱动程序可能会看到 SCSI 磁盘或 ATA 磁盘,但在类级别,它们都只是磁盘。类允许用户空间根据设备的功能而不是它们的连接方式或工作方式来使用设备。
-
enum probe_type¶
设备驱动程序探测类型,用于尝试。设备驱动程序可以选择对其各自的探测例程进行特殊处理。这告诉核心预期和偏好。
常量
PROBE_DEFAULT_STRATEGY
由同步或异步探测都能正常工作的驱动程序使用。
PROBE_PREFER_ASYNCHRONOUS
对于启动系统来说探测顺序不是至关重要的“慢速”设备的驱动程序,可以选择异步执行其探测。
PROBE_FORCE_SYNCHRONOUS
使用此注释需要其探测例程与驱动程序和设备注册同步运行的驱动程序(除了 -EPROBE_DEFER 处理 - 重新探测总是最终异步完成)。
描述
请注意,最终目标是切换内核默认使用异步探测,因此用 PROBE_PREFER_ASYNCHRONOUS
注释驱动程序是一种临时措施,允许我们在验证其余驱动程序时加快启动过程。
-
struct device_driver¶
基本的设备驱动程序结构
定义:
struct device_driver {
const char *name;
const 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);
void (*sync_state)(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 attribute_group **dev_groups;
const struct dev_pm_ops *pm;
void (*coredump) (struct device *dev);
struct driver_private *p;
};
成员
name
设备驱动程序的名称。
bus
此驱动程序的设备所属的总线。
owner
模块所有者。
mod_name
用于内置模块。
suppress_bind_attrs
禁用通过 sysfs 进行绑定/解除绑定。
probe_type
要使用的探测类型(同步或异步)。
of_match_table
开放固件表。
acpi_match_table
ACPI 匹配表。
probe
调用以查询特定设备的存在,此驱动程序是否可以使用它,并将驱动程序绑定到特定设备。
sync_state
在所有链接到此设备(在 late_initcall 时存在)的状态跟踪消费者成功绑定到驱动程序之后,调用以将设备状态同步到软件状态。如果设备没有消费者,则此函数将在 late_initcall_sync 级别调用。如果设备有从不绑定到驱动程序的消费者,则此函数永远不会被调用,直到它们绑定为止。
remove
当设备从系统中移除以解除设备与此驱动程序的绑定时调用。
shutdown
在关闭时调用以使设备静止。
suspend
调用以将设备置于睡眠模式。通常是低功耗状态。
resume
调用以将设备从睡眠模式唤醒。
groups
由驱动程序核心自动创建的默认属性。
dev_groups
一旦设备绑定到驱动程序,附加到设备实例的其他属性。
pm
与此驱动程序匹配的设备的电源管理操作。
coredump
当写入 sysfs 条目时调用。设备驱动程序应调用 dev_coredump API,从而导致 uevent。
p
驱动程序核心的私有数据,除了驱动程序核心之外,任何人都不能触摸此数据。
描述
设备驱动程序模型跟踪系统中已知的所有驱动程序。此跟踪的主要原因是使驱动程序核心能够将驱动程序与新设备匹配。但是,一旦驱动程序成为系统中的已知对象,许多其他事情就会变得可能。设备驱动程序可以导出独立于任何特定设备的信息和配置变量。
设备驱动程序基础¶
-
void driver_init(void)¶
初始化驱动程序模型。
参数
void
无参数
描述
调用驱动程序模型初始化函数以初始化其子系统。在 init/main.c 中早期调用。
-
struct device *driver_find_device_by_name(const struct device_driver *drv, const char *name)¶
设备迭代器,用于查找具有特定名称的特定设备。
参数
const struct device_driver *drv
正在迭代的驱动程序
const char *name
要匹配的设备名称
-
struct device *driver_find_device_by_of_node(const struct device_driver *drv, const struct device_node *np)¶
设备迭代器,用于通过 of_node 指针查找特定设备。
参数
const struct device_driver *drv
正在迭代的驱动程序
const struct device_node *np
要匹配的 of_node 指针。
-
struct device *driver_find_device_by_fwnode(struct device_driver *drv, const struct fwnode_handle *fwnode)¶
设备迭代器,用于通过 fwnode 指针查找特定设备。
参数
struct device_driver *drv
正在迭代的驱动程序
const struct fwnode_handle *fwnode
要匹配的 fwnode 指针。
-
struct device *driver_find_device_by_devt(const struct device_driver *drv, dev_t devt)¶
设备迭代器,用于通过 devt 查找特定设备。
参数
const struct device_driver *drv
正在迭代的驱动程序
dev_t devt
要匹配的 devt 指针。
-
struct device *driver_find_device_by_acpi_dev(const struct device_driver *drv, const struct acpi_device *adev)¶
设备迭代器,用于查找与 ACPI_COMPANION 设备匹配的特定设备。
参数
const struct device_driver *drv
正在迭代的驱动程序
const struct acpi_device *adev
要匹配的 ACPI_COMPANION 设备。
-
module_driver¶
module_driver (__driver, __register, __unregister, ...)
用于在模块初始化/退出时不做任何特殊处理的驱动程序的辅助宏。这消除了大量的样板代码。每个模块只能使用此宏一次,调用它会替换
module_init()
和module_exit()
。
参数
__driver
驱动程序名称
__register
此驱动程序类型的注册函数
__unregister
此驱动程序类型的注销函数
...
要传递给 __register 和 __unregister 的其他参数。
描述
使用此宏来构建用于注册驱动程序的特定于总线的宏,不要单独使用它。
-
builtin_driver¶
builtin_driver (__driver, __register, ...)
用于在初始化时不做任何特殊处理且没有退出的驱动程序的辅助宏。这消除了一些样板代码。每个驱动程序只能使用此宏一次,调用它会替换 device_initcall (或在某些情况下,替换旧的 __initcall)。这旨在与上面的
module_driver()
直接并行,但没有用于内置情况的 __exit 部分。
参数
__driver
驱动程序名称
__register
此驱动程序类型的注册函数
...
要传递给 __register 的其他参数
描述
使用此宏来构建用于注册驱动程序的特定于总线的宏,不要单独使用它。
-
int driver_set_override(struct device *dev, const char **override, const char *s, size_t len)¶
用于设置或清除驱动程序覆盖的辅助函数。
参数
struct device *dev
要更改的设备
const char **override
要更改的字符串的地址(例如
device->driver_override
);内容将被释放并保存新分配的覆盖。const char *s
以 NULL 结尾的字符串,强制匹配的新驱动程序名称,传递空字符串以清除它(“” 或 “n”,其中后者仅用于 sysfs 接口)。
size_t len
s 的长度
描述
用于在设备中设置或清除驱动程序覆盖的辅助函数,适用于驱动程序/总线代码分配 driver_override 字段的情况。
返回
成功时返回 0,失败时返回负错误代码。
-
int driver_for_each_device(struct device_driver *drv, struct device *start, void *data, int (*fn)(struct device*, void*))¶
用于绑定到驱动程序的设备的迭代器。
参数
struct device_driver *drv
正在迭代的驱动程序。
struct device *start
开始的设备
void *data
要传递给回调的数据。
int (*fn)(struct device *, void *)
为每个设备调用的函数。
描述
遍历 drv 的设备列表,为每个设备调用 fn。
-
struct device *driver_find_device(const struct device_driver *drv, struct device *start, const void *data, device_match_t match)¶
用于查找特定设备的设备迭代器。
参数
const struct device_driver *drv
设备的驱动程序
struct device *start
开始的设备
const void *data
要传递给匹配函数的数据
device_match_t match
用于检查设备的回调函数
描述
这类似于上面的 driver_for_each_device()
函数,但它会返回一个对“找到”的设备的引用,以便后续使用,这由 match 回调确定。
如果设备不匹配,回调应返回 0;如果匹配,则返回非零值。 如果回调返回非零值,则此函数将返回给调用者,并且不会迭代任何其他设备。
-
int driver_create_file(const struct device_driver *drv, const struct driver_attribute *attr)¶
为驱动程序创建 sysfs 文件。
参数
const struct device_driver *drv
驱动程序。
const struct driver_attribute *attr
驱动程序属性描述符。
-
void driver_remove_file(const struct device_driver *drv, const struct driver_attribute *attr)¶
为驱动程序删除 sysfs 文件。
参数
const struct device_driver *drv
驱动程序。
const struct driver_attribute *attr
驱动程序属性描述符。
-
int driver_register(struct device_driver *drv)¶
向总线注册驱动程序
参数
struct device_driver *drv
要注册的驱动程序
描述
我们将大部分工作传递给 bus_add_driver() 调用,因为我们必须做的大部分事情都与总线结构有关。
-
void driver_unregister(struct device_driver *drv)¶
从系统中移除驱动程序。
参数
struct device_driver *drv
驱动程序。
描述
同样,我们将大部分工作传递给总线级别的调用。
-
void device_link_wait_removal(void)¶
等待正在进行的 devlink 删除作业终止
参数
void
无参数
-
struct device_link *device_link_add(struct device *consumer, struct device *supplier, u32 flags)¶
在两个设备之间创建链接。
参数
struct device *consumer
链接的消费者端。
struct device *supplier
链接的提供者端。
u32 flags
链接标志。
返回
- 成功后,将返回一个 device_link 结构。
如果发生错误或标志设置无效,将返回 NULL。
描述
调用者负责使链接创建与运行时 PM 正确同步。 首先,设置 DL_FLAG_PM_RUNTIME 标志将导致运行时 PM 框架将链接考虑在内。 其次,如果除了设置 DL_FLAG_PM_RUNTIME 之外还设置了 DL_FLAG_RPM_ACTIVE 标志,则在创建链接时,供应商设备将被强制进入活动元状态并进行引用计数。 如果未设置 DL_FLAG_PM_RUNTIME,则将忽略 DL_FLAG_RPM_ACTIVE。
如果在 flags 中设置了 DL_FLAG_STATELESS,则此函数的调用者应借助 device_link_del()
或 device_link_remove()
直接释放其返回的链接。
但是,如果未设置该标志,则此函数的调用者会将链接的管理完全移交给驱动程序核心,并且其返回值只能用于检查链接是否存在。 在这种情况下,可以使用 DL_FLAG_AUTOREMOVE_CONSUMER 和 DL_FLAG_AUTOREMOVE_SUPPLIER 设备链接标志来向驱动程序核心指示何时可以安全地删除链接。 即,在 flags 中设置其中一个标志,向驱动程序核心指示,在分别从其设备取消绑定消费者或供应商驱动程序后,此链接将不会被(此函数的给定调用者)使用,因此可以在该点删除该链接。 如果没有设置其中任何一个标志,则该链接将一直保留,直到它指向的其中一个设备(消费者或供应商)被注销。
此外,如果 flags 中未设置 DL_FLAG_STATELESS、DL_FLAG_AUTOREMOVE_CONSUMER 和 DL_FLAG_AUTOREMOVE_SUPPLIER(即,正在添加持久托管设备链接),则可以使用 DL_FLAG_AUTOPROBE_CONSUMER 标志来请求驱动程序核心在成功将驱动程序绑定到供应商设备后自动探测消费者驱动程序。
DL_FLAG_STATELESS 与 flags 中设置的 DL_FLAG_AUTOREMOVE_CONSUMER、DL_FLAG_AUTOREMOVE_SUPPLIER 或 DL_FLAG_AUTOPROBE_CONSUMER 之一的组合无效,将导致提前返回 NULL。 但是,如果在此函数被调用时,给定的 consumer 和 supplier 对之间已经存在设备链接,则将返回现有链接,而与其当前类型和状态无关(然后可以修改链接的标志)。 然后,此函数的调用者应将链接视为刚创建的链接,因此(尤其)如果 flags 中传递了 DL_FLAG_STATELESS,则在不再需要时需要显式释放该链接(如上所述)。
链接创建的一个副作用是通过将消费者设备和所有依赖于它的设备移动到这些列表的末尾来重新排序 dpm_list 和 devices_kset 列表(这不会发生在调用此函数时尚未注册的设备上)。
调用此函数时,要求供应商设备已注册,否则将返回 NULL。 但是,不需要注册消费者设备。
-
void device_link_del(struct device_link *link)¶
删除两个设备之间的无状态链接。
参数
struct device_link *link
要删除的设备链接。
描述
调用者必须确保此函数与运行时 PM 正确同步。 如果该链接被添加多次,则需要多次删除。 需要注意热插拔设备:它们的链接在删除时会被清除,并且不再允许调用 device_link_del()
。
参数
void *consumer
链接的消费者端。
struct device *supplier
链接的提供者端。
描述
调用者必须确保此函数与运行时 PM 正确同步。
参数
const struct device *dev
要获取名称的
struct device
描述
如果设备绑定到驱动程序,则会返回设备的驱动程序名称。 如果设备未绑定到驱动程序,则会返回它所连接的总线的名称。 如果它也没有连接到总线,则会返回一个空字符串。
参数
struct device *dev
要为其创建组的设备
const struct attribute_group *grp
要创建的属性组
描述
此函数首次创建一个组。如果正在创建的任何属性文件已存在,它将明确发出警告并报错。
成功返回 0,失败返回错误代码。
-
int device_create_file(struct device *dev, const struct device_attribute *attr)¶
为设备创建 sysfs 属性文件。
参数
struct device *dev
设备。
const struct device_attribute *attr
设备属性描述符。
-
void device_remove_file(struct device *dev, const struct device_attribute *attr)¶
删除 sysfs 属性文件。
参数
struct device *dev
设备。
const struct device_attribute *attr
设备属性描述符。
-
bool device_remove_file_self(struct device *dev, const struct device_attribute *attr)¶
从其自身的方法中删除 sysfs 属性文件。
参数
struct device *dev
设备。
const struct device_attribute *attr
设备属性描述符。
描述
有关详细信息,请参阅 kernfs_remove_self()。
-
int device_create_bin_file(struct device *dev, const struct bin_attribute *attr)¶
为设备创建 sysfs 二进制属性文件。
参数
struct device *dev
设备。
const struct bin_attribute *attr
设备二进制属性描述符。
参数
struct device *dev
设备。
const struct bin_attribute *attr
设备二进制属性描述符。
参数
struct device *dev
设备。
描述
这通过初始化其字段来准备设备以供其他层使用。它是 device_register()
的前半部分(如果由该函数调用),尽管也可以单独调用,因此可以使用 dev 的字段。特别是,在调用此函数后,get_device()
/put_device()
可用于 dev 的引用计数。
dev 中的所有字段必须由调用者初始化为 0,但明确设置为某些其他值的字段除外。最简单的方法是使用 kzalloc()
来分配包含 dev 的结构。
注意
一旦调用此函数,请使用 put_device()
来放弃您的引用,而不是直接释放 dev。
参数
struct device *dev
设备
const char *fmt
设备名称的格式字符串
...
可变参数
参数
struct device *dev
设备。
描述
这是 device_register()
的第 2 部分,尽管如果已单独调用 device_initialize()
,则可以单独调用。
这通过 kobject_add()
将 dev 添加到 kobject 层次结构中,将其添加到设备的全局列表和兄弟列表,然后将其添加到驱动程序模型的其他相关子系统中。
不要对任何设备结构多次调用此例程或 device_register()
。驱动程序模型核心并非设计为与取消注册然后又恢复活动的设备一起工作。(除此之外,很难保证已放弃对 dev 以前版本的所有引用。)请分配并注册一个全新的 struct device
。
经验法则是:如果 device_add()
成功,则当您想要摆脱它时,应调用 device_del()
。如果 device_add()
没有成功,则仅使用 put_device()
来减少引用计数。
注意
即使它返回错误,也 _永远不要_ 在调用此函数后直接释放 dev!始终使用 put_device()
来放弃您的引用。
参数
struct device *dev
指向设备结构的指针
描述
这分为两个清晰的步骤 - 初始化设备并将其添加到系统中。这两个步骤可以单独调用,但这是最简单和最常见的方法。即,如果您在将设备添加到层次结构之前有明确定义的需求来使用和引用计数该设备,则应仅单独调用两个辅助函数。
有关详细信息,请参阅 device_initialize()
和 device_add()
的 kerneldoc。
注意
即使它返回错误,也 _永远不要_ 在调用此函数后直接释放 dev!始终使用 put_device()
来放弃此函数中初始化的引用。
参数
struct device *dev
有问题的设备。
参数
struct device *dev
设备。
描述
这是设备注销序列的第一部分。它从我们在此处控制的列表中删除设备,使其从 device_add()
中添加的其他驱动程序模型子系统中删除,并将其从 kobject 层次结构中删除。
注意
只有在手动调用了 device_add()
的情况下才应手动调用此函数。
参数
struct device *dev
设备即将消失。
描述
我们像 device_register()
一样分两部分执行此操作。首先,我们使用 device_del()
将其从所有子系统中删除,然后通过 put_device()
减少引用计数。如果这是最终的引用计数,则会通过上面的 device_release() 清理设备。否则,该结构将一直存在,直到最终对设备的引用被删除。
-
int device_for_each_child(struct device *parent, void *data, int (*fn)(struct device *dev, void *data))¶
设备子项迭代器。
参数
struct device *parent
void *data
回调的数据。
int (*fn)(struct device *dev, void *data)
为每个设备调用的函数。
描述
迭代 parent 的子设备,并为每个设备调用 fn,并传递 data。
我们每次都会检查 fn 的返回值。如果它返回除 0 之外的任何值,我们将中断并返回该值。
-
int device_for_each_child_reverse(struct device *parent, void *data, int (*fn)(struct device *dev, void *data))¶
按相反顺序的设备子项迭代器。
参数
struct device *parent
void *data
回调的数据。
int (*fn)(struct device *dev, void *data)
为每个设备调用的函数。
描述
迭代 parent 的子设备,并为每个设备调用 fn,并传递 data。
我们每次都会检查 fn 的返回值。如果它返回除 0 之外的任何值,我们将中断并返回该值。
-
int device_for_each_child_reverse_from(struct device *parent, struct device *from, const void *data, int (*fn)(struct device*, const void*))¶
按相反顺序的设备子项迭代器。
参数
struct device *parent
struct device *from
子列表中的可选起始点
const void *data
回调的数据。
int (*fn)(struct device *, const void *)
为每个设备调用的函数。
描述
迭代 parent 的子设备,从 from 开始,并为每个设备调用 fn,并传递 data。当 from 为 NULL 时,此辅助函数与 device_for_each_child_reverse()
完全相同。
每次迭代都会检查 fn。如果它返回除 0 之外的任何值,则迭代停止,并将该值返回给 device_for_each_child_reverse_from()
的调用者;
-
struct device *device_find_child(struct device *parent, void *data, int (*match)(struct device *dev, void *data))¶
用于查找特定设备的设备迭代器。
参数
struct device *parent
void *data
要传递给匹配函数的数据
int (*match)(struct device *dev, void *data)
用于检查设备的回调函数
描述
这类似于上面的 device_for_each_child()
函数,但它返回一个对 “已找到” 的设备的引用,供以后使用,由 match 回调确定。
如果设备不匹配,回调应返回 0,如果匹配,则应返回非零值。如果回调返回非零值并且可以获取对当前设备的引用,则此函数将返回给调用者,并且不会迭代任何其他设备。
注意
使用后,您需要使用 put_device()
来释放引用。
参数
struct device *parent
const char *name
子设备的名称
描述
这类似于上面的 device_find_child()
函数,但它返回对具有名称 name 的设备的引用。
注意
使用后,您需要使用 put_device()
来释放引用。
参数
struct device *parent
描述
这类似于上面的 device_find_child()
函数,但它返回对子设备(如果有)的引用。
注意
使用后,您需要使用 put_device()
来释放引用。
参数
const char *name
根设备名称
struct module *owner
根设备的所属模块,通常是 THIS_MODULE
描述
此函数分配一个根设备,并使用 device_register()
注册它。 为了释放返回的设备,请使用 root_device_unregister()
。
根设备是虚拟设备,允许其他设备分组在 /sys/devices 下。使用此函数分配一个根设备,然后将其用作应显示在 /sys/devices/{name} 下的任何设备的父设备。
/sys/devices/{name} 目录还将包含一个指向 sysfs 中 owner 目录的 ‘module’ 符号链接。
成功时返回 struct device
指针,出错时返回 ERR_PTR()
。
注意
您可能需要使用 root_device_register()。
参数
struct device *dev
要释放的设备
描述
此函数注销并清理由 root_device_register() 创建的设备。
-
struct device *device_create(const struct class *class, struct device *parent, dev_t devt, void *drvdata, const char *fmt, ...)¶
创建设备并将其注册到 sysfs
参数
const struct class *class
指向此设备应注册到的
struct class
的指针struct device *parent
指向此新设备的父
struct device
(如果有)的指针dev_t devt
要添加的字符设备的 dev_t
void *drvdata
要添加到设备以进行回调的数据
const char *fmt
设备的名称字符串
...
可变参数
描述
字符设备类可以使用此函数。将在 sysfs 中创建一个 struct device
,并注册到指定的类。
如果 dev_t 不为 0,0,则将创建一个 “dev” 文件,显示设备的 dev_t。如果传入指向父 struct device
的指针,则新创建的 struct device
将成为 sysfs 中该设备的子设备。指向 struct device
的指针将从调用中返回。可以使用此指针创建可能需要的任何其他 sysfs 文件。
成功时返回 struct device
指针,出错时返回 ERR_PTR()
。
-
struct device *device_create_with_groups(const struct class *class, struct device *parent, dev_t devt, void *drvdata, const struct attribute_group **groups, const char *fmt, ...)¶
创建设备并将其注册到 sysfs
参数
const struct class *class
指向此设备应注册到的
struct class
的指针struct device *parent
指向此新设备的父
struct device
(如果有)的指针dev_t devt
要添加的字符设备的 dev_t
void *drvdata
要添加到设备以进行回调的数据
const struct attribute_group **groups
要创建的属性组的 NULL 终止列表
const char *fmt
设备的名称字符串
...
可变参数
描述
字符设备类可以使用此函数。将在 sysfs 中创建一个 struct device
,并注册到指定的类。还将自动创建在 groups 参数中指定的其他属性。
如果 dev_t 不为 0,0,则将创建一个 “dev” 文件,显示设备的 dev_t。如果传入指向父 struct device
的指针,则新创建的 struct device
将成为 sysfs 中该设备的子设备。指向 struct device
的指针将从调用中返回。可以使用此指针创建可能需要的任何其他 sysfs 文件。
成功时返回 struct device
指针,出错时返回 ERR_PTR()
。
-
void device_destroy(const struct class *class, dev_t devt)¶
删除使用
device_create()
创建的设备
参数
const struct class *class
指向此设备注册到的
struct class
的指针dev_t devt
先前注册的设备的 dev_t
描述
此调用注销并清理通过调用 device_create()
创建的设备。
参数
struct device *dev
指向要重命名的
struct device
的指针const char *new_name
设备的新名称
描述
调用方有责任在同一设备上两次不同的 device_rename 调用之间提供互斥,以确保 new_name 有效,并且不会与其他设备冲突。
但是,如果您正在编写新代码,请不要调用此函数。 Kay Sievers 的以下文字提供了一些见解
在许多级别重命名设备都是竞争的,符号链接和其他内容不是原子替换的,并且您会得到一个“移动” uevent,但是将该事件连接到旧设备和新设备并不容易。 设备节点根本不会重命名,内核现在甚至不支持。
同时,在重命名期间,你的目标名称可能会被另一个驱动程序占用,从而产生冲突。或者旧名称在你重命名后立即被占用——那么在你看到“移动”事件之前,你就会收到同一 DEVPATH 的事件。这简直是一团糟,任何新的东西都不应该依赖内核设备重命名。除此之外,它现在甚至没有为(驱动核心方面非常简单的)网络设备以外的其他东西实现。
在注册任何内容之前,在驱动程序中创建一个“真实”名称,或者添加一些其他属性供用户空间查找设备,或者使用 udev 添加符号链接——但永远不要在以后重命名内核设备,那完全是一团糟。我们甚至不想深入研究并尝试在核心中实现缺失的部分。我们真的有其他部分需要在驱动程序核心中修复。:)
注意
鉴于某些子系统(网络和 InfiniBand)使用此函数,并且没有立即更改的计划,我们不能假设或要求完全不调用此函数。
-
int device_move(struct device *dev, struct device *new_parent, enum dpm_order dpm_order)¶
将设备移动到新的父设备
参数
struct device *dev
要移动的
struct device
的指针struct device *new_parent
设备的新父设备(可以为 NULL)
enum dpm_order dpm_order
如何重新排序 dpm_list
参数
struct device *dev
设备。
kuid_t kuid
新所有者的 kuid
kgid_t kgid
新所有者的 kgid
描述
这将 dev 及其对应的 sysfs 条目的所有者更改为 kuid/kgid。此函数与通过驱动程序核心添加 dev 的方式非常相似。
成功返回 0,失败返回错误代码。
参数
const struct device *dev
指向
struct device
的指针int err
要测试的错误值
const char *fmt
printf 风格的格式字符串
...
格式字符串中指定的参数
描述
此助手实现了探测函数中用于错误检查的常见模式:如果错误值为 -EPROBE_DEFER,则打印调试或错误消息,并将错误向上传播。 如果是 -EPROBE_DEFER,它还会设置延迟探测原因,该原因稍后可以通过读取 devices_deferred debugfs 属性来检查。它替换了以下代码序列
if (err != -EPROBE_DEFER)
dev_err(dev, ...);
else
dev_dbg(dev, ...);
return err;
用
return dev_err_probe(dev, err, ...);
即使已知 err 永远不会是 -EPROBE_DEFER,在你的探测函数中使用此助手也完全没问题。与普通的 dev_err() 相比,好处是错误代码的标准化格式,它是以符号方式发出的(即,你会得到“EAGAIN”而不是“-35”),并且返回错误代码允许更紧凑的错误路径。
返回 err。
参数
const struct device *dev
指向
struct device
的指针int err
要测试的错误值
const char *fmt
printf 风格的格式字符串
...
格式字符串中指定的参数
描述
此助手实现了探测函数中用于错误检查的常见模式:如果错误值为 -EPROBE_DEFER,则打印调试或警告消息,并将错误向上传播。 如果是 -EPROBE_DEFER,它还会设置延迟探测原因,该原因稍后可以通过读取 devices_deferred debugfs 属性来检查。它替换了以下代码序列
if (err != -EPROBE_DEFER)
dev_warn(dev, ...);
else
dev_dbg(dev, ...);
return err;
用
return dev_warn_probe(dev, err, ...);
即使已知 err 永远不会是 -EPROBE_DEFER,在你的探测函数中使用此助手也完全没问题。与普通的 dev_warn() 相比,好处是错误代码的标准化格式,它是以符号方式发出的(即,你会得到“EAGAIN”而不是“-35”),并且返回错误代码允许更紧凑的错误路径。
返回 err。
参数
struct device *dev
要处理的设备。
struct fwnode_handle *fwnode
设备新的主固件节点。
描述
将设备的固件节点指针设置为 fwnode,但如果存在设备的辅助固件节点,则保留它。
- 有效的 fwnode 情况是
主要 -> 次要 -> -ENODEV
主要 -> NULL
次要 -> -ENODEV
NULL
参数
struct device *dev
要处理的设备。
struct fwnode_handle *fwnode
设备新的辅助固件节点。
描述
如果存在设备的主固件节点,则将其辅助指针设置为 fwnode。 否则,将设备的固件节点指针设置为 fwnode。
参数
struct device *dev
要设置其设备树节点的设备
const struct device *dev2
正在重用其设备树节点的设备
描述
在首先删除对旧节点持有的任何引用之后,获取对新设备树节点的另一个引用。
-
void register_syscore_ops(struct syscore_ops *ops)¶
注册一组系统核心操作。
参数
struct syscore_ops *ops
要注册的系统核心操作。
-
void unregister_syscore_ops(struct syscore_ops *ops)¶
注销一组系统核心操作。
参数
struct syscore_ops *ops
要注销的系统核心操作。
-
int syscore_suspend(void)¶
执行所有已注册的系统核心挂起回调。
参数
void
无参数
描述
此函数在单个 CPU 联机且中断禁用的情况下执行。
-
void syscore_resume(void)¶
执行所有已注册的系统核心恢复回调。
参数
void
无参数
描述
此函数在单个 CPU 联机且中断禁用的情况下执行。
-
struct device *class_find_device_by_name(const struct class *class, const char *name)¶
设备迭代器,用于查找具有特定名称的特定设备。
参数
const struct class *class
类类型
const char *name
要匹配的设备名称
-
struct device *class_find_device_by_of_node(const struct class *class, const struct device_node *np)¶
用于定位与 of_node 匹配的特定设备的设备迭代器。
参数
const struct class *class
类类型
const struct device_node *np
要匹配的设备的 of_node。
-
struct device *class_find_device_by_fwnode(const struct class *class, const struct fwnode_handle *fwnode)¶
用于定位与 fwnode 匹配的特定设备的设备迭代器。
参数
const struct class *class
类类型
const struct fwnode_handle *fwnode
要匹配的设备的 fwnode。
-
struct device *class_find_device_by_devt(const struct class *class, dev_t devt)¶
用于定位与设备类型匹配的特定设备的设备迭代器。
参数
const struct class *class
类类型
dev_t devt
要匹配的设备的设备类型。
-
struct device *class_find_device_by_acpi_dev(const struct class *class, const struct acpi_device *adev)¶
设备迭代器,用于查找与 ACPI_COMPANION 设备匹配的特定设备。
参数
const struct class *class
类类型
const struct acpi_device *adev
要匹配的 ACPI_COMPANION 设备。
-
struct class *class_create(const char *name)¶
创建一个
struct class
结构体
参数
const char *name
指向此类的名称字符串的指针。
描述
这用于创建一个 struct class
指针,该指针随后可在调用 device_create()
中使用。
成功时返回 struct class
指针,或在错误时返回 ERR_PTR()
。
请注意,此处创建的指针在完成后需要通过调用 class_destroy()
来销毁。
-
void class_destroy(const struct class *cls)¶
销毁一个
struct class
结构体
-
void class_dev_iter_init(struct class_dev_iter *iter, const struct class *class, const struct device *start, const struct device_type *type)¶
初始化类设备迭代器
参数
struct class_dev_iter *iter
要初始化的类迭代器
const struct class *class
我们要迭代的类
const struct device *start
开始迭代的设备(如果有)
const struct device_type *type
要迭代的设备的 device_type,NULL 表示所有
描述
初始化类迭代器 iter,使其迭代 class 的设备。如果设置了 start,则列表迭代将从此处开始,否则如果为 NULL,则迭代从列表的开头开始。
参数
struct class_dev_iter *iter
要继续的类迭代器
描述
将 iter 移到下一个设备并返回它。如果迭代完成,则返回 NULL。
返回的设备被引用,并且在迭代器移到下一个设备或退出之前不会被释放。调用方可以自由地对设备执行任何操作,包括回调到类代码中。
-
void class_dev_iter_exit(struct class_dev_iter *iter)¶
完成迭代
参数
struct class_dev_iter *iter
要完成的类迭代器
描述
完成迭代。无论迭代是否运行到最后,都请在迭代完成后始终调用此函数。
-
int class_for_each_device(const struct class *class, const struct device *start, void *data, int (*fn)(struct device*, void*))¶
设备迭代器
参数
const struct class *class
我们正在迭代的类
const struct device *start
列表中要开始的设备,如果有的话。
void *data
回调的数据
int (*fn)(struct device *, void *)
为每个设备调用的函数
描述
迭代 **class** 的设备列表,并为每个设备调用 **fn**,传递 **data**。如果设置了 **start**,列表迭代将从那里开始,否则,如果它是 NULL,则迭代从列表的开头开始。
我们每次都会检查 fn 的返回值。如果它返回除 0 之外的任何值,我们将中断并返回该值。
**fn** 允许执行任何操作,包括回调到类代码。没有锁定限制。
-
struct device *class_find_device(const struct class *class, const struct device *start, const void *data, device_match_t match)¶
用于定位特定设备的设备迭代器
参数
const struct class *class
我们正在迭代的类
const struct device *start
开始的设备
const void *data
匹配函数的数据
device_match_t match
检查设备的函数
描述
这类似于上面的 class_for_each_dev() 函数,但它返回一个对“找到”的设备的引用,供以后使用,这由 **match** 回调确定。
如果设备不匹配,回调应返回 0;如果匹配,则返回非零值。 如果回调返回非零值,则此函数将返回给调用者,并且不会迭代任何其他设备。
请注意,使用后您需要使用 put_device()
来删除引用。
**match** 允许执行任何操作,包括回调到类代码。没有锁定限制。
-
struct class_compat *class_compat_register(const char *name)¶
注册一个兼容类
参数
const char *name
类的名称
描述
当将一类类设备转换为总线设备时,兼容类旨在作为临时的用户空间兼容性解决方法。
-
void class_compat_unregister(struct class_compat *cls)¶
注销一个兼容类
参数
struct class_compat *cls
要注销的类
-
int class_compat_create_link(struct class_compat *cls, struct device *dev, struct device *device_link)¶
创建到总线设备的兼容类设备链接
参数
struct class_compat *cls
兼容类
struct device *dev
目标总线设备
struct device *device_link
一个可选的设备,应该为其创建“device”链接
-
void class_compat_remove_link(struct class_compat *cls, struct device *dev, struct device *device_link)¶
删除到总线设备的兼容类设备链接
参数
struct class_compat *cls
兼容类
struct device *dev
目标总线设备
struct device *device_link
一个可选的设备,之前已为其创建了“device”链接
参数
const struct class *class
要检查的类
描述
返回一个布尔值,指示该类是否已在驱动程序核心中注册。请注意,该值可能会在调用后立即切换,因此仅在您“知道”这样做是安全的地方使用它(通常用于确定是否已注册特定的类)。
请谨慎使用此功能。
-
struct node_access_nodes¶
访问类设备以保持用户可见的与其他节点的关系。
定义:
struct node_access_nodes {
struct device dev;
struct list_head list_node;
unsigned int access;
#ifdef CONFIG_HMEM_REPORTING;
struct access_coordinate coord;
#endif;
};
成员
dev
此内存访问类的设备
list_node
节点访问列表中的列表元素
access
访问类等级
coord
异构内存性能坐标
-
struct node_cache_info¶
内存节点缓存的内部跟踪
定义:
struct node_cache_info {
struct device dev;
struct list_head node;
struct node_cache_attrs cache_attrs;
};
成员
dev
表示缓存级别的设备
node
用于在节点中跟踪的列表元素
cache_attrs
此缓存级别的属性
-
void node_add_cache(unsigned int nid, struct node_cache_attrs *cache_attrs)¶
向内存节点添加缓存属性
参数
unsigned int nid
具有新缓存属性的节点标识符
struct node_cache_attrs *cache_attrs
正在添加的缓存的属性
参数
struct node *node
即将消失的节点
描述
注销节点设备 **node**。在调用此函数之前,必须注销节点上的所有设备。
-
int register_memory_node_under_compute_node(unsigned int mem_nid, unsigned int cpu_nid, enum access_coordinate_class access)¶
将内存节点链接到其计算节点,用于给定的访问类。
参数
unsigned int mem_nid
内存节点号
unsigned int cpu_nid
CPU 节点号
enum access_coordinate_class access
要注册的访问类
描述
用于可能具有单独的内存和计算节点的平台。此函数将导出节点关系,链接哪个内存启动器节点可以在给定的排名访问类中访问内存目标。
-
int transport_class_register(struct transport_class *tclass)¶
注册一个初始传输类
参数
struct transport_class *tclass
指向要初始化的传输类结构的指针
描述
传输类包含一个用于标识它的嵌入类。调用者应使用零初始化此结构,然后必须使用实际传输类的唯一名称初始化通用类。有一个宏 DECLARE_TRANSPORT_CLASS() 可以执行此操作(声明的类仍然必须注册)。
成功返回 0,失败返回错误。
-
void transport_class_unregister(struct transport_class *tclass)¶
注销先前注册的类
参数
struct transport_class *tclass
要注销的传输类
描述
必须在释放传输类内存之前调用。
-
int anon_transport_class_register(struct anon_transport_class *atc)¶
注册一个匿名类
参数
struct anon_transport_class *atc
要注册的匿名传输类
描述
匿名传输类包含传输类和容器。匿名类的想法是它实际上没有任何与之关联的设备属性(从而节省了容器存储)。因此,它只能用于触发事件。使用 prezero,然后使用 DECLARE_ANON_TRANSPORT_CLASS() 来初始化匿名传输类存储。
-
void anon_transport_class_unregister(struct anon_transport_class *atc)¶
注销一个匿名类
参数
struct anon_transport_class *atc
指向要注销的匿名传输类的指针
描述
必须在释放匿名传输类的内存之前调用。
参数
struct device *dev
表示要添加的实体的通用设备
描述
通常,dev 表示 HBA 系统中的某些组件(HBA 本身或跨 HBA 总线的远程设备)。此例程只是一个触发点,用于查看任何一组传输类是否希望与添加的设备关联。这会为类设备分配存储并初始化它,但不会将其添加到系统或向其添加属性(您可以使用 transport_add_device 执行此操作)。如果您不需要单独的设置和添加操作,请使用 transport_register_device(请参阅 transport_class.h)。
参数
struct device *dev
表示要添加的实体的通用设备
描述
通常,dev 表示 HBA 系统中的某些组件(HBA 本身或跨 HBA 总线的远程设备)。此例程只是一个触发点,用于将设备添加到系统并为其注册属性。
参数
struct device *dev
表示要配置的设备的通用设备
描述
配置的想法只是在设置过程中提供一个点,以允许传输类在设备设置后从中提取信息。这在 SCSI 中使用,因为我们必须有一个设置设备才能开始使用 HBA,但是在我们发送初始查询后,我们使用配置来提取设备参数。该设备不需要为了被配置而被添加。
参数
struct device *dev
要删除的通用设备
描述
此调用会删除设备(从 sysfs 向用户)的可见性,但不会销毁它。要完全删除设备,您还必须调用 transport_destroy_device。如果您不需要将删除和销毁作为单独的操作执行,请使用 transport_unregister_device()(请参阅 transport_class.h),它将为您执行这两个调用。
参数
struct device *dev
要从传输类中删除的设备。
描述
此调用会触发与传输类设备关联的存储的删除。注意:它实际上只是放弃对类设备的引用。在最后一个引用变为零之前,不会释放内存。另请注意,类设备保留对 dev 的引用计数,因此只要传输类设备存在,dev 也将保留。
参数
struct device *dev
要检查的设备
返回
如果 initcalls 已完成且模块已禁用,则为 -ENODEV。
如果已设置延迟探测超时并且已过期且模块已启用,则为 -ETIMEDOUT。
在其他情况下为 -EPROBE_DEFER。
描述
驱动程序或子系统可以选择调用此函数,而不是直接返回 -EPROBE_DEFER。
参数
struct device *dev
要检查的设备
描述
如果传递的设备已成功完成针对驱动程序的探测,则返回 true。
必须在持有设备锁的情况下调用此函数。
参数
struct device *dev
设备。
描述
允许手动将驱动程序附加到设备。调用者必须已设置 dev->driver。
请注意,这不会修改总线引用计数。请在调用此函数之前验证是否已考虑此因素。(从驱动程序的 probe() 方法调用时,无需其他操作。)
必须在持有设备锁的情况下调用此函数。
调用者应首选使用 device_driver_attach()
。
-
void wait_for_device_probe(void)¶
参数
void
无参数
描述
等待设备探测完成。
参数
struct device *dev
设备。
描述
遍历总线拥有的驱动程序列表,并为每一对调用 driver_probe_device()。如果找到兼容对,则退出并返回。
如果设备已绑定到驱动程序,则返回 1;如果未找到匹配的驱动程序,则返回 0;如果设备未注册,则返回 -ENODEV。
当为 USB 接口调用时,必须持有 dev->parent 锁。
-
int device_driver_attach(const struct device_driver *drv, struct device *dev)¶
将特定驱动程序附加到特定设备。
参数
const struct device_driver *drv
要附加的驱动程序。
struct device *dev
要附加到的设备。
描述
手动将驱动程序附加到设备。如果需要,将获取 **dev** 锁和 **dev->parent** 锁。成功时返回 0,失败时返回 -ERR。
-
int driver_attach(const struct device_driver *drv)¶
尝试将驱动程序绑定到设备。
参数
const struct device_driver *drv
驱动程序。
描述
遍历总线上拥有的设备列表,并尝试将驱动程序与每个设备进行匹配。如果 driver_probe_device() 返回 0 且 **dev->driver** 已设置,则表示已找到兼容的对。
参数
struct device *dev
设备。
描述
手动从驱动程序分离设备。当为 USB 接口调用时,必须持有 **dev->parent** 锁。
如果此函数要在持有 **dev->parent** 锁的情况下调用,请确保提前解除绑定设备的消费者,或者可以在 **dev->parent** 锁下获取它们的锁。
-
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)¶
添加具有资源和平台特定数据的平台级设备。
参数
struct device *parent
我们要添加的设备的父设备。
const char *name
我们要添加的设备的基本名称。
int id
实例 ID。
const struct resource *res
需要为设备分配的资源集。
unsigned int num
资源数量。
const void *data
此平台设备的平台特定数据。
size_t size
平台特定数据的大小。
描述
成功时返回 struct platform_device
指针,失败时返回 ERR_PTR()
。
-
struct platform_device *platform_device_register_simple(const char *name, int id, const struct resource *res, unsigned int num)¶
添加平台级设备及其资源。
参数
const char *name
我们要添加的设备的基本名称。
int id
实例 ID。
const struct resource *res
需要为设备分配的资源集。
unsigned int num
资源数量。
描述
此函数创建一个简单的平台设备,该设备需要最少的资源和内存管理。罐装释放函数释放为设备分配的内存,允许卸载使用此类设备的驱动程序,而无需等待对设备的最后一个引用被删除。
此接口主要用于直接探测硬件的旧驱动程序。由于此类驱动程序自己创建 sysfs 设备节点,而不是让系统基础架构处理此类设备枚举任务,因此它们不完全符合 Linux 驱动程序模型。特别是,当此类驱动程序作为模块构建时,它们无法“热插拔”。
成功时返回 struct platform_device
指针,失败时返回 ERR_PTR()
。
-
struct platform_device *platform_device_register_data(struct device *parent, const char *name, int id, const void *data, size_t size)¶
添加具有平台特定数据的平台级设备。
参数
struct device *parent
我们要添加的设备的父设备。
const char *name
我们要添加的设备的基本名称。
int id
实例 ID。
const void *data
此平台设备的平台特定数据。
size_t size
平台特定数据的大小。
描述
此函数创建一个简单的平台设备,该设备需要最少的资源和内存管理。罐装释放函数释放为设备分配的内存,允许卸载使用此类设备的驱动程序,而无需等待对设备的最后一个引用被删除。
成功时返回 struct platform_device
指针,失败时返回 ERR_PTR()
。
-
struct resource *platform_get_resource(struct platform_device *dev, unsigned int type, unsigned int num)¶
获取设备的资源。
参数
struct platform_device *dev
平台设备。
unsigned int type
资源类型。
unsigned int num
资源索引。
返回
指向资源的指针,如果失败则为 NULL。
-
void __iomem *devm_platform_get_and_ioremap_resource(struct platform_device *pdev, unsigned int index, struct resource **res)¶
为平台设备调用 devm_ioremap_resource() 并获取资源。
参数
struct platform_device *pdev
用于内存资源查找和资源管理的平台设备。
unsigned int index
资源索引。
struct resource **res
可选输出参数,用于存储指向所获取资源的指针。
返回
指向重新映射的内存的指针,如果失败,则返回 ERR_PTR()
编码的错误代码。
-
void __iomem *devm_platform_ioremap_resource(struct platform_device *pdev, unsigned int index)¶
为平台设备调用 devm_ioremap_resource()。
参数
struct platform_device *pdev
用于内存资源查找和资源管理的平台设备。
unsigned int index
资源索引。
返回
指向重新映射的内存的指针,如果失败,则返回 ERR_PTR()
编码的错误代码。
-
void __iomem *devm_platform_ioremap_resource_byname(struct platform_device *pdev, const char *name)¶
为平台设备调用 devm_ioremap_resource,按名称检索资源。
参数
struct platform_device *pdev
用于内存资源查找和资源管理的平台设备。
const char *name
资源的名称。
返回
指向重新映射的内存的指针,如果失败,则返回 ERR_PTR()
编码的错误代码。
-
int platform_get_irq_optional(struct platform_device *dev, unsigned int num)¶
获取设备的可选 IRQ
参数
struct platform_device *dev
平台设备。
unsigned int num
IRQ 编号索引
描述
获取平台设备的 IRQ。设备驱动程序应检查返回值是否有错误,以避免将负整数值传递给 request_irq()
API。这与 platform_get_irq()
相同,只是如果无法获取 IRQ,它不会打印错误消息。
例如
int irq = platform_get_irq_optional(pdev, 0);
if (irq < 0)
return irq;
返回
成功时返回非零 IRQ 编号,失败时返回负错误编号。
-
int platform_get_irq(struct platform_device *dev, unsigned int num)¶
获取设备的 IRQ
参数
struct platform_device *dev
平台设备。
unsigned int num
IRQ 编号索引
描述
获取平台设备的 IRQ,如果查找 IRQ 失败,则打印错误消息。设备驱动程序应检查返回值是否有错误,以避免将负整数值传递给 request_irq()
API。
例如
int irq = platform_get_irq(pdev, 0);
if (irq < 0)
return irq;
返回
成功时返回非零 IRQ 编号,失败时返回负错误编号。
-
int platform_irq_count(struct platform_device *dev)¶
计算平台设备使用的 IRQ 数量
参数
struct platform_device *dev
平台设备。
返回
平台设备使用的 IRQ 数量或 EPROBE_DEFER
-
int devm_platform_get_irqs_affinity(struct platform_device *dev, struct irq_affinity *affd, unsigned int minvec, unsigned int maxvec, int **irqs)¶
devm 方法,用于使用中断亲和性描述符获取设备的 IRQ 集
参数
struct platform_device *dev
平台设备指针
struct irq_affinity *affd
亲和性描述符
unsigned int minvec
中断向量的最小计数
unsigned int maxvec
中断向量的最大计数
int **irqs
用于保存 IRQ 编号的指针
描述
获取平台设备的一组 IRQ,并根据传递的亲和性描述符更新 IRQ 亲和性
返回
成功时返回向量数,失败时返回负错误编号。
-
struct resource *platform_get_resource_byname(struct platform_device *dev, unsigned int type, const char *name)¶
按名称获取设备的资源
参数
struct platform_device *dev
平台设备。
unsigned int type
资源类型。
const char *name
资源名称
-
int platform_get_irq_byname(struct platform_device *dev, const char *name)¶
按名称获取设备的 IRQ
参数
struct platform_device *dev
平台设备。
const char *name
IRQ 名称
描述
像 platform_get_irq()
一样获取 IRQ,但通过名称而不是索引获取。
返回
成功时返回非零 IRQ 编号,失败时返回负错误编号。
-
int platform_get_irq_byname_optional(struct platform_device *dev, const char *name)¶
按名称获取设备的可选 IRQ
参数
struct platform_device *dev
平台设备。
const char *name
IRQ 名称
描述
像 platform_get_irq_byname()
一样按名称获取可选 IRQ。除非无法获取 IRQ,否则它不会打印错误消息。
返回
成功时返回非零 IRQ 编号,失败时返回负错误编号。
-
int platform_add_devices(struct platform_device **devs, int num)¶
添加多个平台设备
参数
struct platform_device **devs
要添加的平台设备数组
int num
数组中平台设备的数量
返回
成功时返回 0,失败时返回负错误编号。
-
void platform_device_put(struct platform_device *pdev)¶
销毁平台设备
参数
struct platform_device *pdev
要释放的平台设备
描述
释放与平台设备关联的所有内存。此函数必须 _仅_ 在错误情况下从外部调用。所有其他用法都是错误。
-
struct platform_device *platform_device_alloc(const char *name, int id)¶
创建平台设备
参数
const char *name
我们要添加的设备的基本名称。
int id
实例 ID。
描述
创建一个平台设备对象,该对象可以附加其他对象,并且在释放时将释放附加的对象。
-
int platform_device_add_resources(struct platform_device *pdev, const struct resource *res, unsigned int num)¶
向平台设备添加资源
参数
struct platform_device *pdev
由 platform_device_alloc 分配的平台设备,用于向其添加资源
const struct resource *res
需要为设备分配的资源集。
unsigned int num
资源数量。
描述
将资源的副本添加到平台设备。当平台设备释放时,将释放与资源关联的内存。
-
int platform_device_add_data(struct platform_device *pdev, const void *data, size_t size)¶
向平台设备添加特定于平台的数据
参数
struct platform_device *pdev
由 platform_device_alloc 分配的平台设备,用于向其添加资源
const void *data
此平台设备的平台特定数据。
size_t size
平台特定数据的大小。
描述
将平台特定数据的副本添加到平台设备的 platform_data 指针。当平台设备被释放时,与平台数据关联的内存将被释放。
-
int platform_device_add(struct platform_device *pdev)¶
将平台设备添加到设备层次结构
参数
struct platform_device *pdev
我们要添加的平台设备
描述
这是 platform_device_register()
的第 2 部分,但如果 pdev 是通过 platform_device_alloc()
分配的,则可以单独调用。
-
void platform_device_del(struct platform_device *pdev)¶
移除平台级设备
参数
struct platform_device *pdev
我们要移除的平台设备
描述
请注意,此函数还将释放设备拥有的所有基于内存和端口的资源(dev->resource)。此函数必须_仅_在错误情况下从外部调用。所有其他用法都是错误。
-
int platform_device_register(struct platform_device *pdev)¶
添加平台级设备
参数
struct platform_device *pdev
我们要添加的平台设备
注意
调用此函数后,_永远不要_直接释放 pdev,即使它返回错误!始终使用 platform_device_put()
来放弃在此函数中初始化的引用。
-
void platform_device_unregister(struct platform_device *pdev)¶
注销平台级设备
参数
struct platform_device *pdev
我们要注销的平台设备
描述
注销分两步完成。首先,我们释放所有资源并将其从子系统中删除,然后我们通过调用 platform_device_put()
来删除引用计数。
-
struct platform_device *platform_device_register_full(const struct platform_device_info *pdevinfo)¶
添加具有资源和平台特定数据的平台级设备。
参数
const struct platform_device_info *pdevinfo
用于创建设备的数据
描述
成功时返回 struct platform_device
指针,失败时返回 ERR_PTR()
。
-
int __platform_driver_register(struct platform_driver *drv, struct module *owner)¶
为平台级设备注册驱动程序
参数
struct platform_driver *drv
平台驱动程序结构
struct module *owner
所有者模块/驱动程序
-
void platform_driver_unregister(struct platform_driver *drv)¶
注销平台级设备的驱动程序
参数
struct platform_driver *drv
平台驱动程序结构
-
int __platform_driver_probe(struct platform_driver *drv, int (*probe)(struct platform_device*), struct module *module)¶
为非热插拔设备注册驱动程序
参数
struct platform_driver *drv
平台驱动程序结构
int (*probe)(struct platform_device *)
驱动程序的探测例程,可能来自 __init 部分
struct module *module
将成为驱动程序所有者的模块
描述
当您知道设备不是热插拔的并且已经注册时,并且您希望在驱动程序绑定到设备后从内存中删除其一次性 probe() 基础结构时,请使用此方法代替 platform_driver_register()。
一个典型的用途是用于集成到片上系统处理器中的控制器的驱动程序,其中控制器设备已配置为板设置的一部分。
请注意,这与延迟探测不兼容。
如果驱动程序注册并绑定到设备,则返回零,否则返回负错误代码,并且不注册驱动程序。
-
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)¶
注册驱动程序并创建相应的设备
参数
struct platform_driver *driver
平台驱动程序结构
int (*probe)(struct platform_device *)
驱动程序的探测例程,可能来自 __init 部分
struct resource *res
需要为设备分配的资源集。
unsigned int n_res
资源数量。
const void *data
此平台设备的平台特定数据。
size_t size
平台特定数据的大小。
struct module *module
将成为驱动程序所有者的模块
描述
在旧式模块中使用此方法,这些模块直接探测硬件并注册单个平台设备和相应的平台驱动程序。
成功时返回 struct platform_device
指针,失败时返回 ERR_PTR()
。
-
int __platform_register_drivers(struct platform_driver *const *drivers, unsigned int count, struct module *owner)¶
注册平台驱动程序数组
参数
struct platform_driver * const *drivers
要注册的驱动程序数组
unsigned int count
要注册的驱动程序数量
struct module *owner
拥有驱动程序的模块
描述
注册由数组指定的平台驱动程序。如果注册驱动程序失败,将注销所有先前注册的驱动程序。此 API 的调用者应使用 platform_unregister_drivers()
以相反的顺序注销驱动程序。
返回
成功时返回 0,失败时返回负错误代码。
-
void platform_unregister_drivers(struct platform_driver *const *drivers, unsigned int count)¶
注销平台驱动程序数组
参数
struct platform_driver * const *drivers
要注销的驱动程序数组
unsigned int count
要注销的驱动程序数量
描述
注销由数组指定的平台驱动程序。这通常用于补充之前对 platform_register_drivers() 的调用。驱动程序按照注册顺序的相反顺序注销。
-
struct device *platform_find_device_by_driver(struct device *start, const struct device_driver *drv)¶
查找具有给定驱动程序的平台设备。
参数
struct device *start
开始搜索的设备。
const struct device_driver *drv
要查找的设备驱动程序。
-
struct device *bus_find_device_by_name(const struct bus_type *bus, struct device *start, const char *name)¶
设备迭代器,用于查找具有特定名称的特定设备。
参数
const struct bus_type *bus
总线类型
struct device *start
开始的设备
const char *name
要匹配的设备名称
-
struct device *bus_find_device_by_of_node(const struct bus_type *bus, const struct device_node *np)¶
用于定位与 of_node 匹配的特定设备的设备迭代器。
参数
const struct bus_type *bus
总线类型
const struct device_node *np
要匹配的设备的 of_node。
-
struct device *bus_find_device_by_fwnode(const struct bus_type *bus, const struct fwnode_handle *fwnode)¶
用于定位与 fwnode 匹配的特定设备的设备迭代器。
参数
const struct bus_type *bus
总线类型
const struct fwnode_handle *fwnode
要匹配的设备的 fwnode。
-
struct device *bus_find_device_by_devt(const struct bus_type *bus, dev_t devt)¶
用于定位与设备类型匹配的特定设备的设备迭代器。
参数
const struct bus_type *bus
总线类型
dev_t devt
要匹配的设备的设备类型。
-
struct device *bus_find_next_device(const struct bus_type *bus, struct device *cur)¶
查找给定总线上给定设备之后的下一个设备。
参数
const struct bus_type *bus
总线类型
struct device *cur
开始搜索的设备。
-
struct device *bus_find_device_by_acpi_dev(const struct bus_type *bus, const struct acpi_device *adev)¶
用于定位与 ACPI COMPANION 设备匹配的特定设备的设备迭代器。
参数
const struct bus_type *bus
总线类型
const struct acpi_device *adev
要匹配的 ACPI COMPANION 设备。
-
int bus_for_each_dev(const struct bus_type *bus, struct device *start, void *data, int (*fn)(struct device*, void*))¶
设备迭代器。
参数
const struct bus_type *bus
总线类型。
struct device *start
开始迭代的设备。
void *data
回调的数据。
int (*fn)(struct device *, void *)
为每个设备调用的函数。
描述
遍历 **bus** 的设备列表,并为每个设备调用 **fn**,并向其传递 **data**。如果 **start** 不为 NULL,我们使用该设备开始迭代。
我们每次都会检查 fn 的返回值。如果它返回除 0 之外的任何值,我们将中断并返回该值。
注意
返回非零值的设备不会以任何方式保留,也不会递增其引用计数。如果调用者需要保留此数据,它应该这样做,并在提供的回调中递增引用计数。
-
struct device *bus_find_device(const struct bus_type *bus, struct device *start, const void *data, device_match_t match)¶
用于查找特定设备的设备迭代器。
参数
const struct bus_type *bus
总线类型
struct device *start
开始的设备
const void *data
要传递给匹配函数的数据
device_match_t match
用于检查设备的回调函数
描述
这与上面的 bus_for_each_dev()
函数类似,但它返回一个对“找到”的设备的引用,供以后使用,由 **match** 回调确定。
如果设备不匹配,回调应返回 0;如果匹配,则返回非零值。 如果回调返回非零值,则此函数将返回给调用者,并且不会迭代任何其他设备。
-
int bus_for_each_drv(const struct bus_type *bus, struct device_driver *start, void *data, int (*fn)(struct device_driver*, void*))¶
驱动程序迭代器
参数
const struct bus_type *bus
我们正在处理的总线。
struct device_driver *start
开始迭代的驱动程序。
void *data
要传递给回调的数据。
int (*fn)(struct device_driver *, void *)
为每个驱动程序调用的函数。
描述
这与上面的设备迭代器几乎相同。我们迭代属于 bus 的每个驱动程序,并为每个驱动程序调用 fn。如果 fn 返回除 0 之外的任何值,我们将跳出并返回该值。如果 start 不为 NULL,我们将其用作列表的头部。
注意
我们不会返回返回非零值的驱动程序,也不会为该驱动程序增加引用计数。如果调用者需要知道该信息,则必须在回调中设置。它还必须确保增加引用计数,使其不会在返回给调用者之前消失。
参数
const struct bus_type *bus
要扫描的总线。
描述
此函数将查找总线上未连接驱动程序的设备,并针对现有驱动程序重新扫描,以查看是否通过调用 device_attach()
与任何驱动程序匹配(对于未绑定的设备)。
参数
struct device *dev
要重新探测的设备
描述
此函数分离给定设备的已连接驱动程序(如果有),并重新启动驱动程序探测过程。如果设备生命周期内的探测标准发生变化,并且驱动程序连接应相应更改,则应使用此函数。
参数
const struct bus_type *bus
要注册的总线
描述
一旦有了这些,我们将总线注册到 kobject 基础结构中,然后注册它拥有的子系统:属于该子系统的设备和驱动程序。
参数
const struct bus_type *bus
总线。
描述
取消注册子系统和总线本身。最后,我们调用 bus_put() 来释放引用计数
-
int subsys_system_register(const struct bus_type *subsys, const struct attribute_group **groups)¶
在 /sys/devices/system/ 注册一个子系统
参数
const struct bus_type *subsys
系统子系统
const struct attribute_group **groups
根设备的默认属性
描述
所有“系统”子系统都有一个 /sys/devices/system/<name> 根设备,其名称为子系统的名称。根设备可以携带子系统范围的属性。所有已注册的设备都位于此单个根设备下,并以子系统名称命名,附加一个简单的枚举数字。已注册的设备未明确命名;只需要设置设备中的“id”。
不要将此接口用于任何新事物,它仅为了与不好的想法兼容而存在。新的子系统应使用普通的子系统;并且应将子系统范围的属性添加到子系统目录本身,而不是添加到位于 /sys/devices/system/<name> 中的某个创建的虚拟根设备。
-
int subsys_virtual_register(const struct bus_type *subsys, const struct attribute_group **groups)¶
在 /sys/devices/virtual/ 注册一个子系统
参数
const struct bus_type *subsys
虚拟子系统
const struct attribute_group **groups
根设备的默认属性
描述
所有“虚拟”子系统都有一个 /sys/devices/system/<name> 根设备,其名称为子系统的名称。根设备可以携带子系统范围的属性。所有已注册的设备都位于此单个根设备下。对设备命名没有任何限制。这适用于需要 sysfs 接口的内核软件结构。
-
struct device_driver *driver_find(const char *name, const struct bus_type *bus)¶
按名称查找总线上的驱动程序。
参数
const char *name
驱动程序的名称。
const struct bus_type *bus
要扫描驱动程序的总线。
描述
调用 kset_find_obj()
遍历总线上的驱动程序列表,以按名称查找驱动程序。如果找到,则返回驱动程序。
此例程不提供任何锁定,以防止其返回的驱动程序在调用者使用时被取消注册或卸载。调用者负责防止这种情况发生。
参数
const struct bus_type *bus
要返回设备根的总线。
描述
如果总线具有“设备根”结构,则返回它,并增加引用计数。
请注意,在完成对设备的操作后,需要调用 put_device()
。
如果设备根不存在(或总线不是有效指针),则将返回 NULL。
设备驱动程序 DMA 管理¶
-
void dmam_free_coherent(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle)¶
托管的 dma_free_coherent()
参数
struct device *dev
要释放相干内存的设备
size_t size
分配的大小
void *vaddr
要释放的内存的虚拟地址
dma_addr_t dma_handle
要释放的内存的 DMA 句柄
描述
托管的 dma_free_coherent()。
-
void *dmam_alloc_attrs(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)¶
托管的 dma_alloc_attrs()
参数
struct device *dev
要为其分配非相干内存的设备
size_t size
分配的大小
dma_addr_t *dma_handle
已分配 DMA 句柄的输出参数
gfp_t gfp
分配标志
unsigned long attrs
DMA_ATTR_* 命名空间中的标志。
描述
托管的 dma_alloc_attrs()。使用此函数分配的内存将在驱动程序分离时自动释放。
返回
成功时指向已分配内存的指针,失败时为 NULL。
-
unsigned int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction dir, unsigned long attrs)¶
为 DMA 映射给定的缓冲区
参数
struct device *dev
执行 DMA 操作的设备
struct scatterlist *sg
描述缓冲区的 sg_table 对象
int nents
要映射的条目数
enum dma_data_direction dir
DMA 方向
unsigned long attrs
映射操作的可选 DMA 属性
描述
映射由 sg 参数中传递的散列表描述的缓冲区,其中包含 nents 段,用于 dev 设备的 dir DMA 操作。
成功时返回映射的条目数(可能小于 nents)。如果发生任何错误,则返回零。
应使用 dma_unmap_sg_attrs() 解除缓冲区的映射,并使用原始的 sg 和原始的 nents(而不是此函数返回的值)。
-
int dma_map_sgtable(struct device *dev, struct sg_table *sgt, enum dma_data_direction dir, unsigned long attrs)¶
为 DMA 映射给定的缓冲区
参数
struct device *dev
执行 DMA 操作的设备
struct sg_table *sgt
描述缓冲区的 sg_table 对象
enum dma_data_direction dir
DMA 方向
unsigned long attrs
映射操作的可选 DMA 属性
描述
映射由给定的 sg_table 对象中存储的散列表描述的缓冲区,用于 dev 设备的 dir DMA 操作。成功后,缓冲区的拥有权将转移到 DMA 域。必须调用 dma_sync_sgtable_for_cpu() 或 dma_unmap_sgtable() 将缓冲区的拥有权移回 CPU 域,然后再由 CPU 访问缓冲区。
成功时返回 0,如果出错则返回负错误代码。支持以下错误代码及其含义
- -EINVAL
无效的参数、未对齐的访问或使用中的其他错误。重试不会成功。
- -ENOMEM
资源不足(例如内存或 IOVA 空间)以完成映射。如果稍后重试,应该会成功。
- -EIO
具有未知含义的旧错误代码。例如,如果较低级别的调用返回 DMA_MAPPING_ERROR,则会返回此代码。
- -EREMOTEIO
DMA 设备无法访问 sg_table 中指定的 P2PDMA 内存。如果重试,则不会成功。
参数
struct device *dev
要检查的设备
描述
如果 dev 支持 dma_mmap_coherent() 和 dma_mmap_attrs()
将 DMA 分配映射到用户空间,则返回 true
。
-
int dma_mmap_attrs(struct device *dev, struct vm_area_struct *vma, void *cpu_addr, dma_addr_t dma_addr, size_t size, unsigned long attrs)¶
将一致的 DMA 分配映射到用户空间
参数
struct device *dev
有效的
struct device
指针,或者对于类似 ISA 和 EISA 的设备为 NULLstruct vm_area_struct *vma
描述请求的用户映射的 vm_area_struct
void *cpu_addr
从 dma_alloc_attrs 返回的内核 CPU 视图地址
dma_addr_t dma_addr
从 dma_alloc_attrs 返回的设备视图地址
size_t size
最初在 dma_alloc_attrs 中请求的内存大小
unsigned long attrs
在 dma_alloc_attrs 中请求的映射属性的属性
描述
将先前由 dma_alloc_attrs 分配的一致 DMA 缓冲区映射到用户空间。在用户空间映射被释放之前,驱动程序不得释放一致的 DMA 缓冲区。
参数
struct device *dev
要检查的设备
描述
如果设备的 DMA 掩码太小,无法寻址系统中的所有内存,则返回 true
,否则返回 false
。缺少寻址位是反弹缓冲的主要原因,但可能不是唯一的原因。
设备驱动程序 PnP 支持¶
-
int pnp_register_protocol(struct pnp_protocol *protocol)¶
将 pnp 协议添加到 pnp 层
参数
struct pnp_protocol *protocol
指向相应 pnp_protocol 结构的指针
示例协议:ISAPNP、PNPBIOS 等
-
void pnp_unregister_protocol(struct pnp_protocol *protocol)¶
从 pnp 层删除 pnp 协议
参数
struct pnp_protocol *protocol
指向相应 pnp_protocol 结构的指针
-
struct pnp_dev *pnp_request_card_device(struct pnp_card_link *clink, const char *id, struct pnp_dev *from)¶
在指定的卡下搜索 PnP 设备
参数
struct pnp_card_link *clink
指向卡链接的指针,不能为 NULL
const char *id
指向 PnP ID 结构的指针,该结构解释了查找设备的规则
struct pnp_dev *from
开始搜索的位置。如果为 NULL,则将从头开始。
-
void pnp_release_card_device(struct pnp_dev *dev)¶
当驱动程序不再需要设备时调用此函数
参数
struct pnp_dev *dev
指向 PnP 设备结构的指针
-
int pnp_register_card_driver(struct pnp_card_driver *drv)¶
向 PnP 层注册 PnP 卡驱动程序
参数
struct pnp_card_driver *drv
指向要注册的驱动程序的指针
-
void pnp_unregister_card_driver(struct pnp_card_driver *drv)¶
从 PnP 层注销 PnP 卡驱动程序
参数
struct pnp_card_driver *drv
指向要注销的驱动程序的指针
-
struct pnp_id *pnp_add_id(struct pnp_dev *dev, const char *id)¶
向指定的设备添加 EISA id
参数
struct pnp_dev *dev
指向目标设备的指针
const char *id
指向 EISA id 字符串的指针
-
int pnp_start_dev(struct pnp_dev *dev)¶
PnP 设备的底层启动
参数
struct pnp_dev *dev
指向目标设备的指针
描述
假设资源已经分配
-
int pnp_stop_dev(struct pnp_dev *dev)¶
PnP 设备的底层禁用
参数
struct pnp_dev *dev
指向目标设备的指针
描述
不释放资源
-
int pnp_activate_dev(struct pnp_dev *dev)¶
激活 PnP 设备以供使用
参数
struct pnp_dev *dev
指向目标设备的指针
描述
不验证或设置资源,因此请小心。
-
int pnp_disable_dev(struct pnp_dev *dev)¶
禁用设备
参数
struct pnp_dev *dev
指向目标设备的指针
描述
通知正确的 pnp 协议,以便其他设备可以使用资源
-
int pnp_is_active(struct pnp_dev *dev)¶
根据其当前资源确定设备是否处于活动状态
参数
struct pnp_dev *dev
指向目标 PnP 设备的指针
用户空间 IO 设备¶
参数
struct uio_info *info
UIO 设备功能
-
int __uio_register_device(struct module *owner, struct device *parent, struct uio_info *info)¶
注册一个新的用户空间 IO 设备
参数
struct module *owner
创建新设备的模块
struct device *parent
父设备
struct uio_info *info
UIO 设备功能
描述
成功时返回零,或返回一个负数的错误代码。
-
int __devm_uio_register_device(struct module *owner, struct device *parent, struct uio_info *info)¶
资源管理的
uio_register_device()
参数
struct module *owner
创建新设备的模块
struct device *parent
父设备
struct uio_info *info
UIO 设备功能
描述
成功时返回零,或返回一个负数的错误代码。
参数
struct uio_info *info
UIO 设备功能
-
struct uio_mem¶
UIO 内存区域的描述
定义:
struct uio_mem {
const char *name;
phys_addr_t addr;
dma_addr_t dma_addr;
unsigned long offs;
resource_size_t size;
int memtype;
void __iomem *internal_addr;
struct device *dma_device;
struct uio_map *map;
};
成员
name
用于标识的内存区域名称
addr
设备内存的地址,四舍五入到页面大小(使用 phys_addr,因为 addr 可以是逻辑地址、虚拟地址或物理地址,并且 phys_addr_t 应始终足够大以处理任何地址类型)
dma_addr
由 dma_alloc_coherent 设置的 DMA 句柄,仅与 UIO_MEM_DMA_COHERENT 一起使用(**addr** 应该是来自相同 dma_alloc_coherent 调用的 void * 返回值)
offs
页面内设备内存的偏移量
size
IO 的大小(页面大小的倍数)
memtype
addr 指向的内存类型
internal_addr
addr 的 ioremap 版本,供驱动程序内部使用
dma_device
传递给 dma_alloc_coherent 的设备结构,仅与 UIO_MEM_DMA_COHERENT 一起使用
map
仅供 UIO 核心使用。
-
struct uio_port¶
UIO 端口区域的描述
定义:
struct uio_port {
const char *name;
unsigned long start;
unsigned long size;
int porttype;
struct uio_portio *portio;
};
成员
name
用于标识的端口区域名称
start
端口区域的起始位置
size
端口区域的大小
porttype
端口类型(请参阅下面的 UIO_PORT_*)
portio
仅供 UIO 核心使用。
-
struct uio_info¶
UIO 设备功能
定义:
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);
};
成员
uio_dev
此 info 所属的 UIO 设备
name
设备名称
version
设备驱动程序版本
mem
可映射内存区域的列表,列表末尾的 size==0
port
端口区域的列表,列表末尾的 size==0
irq
中断号或 UIO_IRQ_CUSTOM
irq_flags
request_irq()
的标志priv
可选的私有数据
handler
设备的 irq 处理程序
mmap
此 uio 设备的 mmap 操作
open
此 uio 设备的 open 操作
release
此 uio 设备的 release 操作
irqcontrol
当 0/1 被写入 /dev/uioX 时禁用/启用 irq
-
uio_register_device¶
uio_register_device (parent, info)
注册一个新的用户空间 IO 设备
参数
parent
父设备
info
UIO 设备功能
描述
成功时返回零,或返回一个负数的错误代码。
-
devm_uio_register_device¶
devm_uio_register_device (parent, info)
资源管理的
uio_register_device()
参数
parent
父设备
info
UIO 设备功能
描述
成功时返回零,或返回一个负数的错误代码。