设备驱动程序基础设施¶
基本设备驱动程序模型结构¶
-
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()
类似,但 SYSFS_PREALLOC
设置在 _mode 上。
-
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)
定义一个由整型支持的设备属性。
-
DEVICE_BOOL_ATTR¶
DEVICE_BOOL_ATTR (_name, _mode, _var)
定义一个由布尔型支持的设备属性。
-
DEVICE_STRING_ATTR_RO¶
DEVICE_STRING_ATTR_RO (_name, _mode, _var)
定义一个由只读字符串支持的设备属性。
参数
_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
DMA 内存范围相对于 RAM 的映射
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 操作实例管理。dma_skip_sync
相干缓冲区可以跳过 DMA 同步操作。
dma_iommu
设备正在使用默认的 IOMMU 实现进行 DMA,并且不依赖于 dma_ops 结构。
示例
- 对于定制板上的设备,正如嵌入式和基于 SoC 的硬件所常见的那样,Linux 通常使用 platform_data 指向描述设备及其接线方式的板特定结构。这可以包括可用的端口、芯片变体、哪些 GPIO 引脚充当哪些附加角色等等。这缩小了“板级支持包”(BSPs)并最大程度地减少了驱动程序中板特定的 #ifdef。
在基于SOC的硬件中,Linux通常使用platform_data指向板级特定结构,描述设备及其连接方式。这可以包括可用的端口、芯片变体、哪些GPIO引脚扮演什么额外角色等等。这缩小了“板级支持包”(BSPs)的范围,并最大限度地减少了驱动程序中板级特定的#ifdefs。
描述
在最低层,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 名称,如果不可用则为其初始名称。
参数
struct device *parent
const char *name
子设备的名称
描述
这类似于上面的 device_find_child()
函数,但它返回一个指向具有名称 name 的设备的引用。
注意
使用后您需要通过 put_device()
释放引用。
参数
struct device *parent
描述
这类似于上面的 device_find_child()
函数,但它返回一个指向子设备的引用(如果有的话)。
注意
使用后您需要通过 put_device()
释放引用。
-
device_lock_set_class¶
device_lock_set_class (dev, key)
在设备附加到驱动程序时指定临时锁类别
参数
dev
要修改的设备
key
锁类别键数据
描述
此函数必须在 device_lock() 已经被持有的情况下调用,例如在驱动程序的 ->probe() 中。请注意只覆盖默认的 lockdep_no_validate 类别。
-
device_lock_reset_class¶
device_lock_reset_class (dev)
将设备返回到默认的 lockdep 无验证状态
参数
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);
const struct cpumask *(*irq_get_affinity)(struct device *dev, unsigned int irq_vec);
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
在关机时调用以使设备静止。
irq_get_affinity
获取此总线上设备的 IRQ 亲和性掩码。
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
以 NUL 结尾的字符串,新的驱动程序名称以强制匹配,传入空字符串以清除它(
""
或"n"
,后者仅用于 sysfs 接口)。size_t len
s 的长度
描述
在设备中设置或清除驱动程序覆盖的辅助函数,适用于 driver_override 字段由驱动程序/总线代码分配的情况。
返回
成功时返回 0,失败时返回负错误代码。
-
int driver_for_each_device(struct device_driver *drv, struct device *start, void *data, device_iter_t fn)¶
绑定到驱动程序的设备的迭代器。
参数
struct device_driver *drv
我们正在迭代的驱动程序。
struct device *start
开始的设备
void *data
要传递给回调的数据。
device_iter_t fn
为每个设备调用的函数。
描述
迭代 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_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 中设置其中一个,表示在分别从其设备解绑消费者或供应商驱动程序后,此函数的给定调用者将不再使用该链接,因此可以在此时删除该链接。如果它们都没有设置,链接将一直保持,直到其指向的设备之一(无论是消费者还是供应商)被注销。
此外,如果 DL_FLAG_STATELESS
、DL_FLAG_AUTOREMOVE_CONSUMER
和 DL_FLAG_AUTOREMOVE_SUPPLIER
未在 flags 中设置(即正在添加一个持久的受管理设备链接),则可以使用 DL_FLAG_AUTOPROBE_CONSUMER
标志来请求驱动核心在成功将驱动程序绑定到供应商设备后自动探测消费者驱动程序。
同时在 flags 中设置 DL_FLAG_STATELESS
以及 DL_FLAG_AUTOREMOVE_CONSUMER
、DL_FLAG_AUTOREMOVE_SUPPLIER
或 DL_FLAG_AUTOPROBE_CONSUMER
的任意一个组合是无效的,并且会导致 upfront 返回 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
以获取名称
描述
如果设备绑定到驱动程序,将返回设备的驱动程序名称。如果设备未绑定到驱动程序,将返回其所连接的总线名称。如果它也未连接到总线,将返回一个空字符串。
-
int devm_device_add_group(struct device *dev, const struct attribute_group *grp)¶
给定一个设备,创建一个受管理的属性组
参数
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()
的第二部分,但如果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()
进行清理。否则,结构将保留直到对设备的最终引用被释放。
参数
struct device *parent
void *data
回调数据。
device_iter_t fn
为每个设备调用的函数。
描述
迭代parent
的子设备,并为每个子设备调用fn
,传入data
。
我们每次都检查fn
的返回值。如果它返回非0值,我们就会中断并返回该值。
-
int device_for_each_child_reverse(struct device *parent, void *data, device_iter_t fn)¶
按反向顺序迭代设备子项。
参数
struct device *parent
void *data
回调数据。
device_iter_t fn
为每个设备调用的函数。
描述
迭代parent
的子设备,并为每个子设备调用fn
,传入data
。
我们每次都检查fn
的返回值。如果它返回非0值,我们就会中断并返回该值。
-
int device_for_each_child_reverse_from(struct device *parent, struct device *from, void *data, device_iter_t fn)¶
按反向顺序迭代设备子项。
参数
struct device *parent
struct device *from
子列表中的可选起始点
void *data
回调数据。
device_iter_t fn
为每个设备调用的函数。
描述
迭代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, const void *data, device_match_t match)¶
用于定位特定设备的设备迭代器。
参数
struct device *parent
const void *data
要传递给匹配函数的数据
device_match_t match
检查设备的回调函数
描述
这类似于上面的device_for_each_child()
函数,但它返回一个对“找到”设备的引用,供以后使用,这由match
回调函数决定。
如果设备不匹配,回调应返回0;如果匹配,则返回非0值。如果回调返回非0值并且可以获取对当前设备的引用,则此函数将返回给调用者,不再迭代其他设备。
注意
使用后您需要通过 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
设备名称字符串
...
可变参数
描述
此函数可用于字符设备类。一个struct device
将在sysfs中创建,并注册到指定的类。
如果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
设备名称字符串
...
可变参数
描述
此函数可用于字符设备类。一个struct device
将在sysfs中创建,并注册到指定的类。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
情况有 primary --> secondary --> -ENODEV
primary --> NULL
secondary --> -ENODEV
NULL
参数
struct device *dev
要处理的设备。
struct fwnode_handle *fwnode
设备的新次级固件节点。
描述
如果设备的主固件节点存在,则将其次级指针设置为fwnode
。否则,将设备的固件节点指针设置为fwnode
。
参数
struct device *dev
其设备树节点正在被移除的设备
参数
struct device *dev
其设备树节点正在被添加的设备
struct device_node *of_node
要添加的
of_node
返回
成功返回0,失败返回错误代码。
参数
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
,列表迭代将从那里开始;否则,如果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, device_iter_t fn)¶
设备迭代器
参数
const struct class *class
我们正在迭代的类
const struct device *start
列表中开始的设备(如果有)。
void *data
回调数据
device_iter_t fn
为每个设备调用的函数
描述
迭代class
的设备列表,并为每个设备调用fn
,传入data
。如果设置了start
,列表迭代将从那里开始;否则,如果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
要注销的类
参数
struct class_compat *cls
兼容性类
struct device *dev
目标总线设备
参数
struct class_compat *cls
兼容性类
struct device *dev
目标总线设备
参数
const struct class *class
要检查的类
描述
返回一个布尔值,表示该类是否在驱动核心中注册。请注意,该值在调用此函数后可能立即改变,因此仅在您“知道”这样做安全的地方使用它(通常用于确定特定类是否已注册)。
使用时请谨慎。
-
struct faux_device¶
一个“仿冒”设备
描述
一个可以创建/销毁的简单仿冒设备。当驱动程序只需要一个设备来“挂载”某些东西时使用。这可用于下载固件或其他基本任务。如果设备完全没有分配资源,请使用它而不是struct platform_device
。
-
struct faux_device_ops¶
struct faux_device
的一组回调函数
定义:
struct faux_device_ops {
int (*probe)(struct faux_device *faux_dev);
void (*remove)(struct faux_device *faux_dev);
};
成员
probe
当驱动核心探测到仿冒设备,但在设备完全绑定到内部仿冒总线代码之前调用。如果探测成功,返回0;否则,返回一个负的错误码以阻止探测序列成功。
remove
当仿冒设备从系统中移除时调用
描述
probe
和remove
都是可选的,如果不需要,请设置为NULL。
-
struct faux_device *faux_device_create_with_groups(const char *name, struct device *parent, const struct faux_device_ops *faux_ops, const struct attribute_group **groups)¶
创建一个仿冒设备并将其注册到驱动核心,然后用一组初始的sysfs属性填充该设备。
参数
const char *name
我们要添加的设备名称,对于所有仿冒设备必须是唯一的。
struct device *parent
指向潜在父
struct device
的指针。如果设置为NULL,设备将在sysfs中的仿冒设备树的“根”下创建。const struct faux_device_ops *faux_ops
新设备将回调的
struct faux_device_ops
,可以为NULL。const struct attribute_group **groups
当此设备注册到驱动核心时,将为其创建的 sysfs 属性集。
描述
创建一个新的 faux 设备并正确注册到驱动核心。如果存在,faux_ops 中的回调函数将在适当的时机,根据设备的生命周期,使用该设备供调用者进行操作。
请注意,当调用此函数时,struct faux_ops 中指定的函数可能在函数返回之前被调用,因此请确保在此时间点之前所有内容都已正确初始化。如果探测回调(如果存在)未成功,则设备的创建将失败并返回 NULL。
返回
如果创建设备时发生错误,则为 NULL
指向已注册到 sysfs 的有效
struct faux_device
的指针
-
struct faux_device *faux_device_create(const char *name, struct device *parent, const struct faux_device_ops *faux_ops)¶
创建一个 faux 设备并注册到驱动核心
参数
const char *name
我们要添加的设备名称,对于所有仿冒设备必须是唯一的。
struct device *parent
指向潜在父
struct device
的指针。如果设置为NULL,设备将在sysfs中的仿冒设备树的“根”下创建。const struct faux_device_ops *faux_ops
新设备将回调的
struct faux_device_ops
,可以为NULL。
描述
创建一个新的 faux 设备并正确注册到驱动核心。如果存在,faux_ops 中的回调函数将在适当的时机,根据设备的生命周期,使用该设备供调用者进行操作。
请注意,当调用此函数时,struct faux_ops 中指定的函数可能在函数返回之前被调用,因此请确保在此时间点之前所有内容都已正确初始化。
返回
如果创建设备时发生错误,则为 NULL
指向已注册到 sysfs 的有效
struct faux_device
的指针
-
void faux_device_destroy(struct faux_device *faux_dev)¶
销毁一个 faux 设备
-
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
要从传输类中消除的设备。
描述
此调用会触发消除与传输类设备关联的存储。注意:它实际所做的只是放弃对 classdev 的引用。直到最后一个引用变为零,内存才会被释放。另请注意,classdev 保留了对 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)¶
使用中断亲和性描述符为设备获取一组 IRQ 的 devm 方法
参数
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 名称
描述
获取 IRQ,类似于 platform_get_irq()
,但按名称而不是索引。
返回
成功返回非零 IRQ 号,失败返回负错误号。
-
int platform_get_irq_byname_optional(struct platform_device *dev, const char *name)¶
按名称获取设备的可选 IRQ
参数
struct platform_device *dev
平台设备
const char *name
IRQ 名称
描述
按名称获取可选 IRQ,类似于 platform_get_irq_byname()
。不同之处在于,如果无法获取 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, device_iter_t fn)¶
设备迭代器。
参数
const struct bus_type *bus
总线类型。
struct device *start
开始迭代的设备。
void *data
回调数据。
device_iter_t fn
为每个设备调用的函数。
描述
遍历 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/
不要将此接口用于任何新事物,它仅为兼容不良设计而存在。新子系统应使用普通子系统;并且子系统范围的属性应添加到子系统目录本身,而不是放置在 /sys/devices/system/
-
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/
-
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 属性
描述
为 dev 设备,通过 sg 参数中具有 nents 段的 scatterlist 描述的缓冲区,映射 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 属性
描述
为 dev 设备,将存储在给定 sg_table 对象中的 scatterlist 描述的缓冲区映射到 dir DMA 操作。成功后,缓冲区的所有权将转移到 DMA 域。在 CPU 访问缓冲区之前,必须调用 dma_sync_sgtable_for_cpu() 或 dma_unmap_sgtable() 将缓冲区的所有权移回 CPU 域。
成功返回 0,错误返回负错误码。支持以下错误码及其含义:
- -EINVAL
无效参数、未对齐访问或使用中的其他错误。重试也不会成功。
- -ENOMEM
资源不足(例如内存或 IOVA 空间)无法完成映射。如果稍后重试,应该会成功。
- -EIO
含义不明的遗留错误码。例如,如果底层调用返回 DMA_MAPPING_ERROR,则返回此错误码。
- -EREMOTEIO
DMA 设备无法访问 sg_table 中指定的 P2PDMA 内存。重试也不会成功。
参数
struct device *dev
要检查的设备
描述
如果此函数返回 false
,驱动程序可以在完成 I/O 后跳过调用 dma_unmap_*。此函数必须在所有可能需要解除映射的映射操作完成后调用。
参数
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 等
-
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
ioremap 后的 addr 版本,供驱动程序内部使用
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
此信息所属的 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 设备的打开操作
release
此 uio 设备的释放操作
irqcontrol
当 0/1 写入 /dev/uioX 时禁用/启用中断
-
uio_register_device¶
uio_register_device (parent, info)
注册新的用户空间 IO 设备
参数
parent
父设备
信息
UIO 设备功能
描述
成功返回零,否则返回负错误码。
-
devm_uio_register_device¶
devm_uio_register_device (parent, info)
资源托管的
uio_register_device()
参数
parent
父设备
信息
UIO 设备功能
描述
成功返回零,否则返回负错误码。