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中找到。

相关文章
|
16天前
|
Linux
genalloc/genpool 子系统 【ChatGPT】
genalloc/genpool 子系统 【ChatGPT】
34 11
|
16天前
|
开发框架 安全 .NET
TEE(可信执行环境)子系统 【ChatGPT】
TEE(可信执行环境)子系统 【ChatGPT】
|
16天前
|
Linux API 芯片
GPIO子系统驱动程序 【ChatGPT】
GPIO子系统驱动程序 【ChatGPT】
|
16天前
|
Linux API 虚拟化
PCI总线子系统 【ChatGPT】
PCI总线子系统 【ChatGPT】
|
16天前
|
Linux 测试技术 API
PINCTRL(PIN CONTROL)子系统 【ChatGPT】
PINCTRL(PIN CONTROL)子系统 【ChatGPT】
|
16天前
|
存储 缓存 Linux
通用互斥子系统 【ChatGPT】
通用互斥子系统 【ChatGPT】
|
1月前
|
人工智能 自然语言处理 搜索推荐
chatgpt这么火,现在AI搜索引擎有哪些呢?
国外AI搜索引擎包括ChatGPT,擅长自然语言处理与内容生成;Google Bard,提供智能个性化搜索体验;Microsoft Bing集成GPT模型增强智能检索;Perplexity AI以简洁答案及文献引用著称;Neeva强调隐私保护与无广告服务。国内方面,天工AI支持多种功能如知识问答与代码编程;腾讯元宝基于混元模型助力内容创造与学习;360AI搜索以精准全面的信息搜索见长;秘塔AI专注提升写作质量和效率;开搜AI搜索提供个性化智能搜索服务。以上引擎均利用先进AI技术提升用户体验。更多详情参阅[AI搜索合集](zhangfeidezhu.com/?page_id=651)。
76 8
chatgpt这么火,现在AI搜索引擎有哪些呢?
|
29天前
|
机器学习/深度学习 人工智能 自然语言处理
HuggingGPT解析:使用 ChatGPT及HuggingFace上的族系解决AI问题
HuggingGPT是一个框架,它使用大型语言模型(如ChatGPT)作为控制器来管理和协调Hugging Face上的AI模型,以语言作为通用接口解决多模态和领域的复杂AI任务。
27 0
HuggingGPT解析:使用 ChatGPT及HuggingFace上的族系解决AI问题
|
20天前
|
机器学习/深度学习 人工智能 算法
为什么ChatGPT等AI大模型都是基于Python开发?
为什么ChatGPT等AI大模型都是基于Python开发?
|
1月前
|
人工智能 自然语言处理 Linux
免费ChatGPT4o灵办AI可体验浏览器插件
灵办AI就是您所需的最佳助手!我们为您带来了一款多功能AI工具,ChatGPT4o不仅能为您提供精准翻译,还能满足您的对话需求、智能续写、AI搜索、文档阅读、代码生成与修正等多种需求。灵办 AI,真正让工作和学习变得轻松高效!一款多功能智能助手,旨在提升工作和学习效率。它提供实时翻译、对话问答、搜索、写作和网页阅读等服务,支持多种浏览器和操作系统,帮助用户随时获取信息,打破语言障碍,优化内容创作和信息处理。