Zynq7000 DMA驱动sysfs属性无法删除问题求助
解决Zynq 7000 DMA驱动sysfs属性未正确移除的问题
看起来你碰到了sysfs属性清理不及时的经典问题,咱们一步步来拆解根源和解决办法:
问题核心:sysfs属性组的清理时机错了
看你的报错信息,重新加载模块时提示enable属性重复,说明上一次卸载模块时,对应DMA设备的sysfs属性没被删掉。再看你的remove函数代码,问题很明显:你把sysfs_remove_group放在了if(!cdown)的条件块里——只有当所有DMA设备都被移除(cdown减到0)的时候才会执行清理,但实际上每个DMA设备在probe阶段都为自己创建了独立的sysfs属性组(对应每个XXX.dma节点),所以每个设备的remove流程都需要单独调用sysfs_remove_group来清理自己的属性,不能等到最后一个设备才统一处理。
修复代码
把sysfs_remove_group移出条件判断,让每个设备在移除时都执行清理操作:
static int my_axi_dma_of_remove(struct platform_device *pdev) { struct my_axi_dma_data* data = platform_get_drvdata(pdev); int major, i; dev_t my_device; printk(KERN_INFO "%s:%i freeing up the allocated irq %d.\n", __FUNCTION__, __LINE__, data -> irq); devm_free_irq(&pdev->dev, data->irq, data); printk(KERN_INFO "%s:%i global irq is %d.\n", __FUNCTION__, __LINE__, global_irq); // 关键修改:每个设备移除时立即清理自己的sysfs属性组 sysfs_remove_group(&pdev->dev.kobj, &my_axi_dma_attr_group); cdown--; if(!cdown) { printk(KERN_INFO "%s:%i Now destroying character devices.\n", __FUNCTION__, __LINE__); major = MAJOR(device_number); for (i = 0; i < num_dev; i++) { my_device = MKDEV(major, i); cdev_del(&my_cdev[i]); device_destroy(my_class, my_device); } class_destroy(my_class); unregister_chrdev_region(device_number, MAX_DEVICES); } return 0; }
额外检查建议
- 确认属性组的独立性:确保
my_axi_dma_attr_group的定义没有共享错误的资源,每个设备的属性组都是针对自身设备节点创建的; - 考虑使用devm系列API:如果你改用
devm_sysfs_create_group代替sysfs_create_group,内核会自动在设备销毁时帮你清理sysfs属性,不需要手动调用sysfs_remove_group,这会更稳妥; - 验证清理效果:修改后卸载模块,执行
ls /devices/soc0/fpga-axi@0/*.dma确认所有DMA节点都被删除,再重新加载模块就不会报错了。
内容的提问来源于stack exchange,提问作者agave1987
相关产品推荐
相关产品推荐

