首页 > 其他分享 >设备链接 【ChatGPT】

设备链接 【ChatGPT】

时间:2023-12-10 14:55:52浏览次数:31  
标签:DL 驱动程序 FLAG device ChatGPT 链接 设备

默认情况下,驱动核心仅强制执行设备之间的依赖关系,这些依赖关系源自设备层次结构中的父/子关系:在挂起、恢复或关闭系统时,设备的顺序是基于这种关系的,即子设备总是在其父设备之前挂起,父设备总是在其子设备之前恢复。

有时需要表示超出纯粹的父/子关系的设备依赖关系,例如兄弟之间的关系,并且让驱动核心自动处理这些关系。

其次,默认情况下,驱动核心不强制执行任何驱动程序存在的依赖关系,即一个设备必须在另一个设备探测或正常运行之前绑定到驱动程序。

通常这两种依赖类型会一起出现,因此一个设备在驱动程序存在和挂起/恢复以及关闭顺序方面都依赖于另一个设备。

设备链接允许在驱动核心中表示这种依赖关系。

在其标准或受控形式中,设备链接结合了这两种依赖类型:它保证了"供应商"设备和其"消费者"设备之间的正确挂起/恢复和关闭顺序,并且保证了供应商的驱动程序存在。在供应商绑定到驱动程序之前,不会探测消费者设备,并且在供应商解绑之前,消费者设备会被解绑。

当供应商的驱动程序存在对消费者的挂起/恢复和关闭顺序没有影响时,设备链接可能只需使用DL_FLAG_STATELESS标志简单设置即可。换句话说,对供应商的驱动程序存在的强制是可选的。

另一个可选功能是运行时PM集成:通过在添加设备链接时设置DL_FLAG_PM_RUNTIME标志,PM核心被指示在消费者运行时恢复时保持供应商设备处于活动状态,直到消费者运行时恢复为止。

用法

设备链接可以在对供应商调用device_add()和对消费者调用device_initialize()之后的最早时间点添加。

稍后添加它们是合法的,但必须注意系统保持一致的状态:例如,不能在挂起/恢复转换过程中添加设备链接,因此需要使用lock_system_sleep()来阻止这样的转换的开始,或者需要从已保证不会与挂起/恢复转换并行运行的函数中添加设备链接,例如从设备->probe回调或引导时的PCI quirk。

另一个不一致状态的例子是,一个设备链接代表了一个驱动程序存在的依赖关系,但是在消费者的->probe回调中添加了该链接,而供应商尚未开始探测:如果驱动核心早些时候已知道设备链接,它就不会首先探测消费者。因此,责任在于消费者在添加链接后检查供应商的存在,并在不存在时推迟探测。[请注意,在供应商仍在探测时从消费者的->probe回调创建链接是有效的,但是消费者必须知道在创建链接时供应商已经可用(例如,如果消费者刚刚获取了一些资源,如果供应商在那时不可用,这些资源将不可用)。]

如果在供应商或消费者驱动程序的->probe回调中添加了具有DL_FLAG_STATELESS设置(即无状态设备链接)的设备链接,通常会在其->remove回调中删除它以保持对称。这样,如果驱动程序被编译为模块,设备链接将在模块加载时添加,并在卸载时有序地删除。适用于设备核心管理的设备链接将由其自动删除。

在设备链接添加时可以指定多个标志,其中已经提到了两个:DL_FLAG_STATELESS用于表示不需要驱动程序存在的依赖关系(但仅需要正确的挂起/恢复和关闭顺序),DL_FLAG_PM_RUNTIME用于表示需要运行时PM集成。

另外两个标志专门针对设备链接从消费者的->probe回调中添加的用例:DL_FLAG_RPM_ACTIVE可以指定在消费者运行时恢复时运行时恢复供应商并防止在消费者运行时挂起之前挂起供应商。DL_FLAG_AUTOREMOVE_CONSUMER导致在消费者无法探测或稍后解绑时自动清除设备链接。

类似地,当设备链接从供应商的->probe回调中添加时,DL_FLAG_AUTOREMOVE_SUPPLIER导致在供应商无法探测或稍后解绑时自动清除设备链接。

如果既未设置DL_FLAG_AUTOREMOVE_CONSUMER也未设置DL_FLAG_AUTOREMOVE_SUPPLIER,则可以使用DL_FLAG_AUTOPROBE_CONSUMER请求驱动核心在链接后自动为消费者驱动程序探测驱动程序。

但是,请注意,DL_FLAG_AUTOREMOVE_CONSUMER、DL_FLAG_AUTOREMOVE_SUPPLIER或DL_FLAG_AUTOPROBE_CONSUMER与DL_FLAG_STATELESS的任何组合都是无效的,不能使用。

限制

驱动程序作者应该意识到,对于受控设备链接的驱动程序存在依赖(即在链接添加时未指定DL_FLAG_STATELESS)可能导致消费者的探测被无限期地推迟。如果要求在达到某个initcall级别之前必须探测消费者,这可能会成为一个问题。更糟糕的是,如果供应商驱动程序被列入黑名单或缺失,消费者将永远不会被探测。

此外,受控设备链接不能直接删除。它们将根据DL_FLAG_AUTOREMOVE_CONSUMER和DL_FLAG_AUTOREMOVE_SUPPLIER标志在不再需要时由驱动核心自动删除。然而,无状态设备链接(即具有DL_FLAG_STATELESS设置的设备链接)预计将由调用device_link_add()添加它们的调用者通过device_link_del()或device_link_remove()来删除。

在调用device_link_add()时传递DL_FLAG_RPM_ACTIVE和DL_FLAG_STATELESS可能会导致在随后调用device_link_del()或device_link_remove()删除返回的设备链接时,供应商设备的PM运行时使用计数保持非零。如果在这些调用之间连续两次为相同的消费者-供应商对调用device_link_add(),则允许供应商的PM运行时使用计数在尝试删除链接时下降,这可能会导致在消费者仍处于PM运行时活动状态时挂起供应商,这必须避免。[为了解决这个限制,只需让消费者至少运行时挂起一次,或者在具有PM运行时禁用的情况下为其调用pm_runtime_set_suspended(),在device_link_add()和device_link_del()或device_link_remove()之间。]

有时驱动程序依赖于可选资源。当这些资源不存在时,它们可以以降级模式(功能集或性能降低)运行。一个例子是SPI控制器可以使用DMA引擎或以PIO模式工作。控制器可以在探测时确定可选资源的存在,但是在不存在时无法知道它们将在不久的将来(由于供应商驱动程序的探测)可用还是永远不可用。因此无法确定是否推迟探测。在探测后,通知驱动程序可选资源何时可用是可能的,但对于驱动程序来说,基于运行时的操作模式切换到这些资源的可用性的机制比基于探测推迟的机制要复杂得多。无论如何,可选资源都超出了设备链接的范围。

示例

  • 一个MMU设备与一个总线主设备并存,两者在同一个电源域中。MMU实现了总线主设备的DMA地址转换,并且在总线主设备活动时应该运行时恢复并保持活动。在MMU设备(供应商)和总线主设备(消费者)之间添加具有运行时PM集成的设备链接,可以实现这一效果。在运行时PM方面的效果与MMU是主设备的效果相同。

  • 事实上,这两个设备共享同一个电源域,通常会建议使用struct dev_pm_domain或struct generic_pm_domain,但是这些不是独立的设备,它们碰巧共享一个电源开关,而是MMU设备为总线主设备提供服务,没有总线主设备,MMU设备就没有用处。设备链接在这些设备之间创建了一个合成的层次关系,因此更合适。

  • 一个雷电主机控制器包括多个PCIe热插拔端口和一个NHI设备来管理PCIe开关。从系统休眠恢复时,NHI设备需要在热插拔端口恢复之前重新建立PCI隧道到连接的设备。如果热插拔端口是NHI的子设备,这种恢复顺序将自动由PM核心强制执行,但不幸的是它们是姑母。解决方案是从热插拔端口(消费者)到NHI设备(供应商)添加设备链接。对于这种用例,不需要驱动程序存在的依赖关系。

  • 混合图形笔记本中的离散GPU通常具有用于HDMI/DP音频的HDA控制器。在设备层次结构中,HDA控制器是VGA设备的兄弟,但两者共享同一个电源域,只有在VGA设备连接了HDMI/DP显示器时才需要HDA控制器。从HDA控制器(消费者)到VGA设备(供应商)的设备链接恰当地表示了这种关系。

  • ACPI允许通过_DEP对象定义设备的启动顺序。一个经典的例子是,当一个设备上的ACPI电源管理方法是基于I2C访问实现的,并且需要特定的I2C控制器存在和正常工作,才能使该设备的电源管理工作。

  • 在一些SoC中,显示、视频编解码器和视频处理IP核对透明存储器访问IP核存在功能依赖关系,后者处理突发访问和压缩/解压缩。

替代方案

  • 可以使用struct dev_pm_domain来覆盖总线、类别或设备类型的回调。它适用于共享单个开关的设备,但它不保证特定的挂起/恢复顺序,这需要单独实现。它本身也不能跟踪所涉及设备的运行时PM状态,并且只有当它们都运行时挂起时才关闭电源开关。此外,它不能用于强制特定的关闭顺序或驱动程序存在的依赖关系。

  • struct generic_pm_domain比设备链接更加复杂,并且不允许关闭顺序或驱动程序存在的依赖关系。它也不能在ACPI系统上使用。

实施

一旦添加了设备链接,设备层次结构(正如其名称所示)将成为一个有向无环图。

在挂起/恢复期间,这些设备的顺序由dpm_list确定。在关闭期间,它由devices_kset确定。如果没有设备链接存在,这两个列表将是设备树的扁平化、一维表示,使得设备被放置在其所有祖先之后。这是通过自上而下遍历ACPI命名空间或OpenFirmware设备树,并在发现它们时将设备附加到列表中来实现的。

一旦添加了设备链接,列表需要满足额外的约束,即设备被递归地放置在其所有供应商之后。为了确保这一点,在添加设备链接时,消费者和整个子图(消费者的所有子设备和消费者)都会被移动到列表的末尾。(从device_link_add()调用device_reorder_to_tail()。)

