Android平台上PMEM的使用及Platform设备注册(二)_pmem.h-程序员宅基地

技术标签: 8 Android开发  

https://blog.csdn.net/gabbzang/article/details/20708425

三、注册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/

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Windgs_YF/article/details/104041187

智能推荐

jax-ws和jax-rs_使用JAX-RS和Spring构建HATEOAS API-程序员宅基地

文章浏览阅读119次。jax-ws和jax-rs 在我以前的博客文章中,我展示了如何使用Spring Boot配置Jersey多么容易。 我对Spring Boot和Jersey的探索并未结束,我研究了在Spring Boot应用程序中将Spring HATEOAS与Jersey一起使用的可能性。 Spring HATEOS允许创建遵循HATEOAS原理的REST表示形式,并且(截至撰写本文时)具有使用链接的基本J..._jax.ws.rs demo

Ubuntu新手入门全攻略_ub社区怎么进-程序员宅基地

文章浏览阅读10w+次,点赞48次,收藏523次。Ubuntu可以说是Linux系统的一面旗帜,相比于大多数发行版,美观易用,具有强大的社区支持,因而也成为了新手入门Linux系统的一个不错选择(再深入点的CentOS之类的就另说了)。笔者在尝试Ubuntu系统的时候遇到了若干问题花了一些时间才解决,本文主要讲解这些Ubuntu入门可能会遇到的问题,有深有浅,欢迎批评指正。_ub社区怎么进

智慧美业系统v6.4.0 营销 O2O 美容_智慧美业系统源码-程序员宅基地

文章浏览阅读214次。【优化】小程序端商品显示。【优化】收银端数据显示。_智慧美业系统源码

定义一个数组,输出数组中的最大值_创建一维数组arr[],将数组中最大的元素输出-程序员宅基地

文章浏览阅读1.1k次。输出数组最大值_创建一维数组arr[],将数组中最大的元素输出

通俗解释 方差,标准差,协方差以及相关系数_方差大白话解释-程序员宅基地

文章浏览阅读1.1w次,点赞16次,收藏29次。本文转载自:http://blog.csdn.net/yangdashi888/article/details/52397990 https://www.zhihu.com/question/208520041、方差,标准差定义 很显然,均值描述的是样本集合的中间点,它告诉我们的信息是很有限的,而标准差给我们描述的则是样本集合的各个样本点到均值的距离之平均。以这两个集_方差大白话解释

Java集合之aHshset_javahdt-程序员宅基地

文章浏览阅读187次。【代码】上周讲课的总结。_javahdt

随便推点

Ubuntu16.04安装CodeChecker及CodeChecker服务器的配置_ubuntu codechecker-程序员宅基地

文章浏览阅读1.3k次。Ubuntu安装CodeChecker首先环境使用的是Ubuntu16.04发行版其自带的python版本为3.5,gcc版本为5CodeChecker需要python版本>=3.6经过实验,发现Ubuntu版本过低时,如果不能按照如下方法使用apt直接安装python,那么需要使用gcc对python源码进行进行编译安装。此时gcc版本应至少>=5。否则无法对python进行编译安装(至少gcc4.8.1不行)因此如果需要gcc降级,那么务必在安装CodeChecker安装结束后再_ubuntu codechecker

3.Mapper.xml 详解-程序员宅基地

文章浏览阅读1.6w次,点赞12次,收藏108次。文章目录Mapper.xml 详解1. parameterType2. resultType3. 级联查询3.1 一对多3.2 多对多Mapper.xml 详解MyBatis 主要有两个的配置文件:config.xml 和 Mapper.xml,这两个配置文件可以自定义文件名。config.xml 是全局配置文件,主要配置 MyBatis 的数据源(DataSource),事务管理(TransactionManager)以及打印 SQL 语句,开启二级缓存,注册 Mapper.xml 等。Map_mapper.xml

ensp提示抓包工具wireshark配置路径不正确_ensp抓包工具wireshark配置路径不正确-程序员宅基地

文章浏览阅读2.4w次,点赞30次,收藏61次。太久没有使用模拟器,今天突然打不开抓包工具了,莫慌,马上上解决方法。出现这个问题的原因可能是因为各位老铁们在升级软件的时候位置变了,或者是先安装了ensp后面才安装的wireshark。解决方法:单击 eNSP的菜单 - 工具 - 选项 - 工具设置,在引用工具里面 设置你安装的 wireshark 路径。有的老铁可能已经忘记了安装路径,这边告知大家如何找到安装路径,先找到电脑里面的wireshark请注意看一下是不是真实的安装路径如果不是请同理选中快捷方式右键选中打开文件所在位置下_ensp抓包工具wireshark配置路径不正确

全网疯传,阿里 P8 技术官的架构笔记外泄:微服务分布式架构实践手册_阿里p8分布式架构笔记-程序员宅基地

文章浏览阅读132次。阿里 P8 大佬的架构笔记:微服务分布式架构实践手册从企业的真实需求出发,理论结合实际,深入讲解 Spring Cloud 微服务和分布式系统的知识。_阿里p8分布式架构笔记

宏基台式计算机编号,ACER如何查询型号名称序列号SNID?-程序员宅基地

文章浏览阅读5.5k次。本帖最后由 fs_2010 于 2012-10-6 21:58 编辑Ps:一年一度的国庆,如今的国庆长假都过了一大半,也相信友友们买到了算了心中的一台本本了,一刚刚开始购买的时候,有许多的方方面面的东西都没有注意到多少,当时在估计也就是为这一个价格而下手的,哪一台本本到手了之后,怎么才能让自己安下心来使用呢?怎么查看出厂日期的?还有保修方面的等等原因……所以提供一点点的信息,让猿们参考参考、、、注..._查看snid

Matlab导出图片模糊的解决办法_matlab画出的三维图,在保存到latex的时候,将渲染器改为painters后为什么图中的虚-程序员宅基地

文章浏览阅读4.3w次,点赞34次,收藏48次。问题描述之前发现,Matlab画图如果figure内的线条过多,或者散点过多,导出的图片会模糊,且图片并非矢量图。试过eps和pdf格式,均是非常模糊,而且用编辑器直接打开eps文本可见大段乱码。解决方案解决方法就在于figure的导出设置中。在设置的渲染选项中,渲染器有两个,分别为painters和OpenGL,分别为矢量格式输出和位图输出。默认情况下,Matlab会..._matlab画出的三维图,在保存到latex的时候,将渲染器改为painters后为什么图中的虚