From e2a6dd074bca0bbb034b4dace6da383149180025 Mon Sep 17 00:00:00 2001 From: xbw Date: Wed, 30 Nov 2011 16:48:11 +0800 Subject: [PATCH] Optimize the SDMMC module for Kernel3.0 after cherry-pick from RK29-2.10SDK --- drivers/mmc/card/block.c | 12 ++++ drivers/mmc/core/core.c | 132 +++++++++++++++++++++++++++++++++- drivers/mmc/core/mmc.c | 12 +++- drivers/mmc/core/sd.c | 9 ++- drivers/mmc/core/sdio.c | 12 +++- drivers/mmc/host/rk29_sdmmc.c | 4 +- 6 files changed, 172 insertions(+), 9 deletions(-) mode change 100644 => 100755 drivers/mmc/card/block.c mode change 100644 => 100755 drivers/mmc/core/mmc.c diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c old mode 100644 new mode 100755 index 625bd9e46d70..5e8e5890d766 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -953,6 +953,9 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req) mmc_queue_bounce_post(mq); +#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) + //delete all retry code. modifyed by xbw at 2011-11-17 +#else /* * sbc.error indicates a problem with the set block count * command. No data will have been transferred. @@ -974,6 +977,7 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req) break; } } +#endif /* * Check for errors relating to the execution of the @@ -986,6 +990,9 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req) goto cmd_abort; } +#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) + //delete all retry code. modifyed by xbw at 2011-11-17 +#else /* * Everything else is either success, or a data error of some * kind. If it was a write, we may have transitioned to @@ -1008,8 +1015,13 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req) } while (!(status & R1_READY_FOR_DATA) || (R1_CURRENT_STATE(status) == R1_STATE_PRG)); } +#endif +#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) + if (brq.sbc.error || brq.cmd.error || brq.stop.error || brq.data.error) { //modifyed by xbw at 2011-11-17 +#else if (brq.data.error) { +#endif pr_err("%s: error %d transferring data, sector %u, nr %u, cmd response %#x, card status %#x\n", req->rq_disk->disk_name, brq.data.error, (unsigned)blk_rq_pos(req), diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 4850f34577ff..21bca485be62 100755 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -213,8 +213,10 @@ static void mmc_wait_done(struct mmc_request *mrq) */ void mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq) { +#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) unsigned long datasize, waittime = 0xFFFF; u32 multi, unit; +#endif DECLARE_COMPLETION_ONSTACK(complete); @@ -1086,8 +1088,12 @@ static void mmc_power_up(struct mmc_host *host) * to reach the minimum voltage. */ mmc_delay(10); - + +#if defined(CONFIG_SDMMC_RK29) || !defined(CONFIG_SDMMC_RK29_OLD) //Modifyed by xbw at 2011-11-17 + host->ios.clock = host->f_min; +#else host->ios.clock = host->f_init; +#endif host->ios.power_mode = MMC_POWER_ON; mmc_set_ios(host); @@ -1636,6 +1642,10 @@ static int mmc_rescan_try_freq(struct mmc_host *host, unsigned freq) { host->f_init = freq; +#if defined(CONFIG_SDMMC_RK29) || !defined(CONFIG_SDMMC_RK29_OLD) //Modifyed by xbw at 2011-11-17 + int init_ret=0; +#endif + #ifdef CONFIG_MMC_DEBUG pr_info("%s: %s: trying to init card at %u Hz\n", mmc_hostname(host), __func__, host->f_init); @@ -1647,7 +1657,104 @@ static int mmc_rescan_try_freq(struct mmc_host *host, unsigned freq) * if the card is being re-initialized, just send it. CMD52 * should be ignored by SD/eMMC cards. */ - sdio_reset(host); +#if defined(CONFIG_SDMMC_RK29) || !defined(CONFIG_SDMMC_RK29_OLD) //Modifyed by xbw at 2011-11-17 +//the process is default for rockchip SDK. noted by xbw at 2011-11-17 + +/* Order's important: probe SDIO, then SD, then MMC */ + +#if !defined(CONFIG_USE_SDMMC0_FOR_WIFI_DEVELOP_BOARD) + if( strncmp( mmc_hostname(host) ,"mmc0" , strlen("mmc0")) ) + { + sdio_reset(host); + mmc_go_idle(host); + + if (!(init_ret=mmc_attach_sdio(host))) + { + printk("%s..%d.. ===== Initialize SDIO successfully. ===xbw[%s]===\n",\ + __FUNCTION__, __LINE__, mmc_hostname(host)); + return 0; + } + else + { + if(0xFF!=init_ret) + { + printk("\n=====\n %s..%d.. ===== Initialize SDIO-card unsuccessfully!!! ===xbw[%s]===\n=====\n",\ + __FUNCTION__, __LINE__, mmc_hostname(host)); + + goto freq_out; + } + } + } + else + { + mmc_go_idle(host); + } +#else + sdio_reset(host); + mmc_go_idle(host); + + if (!(init_ret=mmc_attach_sdio(host))) + { + printk("%s..%d.. ===== Initialize SDIO successfully. ===xbw[%s]===\n",\ + __FUNCTION__, __LINE__, mmc_hostname(host)); + return 0; + } + else + { + if(0xFF!=init_ret) + { + printk("\n=====\n %s..%d.. ===== Initialize SDIO-card unsuccessfully!!! ===xbw[%s]===\n=====\n",\ + __FUNCTION__, __LINE__, mmc_hostname(host)); + + goto freq_out; + } + } +#endif // #end--#if !defined(CONFIG_USE_SDMMC0_FOR_WIFI_DEVELOP_BOARD) + + if (!(init_ret=mmc_attach_sd(host))) + { + printk("%s..%d.. ===== Initialize SD-card successfully. ===xbw[%s]===\n",\ + __FUNCTION__, __LINE__, mmc_hostname(host)); + + return 0; + } + else + { + if(0xFF!=init_ret) + { + printk("\n=====\n%s..%d.. ===== Initialize SD-card unsuccessfully!!! ===xbw[%s]===\n====\n",\ + __FUNCTION__, __LINE__, mmc_hostname(host)); + + goto freq_out; + } + } + + + if (!(init_ret=mmc_attach_mmc(host))) + { + printk("%s...%d.. ===== Initialize MMC-card successfully. ===xbw[%s]===\n",\ + __FUNCTION__, __LINE__, mmc_hostname(host)); + + return 0; + } + else + { + if(0xFF!=init_ret) + { + printk("\n =====\n%s..%d.. ===== Initialize MMC-card unsuccessfully!!! ===xbw[%s]===\n======\n",\ + __FUNCTION__, __LINE__, mmc_hostname(host)); + + goto freq_out; + } + } + +freq_out: + mmc_power_off(host); + return -EIO; + +#else // the default process in ICS. + + sdio_reset(host); mmc_go_idle(host); mmc_send_if_cond(host, host->ocr_avail); @@ -1662,6 +1769,8 @@ static int mmc_rescan_try_freq(struct mmc_host *host, unsigned freq) mmc_power_off(host); return -EIO; +#endif + } void mmc_rescan(struct work_struct *work) @@ -1710,10 +1819,27 @@ void mmc_rescan(struct work_struct *work) */ mmc_bus_put(host); +#if defined(CONFIG_SDMMC_RK29) || !defined(CONFIG_SDMMC_RK29_OLD) //Modifyed by xbw at 2011-11-17 + printk("\n%s...%d.. ===== mmc_rescan Begin....======xbw[%s]=====\n",__FILE__, __LINE__, mmc_hostname(host)); +#endif + if (host->ops->get_cd && host->ops->get_cd(host) == 0) + { +#if defined(CONFIG_SDMMC_RK29) || !defined(CONFIG_SDMMC_RK29_OLD) //Modifyed by xbw at 2011-11-17 + printk("\n=================\n%s..%d.. ====find no SDMMC host.====xbw[%s]=====\n", \ + __FUNCTION__, __LINE__, mmc_hostname(host)); +#endif + goto out; + } mmc_claim_host(host); + +#if defined(CONFIG_SDMMC_RK29) || !defined(CONFIG_SDMMC_RK29_OLD) //Modifyed by xbw at 2011-11-17 + if (!mmc_rescan_try_freq(host, host->f_min)) + extend_wakelock = true; + +#else for (i = 0; i < ARRAY_SIZE(freqs); i++) { if (!mmc_rescan_try_freq(host, max(freqs[i], host->f_min))) { extend_wakelock = true; @@ -1722,6 +1848,8 @@ void mmc_rescan(struct work_struct *work) if (freqs[i] <= host->f_min) break; } +#endif + mmc_release_host(host); out: diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c old mode 100644 new mode 100755 index 406f29efde3a..cb81f94e542f --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -1030,9 +1030,17 @@ int mmc_attach_mmc(struct mmc_host *host) WARN_ON(!host->claimed); err = mmc_send_op_cond(host, 0, &ocr); +#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) if (err) - return err; - + return 0xFF;//return err; Modifyed by xbw at 2011-11-17 + + printk("\n%s..%d.. ===== Begin to identify card as MMC-card ===xbw[%s]===\n", \ + __FUNCTION__, __LINE__, mmc_hostname(host)); +#else + if (err) + return err; +#endif + mmc_attach_bus_ops(host); if (host->ocr_avail_mmc) host->ocr_avail = host->ocr_avail_mmc; diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 550092d600ae..5101d73d81f5 100755 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -1208,9 +1208,16 @@ int mmc_attach_sd(struct mmc_host *host) host->ops->enable_preset_value(host, false); err = mmc_send_app_op_cond(host, 0, &ocr); +#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) + if (err) + return 0xFF;//return err; Modifyed by xbw at 2011-11-17 + + printk("\n%s..%d.. ===== Begin to identify card as SD-card ===xbw[%s]===\n",\ + __FUNCTION__, __LINE__, mmc_hostname(host)); +#else if (err) return err; - +#endif mmc_sd_attach_bus_ops(host); if (host->ocr_avail_sd) host->ocr_avail = host->ocr_avail_sd; diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 689a465cd43d..6a30bf3011d9 100755 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -410,7 +410,6 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, if (err) goto remove; -#if !defined(CONFIG_SDMMC_RK29) || defined(CONFIG_SDMMC_RK29_OLD) /* * Update oldcard with the new RCA received from the SDIO * device -- we're doing this so that it's updated in the @@ -418,7 +417,6 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, */ if (oldcard) oldcard->rca = card->rca; -#endif mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); } @@ -793,9 +791,17 @@ int mmc_attach_sdio(struct mmc_host *host) WARN_ON(!host->claimed); err = mmc_send_io_op_cond(host, 0, &ocr); + +#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) if (err) + return 0xFF;//return err; //Modifyed by xbw at 2011-11-17 + + printk("\n%s..%d.. ===== Begin to identify card as SDIO-card===xbw[%s]===\n",\ + __FUNCTION__, __LINE__, mmc_hostname(host)); +#else + if (err) return err; - +#endif mmc_attach_bus(host, &mmc_sdio_ops); if (host->ocr_avail_sdio) host->ocr_avail = host->ocr_avail_sdio; diff --git a/drivers/mmc/host/rk29_sdmmc.c b/drivers/mmc/host/rk29_sdmmc.c index 7d2e6c01df7d..cd26fc9e85ae 100755 --- a/drivers/mmc/host/rk29_sdmmc.c +++ b/drivers/mmc/host/rk29_sdmmc.c @@ -74,7 +74,7 @@ int debug_level = 5; #define RK29_SDMMC_WAIT_DTO_INTERNVAL 4500 //The time interval from the CMD_DONE_INT to DTO_INT #define RK29_SDMMC_REMOVAL_DELAY 2000 //The time interval from the CD_INT to detect_timer react. -#define RK29_SDMMC_VERSION "Ver.2.13 The last modify date is 2011-10-19,modifyed by XBW." +#define RK29_SDMMC_VERSION "Ver.2.14 The last modify date is 2011-11-17,modifyed by XBW." #if !defined(CONFIG_USE_SDMMC0_FOR_WIFI_DEVELOP_BOARD) #define RK29_CTRL_SDMMC_ID 0 //mainly used by SDMMC @@ -3150,7 +3150,9 @@ static int rk29_sdmmc_probe(struct platform_device *pdev) } mmc->ops = &rk29_sdmmc_ops[pdev->id]; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) mmc->pm_flags |= MMC_PM_IGNORE_PM_NOTIFY; +#endif mmc->f_min = FOD_FREQ; #if RK29_SDMMC_DEFAULT_SDIO_FREQ -- 2.34.1