dts platform probe


原文链接: dts platform probe

driver使用dts的前提是driver已经是支持platform框架的driver,这样dts才可以发挥作用,因为dts和platform是配合工作的。

step1:创建dts结构体

static struct of_device_id xx_of_match[] = {
    {.compatible = "xx_tech,devic_xx",},
    {},
};

step2:注册该driver的dts

MODULE_DEVICE_TABLE(of, ali_of_match);

step3: 将该结构体加入platform成员

static struct platform_driver nim_platform_driver = {
    .probe    = xx_probe, 
    .remove   = xx_remove,
    .suspend  = xx_suspend,
    .resume   = xx_resume,
    .driver   = {
            .owner  = THIS_MODULE,
            .name   = "x_name", //这个name是用来和注册platform device的时候匹配用的
            .of_match_table = xx_of_match,
    },
};
step4:在dts文件中加入该节点
device_xx:device_xx1@0x18030000{
            compatible = "xx_tech,devic_xx";  /*dvbc*/
}

linux 设备驱动文件在与 dts 中的设备板级硬件信息匹配的关键字是 compatible 属性。即比较驱动文件中 of_device_id 结构体元素的 .compatible 成员变量和 dts 文件中 node 中 compatible 属性两个字符串。

DTS及驱动probe

使用Device Tree后,驱动需要与.dts中描述的设备结点进行匹配,从而引发驱动的probe()函数执行。

对于I2C和SPI从设备而言,同样也可以透过of_match_table添加匹配的.dts中的相关结点的compatible属性

dtsi 及 dts
.dts文件是一种ASCII 文本格式的Device Tree描述,此文本格式非常人性化,适合人类的阅读习惯。基本上,在ARM Linux在,一个.dts文件对应一个ARM的machine,一般放置在内核的arch/arm/boot/dts/目录。

由于一个SoC可能对应多个machine(一个SoC可以对应多个产品和电路板),势必这些.dts文件需包含许多共同的部分,Linux内核为了简化,把SoC公用的部分或者多个machine共同的部分一般提炼为.dtsi,类似于C语言的头文件。其他的machine对应的.dts就include这个.dtsi。

匹配步骤
进入probe:   module_init()-->of_match_table --> ".compatible" --> 进入probe()

添加设备: class_create()  --> alloc_chrdev_region()  --> device_create(class…majorno…)  --> cdev_init() -->cdev_add()

设备号,动态申请函数为alloc_chrdev_region,相对应的释放函数为unregister_chrdev_region。

/*下面两行是创建了一个总线类型,会在/sys/class下生成cdevdemo目录 
      这里的还有一个主要作用是执行device_create后会在/dev下自动生成 /dev/cdevdemo设备节点。
      而如果不调用此函数,如果想通过设备节点访问设备 
      需要手动mknod来创建设备节点后再访问。*/  
    cdevdemo_class = class_create(THIS_MODULE, "cdevdemo");  
    device_create(cdevdemo_class, NULL, MKDEV(cdevdemo_major, 0), NULL, "cdevdemo");
/*初始化一个字符设备,设备所支持的操作在cdevdemo_fops中*/     
    cdev_init(&dev->cdev, &cdevdemo_fops);  
    printk(KERN_NOTICE "======== cdevdemo_setup_cdev 3");     
    dev->cdev.owner = THIS_MODULE;  
    dev->cdev.ops = &cdevdemo_fops;  
    printk(KERN_NOTICE "======== cdevdemo_setup_cdev 4");     
    err = cdev_add(&dev->cdev, devno, 1);  
    printk(KERN_NOTICE "======== cdevdemo_setup_cdev 5");  

作者:无声蝉
来源:CSDN
原文:https://blog.csdn.net/zhuxipan1990/article/details/80743288
版权声明:本文为博主原创文章,转载请附上博文链接!

`