0 前言
无论是《MINI2440看门狗驱动》、《SMDK6410 LCD驱动(FB)》还是《Tiny4412 LCD驱动(DRM)》,LCD平台驱动设备的添加方法都基本一致,是传统的方法。然而,本将基于linux-3.18.2介绍一种新的方法(新版内核推荐使用的方法),就是如何通过设备树来展开平台设备。
1 平台设备
与《MINI2440看门狗驱动》、《SMDK6410 LCD驱动(FB)》和《Tiny4412 LCD驱动(DRM)》不同的是,这里并不需要显式的定义struct platform_device,在系统初始化的时候会自动根据设备树创建相应的平台设备。
Tips:关于设备树是如果被加载并解析成设备节点的,详见参考资料[1],本文重点分析如何利用设备节点创建相应的平台设备。
1.1 创建&注册
(1)设备匹配表
const struct of_device_id of_default_bus_match_table[] = {
{ .compatible = "simple-bus", },
#ifdef CONFIG_ARM_AMBA
{ .compatible = "arm,amba-bus", },
#endif /* CONFIG_ARM_AMBA */
{} /* Empty terminated list */
};
// @file: drivers/of/platform.c
(2)入口定义
DT_MACHINE_START(S3C6400_DT, "Samsung S3C64xx (Flattened Device Tree)")
/* Maintainer: Tomasz Figa <tomasz.figa@gmail.com> */
.dt_compat = s3c64xx_dt_compat,
.map_io = s3c64xx_dt_map_io,
.init_machine = s3c64xx_dt_init_machine,
.restart = s3c64xx_dt_restart,
MACHINE_END
// @file: arch/arm/mach-s3c64xx/mach-s3c64xx-dt.c
对比分析:与《Linux设备驱动--LCD平台设备与驱动(smdk6410)》不同的是,这里不再使用MACHINE_START,而是使用DT_MACHINE_START取代之[5]。
(3)s3c64xx入口函数
static void __init s3c64xx_dt_init_machine(void)
{
samsung_wdt_reset_of_init();
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); /* 创建平台设备. */
}
// @file: arch/arm/mach-s3c64xx/mach-s3c64xx-dt.c
在s3c64xx入口函数中,调用of_platform_populate()函数根据设备节点创建相应的平台设备,流程如下:
of_platform_populate()
|-->for_each_child_of_node(root, child)
|-->of_platform_bus_create()
|-->of_platform_device_create_pdata()
|-->of_device_add()
|-->device_add()
比较分析:与《Linux设备驱动--LCD平台设备与驱动(smdk2440)》、《Linux设备驱动--LCD平台设备与驱动(smdk6410)》和《Linux设备驱动--LCD平台设备与驱动(tiny4412)》所不同的是,这里并没有使用platform_add_devices() / platform_device_register()注册平台设备,而是使用device_add()来注册平台设备里面的普通设备(ofdev->dev)。
2 平台驱动
和传统使用非设备树方案的一样,可参考《MINI2440看门狗驱动》、《SMDK6410 LCD驱动(FB)》以及《Tiny4412 LCD驱动(DRM)》等,本文不再赘述。
参考资料
[1]Linux 3.10 ARM Device Tree 的初始化
[2]Linux加载DTS设备节点的过程(以高通8974平台为例)
[3]论dts中的of_platform_populate如何选择性加载device node为platform device
[5]ARM Linux 3.x的设备树(Device Tree)
[6]linux2.6中的platform和of_platform机制B
[7]基于tiny4412的Linux内核移植 -- 设备树的展开
[8]编写设备驱动程序
[9]Linux 设备树详解