您的位置:首页 > 运维架构 > Linux

Jaguar.Yuan 的Linux驱动之行——Platform驱动框架介绍(二)

2012-04-12 10:32 260 查看
二、 platform_device与驱动的联系

下面这个结构 体,对于移植过系统的来说已经不陌生了,而系统也正是通过这个结构体加载相关驱动,下面这个结构体只列出比较的几个驱动程序,其实系统中远不只如此。

static struct
platform_device *smdk2410_devices[] __initdata = {
&s3c_device_lcd,
&s3c_device_bl,
&s3c_device_wdt,
&s3c_device_i2c,//下面的案例
&s3c_device_adc,

&s3c_device_nand,
&s3c_device_ts,
&s3c_device_buttons,
&s3c_device_rtc,
};
下面就以一个 s3c2440的I2C驱动为例进行说明:

static
struct resource s3c_i2c_resource[]
= {

[0]
= {

.start
= S3C24XX_PA_IIC,//内存资源

.end
= S3C24XX_PA_IIC
+ S3C24XX_SZ_IIC
- 1,

.flags
= IORESOURCE_MEM,

},

[1]
= {

.start
= IRQ_IIC,
//中断资源,只有一个中断

.end
= IRQ_IIC,

.flags
= IORESOURCE_IRQ,

}

};

这里定义了两组resource,它描述了一个I2C设备的资源,第1组描
述了这个I2C设备所占用的总线地址范围, IORESOURCE_MEM表示第1组描述的是内存类型的资源信息,第2组描述了这个I2C设备的中断号,
IORESOURCE_IRQ表示第2组描述的是中断资源信息。设备驱动会根据flags来获取相应的资源信息。有了resource信息,就可以定义platform_device了:

struct platform_device s3c_device_i2c
= {//这个名称是在static struct
platform_device *smdk2410_devices[] __initdata中,系统加载时调用

.name
= "s3c2410-i2c",//这个名是实现device与driver匹配的关键,与后面的driver将相同

.id
= -1,

.num_resources
= ARRAY_SIZE(s3c_i2c_resource),//可用资源数

.resource
= s3c_i2c_resource,//前面出现的资源

};
定义好了platform_device结构体后就可以调用函数platform_add_devices向系统中添加该设备了,之后可以调用platform_driver_register()进行设备注册。要注意的是,这里的platform_device设备的注册过程必须在相应设备驱动加载之前被调用,即执行platform_driver_register之前,原因是因为驱动注册时需要匹配内核中所以已注册的设备名。

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",

},

};

在驱动初始化函数中调用函数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函数后,需要获取设备的资源信息,常用获取资源的函数主要是:
struct resource * platform_get_resource(struct platform_device *dev, unsigned int type, unsigned int num);
根据参数type所指定类型,例如IORESOURCE_MEM,来获取指定的资源。
struct int platform_get_irq(struct platform_device *dev, unsigned int num);获取资源中的中断号。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: