• linux设备树节点添加新的复位属性之后设备驱动加载异常问题分析


    该问题是在调试linux设备驱动时出现,根据当时对该问题的理解以及对应的验证方法去整理为该文档。

    1 linux原始设备驱动信息

    1.1 设备树节点信息

    / {
            test_fw_load@0x100000000 {
                    compatible = "test,test-x280-fw";
                    reg = < 0x01 0x00000000 0x0 0x20000000 >, < 0x0 0x4000f000 0x0 0x200>;
            };
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    1.2 linux设备驱动

    这里只给出一个驱动代码的示意test_fw.c,probe函数具体的功能就不再贴出。

    // SPDX-License-Identifier: GPL-2.0-or-later
    
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    #include 
    #include 
    #include 
    
    #define TEST_FW_LOAD_VERSION "1.0"
    
    
    static int test_fw_probe(struct platform_device *pdev)
    {
    	printk("test fw probe\r\n");
    	return 0;
    }
    
    /**
     * test_fw_remove - set driver_data of the device to NULL
     * @pdev: pointer to platform device handle
     *
     * Always returns 0
     */
    static int test_fw_remove(struct platform_device *pdev)
    {
    	printk("test fw probe\r\n");
    
    	return 0;
    }
    
    static const struct of_device_id test_fw_match[] = {
    	{ .compatible = "test,test-x280-fw", },
    	{},
    };
    MODULE_DEVICE_TABLE(of, test_fw_match);
    
    static struct platform_driver test_fw_load_driver = {
    	.driver = {
    		.name           = "test_fw_load",
    		.of_match_table = test_fw_match,
    	},
    	.probe  = test_fw_probe,
    	.remove = test_fw_remove,
    };
    module_platform_driver(test_fw_load_driver);
    
    MODULE_AUTHOR("W Test ");
    MODULE_VERSION(TEST_FW_LOAD_VERSION);
    MODULE_LICENSE("GPL V2");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57

    1.3 makefile

    obj-$(CONFIG_TEST_FW_LOAD)      += test_fw.o
    
    • 1

    1.4 Kconfig

    config TEST_FW_LOAD
            tristate "X280 Fw load on Test Platform"
            select FW_LOADER
            help
              This option enables support for the Test load X280 FW
    
              You may select when support test fw load. To compile this as a module
              choose M.
    
              If unsure, say N.
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    1.5 对应的defconfig文件

    CONFIG_TEST_FW_LOAD=y
    
    • 1

    2 修改之后的linux设备驱动

    2.1 修改之后的设备树节点信息

    给test_fw_load节点添加了复位属性。

    / {
    	test_reset: test_reset {
    		compatible = "test,scmi-reset";
    		#reset-cells = <1>;
    	};
    };
    
    / {
            test_fw_load@0x100000000 {
                    compatible = "test,test-x280-fw";
                    reg = < 0x01 0x00000000 0x0 0x20000000 >, < 0x0 0x4000f000 0x0 0x200>;
                    resets = <&test_reset 1>;
                    reset-names = "test_reset";
            };
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    2.2 原始test_fw.c出现的问题以及原因分析

    2.2.1 原始test_fw.c出现的问题

    当给test_fw.c对应的设备树添加了复位属性之后就开始出现test_fw.c驱动的probe函数不被执行,整个设备驱动好像就没有被调用。
    可以确定test_fw.c所对应的makefile,Kconfig,defconfig均已正常添加对应的配置选项,且之前test_fw.c所对应的驱动运行良好。
    同时,如果把复位属性注释掉则驱动又恢复运行良好。

    2.2.2 原始test_fw.c出现的问题的原因分析

    由于添加上复位属性设备驱动就会出现加载异常,注释掉复位属性驱动就运行OK,那么我们可以确定问题是由于添加复位属性引入的。
    该问题的主要原因是使用test_reset的复位节点配置,但是test_reset节点所对应的驱动并没有处理并加载,导致test_fw.c所对应的驱动加载异常。

    2.3 解决test_fw.c对应驱动加载异常的方法

    解决test_fw.c对应驱动加载异常的方法就是添加test_reset设备树节点对应节点的设备驱动,下面是已对应的示意代码为例来介绍的。

    2.3.1 添加对应的test_reset.c驱动文件

    // SPDX-License-Identifier: GPL-2.0-or-later
    
    #include 
    
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    #include 
    #include 
    
    /**
     * test_reset_probe - probe routine of the driver
     * @pdev: pointer to Platform device handle
     *
     * Return zero for success and non-zero for failure
     */
    static int test_reset_probe(struct platform_device *pdev)
    {
            return 0;
    }
    
    /**
     * test_reset_remove - set driver_data of the device to NULL
     * @pdev: pointer to platform device handle
     *
     * Always returns 0
     */
    static int test_reset_remove(struct platform_device *pdev)
    {
            return 0;
    }
    
    static const struct of_device_id test_reset_match[] = {
            { .compatible = "test,scmi-reset", },
            {},
    };
    MODULE_DEVICE_TABLE(of, test_reset_match);
    
    static struct platform_driver test_reset_driver = {
            .driver = {
                    .name           = "test_reset",
                    .of_match_table = test_reset_match,
            },
            .probe  = test_reset_probe,
            .remove = test_reset_remove,
    };
    module_platform_driver(test_reset_driver);
    
    MODULE_AUTHOR("W Test ");
    MODULE_DESCRIPTION("TEST RESET driver");
    MODULE_LICENSE("GPL V2");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57

    2.3.2 makefile添加对test_reset.c的支持

    obj-$(CONFIG_TEST_RESET)    += test_reset.o
    
    • 1

    2.3.3 Kconfig添加对test_reset功能的支持

    config TEST_RESET
            tristate "test reset on Test Platform"
            help
              This option enables support for the TEST RESET
    
              You may select when support test reset. To compile this as a module
              choose M.
    
              If unsure, say N.
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    2.3.4 defconfig文件添加对test_reset功能的支持

    CONFIG_TEST_RESET=y
    
    • 1

    3 对于该问题的总结

    3.1 添加一个新的linux设备驱动需要兼顾的几点

    在这里插入图片描述

    3.2 设备树节点添加新的属性的处理

    • 若新添加的设备属性需要执行具体的功能,那需要按照3.1章的部分去添加对应的设备驱动程序。
    • 若不需要,则在原始的设备驱动初始化流程直接去解析对应的设备属性即可。
  • 相关阅读:
    JavaScript includes() 方法
    使用extundelete恢复文件-尚文网络xUP楠哥
    Obsidian+SyncTrayzor打造个人文档云同步平台
    程序化广告还有未来么?(4/5)——程序化领域变化的底层逻辑和反思
    Python测试框架 Pytest —— mock使用(pytest-mock)
    【数据结构与算法】顺序表&手撕vector
    1444_TC275 DataSheet阅读笔记5_部分管脚功能的梳理
    江苏显卡服务器适用于哪些场景?
    欧科云链研究院:仰传统机构之“鼻息”,RWA的关键不在于Web3技术
    9.28 - 每日一题 - 408
  • 原文地址:https://blog.csdn.net/u014100559/article/details/132865277