platform设备模型
platform设备驱动,对与usb、iic等有总线依附的设备可以不用考虑,对于不依附于此类总线比较特殊设备,提供platform虚拟总线来完成,例如网卡、LCD这些。
这些设备有一个基本的特征:可以通过CPU bus直接寻址(例如在嵌入式系统常见的“寄存器”)。由于这个共性,内核在设备模型的基础上(device和device_driver),对这些设备进行了更进一步的封装,抽象出paltform bus、platform device和platform driver,以便驱动开发人员可以方便的开发这类设备的驱动。总的来说就是一种分层思想,有利于驱动可移植性。
1.platform的API
platform_device数据结构
struct platform_device { const char *name; //设备名称 int id; //设备ID bool id_auto; //布尔变量指定是否自动赋予ID struct device dev; //真正设备数据结构 u32 num_resources; struct resource *resource; //描述一个地址资源或中断资源 const struct platform_device_id *id_entry; /* MFD cell pointer */ struct mfd_cell *mfd_cell;
struct resource { resource_size_t start; //资源开始的位置,如果是IO地址资源,就是起始物理地址,如果是中断资源,就是中断号; resource_size_t end; //资源结束的位置,如果是IO地址地址,就是映射的最后一个物理地址,如果是中断资源,就不用填 const char *name; //个资源的名字 unsigned long flags; //资源类型,提取函数在寻找资源的时候会对比自己传入的参数和这个成员,这些宏在"ioport.h"中进行了定义,比如IORESOURCE_MEM表示这个资源是地址资源,IORESOURCE_IRQ表示这个资源是中断资源 unsigned long desc; struct resource *parent, *sibling, *child; };
//include/linux/ioport.h #define IORESOURCE_BITS 0x000000ff /* Bus-specific bits */ #define IORESOURCE_TYPE_BITS 0x00001f00 /* Resource type */ #define IORESOURCE_IO 0x00000100 /* PCI/ISA I/O ports */ #define IORESOURCE_MEM 0x00000200 #define IORESOURCE_REG 0x00000300 /* Register offsets */ #define IORESOURCE_IRQ 0x00000400 #define IORESOURCE_DMA 0x00000800 #define IORESOURCE_BUS 0x00001000 ... //推荐使用下面宏进行recource初始化 #define DEFINE_RES_IO(_start, _size) #define DEFINE_RES_MEM(_start, _size) #define DEFINE_RES_IRQ(_irq) #define DEFINE_RES_DMA(_dma)
platform_driver数据结构
struct platform_driver { //和普通驱动device_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 (*resume)(struct platform_device *); struct device_driver driver; const struct platform_device_id *id_table; //与of_match_table功能类似 };
设备的注册注销
/** *注册:把指定设备添加到内核中平台总线的设备列表,等待匹配,匹配成功则回调驱动中probe; */ int platform_device_register(struct platform_device *); /** *注销:把指定设备从设备列表中删除,如果驱动已匹配则回调驱动方法和设备信息中的release; */ void platform_device_unregister(struct platform_device *);