PHY 子系统 【ChatGPT】

简介: PHY 子系统 【ChatGPT】

PHY子系统

作者

本文档解释了通用PHY框架以及提供的API,以及如何使用。

简介

PHY是物理层的缩写。它用于将设备连接到物理介质,例如,USB控制器具有PHY来提供序列化、反序列化、编码、解码等功能,并负责获取所需的数据传输速率。需要注意的是,一些USB控制器内嵌了PHY功能,而其他一些使用外部PHY。其他使用PHY的外围设备包括无线局域网、以太网、SATA等。

创建此框架的目的是将分散在Linux内核中的PHY驱动程序整合到drivers/phy中,以增加代码重用性和提高代码可维护性。

此框架仅适用于使用外部PHY的设备(PHY功能未嵌入在控制器内部)。

注册/注销PHY提供者

PHY提供者是指实现一个或多个PHY实例的实体。对于简单情况,其中PHY提供者仅实现PHY的单个实例,框架提供了of_xlate的自己实现of_phy_simple_xlate。如果PHY提供者实现了多个实例,则应提供自己的of_xlate实现。of_xlate仅用于设备树引导情况。

#define of_phy_provider_register(dev, xlate)    \
        __of_phy_provider_register((dev), NULL, THIS_MODULE, (xlate))
#define devm_of_phy_provider_register(dev, xlate)       \
        __devm_of_phy_provider_register((dev), NULL, THIS_MODULE,
                                        (xlate))

of_phy_provider_registerdevm_of_phy_provider_register宏可用于注册phy_provider,它们接受设备和of_xlate作为参数。对于设备树引导情况,所有PHY提供者都应使用上述2个宏之一来注册PHY提供者。

与PHY提供者相关的设备树节点通常包含一组子节点,每个子节点代表一个单独的PHY。一些绑定可能在额外的级别中嵌套子节点以提供上下文和可扩展性,在这种情况下,可以使用低级别的of_phy_provider_register_full()devm_of_phy_provider_register_full()宏来覆盖包含子节点的节点。

#define of_phy_provider_register_full(dev, children, xlate) \
        __of_phy_provider_register(dev, children, THIS_MODULE, xlate)
#define devm_of_phy_provider_register_full(dev, children, xlate) \
        __devm_of_phy_provider_register_full(dev, children,
                                             THIS_MODULE, xlate)

devm_of_phy_provider_unregisterof_phy_provider_unregister可用于注销PHY。

创建PHY

PHY驱动程序应创建PHY,以便其他外围控制器可以使用它。PHY框架提供了2个API来创建PHY。

struct phy *phy_create(struct device *dev, struct device_node *node,
const struct phy_ops *ops);
struct phy *devm_phy_create(struct device *dev,
struct device_node *node,
const struct phy_ops *ops);

PHY驱动程序可以使用上述2个API之一来创建PHY,通过传递设备指针和PHY操作。phy_ops是一组用于执行PHY操作的函数指针,例如初始化、退出、上电和下电。

为了解引用私有数据(在phy_ops中),PHY提供者驱动程序可以在创建PHY后使用phy_set_drvdata(),并在phy_ops中使用phy_get_drvdata()来获取私有数据。

获取PHY的引用

在控制器可以使用PHY之前,它必须获取对其的引用。该框架提供以下API来获取对PHY的引用。

struct phy *phy_get(struct device *dev, const char *string);
struct phy *devm_phy_get(struct device *dev, const char *string);
struct phy *devm_phy_optional_get(struct device *dev,
const char *string);
struct phy *devm_of_phy_get(struct device *dev, struct device_node *np,
const char *con_id);
struct phy *devm_of_phy_optional_get(struct device *dev,
struct device_node *np,
const char *con_id);
struct phy *devm_of_phy_get_by_index(struct device *dev,
struct device_node *np,
int index);

phy_getdevm_phy_getdevm_phy_optional_get可用于获取PHY。在设备树引导的情况下,字符串参数应包含设备树数据中给定的PHY名称,在非设备树引导的情况下,应包含PHY的标签。两个devm_phy_get使用devres将设备与PHY关联,成功获取PHY时会调用驱动程序分离时的释放函数,并释放devres数据。在PHY不可用时,_optional_get变体应该被使用,这些函数在PHY无法找到时不会返回-ENODEV,而是返回NULL。一些通用驱动程序,例如ehci,可能使用多个PHY。在这种情况下,可以使用devm_of_phy_getdevm_of_phy_get_by_index根据名称或索引获取PHY引用。

应该注意到,NULL是一个有效的PHY引用。对NULL PHY的所有PHY消费者调用都将成为NOP。也就是说,对NULL PHY的释放调用、phy_init()phy_exit()调用,以及phy_power_on()phy_power_off()调用在应用于NULL PHY时都是NOP。在处理可选PHY设备的设备中,NULL PHY是有用的。

API调用顺序

通常的调用顺序应该是:

[devm_][of_]phy_get()

phy_init()

phy_power_on()

[phy_set_mode_ext]

...

phy_power_off()

phy_exit()

[[of_]phy_put()]

一些PHY驱动程序可能不实现phy_init()phy_power_on(),但控制器应始终调用这些函数以与其他PHY兼容。一些PHY可能需要phy_set_mode,而其他可能使用默认模式(通常通过设备树或其他固件配置)。为了兼容性,如果知道将要使用的模式,应始终调用此函数。通常情况下,应在phy_power_on()之后调用此函数,尽管一些PHY驱动程序可能允许在任何时候调用它。

