platform设备的添加流程.doc
- 文档编号:231625
- 上传时间:2022-10-07
- 格式:DOC
- 页数:20
- 大小:120KB
platform设备的添加流程.doc
《platform设备的添加流程.doc》由会员分享,可在线阅读,更多相关《platform设备的添加流程.doc(20页珍藏版)》请在冰豆网上搜索。
platform设备的添加流程
今天我以fb设备的注册过程来分析platform设备的添加流程
platform总线是kernel中最近加入的一种虚拟总线,它被用来连接处在仅有最少基本组件的总线上的那些设备.这样的总线包括许多片上系统上的那些用来整合外设的总线,也包括一些"古董"PC上的连接器;但不包括像PCI或USB这样的有庞大正规说明的总线.
平台设备
~~~~~~
平台设备通常指的是系统中的自治体,包括老式的基于端口的设备和连接外设总线的北桥(hostbridges),以及集成在片上系统中的绝大多数控制器.它们通常拥有的一个共同特征是直接编址于CPU总线上.即使在某些罕见的情况下,平台设备会通过某段其他类型的总线连入系统,它们的寄存器也会被直接编址.平台设备会分到一个名称(用在驱动绑定中)以及一系列诸如地址和中断请求号(IRQ)之类的资源.
那什么情况可以使用platformdriver机制编写驱动呢?
我的理解是只要和内核本身运行依赖性不大的外围设备(换句话说只要不在内核运行所需的一个最小系统之内的设备),相对独立的,拥有各自独自的资源(addressesandIRQs),都可以用platform_driver实现。
如:
lcd,usb,uart等,都可以用platfrom_driver写,而timer,irq等最小系统之内的设备则最好不用platfrom_driver机制,实际上内核实现也是这样的。
下面继续我们的分析过程。
1首先要定义一个platform_device,
我们先来看一下platform_device结构的定义,如下所示:
//include/linux/platform_device.h:
16structplatform_device{
17 constchar *name;
18 u32 id;
19 structdevice dev;
20 u32 num_resources;
21 structresource*resource;
22};
下面是对应的FB设备的变量定义
//arch/arm/mach-pxa/generic.c
229staticstructplatform_devicepxafb_device={
230 .name ="pxa2xx-fb",
231 .id =-1,
232 .dev ={
233 .platform_data =&pxa_fb_info,
234 .dma_mask =&fb_dma_mask,
235 .coherent_dma_mask=0xffffffff,
236 },
237 .num_resources =ARRAY_SIZE(pxafb_resources),
238 .resource =pxafb_resources,
239};
由上可以看出,name成员表示设备名,系统正是通过这个名字来与驱动绑定的,所以驱动里面相应的设备名必须与该项相符合;id表示设备编号,id的值为-1表示只有一个这样的设备。
该结构中比较重要的一个成员就是resource,Linux设计了这个通用的数据结构来描述各种I/O资源(如:
I/O端口、外设内存、DMA和IRQ等)。
它的定义如下:
//include/linux/ioport.h:
16structresource{
17 constchar*name;
18 unsignedlongstart,end;
19 unsignedlongflags;
20 structresource*parent,*sibling,*child;
21};
下面关于这方面的内容,参考了
structresource是linux对挂接在4G总线空间上的设备实体的管理方式。
一个独立的挂接在cpu总线上的设备单元,一般都需要一段线性的地址空间来描述设备自身,linux是怎么管理所有的这些外部"物理地址范围段",进而给用户和linux自身一个比较好的观察4G总线上挂接的一个个设备实体的简洁、统一级联视图的呢?
linux采用structresource结构体来描述一个挂接在cpu总线上的设备实体(32位cpu的总线地址范围是0~4G):
resource->start 描述设备实体在cpu总线上的线性起始物理地址;
resource->end 描述设备实体在cpu总线上的线性结尾物理地址;
resource->name 描述这个设备实体的名称,这个名字开发人员可以随意起,但最好贴切;
resource->flag 描述这个设备实体的一些共性和特性的标志位;
只需要了解一个设备实体的以上4项,linux就能够知晓这个挂接在cpu总线的上的设备实体的基本使用情况,也就是[resource->start,resource->end]这段物理地址现在是空闲着呢,还是被什么设备占用着呢?
linux会坚决避免将一个已经被一个设备实体使用的总线物理地址区间段[resource->start,resource->end],再分配给另一个后来的也需要这个区间段或者区间段内部分地址的设备实体,进而避免设备之间出现对同一总线物理地址段的重复引用,而造成对唯一物理地址的设备实体二义性.
以上的4个属性仅仅用来描述一个设备实体自身,或者是设备实体可以用来自治的单元,但是这不是linux所想的,linux需要管理4G物理总线的所有空间,所以挂接到总线上的形形色色的各种设备实体,这就需要链在一起,因此resource结构体提供了另外3个成员:
指针parent、sibling和child:
分别为指向父亲、兄弟和子资源的指针,它们的设置是为了以一种树的形式来管理各种I/O资源,以rootsource为例,root->child(*pchild)指向root所有孩子中地址空间最小的一个;pchild->sibling是兄弟链表的开头,指向比自己地址空间大的兄弟。
属性flags是一个unsignedlong类型的32位标志值,用以描述资源的属性。
比如:
资源的类型、是否只读、是否可缓存,以及是否已被占用等。
下面是一部分常用属性标志位的定义
//include/linux/ioport.h:
29/*
30*IOresourceshavethesedefinedflags.
31*/
32#defineIORESOURCE_BITS 0x000000ff /*Bus-specificbits*/
33
34#defineIORESOURCE_IO 0x00000100 /*Resourcetype*/
35#defineIORESOURCE_MEM 0x00000200
36#defineIORESOURCE_IRQ 0x00000400
37#defineIORESOURCE_DMA 0x00000800
38
39#defineIORESOURCE_PREFETCH 0x00001000 /*Nosideeffects*/
40#defineIORESOURCE_READONLY 0x00002000
41#defineIORESOURCE_CACHEABLE 0x00004000
42#defineIORESOURCE_RANGELENGTH 0x00008000
43#defineIORESOURCE_SHADOWABLE 0x00010000
44#defineIORESOURCE_BUS_HAS_VGA 0x00080000
45
46#defineIORESOURCE_DISABLED 0x10000000
47#defineIORESOURCE_UNSET 0x20000000
48#defineIORESOURCE_AUTO 0x40000000
49#defineIORESOURCE_BUSY 0x80000000 /*Driverhasmarkedthisresourcebusy*/
下面来看我们所使用的LCD所占用的资源,如下所示:
//arch/arm/mach-pxa/generic.c
staticstructresourcepxafb_resources[]={
[0]={
.start =0x44000000,
.end =0x4400ffff,
.flags =IORESOURCE_MEM,
},
[1]={
.start =IRQ_LCD,
.end =IRQ_LCD,
.flags =IORESOURCE_IRQ,
},
};
由上可知LCD占用的资源包括两类,一类是MEM类型,一类是IRQ类型。
MEME类型资源对应的物理地址范围是0x44000000-0x4400ffff;IRQ类型资源对应的物理地址范围是IRQ_LCD,查看相应的定义:
//include/asm-arm/arch-pxa/irqs.h:
15#ifdefCONFIG_PXA27x
16#definePXA_IRQ_SKIP 0
17#else
18#definePXA_IRQ_SKIP 7
19#endif
20
21#definePXA_IRQ(x) ((x)-PXA_IRQ_SKIP)
43#defineIRQ_LCD PXA_IRQ(17) /*LCDControllerServiceRequest*/
我们所使用的处理器为PXA255,所以对应的PXA_IRQ_SKIP应该为7,所以IRQ_LCD=10,也就是它对应的中断信号线为10。
设置完了platform_device的相关成员后,下一步就是
2调用platform_add_devices添加设备
首先来看它的定义:
//drivers/base/platform.c:
/**
* platform_add_devices-addanumbersofplatformdevices
* @devs:
arrayofplatformdevicestoadd
* @num:
numberofplatformdevicesinarray
*/
intplatform_add_devices(structplatform_device**devs,intnum)
{
int
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- platform 设备 添加 流程