0

我正在尝试在我的 SoC (Zynq 7000) 的 FPGA 部分中为 DMA 设备编写驱动程序。通过调用sysfs_create_group我的probe()函数,我可以为我的每个设备创建一个属性。该属性是在/sys/devices/soc0/fpga-axi@0/XXX.dmaXXX 是我的三个 DMA 的地址的位置创建的。

现在,我正在调用sysfs_remove_group我的remove()函数。但是,该属性没有被删除,因此当我再次尝试插入模块时内核会抱怨:

------------[ cut here ]------------
WARNING: CPU: 1 PID: 2251 at fs/sysfs/dir.c:31 sysfs_warn_dup+0x64/0x74
sysfs: cannot create duplicate filename '/devices/soc0/fpga-axi@0/40420000.dma/enable'
Modules linked in: my_axi_dma_new(O+) mwipcore mwipcore_iio_streaming mwipcore_dma_streaming mathworks_ip_common [last unloaded: my_axi_dma_new]
CPU: 1 PID: 2251 Comm: insmod Tainted: G        W  O    4.14.0-g4fea7c58ad92-dirty #3
Hardware name: Xilinx Zynq Platform
[<c010edbc>] (unwind_backtrace) from [<c010b6f4>] (show_stack+0x10/0x14)
[<c010b6f4>] (show_stack) from [<c06edd44>] (dump_stack+0x8c/0xa0)
[<c06edd44>] (dump_stack) from [<c011c890>] (__warn+0xe8/0x100)
[<c011c890>] (__warn) from [<c011c8e0>] (warn_slowpath_fmt+0x38/0x48)
[<c011c8e0>] (warn_slowpath_fmt) from [<c0253380>] (sysfs_warn_dup+0x64/0x74)
[<c0253380>] (sysfs_warn_dup) from [<c0253098>] (sysfs_add_file_mode_ns+0x148/0x194)
[<c0253098>] (sysfs_add_file_mode_ns) from [<c02539e0>] (internal_create_group+0xf8/0x2e8)
[<c02539e0>] (internal_create_group) from [<bf02d77c>] (my_axi_dma_of_probe+0x254/0x284 [my_axi_dma_new])
[<bf02d77c>] (my_axi_dma_of_probe [my_axi_dma_new]) from [<c03b2a20>] (platform_drv_probe+0x50/0xac)
[<c03b2a20>] (platform_drv_probe) from [<c03b1240>] (driver_probe_device+0x238/0x2e8)
[<c03b1240>] (driver_probe_device) from [<c03b1394>] (__driver_attach+0xa4/0xa8)
[<c03b1394>] (__driver_attach) from [<c03af7a0>] (bus_for_each_dev+0x4c/0x9c)
[<c03af7a0>] (bus_for_each_dev) from [<c03b07a0>] (bus_add_driver+0x188/0x20c)
[<c03b07a0>] (bus_add_driver) from [<c03b1c3c>] (driver_register+0x78/0xf4)
[<c03b1c3c>] (driver_register) from [<bf032014>] (my_module_init+0x14/0x1000 [my_axi_dma_new])
[<bf032014>] (my_module_init [my_axi_dma_new]) from [<c0101a20>] (do_one_initcall+0x44/0x168)
[<c0101a20>] (do_one_initcall) from [<c018895c>] (do_init_module+0x60/0x1f0)
[<c018895c>] (do_init_module) from [<c01875f0>] (load_module+0x1b8c/0x23a0)
[<c01875f0>] (load_module) from [<c0188008>] (SyS_finit_module+0x9c/0xb4)
[<c0188008>] (SyS_finit_module) from [<c0107960>] (ret_fast_syscall+0x0/0x48)
---[ end trace ae99db187b2dddb3 ]---

这是我的remove()函数的代码:

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);
    // free_irq(data->irq, NULL);
    devm_free_irq(&pdev->dev, data->irq, data);
    printk(KERN_INFO "%s:%i global irq is %d.\n", __FUNCTION__, __LINE__, global_irq);

    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);
        }
        sysfs_remove_group(&pdev->dev.kobj, &my_axi_dma_attr_group);
        class_destroy(my_class);
        unregister_chrdev_region(device_number, MAX_DEVICES);

    }
    return 0;
}

有什么见解吗?

4

1 回答 1

0

通过将我的电话移至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);
    // free_irq(data->irq, NULL);
    devm_free_irq(&pdev->dev, data->irq, data);
    printk(KERN_INFO "%s:%i global irq is %d.\n", __FUNCTION__, __LINE__, global_irq);
    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;
}
于 2020-05-19T16:05:51.553 回答