接前一篇文章:Linux网络驱动之Fixed-Link(17)
本文内容参考:
linux phy处理流程一:探测phy设备_phy link过程-CSDN博客
linux phy处理流程三:fixed-link处理-CSDN博客
ARM与交换芯片mac_to_mac固定模式总结_mac to mac-CSDN博客
rk3399 mac to mac 连接switch - tccxy - 博客园
特此致谢!
三、深入了解
前边用了几个回目的篇幅讲解了of_mdiobus_register和mdiobus_register函数的区别。本回要回归到当初引出这段讲解的地方,参见Linux网络驱动之Fixed-Link(13)-CSDN博客:


之前先围绕着第3个函数调用:
cpp
ret = mdiobus_register(fmb->mii_bus);
进行了深入解析。现在要拉回来,讲解第1个函数调用:
cpp
pdev = platform_device_register_simple("Fixed MDIO bus", 0, NULL, 0);
if (IS_ERR(pdev))
return PTR_ERR(pdev);
platform_device_register_simple函数是一个内联函数,在kernel/linux-5.10-origin/include/linux/platform_device.h中,代码如下:
cpp
/**
* platform_device_register_simple - add a platform-level device and its resources
* @name: base name of the device we're adding
* @id: instance id
* @res: set of resources that needs to be allocated for the device
* @num: number of resources
*
* This function creates a simple platform device that requires minimal
* resource and memory management. Canned release function freeing memory
* allocated for the device allows drivers using such devices to be
* unloaded without waiting for the last reference to the device to be
* dropped.
*
* This interface is primarily intended for use with legacy drivers which
* probe hardware directly. Because such drivers create sysfs device nodes
* themselves, rather than letting system infrastructure handle such device
* enumeration tasks, they don't fully conform to the Linux driver model.
* In particular, when such drivers are built as modules, they can't be
* "hotplugged".
*
* Returns &struct platform_device pointer on success, or ERR_PTR() on error.
*/
static inline struct platform_device *platform_device_register_simple(
const char *name, int id,
const struct resource *res, unsigned int num)
{
return platform_device_register_resndata(NULL, name, id,
res, num, NULL, 0);
}
platform_device_register_simple函数说明如下:
函数原型
static inline struct platform_device *platform_device_register_simple(
const char *name, int id,
const struct resource *res, unsigned int num);
函数功能
添加平台级设备及其资源。
此函数创建了一个需要最少资源和内存管理的简单平台设备。释放为设备所分配内存的封装函数,允许使用此类设备的驱动程序被卸载,而无需等待删除对设备的最后一次引用。
此接口主要用于直接探测硬件的传统驱动程序。因为这样的驱动程序自己创建sysfs设备结点,而不是让系统基础设施处理这样的设备枚举任务,因此它们并不完全符合Linux驱动程序模型。特别地,当这些驱动程序被构建(编译)为模块时,它们不能被"热插拔"。
参数说明
- name:要添加的设备的基本名称
- id:实例id
- res:需要为设备分配的资源集
- num:资源的数量
返回值
成功返回指向struct platform_device的指针;失败返回ERR_PTR。
对照着上边实际调用进行理解:
cpp
pdev = platform_device_register_simple("Fixed MDIO bus", 0, NULL, 0);
if (IS_ERR(pdev))
return PTR_ERR(pdev);
要添加的平台级设备名称为"Fixed MDIO bus";实例id为0;不需要分配资源(集);资源的数量为0。
真正完成工作的是platform_device_register_resndata函数。它也在include/linux/platform_device.h中(就在上边),代码如下:
cpp
/**
* platform_device_register_resndata - add a platform-level device with
* resources and platform-specific data
*
* @parent: parent device for the device we're adding
* @name: base name of the device we're adding
* @id: instance id
* @res: set of resources that needs to be allocated for the device
* @num: number of resources
* @data: platform specific data for this platform device
* @size: size of platform specific data
*
* Returns &struct platform_device pointer on success, or ERR_PTR() on error.
*/
static inline 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 platform_device_info pdevinfo = {
.parent = parent,
.name = name,
.id = id,
.res = res,
.num_res = num,
.data = data,
.size_data = size,
.dma_mask = 0,
};
return platform_device_register_full(&pdevinfo);
}
对于该函数的解析,请看下回。