Linux SD卡驱动开发(五) —— SD 卡驱动分析Core补充篇

 Core层中有两个重要函数 mmc_alloc_host 用于构造host,前面已经学习过,这里不再阐述;另一个就是 mmc_add_host,用于注册host

     前面探测函数s3cmci_probe,现在就来回顾一下这个函数的作用。先简要的概括一下这个函数的功能:

1、s3cmci_probe 最重要的作用是host 的注册,那么首先必须构造出一个host,这个host就是通过s3cmci_alloc_host函数来构造出来的,它是一个struct s3cmci_host类型的结构体。同时,也通过mmc_alloc_host函数构造了一个struct mmc_host的结构体变量mmc。

2、初始化host的时钟,设置host的gpio等等其他一些“乱七八糟”的参数初始化(前面分析过)。

3、通过s3cmci_add_host函数来注册host。


下面是这个函数的详细分析

mmc_add_host [core/host.c]

[cpp] view plaincopy
在CODE上查看代码片派生到我的代码片
  1. /** 
  2.  *  mmc_add_host - initialise host hardware 
  3.  *  @host: mmc host 
  4.  * 
  5.  *  Register the host with the driver model. The host must be 
  6.  *  prepared to start servicing requests before this function 
  7.  *  completes. 
  8.  */  
  9. int mmc_add_host(struct mmc_host *host)  
  10. {  
  11.     int err;  
  12.   
  13.     WARN_ON((host->caps & MMC_CAP_SDIO_IRQ) &&  
  14.         !host->ops->enable_sdio_irq);  
  15.   
  16.     err = device_add(&host->class_dev);  
  17.     if (err)  
  18.         return err;  
  19.   
  20.     led_trigger_register_simple(dev_name(&host->class_dev), &host->led);  
  21.   
  22. #ifdef CONFIG_DEBUG_FS  
  23.     mmc_add_host_debugfs(host);  
  24. #endif  
  25.     mmc_host_clk_sysfs_init(host);  
  26.   
  27.     mmc_start_host(host);  
  28.     register_pm_notifier(&host->pm_notify);  
  29.   
  30.     return 0;  
  31. }  

     我们看一下mmc_add_host这个函数,它的功能就是通过device_add函数将设备注册进linux设备模型,最终的结果就是在sys/bus/platform/devices目录下能见到s3c-sdhci.1,s3c-sdhci.2,s3c-sdhci.3设备节点。

     重点是mmc_start_host(host);这也是core层的函数具体的方法如下:

mmc_start_host  [core/core.c]

[cpp] view plaincopy
在CODE上查看代码片派生到我的代码片
  1. void mmc_start_host(struct mmc_host *host)  
  2. {  
  3.     host->f_init = max(freqs[0], host->f_min);  
  4.     host->rescan_disable = 0;  
  5.     if (host->caps2 & MMC_CAP2_NO_PRESCAN_POWERUP)  
  6.         mmc_power_off(host);  
  7.     else  
  8.         mmc_power_up(host, host->ocr_avail);  
  9.     _mmc_detect_change(host, 0, false);  
  10. }  

首先来看一下mmc_power_off,内容如下:

[core/core.c]

[cpp] view plaincopy
在CODE上查看代码片派生到我的代码片
  1. void mmc_power_off(struct mmc_host *host)  
  2. {  
  3.     if (host->ios.power_mode == MMC_POWER_OFF)  
  4.         return;  
  5.   
  6.     mmc_host_clk_hold(host);  
  7.   
  8.     host->ios.clock = 0;  
  9.     host->ios.vdd = 0;  
  10.   
  11.     if (!mmc_host_is_spi(host)) {  
  12.         host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;  
  13.         host->ios.chip_select = MMC_CS_DONTCARE;  
  14.     }  
  15.     host->ios.power_mode = MMC_POWER_OFF;  
  16.     host->ios.bus_width = MMC_BUS_WIDTH_1;  
  17.     host->ios.timing = MMC_TIMING_LEGACY;  
  18.     mmc_set_ios(host);  
  19.   
  20.     /* 
  21.      * Some configurations, such as the 802.11 SDIO card in the OLPC 
  22.      * XO-1.5, require a short delay after poweroff before the card 
  23.      * can be successfully turned on again. 
  24.      */  
  25.     mmc_delay(1);  
  26.   
  27.     mmc_host_clk_release(host);  
  28. }  

     关心最多的就是host->iOS当中的内容,前段的赋值真正作用在硬件上是调用host层向上提供的struct mmc_host_ops接口。这里18行实际上就是完成了这个工作。

     回到mmc_start_host,mmc_detect_change(host, 0) 看名字就知道是用来检测SD卡的,内容如下:

