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_MEMIORESOURCE_IRQ两种资源,其IORESOURCE_MEM的起始地址为0xC0000000,结束地址为0xC0020000IORESOURCE_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[email protected]

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

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

 

你可能感兴趣的:(android,struct,平台,resources,Numbers,structure)