从linux-2.6开始引入了一套新的驱动管理和注册机制:platform_device和platform_driver.
linux中的大部分设备驱动,都可以使用该机制,设备用platform_device表示,驱动用platform_deriver进行注册。
platform是linux的一个虚拟的地址总线,主要是用来描述芯片的片内资源,它直接取片内地址进行资源读写。因此和内核相关性不大,象lcd,rtc,watchdog,uart等都是这类。
看看这个:
http://www.eetop.cn/blog/html/45/11145-676.html
platform_device结构体用来描述设备的名称、资源信息等,该结构被定义在include/linux/platform_device.h中
#include
//该头文件就是以前Linux-2.4驱动的头文件,利用driver_register()进行驱动注册
struct platform_device { // 设备结构体信息
const char * name; // 该平台设备的名称 u32 id; struct device dev; u32 num_resources; struct resource * resource; // 定义平台设备的资源
};
|
其中最重要的是struct resource *resource结构,该结构定义在include/linux/ioport.h中
struct resource {
resource_size_t start; // 定义资源的起始地址 resource_size_t end; // 定义资源的结束地址 const char *name; // 定义资源的名称 unsigned long flags; // 定义资源的类型,例如MEM, IO ,IRQ, DMA类型 struct resource *parent, *sibling, *child; //资源链表指针
};
|
//////////////////设备在内核中也需要注册,通过调用函数platform_add_devices()向系统添加该设备,在该函数内部会调用platform_device_register()向系统内核进行设备的注册。
//////////////////注意设备的注册要在驱动的注册之前,即驱动注册platform_driver_register()注册之前,因为驱动注册时需要匹配内核中所有已经注册了的设备名。
那么接下来我们开始驱动的注册定义:主要结构体是platform_driver,该结构体也是定义在incluce/linux/platform_device.h中的:
struct platform_driver { int (*probe)(struct platform_device *); // 设备的检测,所以需要先前的设备注册
int (*remove)(struct platform_device *); // 删除该设备
void (*shutdown)(struct platform_device *); //关闭该设备
int (*suspend)(struct platform_device *, pm_message_t state); int (*suspend_late)(struct platform_device *, pm_message_t state); int (*resume_early)(struct platform_device *); int (*resume)(struct platform_device *); struct device_driver driver; //老设备驱动,定义在include/linux/device.h中
};
|
然后内核提供的platform_driver结构体的注册函数为platform_driver_register(),该函数定义在driver/base/platform.c中
函数原型:
int platform_driver_register(struct platform_driver *drv) { drv->driver.bus = &platform_bus_type; //驱动总线类型: IO, IRQ,DMA,MEM类型
if (drv->probe) drv->driver.probe = platform_drv_probe; //设备探测
if (drv->remove) drv->driver.remove = platform_drv_remove; if (drv->shutdown) drv->driver.shutdown = platform_drv_shutdown; if (drv->suspend) drv->driver.suspend = platform_drv_suspend; if (drv->resume) drv->driver.resume = platform_drv_resume; return driver_register(&drv->driver); //这个就是老的设备驱动注册了
} EXPORT_SYMBOL_GPL(platform_driver_register);
|
举例设备驱动:
static struct platform_driver mxc_kpd_driver = { .driver = { .name = "mxc_keypad", .bus = &platform_bus_type, }, .suspend = mxc_kpp_suspend, .resume = mxc_kpp_resume, .probe = mxc_kpp_probe, .remove = mxc_kpp_remove };
|
////////////////////还有一个函数input_register_device();是将该驱动添加到/class/input/input0-12中。
阅读(1535) | 评论(0) | 转发(0) |