释放对PHY的引用

当控制器不再需要PHY时,必须释放在上述部分提到的API中获取的对PHY的引用。PHY框架提供了2个API来释放对PHY的引用。

void phy_put(struct phy *phy);
void devm_phy_put(struct device *dev, struct phy *phy);

这两个API用于释放对PHY的引用,devm_phy_put销毁与此PHY关联的devres。

销毁PHY

当创建PHY的驱动程序被卸载时,应使用以下2个API之一销毁所创建的PHY:

void phy_destroy(struct phy *phy);
void devm_phy_destroy(struct device *dev, struct phy *phy);

这两个API销毁PHY,devm_phy_destroy销毁与此PHY关联的devres。

PM Runtime

此子系统已启用pm runtime。因此,在创建PHY时,将调用此子系统创建的phy设备的pm_runtime_enable,而在销毁PHY时,将调用pm_runtime_disable。需要注意的是,此子系统创建的phy设备将是调用phy_create(PHY提供者设备)的设备的子设备。

因此,此子系统创建的phy设备的pm_runtime_get_sync将调用PHY提供者设备的pm_runtime_get_sync,因为它们之间存在父子关系。还应该注意的是,phy_power_onphy_power_off执行phy_pm_runtime_get_syncphy_pm_runtime_put。有一些导出的API,例如phy_pm_runtime_getphy_pm_runtime_get_syncphy_pm_runtime_putphy_pm_runtime_put_syncphy_pm_runtime_allowphy_pm_runtime_forbid,用于执行PM操作。

PHY映射

为了在没有设备树的帮助下获取对PHY的引用,该框架提供了查找功能,可以将其与允许将clk结构绑定到设备的clkdev进行比较。在运行时,可以进行查找,当已存在对结构体PHY的句柄时。

该框架提供了以下API来注册和注销查找:

int phy_create_lookup(struct phy *phy, const char *con_id,
const char *dev_id);
void phy_remove_lookup(struct phy *phy, const char *con_id,
const char *dev_id);

设备树绑定

PHY设备树绑定的文档可以在Documentation/devicetree/bindings/phy/phy-bindings.txt中找到。

相关文章
genalloc/genpool 子系统 【ChatGPT】
genalloc/genpool 子系统 【ChatGPT】
162 11
|
开发框架 安全 .NET
TEE(可信执行环境)子系统 【ChatGPT】
TEE(可信执行环境)子系统 【ChatGPT】
|
Linux API 芯片
GPIO子系统驱动程序 【ChatGPT】
GPIO子系统驱动程序 【ChatGPT】
|
Linux API 虚拟化
PCI总线子系统 【ChatGPT】
PCI总线子系统 【ChatGPT】
|
Linux 测试技术 API
PINCTRL(PIN CONTROL)子系统 【ChatGPT】
PINCTRL(PIN CONTROL)子系统 【ChatGPT】
|
存储 缓存 Linux
通用互斥子系统 【ChatGPT】
通用互斥子系统 【ChatGPT】
|
2月前
|
机器学习/深度学习 数据采集 人工智能
从ChatGPT到文心一言:AI为什么能“懂人话”?——大语言模型的底层逻辑揭秘
从ChatGPT到文心一言:AI为什么能“懂人话”?——大语言模型的底层逻辑揭秘
275 9
|
5月前
|
传感器 存储 人工智能
ChatGPT让AI展现‘智能’魅力,函数调用和RAG如何助力迈向AI Agent?
本文由AI产品专家三桥君探讨了AI从被动响应到主动决策的演进路径,重点分析了函数调用和RAG技术在构建AI Agent中的关键作用。文章梳理了大模型能力的迭代(原生能力与涌现能力),技术演进的三个阶段(提示工程→函数调用→RAG),并提出AI Agent需具备环境感知、推理决策和行动执行的核心要素。AI产品专家三桥君认为,未来AGI需突破跨领域学习、实时更新和安全性挑战,最终实现如"贾维斯"般的智能伙伴。
196 1
ChatGPT让AI展现‘智能’魅力,函数调用和RAG如何助力迈向AI Agent?
|
5月前
|
机器学习/深度学习 人工智能 文字识别
浏览器AI模型插件下载,支持chatgpt、claude、grok、gemini、DeepSeek等顶尖AI模型!
极客侧边栏是一款浏览器插件,集成ChatGPT、Claude、Grok、Gemini等全球顶尖AI模型,支持网页提问、文档分析、图片生成、智能截图、内容总结等功能。无需切换页面,办公写作效率倍增。内置书签云同步与智能整理功能,管理更高效。跨平台使用,安全便捷,是AI时代必备工具!
376 8
|
10月前
|
人工智能 Linux API
Omnitool:开发者桌面革命!开源神器一键整合ChatGPT+Stable Diffusion等主流AI平台,本地运行不联网
Omnitool 是一款开源的 AI 桌面环境,支持本地运行,提供统一交互界面,快速接入 OpenAI、Stable Diffusion、Hugging Face 等主流 AI 平台,具备高度扩展性。
1009 94
Omnitool:开发者桌面革命!开源神器一键整合ChatGPT+Stable Diffusion等主流AI平台,本地运行不联网

热门文章

最新文章