mmc_detect_change(host, 0)

[core/core.c]

[cpp] view plaincopy
在CODE上查看代码片派生到我的代码片
  1. static void _mmc_detect_change(struct mmc_host *host, unsigned long delay,  
  2.                 bool cd_irq)  
  3. {  
  4. #ifdef CONFIG_MMC_DEBUG  
  5.     unsigned long flags;  
  6.     spin_lock_irqsave(&host->lock, flags);  
  7.     WARN_ON(host->removed);  
  8.     spin_unlock_irqrestore(&host->lock, flags);  
  9. #endif  
  10.   
  11.     /* 
  12.      * If the device is configured as wakeup, we prevent a new sleep for 
  13.      * 5 s to give provision for user space to consume the event. 
  14.      */  
  15.     if (cd_irq && !(host->caps & MMC_CAP_NEEDS_POLL) &&  
  16.         device_can_wakeup(mmc_dev(host)))  
  17.         pm_wakeup_event(mmc_dev(host), 5000);  
  18.   
  19.     host->detect_change = 1;  
  20.     mmc_schedule_delayed_work(&host->detect, delay);  
  21. }  

除了20行说了句人话,其他的百分之九十九的都是废话。曾几何时我们说过内核有个延时工作队列,没错就是他了。当然这可不是随便拿来玩的,与之对应的初始化前面已经说过即INIT_DELAYED_WORK(&host->detect, mmc_rescan);好了20 行作用的结果估计大家都能猜到了,就是延时delay 时间后就会去调用mmc_rescan了。前面我们传递的delay=0,那么这里就没有延时了,既然驱动都等不及要rescan了,我们也就不再卖关子了,直接mmc_rescan它的功能就是扫描所插入的卡

这就回到了Linux SD卡驱动开发(三) —— SD 卡驱动分析CORE篇 了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/401906.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

navicat连接oracle 报 ORA-12737 set CHS16GBK

