生活随笔
收集整理的這篇文章主要介紹了
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
? ? ? ? ? ? ? ?? 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這個函數,它的功能就是通過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
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,內容如下:
[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);?? }??
? ? ?關心最多的就是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
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行說了句人話,其他的百分之九十九的都是廢話。曾幾何時我們說過內核有個延時工作隊列,沒錯就是他了。當然這可不是隨便拿來玩的,與之對應的初始化前面已經說過即INIT_DELAYED_WORK(&host->detect, mmc_rescan);好了20 行作用的結果估計大家都能猜到了,就是延時delay 時間后就會去調用mmc_rescan了。前面我們傳遞的delay=0,那么這里就沒有延時了,既然驅動都等不及要rescan了,我們也就不再賣關子了,直接mmc_rescan。它的功能就是掃描所插入的卡
這就回到了Linux SD卡驅動開發(三) —— SD 卡驅動分析CORE篇?了
總結
以上是生活随笔為你收集整理的Linux SD卡驱动开发(五) —— SD 卡驱动分析Core补充篇的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。