Linux网络驱动之Fixed-Link(19)

发布时间:2026/7/2 13:16:48

Linux网络驱动之Fixed-Link(19) 接前一篇文章Linux网络驱动之Fixed-Link18本文内容参考linux phy fixed-link-CSDN博客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 - 博客园特此致谢三、深入了解上一回开始解析fixed_mdio_bus_init函数中的第1步 —— platform_device_register_simple函数。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中代码如下/** * platform_device_register_simple - add a platform-level device and its resources * name: base name of the device were 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 dont fully conform to the Linux driver model. * In particular, when such drivers are built as modules, they cant 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_resndata函数。其也在include/linux/platform_device.h中代码如下/** * platform_device_register_resndata - add a platform-level device with * resources and platform-specific data * * parent: parent device for the device were adding * name: base name of the device were 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); }platform_device_register_resndata函数说明如下函数原型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);函数功能添加一个包含资源和平台特定数据的平台级设备。参数说明parent要添加设备的父设备name要添加设备的总线名称id实例idres需要分配给设备的资源集num资源的数量data此平台设备的平台特定数据size平台特定数据的大小返回值成功返回指向struct platform_device的指针失败返回ERR_PTR。代入实际值​ platform_device_register_simple(Fixed MDIO bus, 0, NULL, 0);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); }得到struct platform_device_info pdevinfo { .parent NULL, .name Fixed MDIO bus, .id 0, .res NULL, .num_res 0, .data NULL, .size_data 0, .dma_mask 0, };之后platform_device_register_resndata函数就将工作交给了platform_device_register_full函数颇有点“大懒支小懒”的意思。platform_device_register_full函数在drivers/base/platform.c中代码如下/** * platform_device_register_full - add a platform-level device with * resources and platform-specific data * * pdevinfo: data used to create device * * Returns struct platform_device pointer on success, or ERR_PTR() on error. */ struct platform_device *platform_device_register_full( const struct platform_device_info *pdevinfo) { int ret; struct platform_device *pdev; pdev platform_device_alloc(pdevinfo-name, pdevinfo-id); if (!pdev) return ERR_PTR(-ENOMEM); pdev-dev.parent pdevinfo-parent; pdev-dev.fwnode pdevinfo-fwnode; pdev-dev.of_node of_node_get(to_of_node(pdev-dev.fwnode)); pdev-dev.of_node_reused pdevinfo-of_node_reused; if (pdevinfo-dma_mask) { pdev-platform_dma_mask pdevinfo-dma_mask; pdev-dev.dma_mask pdev-platform_dma_mask; pdev-dev.coherent_dma_mask pdevinfo-dma_mask; } ret platform_device_add_resources(pdev, pdevinfo-res, pdevinfo-num_res); if (ret) goto err; ret platform_device_add_data(pdev, pdevinfo-data, pdevinfo-size_data); if (ret) goto err; if (pdevinfo-properties) { ret platform_device_add_properties(pdev, pdevinfo-properties); if (ret) goto err; } ret platform_device_add(pdev); if (ret) { err: ACPI_COMPANION_SET(pdev-dev, NULL); platform_device_put(pdev); return ERR_PTR(ret); } return pdev; } EXPORT_SYMBOL_GPL(platform_device_register_full);对于此函数的解析请看下回。

相关新闻