当前位置: 首页 > news >正文

drivers/mfd/Mfd-core.c

mfd: multifunction device drivers---多功能设备驱动开发;
A product or device that has multiple functions. An example of this might be a printer that also makes copies, faxes, and scans. Another example is a CD or DVD that might contain multiple applications on the same disk; this may be a Mac and PC version of the same software or media meant to be played on more than one platform. Also called multi function product (MFP), all-in-one.

源码主要是做了一些platform_device的注册和添加删除工作。

 

[cpp]  view plain  copy
 
 在CODE上查看代码片派生到我的代码片
  1. int mfd_add_devices(struct device *parent, int id,  
  2.             struct mfd_cell *cells, int n_devs,  
  3.             struct resource *mem_base,  
  4.             int irq_base)  
  5. {  
  6.     int i;  
  7.     int ret = 0;  
  8.     atomic_t *cnts;  
  9.   
  10.     /* initialize reference counting for all cells */  
  11.     cnts = kcalloc(n_devs, sizeof(*cnts), GFP_KERNEL);  
  12.     if (!cnts)  
  13.         return -ENOMEM;  
  14.   
  15.     for (i = 0; i < n_devs; i++) {  
  16.         atomic_set(&cnts[i], 0);  
  17.         cells[i].usage_count = &cnts[i];  
  18.         ret = mfd_add_device(parent, id, cells + i, mem_base, irq_base); 调用mfd_add_device()  
  19.         if (ret)  
  20.             break;  
  21.     }  
  22.   
  23.     if (ret)  
  24.         mfd_remove_devices(parent);  
  25.   
  26.     return ret;  
  27. }  
  28. EXPORT_SYMBOL(mfd_add_devices);  

在这个函数中,参数cells是数组,个数为参数n_devs。用户调用此函数前初始化了cells部分内容,但其中成员由本函数初始化:

 

 

[cpp]  view plain  copy
 
 在CODE上查看代码片派生到我的代码片
  1. /* 
  2.  * This struct describes the MFD part ("cell"). 
  3.  * After registration the copy of this structure will become the platform data 
  4.  * of the resulting platform_device 
  5.  */  
  6. struct mfd_cell {  //个人理解:注册mfd_cell后等效为platform_device
  7.     const char      *name;       
  8.     int         id;                    
  9.   
  10.     /* refcounting for multiple drivers to use a single cell */  
  11.     atomic_t        *usage_count;    //本函数初始化  
  12.     int         (*enable)(struct platform_device *dev);  
  13.     int         (*disable)(struct platform_device *dev);  
  14.   
  15.     int         (*suspend)(struct platform_device *dev);  
  16.     int         (*resume)(struct platform_device *dev);  
  17.   
  18.     /* platform data passed to the sub devices drivers */  
  19.     void            *platform_data;  
  20.     size_t          pdata_size;  
  21.   
  22.     /* 
  23.      * These resources can be specified relative to the parent device. 
  24.      * For accessing hardware you should use resources from the platform dev 
  25.      */  
  26.     int         num_resources;  
  27.     const struct resource   *resources;  
  28.   
  29.     /* don't check for resource conflicts */  
  30.     bool            ignore_resource_conflicts;  
  31.   
  32.     /* 
  33.      * Disable runtime PM callbacks for this subdevice - see 
  34.      * pm_runtime_no_callbacks(). 
  35.      */  
  36.     bool            pm_runtime_no_callbacks;  
  37. };  

再来看mfd_add_device()

 

 

