Linux of_platform_depopulate()无法卸载子驱动问题咨询
问题
我有一个MFD驱动,使用of_platform_default_populate()从设备树填充子节点。选择该函数而非devm_of_platform_populate()是因为它使用包含simple-bus的of_default_bus_match_table。
该函数工作正常,但调用of_platform_depopulate()时子驱动并未卸载。子驱动为平台驱动,初始化代码如下:
static const struct of_device_id cca_dma_of_ids[] = { { .compatible = "cca,dma" }, {} }; MODULE_DEVICE_TABLE(of, cca_dma_of_ids); static int cca_dma_remove(struct platform_device *pdev) { pr_info("DMA driver removed\n"); return 0; } static struct platform_driver cca_dma_driver = { .driver = { .name = DEVICE_NAME, .of_match_table = cca_dma_of_ids, }, .probe = cca_dma_probe, .remove = cca_dma_remove, }; module_platform_driver(cca_dma_driver);
dmesg显示cca_dma_remove()已执行(输出“DMA driver removed”),但lsmod仍显示驱动处于加载状态。执行rmmod cca_dma可正常卸载,请问还需额外操作才能完全卸载驱动吗?我使用的是Linux内核v5.15.32。
解答
这是正常的内核驱动生命周期行为,具体说明如下:
- 设备实例与驱动模块是分离的:
of_platform_depopulate()仅负责销毁由of_platform_default_populate()创建的平台设备实例,触发驱动的remove函数释放设备相关资源,但不会卸载驱动模块本身。lsmod展示的是模块的加载状态,只要模块的引用计数未降到0,就会保持加载状态。 module_platform_driver()的特性:该宏注册的平台驱动,在没有匹配设备时,模块引用计数不会自动清零。只有执行rmmod命令,才会触发模块的退出逻辑,完成整个驱动模块的卸载。- 无需额外操作(按需选择自动卸载):如果你的需求只是释放设备资源,当前流程已经完成——
cca_dma_remove()执行说明设备资源已被正确释放。如果需要在设备销毁后自动卸载模块,可以在cca_dma_remove()末尾添加module_put(THIS_MODULE),但需注意:如果驱动还存在其他匹配的设备实例,该操作会导致错误,需谨慎使用。
补充说明:of_platform_depopulate()的职责是清理设备树生成的平台设备,和驱动模块的生命周期管理是两个独立的流程。模块卸载只能通过rmmod命令,或内核自动模块卸载机制(需开启CONFIG_MODULE_UNLOAD配置且模块引用计数为0)触发。
内容的提问来源于stack exchange,提问作者ozimki
相关产品推荐
相关产品推荐

