从Linux 2.6 起引入了一套新的驱动管理和注册机制:Platform_device 和Platform_driver 。
Linux 中大部分的设备驱动,都可以使用这套机制, 设备用Platform_device 表示,驱动用Platform_driver 进行注册。
Linux platform driver 机制和传统的device driver 机制( 通过driver_register 函数进行注册) 相比,一个十分明显的优势在于platform 机制将设备本身的资源注册进内核,由内核统一管理,在驱动程序中使用这些资源时通过platform device 提供的标准接口进行申请并使用。这样提高了驱动和资源管理的独立性,并且拥有较好的可移植性和安全性( 这些标准接口是安全的) 。
Platform 机制的本身使用并不复杂,由两部分组成:platform_device 和platfrom_driver 。
通过Platform 机制开发发底层驱动的大致流程为: 定义 platform_add_devices 注册 platform_device, 定义 platform_add_driver 注册 platform_driver 。
1、platform_device注册过程:
首先要确认的就是设备的资源信息,例如设备的地址,中断号等。
在2.6 内核中platform 设备用结构体platform_device 来描述,该结构体定义在kernel/include/linux/platform_device.h 中,
该结构一个重要的元素是resource ,该元素存入了最为重要的设备资源信息,定义在kernel/include/linux/ioport.h 中
下面举s3c6410 平台的i2c 驱动作为例子来说明:
把一个或几个设备资源放在一起,便于集中管理,其中IIC设备platform_device如下:
具体resource如下:
这里定义了两组resource ,它描述了一个I2C 设备的资源,第1 组描述了这个I2C 设备所占用的总线地址范围,IORESOURCE_MEM 表示第1 组描述的是内存类型的资源信息,第2 组描述了这个I2C 设备的中断号,IORESOURCE_IRQ 表示第2 组描述的是中断资源信息。设备驱动会根据flags 来获取相应的资源信息。
定义好了platform_device 结构体后就可以调用函数platform_add_devices 向系统中添加该设备了,之后可以调用platform_driver_register() 进行设备注册。
s3c6410-i2c的platform_device是在系统启动时,在mach-smdk6410.c里的smdk6410_machine_init()函数里进行注册的,这个函数申明为arch_initcall的函数调用,arch_initcall的优先级高于module_init。所以会在Platform驱动注册之前调用。(详细参考imach-smdk6410.c)
2. platform_driver注册过程:
在platform_device注册完成后,就可以进行platform_driver注册了,在驱动初始化函数中调用函数platform_driver_register() 注册platform_driver ,需要注意的是 s3c_device_i2c 结构中name 元素和s3c6410_i2c_driver 结构中driver.name 必须是相同的,这样在platform_driver_register() 注册时会对所有已注册的所有platform_device 中的name 和当前注册的platform_driver 的driver.name 进行比较,只有找到相同的名称的platfomr_device 才能注册成功。