



全文预览已结束
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
2. 设备节点兼容性在.dts文件的每个设备节点中,都有一个兼容属性,兼容属性用于驱动和设备的绑定。兼容属性是一个字符串的列表,列表中的第一个字符串表征了节点代表的确切设备,形式为,其后的字符串表征可兼容的其他设备。可以说前面的是特指,后面的则涵盖更广的范围。如在vexpress-v2m.dtsi中的Flash节点如下:flash0,00000000 compatible = arm,vexpress-flash, cfi-flash; reg = ,; b1ank-width = ; ;兼容属性的第2个字符串cfi-flash明显比第1个字符串arm,vexpress-flash涵盖的范围更广。再如,Freescale MPC8349SoC含一个串口设备,它实现了国家半导体(National Sem-iconductor)的NS16550寄存器接口。则MPC8349串口设备的兼容属性为compatible=fsl,mpc8349-uart,ns16550。其中,fsl,mpc8349-uart指代了确切的设备,ns16550代表该设备与NS16550UART保持了寄存器兼容。因此,设备节点的兼容性和根节点的兼容性是类似的,都是“从具体到抽象”。使用设备树后,驱动需要与.dts中描述的设备节点进行匹配,从而使驱动的probe()函数执行。对于platform_driver而言,需要添加一个OF匹配表,如前文的.dts文件的acme,a1234-i2c-bus兼容I2C控制器节点的OF匹配表,具体代码如下所示。1static const struct of_device_id a1234_i2c_of_match = 2 .compatible = acme,a1234-i2c-bus, , 3 , 4; 5MODULE_DEVICE_TABLE(of, a1234_i2c_of_match); 6 7static struct platform_driver i2c_a1234_driver = 8 .driver = 9 .name = a1234-i2c-bus,10 .owner = THIS_MODULE,11 .of_match_table = a1234_i2c_of_match,12 ,13 .probe = i2c_a1234_probe,14 .remove = i2c_a1234_remove,15;16 module_platform_driver(i2c_a1234_driver);对于I2C和SPI从设备而言,同样也可以通过of_match_ta-ble添加匹配的.dts中的相关节点的兼容属性,如sound/soc/codecs/wm8753.c中的针对WolfsonWM8753的of_match_ta-ble,具体代码如下所示。1static const struct of_device_id wm8753_of_match = 2 .compatible = wlf,wm8753, , 3 4; 5MODULE_DEVICE_TABLE(of, wm8753_of_match); 6static struct spi_driver wm8753_spi_driver = 7 .driver = 8 .name = wm8753, 9 .owner = THIS_MODULE,10 .of_match_table = wm8753_of_match,11 ,12 .probe = wm8753_spi_probe,13 .remove = wm8753_spi_remove,14;15static struct i2c_driver wm8753_i2c_driver = 16 .driver = 17 .name = wm8753,18 .owner = THIS_MODULE,19 .of_match_table = wm8753_of_match,20 ,21 .probe = wm8753_i2c_probe,22 .remove = wm8753_i2c_remove,23 .id_table = wm8753_i2c_id,24;上述代码中的第2行显示WM8753的供应商是“wlf”,它其实是对应于Wolfson Microe-lectronics的前缀。详细的前缀可见于内核文档:Documentation/devicetree/bindings/vendor-pre-fixes.txt对于I2C、SPI还有一点需要提醒的是,I2C和SPI外设驱动和设备树中设备节点的兼容属性还有一种弱式匹配方法,就是“别名”匹配。兼容属性的组织形式为,别名其实就是去掉兼容属性中manufacturer前缀后的部分。关于这一点,可查看drivers/spi/spi.c的源代码,函数spi_match_device()暴露了更多的细节,如果别名出现在设备spi_driver的id_table里面,或者别名与spi_driver的name字段相同,SPI设备和驱动都可以匹配上,代码清单18.8显示了SPI的别名匹配。 1static int spi_match_device(struct device *dev, struct device_driver *drv) 2 3 const struct spi_device *spi = to_spi_device(dev); 4 const struct spi_driver *sdrv = to_spi_driver(drv); 5 6 /* Attempt an OF style match */7 if (of_driver_match_device(dev, drv) 8 return 1; 910 /* Then try ACPI */11 if (acpi_driver_match_device(dev, drv)12 return 1;1314 if (sdrv-id_table)15 return !spi_match_id(sdrv-id_table, spi);1617 return strcmp(spi-modalias, drv-name) = 0;18 19static const struct spi_device_id *spi_match_id(const struct spi_device_id *id,20 const struct spi_device *sdev)2122 while (id-name0) 23 if (!strcmp(sdev-modalias, id-name)24 return id;25 id+;26 27 return NULL;28通过这个别名匹配,实际上,SPI和I2C的外设驱动即使没有of_match_table,还是可以和设备树中的节点匹配上的。一个驱动可以在of_match_table中兼容多个设备,在Linux内核中常常使用如下API来判断具体的设备是什么:int of_device_is_compatible(const struct device_node *device,const char *compat);此函数用于判断设备节点的兼容属性是否包含compat指定的字符串。这个API多用于一个驱动支持两个以上设备的时候。当一个驱动支持两个或多个设备的时候,这些不同.dts文件中设备的兼容属性都会写入驱动OF匹配表。因此驱动可以通过Bootloader传递给内核设备树中的真正节点的兼容属性以确定究竟是哪一种设备,从而根据不同的设备类型进行不同的处理。如arch/powerpc/platforms/83xx/usb.c中的mpc831x_usb_cfg()就进行了类似处理:if(immr_node&(of_device_is_compatible(immr_node, fsl,mpc8315-immr)|of_device_is_compatible(immr_node, fsl,mpc8308-immr)clrsetbits_be32(immap + MPC83XX_SCCR_OFFS,MPC8315_SCCR_USB_MASK,MPC8315_SCCR_USB_DRCM_01);elseclrsetbits_be32(immap + MPC83XX_SCCR_OFFS,MPC8315_SCCR_USB_MASK,MPC8315_SCCR_USB_DRCM_11);它根据具体的设备是fsl,mpc8315-immr和fsl,mpc8308-immr、中的哪一种来进行不同的处理。当一个驱动可以兼容多种设备时,除了of_devcice_is_compatinle()这种判断方法之外,还可以采用在驱动的of_device_id表中填充.data成员的形式。譬如,arch/arm/mm/cache-l2x0.c支持“arm,l210-cache”“arm,pl310-cache”“arm,l220-cache”等多种设备,其of_device_id表如代码清单18.9所示。1#define L2C_ID(name, fns) .compatible = name, .data = (void *)&fns 2static const struct of_device_id l2x0_ids _initconst = 3 L2C_ID(arm,l210-cache, of_l2c210_data), 4 L2C_ID(arm,l220-cache, of_l2c220_data), 5 L2C_ID(arm,pl310-cache, of_l2c310_data), 6 L2C_ID(brcm,bcm11351-a2-pl310-cache, of_bcm_l2x0_data), 7 L2C_ID(marvell,aurora-outer-cache, of_aurora_with_outer_data), 8 L2C_ID(marvell,aurora-system-cache, of_aurora_no_outer_data), 9 L2C_ID(marvell,tauros3-cache, of_tauros3_data),10 /* Deprecated IDs */11 L2C_ID(bcm,bcm11351-a2-pl310-cache, of_bcm_l2x0_data),12 13 ;在驱动中,通过如代码清单18.10的方法拿到了对应于L2缓存类型的.data成员,其中主要用到了of_match_node()这个API。1int _init l2x0_of_init(u32 aux_val, u32 aux_mask) 2 3 const struct l2c_init_data *data; 4 struct device_node *np; 5 6 np = of_find_matching_node(NULL, l2x0_ids); 7 if (!np) 8 return -ENODEV; 9 10 data = of_match_node(l2x0_ids, np)-data;11如果电路板的.dts文件中L2缓存是arm,pl310-cache,那么上述代码第10行找到的data就是of_l2c310_data,它是l2c_init_data结构体的一个实例。l2c_init_data是一个由L2缓存驱动自定义的数据结构,在其定义中既可以保护数据成员,又可以包含函数指针,如代码清单18.11所示。 1struct l2c_init_data 2 const char *type; 3 unsigned way_size_0; 4 unsigned num_lock; 5 void (*of_parse)(const struct device_node *, u32 *, u
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 服饰搭配示范指南
- 创新促销方案的营销报告
- 家庭医生签约服务的服务态度要求
- 职业培训需求分析及课程设计
- 古代小说《开辟演义》史料解析
- 2025医院三基考试检测卷含答案详解
- 城市公交优先发展的规程
- 分享致辞方案
- 职业发展规划实现策略
- 人工智能应用案例企业白皮书
- 2025年中小学生国防知识竞赛题库及答案
- 机械制图选择题试题库及答案
- 湖南省科技创新惠企助企政策汇编 2025
- 医院安全警示教育
- DB45∕T 2746-2023 国家储备林培育技术规程
- 医保基金监管培训课件
- 药厂变更管理培训
- 技术部工作汇报与未来规划
- 体育安全与急救知识培训
- 小区装修工具管理制度
- 2026年日历表(带农历 每月一张可打印)
评论
0/150
提交评论