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);获取资源中的中断号。
下面这个结构 体,对于移植过系统的来说已经不陌生了,而系统也正是通过这个结构体加载相关驱动,下面这个结构体只列出比较的几个驱动程序,其实系统中远不只如此。
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);获取资源中的中断号。
相关文章推荐
- Jaguar.Yuan 的Linux驱动之行——Platform驱动框架介绍(一)
- Linux驱动框架----platform简介明了的介绍
- Linux虚拟总线platform驱动框架之地址对齐省内存
- Linux驱动框架----platform
- linux下platform设备驱动框架的实现与作用解析
- Linux Framebuffer 驱动框架之一概念介绍及LCD硬件原理
- Linux虚拟总线platform驱动框架之地址对齐省内存
- linux驱动下platform总线框架
- Linux Framebuffer 驱动框架之一概念介绍及LCD硬件原理
- Linux Framebuffer 驱动框架之一概念介绍及LCD硬件原理
- Linux驱动(七)设备模型介绍以及platform设备驱动
- Linux Framebuffer 驱动框架之一概念介绍及LCD硬件原理【转】
- 09-S3C2440驱动学习(三)嵌入式linux-platform平台总线驱动程序及分离分层构建驱动框架
- Linux驱动框架----platform
- Linux 字符设备驱动框架详细介绍
- Linux ALSA声卡驱动之八:ASoC架构中的Platform
- Linux ALSA声卡驱动之八:ASoC架构中的Platform
- Linux驱动程序开发001 - 驱动程序基本框架
- Linux驱动修炼之道-SPI驱动框架源码分析
- FS4412开发板使用Linux IIO驱动框架实现ADC驱动