生活随笔
收集整理的這篇文章主要介紹了
Linux SD卡驱动开发(五) —— SD 卡驱动分析Core补充篇
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
?Core層中有兩個(gè)重要函數(shù)?mmc_alloc_host?用于構(gòu)造host,前面已經(jīng)學(xué)習(xí)過,這里不再闡述;另一個(gè)就是?mmc_add_host,用于注冊(cè)host
? ? ?前面探測(cè)函數(shù)s3cmci_probe,現(xiàn)在就來回顧一下這個(gè)函數(shù)的作用。先簡(jiǎn)要的概括一下這個(gè)函數(shù)的功能:
1、s3cmci_probe?最重要的作用是host 的注冊(cè),那么首先必須構(gòu)造出一個(gè)host,這個(gè)host就是通過s3cmci_alloc_host函數(shù)來構(gòu)造出來的,它是一個(gè)struct s3cmci_host類型的結(jié)構(gòu)體。同時(shí),也通過mmc_alloc_host函數(shù)構(gòu)造了一個(gè)struct mmc_host的結(jié)構(gòu)體變量mmc。
2、初始化host的時(shí)鐘,設(shè)置host的gpio等等其他一些“亂七八糟”的參數(shù)初始化(前面分析過)。
3、通過s3cmci_add_host函數(shù)來注冊(cè)host。
下面是這個(gè)函數(shù)的詳細(xì)分析
mmc_add_host?[core/host.c]
[cpp]?view plaincopy
? ? ? ? ? ? ? ?? int?mmc_add_host(struct?mmc_host?*host)?? {?? ????int?err;?? ?? ????WARN_ON((host->caps?&?MMC_CAP_SDIO_IRQ)?&&?? ????????!host->ops->enable_sdio_irq);?? ?? ????err?=?device_add(&host->class_dev);?? ????if?(err)?? ????????return?err;?? ?? ????led_trigger_register_simple(dev_name(&host->class_dev),?&host->led);?? ?? #ifdef?CONFIG_DEBUG_FS?? ????mmc_add_host_debugfs(host);?? #endif?? ????mmc_host_clk_sysfs_init(host);?? ?? ????mmc_start_host(host);?? ????register_pm_notifier(&host->pm_notify);?? ?? ????return?0;?? }??
? ? ?我們看一下mmc_add_host這個(gè)函數(shù),它的功能就是通過device_add函數(shù)將設(shè)備注冊(cè)進(jìn)linux設(shè)備模型,最終的結(jié)果就是在sys/bus/platform/devices目錄下能見到s3c-sdhci.1,s3c-sdhci.2,s3c-sdhci.3設(shè)備節(jié)點(diǎn)。
? ? ?重點(diǎn)是mmc_start_host(host);這也是core層的函數(shù)具體的方法如下:
mmc_start_host??[core/core.c]
[cpp]?view plaincopy
void?mmc_start_host(struct?mmc_host?*host)?? {?? ????host->f_init?=?max(freqs[0],?host->f_min);?? ????host->rescan_disable?=?0;?? ????if?(host->caps2?&?MMC_CAP2_NO_PRESCAN_POWERUP)?? ????????mmc_power_off(host);?? ????else?? ????????mmc_power_up(host,?host->ocr_avail);?? ????_mmc_detect_change(host,?0,?false);?? }??
首先來看一下mmc_power_off,內(nèi)容如下:
[core/core.c]
[cpp]?view plaincopy
void?mmc_power_off(struct?mmc_host?*host)?? {?? ????if?(host->ios.power_mode?==?MMC_POWER_OFF)?? ????????return;?? ?? ????mmc_host_clk_hold(host);?? ?? ????host->ios.clock?=?0;?? ????host->ios.vdd?=?0;?? ?? ????if?(!mmc_host_is_spi(host))?{?? ????????host->ios.bus_mode?=?MMC_BUSMODE_OPENDRAIN;?? ????????host->ios.chip_select?=?MMC_CS_DONTCARE;?? ????}?? ????host->ios.power_mode?=?MMC_POWER_OFF;?? ????host->ios.bus_width?=?MMC_BUS_WIDTH_1;?? ????host->ios.timing?=?MMC_TIMING_LEGACY;?? ????mmc_set_ios(host);?? ?? ????? ? ? ? ?? ????mmc_delay(1);?? ?? ????mmc_host_clk_release(host);?? }??
? ? ?關(guān)心最多的就是host->iOS當(dāng)中的內(nèi)容,前段的賦值真正作用在硬件上是調(diào)用host層向上提供的struct mmc_host_ops接口。這里18行實(shí)際上就是完成了這個(gè)工作。
? ? ?回到mmc_start_host,mmc_detect_change(host, 0)?看名字就知道是用來檢測(cè)SD卡的,內(nèi)容如下:
mmc_detect_change(host, 0)
[core/core.c]
[cpp]?view plaincopy
static?void?_mmc_detect_change(struct?mmc_host?*host,?unsigned?long?delay,?? ????????????????bool?cd_irq)?? {?? #ifdef?CONFIG_MMC_DEBUG?? ????unsigned?long?flags;?? ????spin_lock_irqsave(&host->lock,?flags);?? ????WARN_ON(host->removed);?? ????spin_unlock_irqrestore(&host->lock,?flags);?? #endif?? ?? ????? ? ? ?? ????if?(cd_irq?&&?!(host->caps?&?MMC_CAP_NEEDS_POLL)?&&?? ????????device_can_wakeup(mmc_dev(host)))?? ????????pm_wakeup_event(mmc_dev(host),?5000);?? ?? ????host->detect_change?=?1;?? ????mmc_schedule_delayed_work(&host->detect,?delay);?? }??
除了20行說了句人話,其他的百分之九十九的都是廢話。曾幾何時(shí)我們說過內(nèi)核有個(gè)延時(shí)工作隊(duì)列,沒錯(cuò)就是他了。當(dāng)然這可不是隨便拿來玩的,與之對(duì)應(yīng)的初始化前面已經(jīng)說過即INIT_DELAYED_WORK(&host->detect, mmc_rescan);好了20 行作用的結(jié)果估計(jì)大家都能猜到了,就是延時(shí)delay 時(shí)間后就會(huì)去調(diào)用mmc_rescan了。前面我們傳遞的delay=0,那么這里就沒有延時(shí)了,既然驅(qū)動(dòng)都等不及要rescan了,我們也就不再賣關(guān)子了,直接mmc_rescan。它的功能就是掃描所插入的卡
這就回到了Linux SD卡驅(qū)動(dòng)開發(fā)(三) —— SD 卡驅(qū)動(dòng)分析CORE篇?了
總結(jié)
以上是生活随笔為你收集整理的Linux SD卡驱动开发(五) —— SD 卡驱动分析Core补充篇的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。