Android平台上PMEM的使用及Platform设备注册(二)

三、注册PMEM设备

这里我们除了描述PMEM设备,还将注册一个拥有memory空间和IRQ资源的示例设备example_device。

对于example_device,定义如下结构体:

static struct resource example_resources[] = {

[0] = {

.start  = 0xC0000000,

.end    = 0xC0020000,

.flags  = IORESOURCE_MEM,

},

[1] = {

.start  = 30,

.end    = 30,

.flags  = IORESOURCE_IRQ,

},

};

static struct platform_device example_device = {

.name           = "example",

.id             = 0,

.num_resources  = ARRAY_SIZE(example_resources),

.resource       = example_resources,

};

example_device设备拥有IORESOURCE_MEM和IORESOURCE_IRQ两种资源,其IORESOURCE_MEM的起始地址为0xC0000000,结束地址为0xC0020000,IORESOURCE_IRQ的中断号为30。

对于PMEM设备,我们先要介绍一下结构体android_pmem_platform_data。它被定义在文件/kernel/include/linux/android_pmem.h中。其定义为:

struct android_pmem_platform_data

{

const char* name;

/* starting physical address of memory region */

unsigned long start;

/* size of memory region */

unsigned long size;

/* set to indicate the region should not be managed with an allocator */

unsigned no_allocator;

/* set to indicate maps of this region should be cached, if a mix of

* cached and uncached is desired, set this and open the device with

* O_SYNC to get an uncached region */

unsigned cached;

/* The MSM7k has bits to enable a write buffer in the bus controller*/

unsigned buffered;

};

我们为PMEM设备定义如下结构体:

static struct android_pmem_platform_data android_pmem0_pdata = {

.name = "pmem0",

.start = PMEM_0_BASE,

.size = PMEM_0_SIZE,

.no_allocator = 0,

.cached = 1,

};

static struct android_pmem_platform_data android_pmem1_pdata = {

.name = "pmem1",

.start = PMEM_1_BASE,

.size = PMEM_1_SIZE,

.no_allocator = 0,

.cached = 1,

};

struct platform_device android_pmem0_device = {

.name = "android_pmem",

.id = 0,

.dev = { .platform_data = &android_pmem0_pdata },

};

struct platform_device android_pmem1_device = {

.name = "android_pmem",

.id = 1,

.dev = { .platform_data = &android_pmem1_pdata },

};

然后将这几个设备结构体放置到一个platform_device的数组中,

static struct platform_device *devices[] __initdata = {

&example_device,

&android_pmem0_device,

&android_pmem1_device,

};

最后通过调用函数platform_add_devices()向系统中添加这些设备。

static void __init androidphone_init(void)

{

……

platform_add_devices(devices, ARRAY_SIZE(devices));

……

}

函数platform_add_devices()内部调用platform_device_register( )进行设备注册。要注意的是,这里的platform_device设备的注册过程必须在相应设备驱动加载之前被调用,即执行platform_driver_register()之前,原因是驱动注册时需要匹配内核中所有已注册的设备名。

函数platform_add_devices()定义在文件/kernel/driver/base/platform.c中,

/**

* platform_add_devices - add a numbers of platform devices

* @devs: array of platform devices to add

* @num: number of platform devices in array

*/

int platform_add_devices(struct platform_device **devs, int num)

{

int i, ret = 0;

for (i = 0; i < num; i++) {

ret = platform_device_register(devs[i]);

if (ret) {

while (--i >= 0)

platform_device_unregister(devs[i]);

break;

}

}

return ret;

}

EXPORT_SYMBOL_GPL(platform_add_devices);

最后,需要说明的结构体是platform_driver,它的原型定义,在

/kernel/include/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 (*resume)(struct platform_device *);

struct device_driver driver;

struct platform_device_id *id_table;

};

内核提供的platform_driver结构体的注册函数为platform_driver_register(),其原型定义在/kernel/driver/base/platform.c文件中,具体实现代码如下:

/**

* platform_driver_register

* @drv: platform driver structure

*/

int platform_driver_register(struct platform_driver *drv)

{

drv->driver.bus = &platform_bus_type;

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;

return driver_register(&drv->driver);

}

EXPORT_SYMBOL_GPL(platform_driver_register);

如果想深入了解Platform机制,可以参考下面的文章:

Linux Platform驱动程序框架解析

http://www.linuxidc.com/Linux/2011-01/31291.htm

Linux内核驱动的的platform机制

http://intq.blog.163.com/blog/static/671231452010124112546491/

E-mail:wxiaozhe@163.com

QQ:1226062415
Date:2011/5/14
Blog:http://blog.csdn.net/wxzking

欢迎交流,欢迎转载,转载时请保留以上信息。

上一篇:Android SDK Manager 无法更新SDK


下一篇:玩转大数据:深入浅出大数据挖掘技术(Apriori算法、Tanagra工具、决策树)