2019独角兽企业重金招聘Python工程师标准>>> 1首 先,我们打开“工具”-->"选项"菜单,见到如下界面,依据OCI library(oci.dll) 路径,导航到 navicat oci 目录下,备份里面的文件(通过…

Linux SD卡驱动开发(六) —— SD卡启动过程总体分析

一、工作流程 mmc驱动主要文件包括 drivers/mmc/card/block.c drivers/mmc/card/queue.c drivers/mmc/core/core.c drivers/mmc/core/host.c drivers/mmc/core/ 内核启动时,首先执行core/core.c的mmc_init,注册mmc、sd总线,以及一个host clas…

svn怎么上传文件 — 百度经验无耻推广

2019独角兽企业重金招聘Python工程师标准>>> svn怎么上传文件 — 欢乐地点进去捧场 PS:觉得笔者太无耻,直接在下方评论抨击 转载于:https://my.oschina.net/cenqingbo/blog/212284

apache 重写和虚拟目录配置

要求:假如我请求一个地址:www.lxy.com/news-sport-id123.html转成:www.lxy.com/show.php?catenews&classsport&id123步骤:①首先我们需要在apache中启用rewrite模块打开apache的httpd.conf文件,找到#LoadModu…

JavaScript代码片段

简介:本文收集了我常用的JavaScript代码片段,欢迎提意见! 大灰狼边敲门边说:“小兔子乖乖,把门儿开开!” 小兔子听到后,连忙去开门:“来喽!” 兔妈妈对小兔子喊道&#x…

路由器开发(一)—— 路由器硬件结构及软件体系

一、路由器的硬件构成 路由器主要由以下几个部分组成:输入/输出接口部分、包转发或交换结构部分(switching fabric)、路由计算或处理部分。如图所示 图1 路由器的基本组成 输入端口是物理链路和输入包的进口处。端口通常由线卡提供&#…

路由器开发(二)—— 路由器工作原理

当信息需要在两个网络之间传输时,常用路由器这种互连设备来负责数据的传输。路由器的主要工作是:路径的决定和数据包的转发(从路由器一个接口输入,然后选择合适接口输出);维护路由表。 路由器工作的方式非常…

Android颜色渐变的分隔线(ListView)

2019独角兽企业重金招聘Python工程师标准>>> shape.xml xx <?xml version"1.0" encoding"utf-8"?><shape xmlns:android"http://schemas.android.com/apk/res/android" > <gradient android:startColor&qu…

项目实践中Linux集群的总结和思考

2019独角兽企业重金招聘Python工程师标准>>> 前言&#xff1a;作为一名Linux/unix系统工程师、项目实施工程师&#xff0c;这几年一直在涉及到对外项目&#xff0c;经手过许多小中型网站的架构&#xff0c;F5、LVS及Nginx接触的都比较多&#xff0c;我想一种比较通俗…

路由器基础知识详解

第一章 网络互联 网络的根本目的非常简单&#xff1a;方便人们交换所获得的信息。但是网络的应用需求非常复杂&#xff1a;有的用户希望高带宽&#xff0c;但并不要求很长的传输距离&#xff1b;有的用户要求很长的距离&#xff0c;但对带宽要求很低&#xff1b;有的对网络的…

事务与锁机制

2019独角兽企业重金招聘Python工程师标准>>> 事务定义&#xff1a; 访问并可能更新数据库&#xff1a;一句或一组SQL&#xff0c;或者是一段程序&#xff0c;反正update了就是事务 ACID的4原则&#xff1a; 原子性&#xff1a; 一致性&#xff1a; 隔离性&#xff1…

路由器 VS OSI七层模型

OSI Open Source Initiative&#xff08;简称OSI&#xff0c;有译作开放源代码促进会、开放原始码组织&#xff09;是一个旨在推动开源软件发展的非盈利组织。OSI参考模型&#xff08;OSI/RM&#xff09;的全称是开放系统互连参考模型&#xff08;Open System Interconnection …

Linux Wireless架构总结

1、无线网络驱动(ath9k_htc) ath9k_htc是一个基于USB接口的SoftMAC无线网络适配器。为了其驱动能正常工作&#xff0c;首先必须调用usb_register来注册驱动定义的usb_driver&#xff0c;以借助USB Core的力量来处理与USB协议相关的事件。其代码如下&#xff1a;[cpp] view plai…

MySQL 日志文件 说明

MySQL 5.5 官方文档上有关日志的分类&#xff1a;By default, nologs are enabled. The following log-specific sections provide information about the server options that enable logging.--默认情况下&#xff0c;没有启动任何log&#xff0c;可以通过如下log 选项来启动…

Linux 下wifi 驱动开发(四)—— USB接口WiFi驱动浅析

前面学习了SDIO接口的WiFi驱动&#xff0c;现在我们来学习一下USB接口的WiFi驱动&#xff0c;二者的区别在于接口不同。而USB接口的设备驱动&#xff0c;我们前面也有学习&#xff0c;比如USB摄像头驱动、USB鼠标驱动&#xff0c;同样都符合LinuxUSB驱动结构&#xff1a; USB设…

Linux 下wifi 驱动开发(三)—— SDIO接口WiFi驱动浅析

SDIO-Wifi模块是基于SDIO接口的符合wifi无线网络标准的嵌入式模块&#xff0c;内置无线网络协议IEEE802.11协议栈以及TCP/IP协议栈&#xff0c;能够实现用户主平台数据通过SDIO口到无线网络之间的转换。SDIO具有传输数据快&#xff0c;兼容SD、MMC接口等特点。 对于SDIO接口的w…

Erlang并发机制 –进程调度

2019独角兽企业重金招聘Python工程师标准>>> Erlang调度器主要完成对Erlang进程的调度&#xff0c;它是Erlang实现软件实时和进程之间公平使用CPU的关键。Erlang运行时&#xff0c;有4种任务需要被调度&#xff1a;进程&#xff0c;Port&#xff0c;Linked-in drive…

Linux 下wifi 驱动开发(二)—— WiFi模块浅析

一、什么是wifi 模块 百度百科上这样定义&#xff1a; Wi-Fi模块又名串口Wi-Fi模块&#xff0c;属于物联网传输层&#xff0c;功能是将串口或TTL电平转为符合Wi-Fi无线网络通信标准的嵌入式模块&#xff0c;内置无线网络协议IEEE802.11b.g.n协议栈以及TCP/IP协议栈。传统的硬件…

Linux 下wifi 驱动开发(一)—— WiFi基础知识解析

一、WiFi相关基础概念 1、什么是wifi 我们看一下百度百科是如何定义的&#xff1a; Wi-Fi是一种可以将个人电脑、手持设备&#xff08;如pad、手机&#xff09;等终端以无线方式互相连接的技术&#xff0c;事实上它是一个高频无线电信号。[1] 无线保真是一个无线网络通信技术…

Linux 网络设备驱动开发(一) —— linux内核网络分层结构

Linux内核对网络驱动程序使用统一的接口&#xff0c;并且对于网络设备采用面向对象的思想设计。 Linux内核采用分层结构处理网络数据包。分层结构与网络协议的结构匹配&#xff0c;既能简化数据包处理流程&#xff0c;又便于扩展和维护。 一、内核网络结构 在Linux内核中&#…