为了防止将依赖关系循环引入图中,设备链接添加时会验证供应商不依赖于消费者或消费者的任何子设备或消费者。(从device_link_add()调用device_is_dependent()。)如果违反了该约束,device_link_add()将返回NULL,并记录一个警告。

值得注意的是,这也防止了从父设备到子设备的设备链接的添加。但是相反是允许的,即从子设备到父设备的设备链接。由于驱动核心已经保证了父子之间的正确挂起/恢复和关闭顺序,因此只有在需要驱动程序存在的依赖关系时,这样的设备链接才有意义。在这种情况下,驱动程序作者应该仔细权衡设备链接是否是合适的工具。一个更合适的方法可能是简单地使用延迟探测或添加一个设备标志,导致父驱动在子驱动之前被探测。

状态机

https://www.kernel.org/doc/html/v6.6/driver-api/device_link.html#c.device_link_state

API

https://www.kernel.org/doc/html/v6.6/driver-api/device_link.html#api

标签:DL,驱动程序,FLAG,device,ChatGPT,链接,设备
From: https://www.cnblogs.com/pengdonglin137/p/17892652.html

相关文章

  • DMA-BUF缓冲区共享和同步【ChatGPT】
    https://www.kernel.org/doc/html/v6.6/driver-api/dma-buf.html#DMA-BUF缓冲区共享和同步DMA-BUF子系统提供了一个框架,用于在多个设备驱动程序和子系统之间共享硬件(DMA)访问的缓冲区,并用于同步异步硬件访问。例如,drm的“prime”多GPU支持就使用了这个框架,但当然不仅限于GPU的......
  • ioctl基于接口 【ChatGPT】
    https://www.kernel.org/doc/html/v6.6/driver-api/ioctl.htmlioctl基于接口ioctl()是应用程序与设备驱动程序进行接口交互的最常见方式。它灵活且易于通过添加新命令进行扩展,并且可以通过字符设备、块设备以及套接字和其他特殊文件描述符进行传递。然而,很容易错误地定义ioct......
  • 将驱动程序移植到新的驱动模型 【ChatGPT】
    https://www.kernel.org/doc/html/v6.6/driver-api/driver-model/porting.html将驱动程序移植到新的驱动模型PatrickMochel2003年1月7日概述请参阅Documentation/driver-api/driver-model/*.rst以获取各种驱动程序类型和概念的定义。将设备驱动程序移植到新模型的大部分......
  • 平台设备和驱动程序 【ChatGPT】
    https://www.kernel.org/doc/html/v6.6/driver-api/driver-model/platform.html平台设备和驱动程序请参阅<linux/platform_device.h>以获取与平台总线的驱动程序模型接口相关的信息:platform_device和platform_driver。这个伪总线用于连接具有最小基础设施的总线上的设备,例如用......
  • 设备驱动程序 【ChatGPT】
    https://www.kernel.org/doc/html/v6.6/driver-api/driver-model/driver.html设备驱动程序请参阅结构体device_driver的kerneldoc。分配设备驱动程序是静态分配的结构。尽管系统中可能有多个驱动程序支持的设备,但structdevice_driver代表了整个驱动程序(而不是特定的设备实......
  • 总线类型 【ChatGPT】
    https://www.kernel.org/doc/html/v6.6/driver-api/driver-model/bus.html总线类型定义请参阅结构体bus_type的内核文档。intbus_register(structbus_type*bus);声明内核中的每个总线类型(如PCI、USB等)应该声明一个此类型的静态对象。它们必须初始化name字段,并可以选......
  • 设备驱动设计模式 【ChatGPT】
    https://www.kernel.org/doc/html/v6.6/driver-api/driver-model/design-patterns.html设备驱动设计模式这份文档描述了设备驱动中常见的设计模式。子系统维护者可能会要求驱动开发者遵循这些设计模式。状态容器container_of()1.状态容器虽然内核中包含一些设备驱动,假......
  • 设备基本结构 【ChatGPT】
    https://www.kernel.org/doc/html/v6.6/driver-api/driver-model/device.html设备基本结构请参阅内核文档以了解structdevice的结构。编程接口发现设备的总线驱动程序使用以下方法将设备注册到核心:intdevice_register(structdevice*dev);总线应该初始化以下字段:p......
  • Devres - 管理设备资源 【ChatGPT】
    https://www.kernel.org/doc/html/v6.6/driver-api/driver-model/devres.htmlDevres-管理设备资源[email protected]首稿日期:2007年1月10日1.简介在尝试将libata转换为使用iomap时,出现了devres。每个iomapped地址应该在驱动程序分离时保留和取消映射。例如,一个普......
  • 驱动绑定 【ChatGPT】
    https://www.kernel.org/doc/html/v6.6/driver-api/driver-model/binding.html驱动绑定驱动绑定是将设备与能够控制它的设备驱动程序关联起来的过程。通常由总线驱动程序处理这一过程,因为总线特定的结构用于表示设备和驱动程序。使用通用设备和设备驱动程序结构后,大部分绑定可......