linux驱动的三个概念:设备、驱动、总线
probe何时被调用:在总线上驱动和设备的名字匹配,就会调用驱动的probe函数
probe函数被调用后,系统就调用platform设备的probe函数完成驱动注册最后工作。下面是probe被调用前的一些流程。
device一般是先于driver注册,但也不全是这样的顺序。Linux的Device和Driver的注册过程分别枚举挂在该BUS上所有的Driver和Device实现了这种时序无关性。
Platform机制的本身使用并不复杂,由两部分组成:platform_device 和 platfrom_driver。
通过Platform机制开发发底层驱动的大致流程为: 定义 platform_device 注册 platform_device 定义 platform_driver 注册 platform_driver。
在2.6内核中platform设备用结构体platform_device来描述,该结构体定义在kernel\include\linux\platform_device.h中,
struct platform_device {
const char * name;
u32 id;
struct device dev;
u32 num_resources;
struct resource * resource;
};
以i2c驱动为例,定义一个device
struct platform_device s3c_device_i2c = {
.name = "s3c2410-i2c",
.id = -1,
.num_resources = ARRAY_SIZE(s3c_i2c_resource),
.resource = s3c_i2c_resource,
};
定义好了platform_device结构体后就可以调用函数platform_add_devices()向系统中添加该设备了,之后可以调用platform_device_register()进行设备注册。要注意的是,这里的platform_device设备的注册过程必须在相应设备驱动加载之前被调用,即执行platform_driver_register之前,原因是因为驱动注册时需要匹配内核中所以已注册的设备名。
s3c2410-i2c的platform_device是在系统启动时,在cpu.c里的s3c_arch_init()函数里进行注册的,这个函数申明为arch_initcall(s3c_arch_init);会在系统初始化阶段被调用。
arch_initcall的优先级高于module_init(driver在这个函数中被注册到总线中)。所以会在Platform驱动注册之前调用。(详细参考include/linux/init.h)
驱动程序需要实现结构体struct platform_driver,参考drivers/i2c/busses
/* device driver for platform bus bits */
static struct platform_driver s3c2410_i2c_driver = {
.probe = s3c24xx_i2c_probe,
.remove = s3c24xx_i2c_remove,
.resume = s3c24xx_i2c_resume,
.driver = {
.owner = THIS_MODULE,
.name = "s3c2410-i2c",
},
};
...
static int __init s3c2410_i2c_init(void)
{
return platform_driver_register(&s3c2410_i2c_driver); //注册平台驱动
}
module_init(s3c2410_i2c_init);
在驱动初始化函数中调用函数platform_driver_register()注册platform_driver,需要注意的是s3c_device_i2c结构中name元素和s3c2410_i2c_driver结构中driver.name必须是相同的,这样在platform_driver_register()注册时会对所有已注册的所有platform_device中的name和当前注册的platform_driver的driver.name进行比较,只有找到相同的名称的platfomr_device才能注册成功,具体调用流程可以参考文章开头的流程图。当注册成功时会调用platform_driver结构元素probe函数指针,这里就是s3c24xx_i2c_probe,当进入probe函数后,需要获取设备的资源信息,注册定时器、中断、创建设备节点等等。
本文章部分内容转自:
https://www.cnblogs.com/lifan3a/articles/5045447.html
http://blog.csdn.net/thl789/article/details/6723350