[cpp]  view plain  copy
 
 在CODE上查看代码片派生到我的代码片
  1. static int mfd_add_device(struct device *parent, int id,  
  2.               const struct mfd_cell *cell,  
  3.               struct resource *mem_base,  
  4.               int irq_base)  
  5. {  
  6.     struct resource *res;  
  7.     struct platform_device *pdev;  
  8.     int ret = -ENOMEM;  
  9.     int r;  
  10.   
  11.     pdev = platform_device_alloc(cell->name, id + cell->id); //申请pdev内存并初始化name和id  
  12.     if (!pdev)  
  13.         goto fail_alloc;  
  14.   
  15.     res = kzalloc(sizeof(*res) * cell->num_resources, GFP_KERNEL);  
  16.     if (!res)  
  17.         goto fail_device;  
  18.   
  19.     pdev->dev.parent = parent;  
  20.     pdev->dev.type = &mfd_dev_type;  
  21.   
  22.     if (cell->pdata_size) {  //重新分配pdev->dev. platform_data内存并将cell->platform_data赋给它。  
  23.         ret = platform_device_add_data(pdev,  
  24.                     cell->platform_data, cell->pdata_size);  
  25.         if (ret)  
  26.             goto fail_res;  
  27.     }  
  28.   
  29.     ret = mfd_platform_add_cell(pdev, cell); //重新分配pdev->mfd_cell内存并将cell赋给它。  
  30.     if (ret)  
  31.         goto fail_res;  
  32.   
  33. //初始化cell->num_resources 个数量的res将它赋给pdev->resource  
  34.     for (r = 0; r < cell->num_resources; r++) {  
  35.         res[r].name = cell->resources[r].name;  
  36.         res[r].flags = cell->resources[r].flags;  
  37.   
  38.         /* Find out base to use */  
  39.         if ((cell->resources[r].flags & IORESOURCE_MEM) && mem_base) {  
  40.             res[r].parent = mem_base;  
  41.             res[r].start = mem_base->start +    //cell中的每个内存start都要加上mem_base->start  
  42.                 cell->resources[r].start;  
  43.             res[r].end = mem_base->start +  
  44.                 cell->resources[r].end;  
  45.         } else if (cell->resources[r].flags & IORESOURCE_IRQ) {  
  46.             res[r].start = irq_base +           //每个cell中的irq都要加上irq_base。  
  47.                 cell->resources[r].start;  
  48.             res[r].end   = irq_base +  
  49.                 cell->resources[r].end;  
  50.         } else {  
  51.             res[r].parent = cell->resources[r].parent;  
  52.             res[r].start = cell->resources[r].start;  
  53.             res[r].end   = cell->resources[r].end;  
  54.         }  
  55.   
  56.         if (!cell->ignore_resource_conflicts) {  
  57.             ret = acpi_check_resource_conflict(&res[r]);  
  58.             if (ret)  
  59.                 goto fail_res;  
  60.         }  
  61.     }  
  62.   
  63.     ret = platform_device_add_resources(pdev, res, cell->num_resources);//将多个res赋给pdev  
  64.     if (ret)  
  65.         goto fail_res;  
  66.   
  67.     ret = platform_device_add(pdev); //添加一个platform_device到系统,这时在dev的驱动中会使用这些res数据。  
  68.     if (ret)  
  69.         goto fail_res;  
  70.   
  71.     if (cell->pm_runtime_no_callbacks)  
  72.         pm_runtime_no_callbacks(&pdev->dev);  
  73.   
  74.     kfree(res);  
  75.   
  76.     return 0;  
  77.   
  78. fail_res:  
  79.     kfree(res);  
  80. fail_device:  
  81.     platform_device_put(pdev);  
  82. fail_alloc:  
  83.     return ret;  
  84. }  



转载于:https://www.cnblogs.com/Ph-one/p/5785054.html

相关文章:

  • LInux ugo权限详解[修]
  • Camera 图像处理原理分析
  • camera isp
  • isp和3a的联系与区别是什么?
  • ihalcon网站
  • Android系统中 setprop,getprop,watchprops命令的使用
  • Linux/Unix里,ln -s
  • ubuntu下环境变量
  • ubuntu /etc/profile和/etc/environment的比较
  • 【图像处理】ISP 图像传感器camera原理
  • 什么是RAW数据?
  • linux设备驱动编写_tasklet机制
  • hrtimer和work工作队列的使用
  • nautilus-open-terminal很有用的插件--鼠标右键打开终端
  • userdebug版本开机串口log打开
  • IE9 : DOM Exception: INVALID_CHARACTER_ERR (5)
  • -------------------- 第二讲-------- 第一节------在此给出链表的基本操作
  • 5分钟即可掌握的前端高效利器:JavaScript 策略模式
  • ComponentOne 2017 V2版本正式发布
  • JS专题之继承
  • JWT究竟是什么呢?
  • Netty 4.1 源代码学习:线程模型
  • PaddlePaddle-GitHub的正确打开姿势
  • 干货 | 以太坊Mist负责人教你建立无服务器应用
  • 回流、重绘及其优化
  • 前端之Sass/Scss实战笔记
  • 线性表及其算法(java实现)
  • 一起来学SpringBoot | 第十篇:使用Spring Cache集成Redis
  • 译自由幺半群
  • 找一份好的前端工作,起点很重要
  • LevelDB 入门 —— 全面了解 LevelDB 的功能特性
  • ​secrets --- 生成管理密码的安全随机数​
  • ​虚拟化系列介绍(十)
  • #Linux(权限管理)
  • (C#)获取字符编码的类
  • (cljs/run-at (JSVM. :browser) 搭建刚好可用的开发环境!)
  • (C语言版)链表(三)——实现双向链表创建、删除、插入、释放内存等简单操作...
  • (超详细)2-YOLOV5改进-添加SimAM注意力机制
  • (附源码)ssm基于微信小程序的疫苗管理系统 毕业设计 092354
  • (十三)Flask之特殊装饰器详解
  • (一)认识微服务
  • .NET 中各种混淆(Obfuscation)的含义、原理、实际效果和不同级别的差异(使用 SmartAssembly)
  • .NET:自动将请求参数绑定到ASPX、ASHX和MVC(菜鸟必看)
  • .NET6使用MiniExcel根据数据源横向导出头部标题及数据
  • .NetCore Flurl.Http 升级到4.0后 https 无法建立SSL连接
  • .NET的数据绑定
  • .stream().map与.stream().flatMap的使用
  • :not(:first-child)和:not(:last-child)的用法
  • ??如何把JavaScript脚本中的参数传到java代码段中
  • @GlobalLock注解作用与原理解析
  • @ModelAttribute 注解
  • @WebServiceClient注解,wsdlLocation 可配置
  • [ vulhub漏洞复现篇 ] ECShop 2.x / 3.x SQL注入/远程执行代码漏洞 xianzhi-2017-02-82239600
  • [Android Pro] Notification的使用
  • [dart学习]第四篇:函数