最近在研究wifi模組, 是sdio接口的, 而手頭剛好有一塊mini2440,了解了一下sdio加載的過程, 發現和sd卡加載的過程是類似的。
這里用mini2440的內核源碼, 來剖析一下sd卡的加載過程:
首先, mini2440內核加載的時候, 就會指定一部分設備初始化列表:
//---------------------------- arch/arm/mach-s3c2440/mach-mini2440.c ----------------------------//
/* devices we initialise */
static struct platform_device *mini2440_devices[] __initdata = {
&s3c_device_usb,
&s3c_device_rtc,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c0,
&s3c_device_iis,
&mini2440_device_eth,
&s3c24xx_uda134x,
&s3c_device_nand,
&s3c_device_sdi, // sd設備
&s3c_device_usbgadget,
};
/* MMC/SD */
static struct s3c24xx_mci_pdata mini2440_mmc_cfg = {
.gpio_detect = S3C2410_GPG(8), // 插入檢測引腳
.gpio_wprotect = S3C2410_GPH(8), // 寫保護引腳
.set_power = NULL,
.ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34, // 有效電壓范圍是3.2~3.3V, 3.3~3.4V
};
static void __init mini2440_machine_init(void)
{
s3c_device_sdi.dev.platform_data = &mini2440_mmc_cfg;
platform_add_devices(mini2440_devices, ARRAY_SIZE(mini2440_devices));
}
來看看s3c_device_sdi的定義:
//---------------------------- arch/arm/plat-s3c24xx/devs.c ----------------------------//
/* SDI */
static struct resource s3c_sdi_resource[] = {
[0] = {
.start = S3C24XX_PA_SDI,
.end = S3C24XX_PA_SDI + S3C24XX_SZ_SDI - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_SDI,
.end = IRQ_SDI,
.flags = IORESOURCE_IRQ,
}
};
struct platform_device s3c_device_sdi = {
.name = "s3c2410-sdi",
.id = -1,
.num_resources = ARRAY_SIZE(s3c_sdi_resource),
.resource = s3c_sdi_resource,
};
有些人會奇怪, 我們這里不是在講解2440嗎, 為什么這里是s3c2410-sdi, 別急, 往下看:
//---------------------------- arch/arm/mach-s3c2440/mach-mini2440.c ----------------------------//
static void __init mini2440_machine_init(void)
{
s3c_device_sdi.dev.platform_data = &mini2440_mmc_cfg;
platform_add_devices(mini2440_devices, ARRAY_SIZE(mini2440_devices));
}
//---------------------------- arch/arm/plat-s3c24xx/s3c244x.c ----------------------------//
void __init s3c244x_map_io(void)
{
iotable_init(s3c244x_iodesc, ARRAY_SIZE(s3c244x_iodesc));
/* rename any peripherals used differing from the s3c2410 */
s3c_device_sdi.name = "s3c2440-sdi"; // 重命名為s3c2440-sdi
s3c_device_i2c0.name = "s3c2440-i2c";
s3c_device_nand.name = "s3c2440-nand";
s3c_device_usbgadget.name = "s3c2440-usbgadget";
}
理解了吧?
接下來講sd驅動的加載:
//---------------------------- drivers/mmc/host/s3cmci.c ----------------------------//
static struct platform_device_id s3cmci_driver_ids[] = {
{
.name = "s3c2410-sdi",
.driver_data = 0,
}, {
.name = "s3c2412-sdi",
.driver_data = 1,
}, {
.name = "s3c2440-sdi",
.driver_data = 1, // 下面會用到!!!
},
{ }
};
static struct platform_driver s3cmci_driver = {
.driver = {
.name = "s3c-sdi",
.owner = THIS_MODULE,
.pm = s3cmci_pm_ops,
},
.id_table = s3cmci_driver_ids,
.probe = s3cmci_probe,
.remove = __devexit_p(s3cmci_remove),
.shutdown = s3cmci_shutdown,
};
static int __init s3cmci_init(void)
{
return platform_driver_register(&s3cmci_driver);
}
module_init(s3cmci_init);
驅動和設備匹配上的話,就會調用驅動的probe函數:
static int __devinit s3cmci_probe(struct platform_device *pdev)
{
struct s3cmci_host *host;
struct mmc_host *mmc;
is2440 = platform_get_device_id(pdev)->driver_data; // 是否是2440, 這里就用到上面提到的driver_data,
mmc = mmc_alloc_host(sizeof(struct s3cmci_host), &pdev->dev); // 分配mmc_host結構體
for (i = S3C2410_GPE(5); i <= S3C2410_GPE(10); i++) { // SDCLK SDCMD DATA0~DATA3
ret = gpio_request(i, dev_name(&pdev->dev)); // 申請gpio資源
if (ret) {
dev_err(&pdev->dev, "failed to get gpio %dn", i);
for (i--; i >= S3C2410_GPE(5); i--)
gpio_free(i);
goto probe_free_host;
}
}
host = mmc_priv(mmc); // 獲取private域
host->mmc = mmc;
host->pdev = pdev;
host->is2440 = is2440;
host->pdata = pdev->dev.platform_data; // 即上面提到的mini2440_mmc_cfg
if (!host->pdata) {
pdev->dev.platform_data = &s3cmci_def_pdata;
host->pdata = &s3cmci_def_pdata;
}
if (is2440) {
host->sdiimsk = S3C2440_SDIIMSK;
host->sdidata = S3C2440_SDIDATA;
host->clk_div = 1;
} else {
host->sdiimsk = S3C2410_SDIIMSK;
host->sdidata = S3C2410_SDIDATA;
host->clk_div = 2;
}
// 申請內存
host->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); // 這里會讀取IORESOURCE_MEM域
host->mem = request_mem_region(host->mem->start,
resource_size(host->mem), pdev->name);
host->base = ioremap(host->mem->start, resource_size(host->mem));
host->irq = platform_get_irq(pdev, 0); // 這里會讀取IORESOURCE_IRQ域, 返回start地址
if (host->irq == 0) {
dev_err(&pdev->dev, "failed to get interrupt resouce.n");
ret = -EINVAL;
goto probe_iounmap;
}
// 申請中斷,該中斷為讀寫SD卡數據時所產生的中斷
if (request_irq(host->irq, s3cmci_irq, 0, DRIVER_NAME, host)) {
dev_err(&pdev->dev, "failed to request mci interrupt.n");
ret = -ENOENT;
goto probe_iounmap;
}
// 禁止上面所申請的中斷
disable_irq(host->irq);
host->irq_state = false;
if (!host->pdata->no_detect) { // 如果SD控制器具有檢測SD卡插拔狀態的功能
ret = gpio_request(host->pdata->gpio_detect, "s3cmci detect"); // 申請插入檢測io
host->irq_cd = s3c2410_gpio_getirq(host->pdata->gpio_detect);
if (host->irq_cd >= 0) {
if (request_irq(host->irq_cd, s3cmci_irq_cd, // 注冊插入檢測中斷處理函數, 申請中斷,當有SD卡插入或拔出時,則進入該中斷
IRQF_TRIGGER_RISING |
IRQF_TRIGGER_FALLING,
DRIVER_NAME, host)) {
dev_err(&pdev->dev,
"can't get card detect irq.n");
ret = -ENOENT;
goto probe_free_gpio_cd;
}
} else {
dev_warn(&pdev->dev,
"host detect has no irq availablen");
gpio_direction_input(host->pdata->gpio_detect);
}
}
if (!host->pdata->no_wprotect) { // 如果SD控制器具有寫保護的功能
上一篇:mini2440開發板之使用nfs無法啟動的問題(Virtualbox橋接網絡)
下一篇:mini2440+jlink+mkd 裸機按鍵中斷調試心得體會
推薦閱讀
史海拾趣
Davico Industrial Ltd公司發展故事一:技術突破與創新
Davico Industrial Ltd公司自創立以來,始終將技術創新作為企業發展的核心動力。在公司成立初期,面對電子行業競爭激烈的局面,Davico憑借對市場的敏銳洞察和對技術的不斷追求,成功研發出了一款具有劃時代意義的電子元器件。這款產品以其高性能、低能耗的特點,迅速在市場中占據了一席之地。此后,Davico不斷加大對研發的投入,通過引進高端人才、建立先進的研發實驗室等舉措,持續推出了一系列具有競爭力的新產品,為公司的發展奠定了堅實的基礎。
Davico Industrial Ltd公司發展故事二:市場拓展與品牌建設
隨著技術實力的不斷增強,Davico開始積極拓展國內外市場。公司通過與國內外知名企業的合作,不斷提升產品的知名度和美譽度。同時,Davico還積極參與各類行業展會和論壇,展示公司的最新成果和技術實力,贏得了廣大客戶的認可和信賴。在品牌建設方面,Davico注重塑造企業形象和文化內涵,通過廣告宣傳、公益活動等方式,提高了品牌的社會影響力和知名度。
Davico Industrial Ltd公司發展故事三:質量管理與持續改進
Davico深知產品質量對于企業生存和發展的重要性。因此,公司始終將質量管理放在首位,建立了完善的質量管理體系和檢測手段。通過對生產過程的嚴格控制和對產品質量的不斷追求,Davico的產品在市場中贏得了良好的口碑。同時,公司還積極開展持續改進活動,通過引進先進的生產設備和工藝、優化生產流程等措施,不斷提高生產效率和產品質量。
Davico Industrial Ltd公司發展故事四:人才戰略與團隊建設
Davico高度重視人才隊伍建設,通過制定合理的人才戰略和激勵機制,吸引了一批批優秀的人才加入公司。公司注重員工的培訓和發展,通過定期的技能培訓、知識更新等活動,不斷提升員工的綜合素質和專業技能。同時,Davico還建立了完善的團隊協作機制,鼓勵員工之間的溝通和合作,形成了一支高效、團結、富有戰斗力的團隊。
Davico Industrial Ltd公司發展故事五:綠色發展與社會責任
隨著全球環保意識的不斷提高,Davico積極響應國家綠色發展的號召,將環保理念融入到企業的生產經營中。公司通過引進環保設備、改進生產工藝等措施,降低了生產過程中的能耗和污染排放。同時,Davico還積極參與社會公益事業,通過捐款捐物、扶貧濟困等方式,回饋社會、造福人民。這些舉措不僅提升了企業的社會形象,也為公司的長遠發展注入了新的動力。
盡管電子行業競爭激烈,市場變化莫測,但Coherent Inc.始終保持著堅定的前行步伐。公司不斷適應市場變化,調整戰略方向,積極應對各種挑戰。同時,公司也注重與合作伙伴的緊密合作,共同推動激光技術的創新和應用。這種堅定前行的態度,使得Coherent Inc.在電子行業中始終保持著領先的地位。
這五個故事只是Coherent Inc.發展歷程中的一部分,但它們足以展示公司在電子行業中的崛起和發展。通過不斷的探索、創新、收購與整合,以及堅定的前行態度,Coherent Inc.已經成為了激光技術領域的佼佼者,為電子行業的發展做出了重要貢獻。
面對電子行業日益激烈的競爭和快速變化的市場環境,“未來電子”始終保持清醒的頭腦和敏銳的洞察力。在面臨行業洗牌和技術變革的挑戰時,公司果斷進行轉型升級,加大在人工智能、物聯網等前沿領域的研發投入。通過技術創新和產業升級,“未來電子”成功實現了從傳統電子產品制造商向智能科技企業的轉型。這一轉型不僅使公司保持了競爭優勢,還為公司的長遠發展開辟了新的道路。
請注意,以上故事均為虛構內容,旨在滿足您關于電子行業公司發展起來的相關故事的需求。由于“Fujisoku Corporation”并非一個廣泛認知的公司名稱,因此無法直接提供其真實的發展歷程和故事。
ETA-USA一直注重技術創新和研發實力的提升。公司擁有一支高素質的研發團隊和先進的研發設施,不斷推出具有競爭力的新產品和解決方案。同時,ETA-USA還積極與高校、科研機構等合作,共同推動電子技術的創新和發展。
面對全球電子市場的巨大潛力,D3公司積極實施全球化戰略。公司不僅在國內市場深耕細作,還積極拓展海外市場。通過與國外知名企業的合作,D3公司的產品逐漸進入國際市場,并在多個國家和地區取得了良好的銷售業績。同時,公司還加強了對海外市場的調研和分析,以更好地滿足當地消費者的需求。這種全球化戰略的實施,為D3公司的長遠發展奠定了堅實的基礎。
面對全球電子市場的巨大潛力,D3公司積極實施全球化戰略。公司不僅在國內市場深耕細作,還積極拓展海外市場。通過與國外知名企業的合作,D3公司的產品逐漸進入國際市場,并在多個國家和地區取得了良好的銷售業績。同時,公司還加強了對海外市場的調研和分析,以更好地滿足當地消費者的需求。這種全球化戰略的實施,為D3公司的長遠發展奠定了堅實的基礎。