From 2e19d619afa1a21b52afadb7933f38e67bf69dad Mon Sep 17 00:00:00 2001 From: =?utf8?q?=E9=BB=84=E6=B6=9B?= Date: Mon, 1 Aug 2011 02:05:41 +0800 Subject: [PATCH] Revert "temp revert mmc change" This reverts commit 77d6545a14db425b338c866cf4688f277fc17f89. Conflicts: drivers/mmc/card/block.c drivers/mmc/core/core.c drivers/mmc/core/host.c drivers/mmc/core/sd.c drivers/mmc/core/sdio.c --- drivers/mmc/card/block.c | 74 +++++++++++++-- drivers/mmc/core/bus.c | 3 + drivers/mmc/core/core.c | 193 +++++++++++++++++++++++++++++++++++++++ drivers/mmc/core/host.c | 9 ++ drivers/mmc/core/mmc.c | 38 +++++++- drivers/mmc/core/sd.c | 69 +++++++++++++- drivers/mmc/core/sdio.c | 17 +++- 7 files changed, 390 insertions(+), 13 deletions(-) diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index e6f74718e06f..1d96e4aba9a9 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -52,6 +52,10 @@ MODULE_ALIAS("mmc:block"); #define INAND_CMD38_ARG_SECTRIM1 0x81 #define INAND_CMD38_ARG_SECTRIM2 0x88 +#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) +static DEFINE_MUTEX(block_mutex); //added by xbw at 2011-04-21 +#endif + /* * max 8 partitions per card */ @@ -110,6 +114,10 @@ static int mmc_blk_open(struct block_device *bdev, fmode_t mode) { struct mmc_blk_data *md = mmc_blk_get(bdev->bd_disk); int ret = -ENXIO; + +#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) + mutex_lock(&block_mutex); //added by xbw at 2011-04-21 +#endif lock_kernel(); if (md) { @@ -124,16 +132,29 @@ static int mmc_blk_open(struct block_device *bdev, fmode_t mode) } unlock_kernel(); +#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) + mutex_unlock(&block_mutex); +#endif + return ret; } static int mmc_blk_release(struct gendisk *disk, fmode_t mode) { struct mmc_blk_data *md = disk->private_data; + +#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) + mutex_lock(&block_mutex); //added by xbw at 2011-04-21 +#endif lock_kernel(); mmc_blk_put(md); unlock_kernel(); + +#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) + mutex_unlock(&block_mutex); +#endif + return 0; } @@ -233,6 +254,13 @@ static u32 mmc_sd_num_wr_blocks(struct mmc_card *card) return result; } +#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) //Deleted by xbw@2011-03-21 +//static u32 get_card_status(struct mmc_card *card, struct request *req) +//{ +// return 0; +//} + +#else static u32 get_card_status(struct mmc_card *card, struct request *req) { struct mmc_command cmd; @@ -245,10 +273,11 @@ static u32 get_card_status(struct mmc_card *card, struct request *req) cmd.flags = MMC_RSP_SPI_R2 | MMC_RSP_R1 | MMC_CMD_AC; err = mmc_wait_for_cmd(card->host, &cmd, 0); if (err) - printk(KERN_ERR "%s: error %d sending status comand", + printk(KERN_DEBUG "%s: error %d sending status comand", req->rq_disk->disk_name, err); return cmd.resp[0]; } +#endif static int mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req) { @@ -355,13 +384,22 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req) mmc_claim_host(card->host); do { - struct mmc_command cmd; + #if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) + //struct mmc_command cmd;//Deleted by xbw@2011-03-21 + #else + struct mmc_command cmd; + #endif + u32 readcmd, writecmd, status = 0; memset(&brq, 0, sizeof(struct mmc_blk_request)); brq.mrq.cmd = &brq.cmd; brq.mrq.data = &brq.data; - + + #if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) + brq.cmd.retries = 2; //suppot retry read-write; added by xbw@2011-03-21 + #endif + brq.cmd.arg = blk_rq_pos(req); if (!mmc_card_blockaddr(card)) brq.cmd.arg <<= 9; @@ -441,6 +479,11 @@ 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) + //not turn CMD18 to CMD17. deleted by xbw at 2011-04-21 + + #else + /* * Check for errors here, but don't jump to cmd_err * until later as we need to wait for the card to leave @@ -449,7 +492,7 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req) if (brq.cmd.error || brq.data.error || brq.stop.error) { if (brq.data.blocks > 1 && rq_data_dir(req) == READ) { /* Redo read one sector at a time */ - printk(KERN_WARNING "%s: retrying using single " + printk(KERN_DEBUG "%s: retrying using single " "block read\n", req->rq_disk->disk_name); disable_multi = 1; continue; @@ -457,10 +500,11 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req) status = get_card_status(card, req); } else if (disable_multi == 1) { disable_multi = 0; - } + } + #endif if (brq.cmd.error) { - printk(KERN_ERR "%s: error %d sending read/write " + printk(KERN_DEBUG "%s: error %d sending read/write " "command, response %#x, card status %#x\n", req->rq_disk->disk_name, brq.cmd.error, brq.cmd.resp[0], status); @@ -470,7 +514,7 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req) if (brq.data.error == -ETIMEDOUT && brq.mrq.stop) /* 'Stop' response contains card status */ status = brq.mrq.stop->resp[0]; - printk(KERN_ERR "%s: error %d transferring data," + printk(KERN_DEBUG "%s: error %d transferring data," " sector %u, nr %u, card status %#x\n", req->rq_disk->disk_name, brq.data.error, (unsigned)blk_rq_pos(req), @@ -478,12 +522,16 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req) } if (brq.stop.error) { - printk(KERN_ERR "%s: error %d sending stop command, " + printk(KERN_DEBUG "%s: error %d sending stop command, " "response %#x, card status %#x\n", req->rq_disk->disk_name, brq.stop.error, brq.stop.resp[0], status); } + #if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) + //Deleted by xbw@2011-03-21 + + #else if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) { do { int err; @@ -493,7 +541,7 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req) cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; err = mmc_wait_for_cmd(card->host, &cmd, 5); if (err) { - printk(KERN_ERR "%s: error %d requesting status\n", + printk(KERN_DEBUG "%s: error %d requesting status\n", req->rq_disk->disk_name, err); goto cmd_err; } @@ -513,8 +561,9 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req) goto cmd_err; #endif } +#endif - if (brq.cmd.error || brq.stop.error || brq.data.error) { + if (brq.cmd.error || brq.stop.error || brq.data.error) { if (rq_data_dir(req) == READ) { /* * After an error, we redo I/O one sector at a @@ -667,6 +716,11 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) sprintf(md->disk->disk_name, "mmcblk%d", devidx); +#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) + printk("%s..%d **** devidx=%d, dev_use[0]=%lu, disk_name=%s *** ==xbw[%s]==\n",\ + __FUNCTION__,__LINE__, devidx, dev_use[0], md->disk->disk_name,mmc_hostname(card->host)); +#endif + blk_queue_logical_block_size(md->queue.queue, 512); if (!mmc_card_sd(card) && mmc_card_blockaddr(card)) { diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index 7cd9749dc21d..68ace37a1c05 100755 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c @@ -289,6 +289,9 @@ void mmc_remove_card(struct mmc_card *card) #endif if (mmc_card_present(card)) { +#if defined(CONFIG_SDMMC_RK29) && defined(CONFIG_SDMMC_RK29_OLD) + mmc_card_clr_present(card); +#endif if (mmc_host_is_spi(card->host)) { printk(KERN_INFO "%s: SPI card removed\n", mmc_hostname(card->host)); diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index ad32bd77321f..53b5b4b04cef 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -218,7 +218,11 @@ void mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq) mmc_start_request(host, mrq); +#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) + wait_for_completion_timeout(&complete,HZ*3); //for cmd dead. Modifyed by xbw at 2011-06-02 +#else wait_for_completion(&complete); +#endif } EXPORT_SYMBOL(mmc_wait_for_req); @@ -1428,6 +1432,155 @@ int mmc_erase_group_aligned(struct mmc_card *card, unsigned int from, } EXPORT_SYMBOL(mmc_erase_group_aligned); +#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) +void mmc_rescan(struct work_struct *work) +{ + struct mmc_host *host = + container_of(work, struct mmc_host, detect.work); + u32 ocr; + int err; + int extend_wakelock = 0; + + + mmc_bus_get(host); + + /* if there is a card registered, check whether it is still present */ + if ((host->bus_ops != NULL) && host->bus_ops->detect && !host->bus_dead) + host->bus_ops->detect(host); + + /* If the card was removed the bus will be marked + * as dead - extend the wakelock so userspace + * can respond */ + if (host->bus_dead) + extend_wakelock = 1; + + mmc_bus_put(host); + + + mmc_bus_get(host); + + /* if there still is a card present, stop here */ + if (host->bus_ops != NULL) { + mmc_bus_put(host); + goto out; + } + + /* detect a newly inserted card */ + + /* + * Only we can add a new handler, so it's safe to + * release the lock here. + */ + mmc_bus_put(host); + printk("\n%s...%d.. ===== mmc_rescan Begin....======xbw[%s]=====\n",__FILE__, __LINE__, mmc_hostname(host)); + + if (host->ops->get_cd && host->ops->get_cd(host) == 0) + { + printk("\n=================\n%s..%d.. ====find no SDMMC host.====xbw[%s]=====\n", \ + __FUNCTION__, __LINE__, mmc_hostname(host)); + + goto out; + } + + mmc_claim_host(host); + + mmc_power_up(host); + + mmc_go_idle(host); + + /* + In oder to improve the initialization process in rockchip IC, I modify the following code about the the initialization process of SDIO-SD-MMC. + So I deleted the CMD8 and add a conditional to distinguish between the two card type,i.e.SDMMC process and SDIO process. + For detail,please refer to "RK29XX Technical Reference Manual" and "SD-MMC-SDIO Specifications". + Noted by xbw@2011-04-09 + */ + + //mmc_send_if_cond(host, host->ocr_avail); //deleted by xbw@2011-04-09 + + if( strncmp( mmc_hostname(host) ,"mmc0" , strlen("mmc0")) ){ + /* + * First we search for SDIO... + */ + err = mmc_send_io_op_cond(host, 0, &ocr); + if (!err) { + printk("\n%s..%d.. ===== Begin to identify card as SDIO-card===xbw[%s]===\n",__FUNCTION__, __LINE__, mmc_hostname(host)); + + if (mmc_attach_sdio(host, ocr)) + { + printk("\n=====\n %s..%d.. ===== Initialize SDIO-card unsuccessfully!!! ===xbw[%s]===\n=====\n",\ + __FUNCTION__, __LINE__, mmc_hostname(host)); + + mmc_power_off(host); + } + else + { + printk("%s..%d.. ===== Initialize SDIO successfully. ===xbw[%s]===\n",__FUNCTION__, __LINE__, mmc_hostname(host)); + } + extend_wakelock = 1; + goto out; + } + } + + + /* + * ...then normal SD... + */ + err = mmc_send_app_op_cond(host, 0, &ocr); + if (!err) { + printk("\n%s..%d.. ===== Begin to identify card as SD-card ===xbw[%s]===\n",__FUNCTION__, __LINE__, mmc_hostname(host)); + + if (mmc_attach_sd(host, ocr)) + { + printk("\n=====\n%s..%d.. ===== Initialize SD-card unsuccessfully!!! ===xbw[%s]===\n====\n",\ + __FUNCTION__, __LINE__, mmc_hostname(host)); + + mmc_power_off(host); + } + else + { + printk("%s..%d.. ===== Initialize SD-card successfully. ===xbw[%s]===\n",__FUNCTION__, __LINE__, mmc_hostname(host)); + } + extend_wakelock = 1; + goto out; + } + + /* + * ...and finally MMC. + */ + err = mmc_send_op_cond(host, 0, &ocr); + if (!err) { + printk("\n%s..%d.. ===== Begin to identify card as MMC-card ===xbw[%s]===\n", __FUNCTION__, __LINE__, mmc_hostname(host)); + + if (mmc_attach_mmc(host, ocr)) + { + printk("\n =====\n%s..%d.. ===== Initialize MMC-card unsuccessfully!!! ===xbw[%s]===\n======\n",\ + __FUNCTION__, __LINE__, mmc_hostname(host)); + + mmc_power_off(host); + } + else + { + printk("%s...%d.. ===== Initialize MMC-card successfully. ===xbw[%s]===\n",__FUNCTION__, __LINE__, mmc_hostname(host)); + } + extend_wakelock = 1; + goto out; + } + + mmc_release_host(host); + mmc_power_off(host); + +out: + + if (extend_wakelock) + wake_lock_timeout(&mmc_delayed_work_wake_lock, HZ / 2); + else + wake_unlock(&mmc_delayed_work_wake_lock); + + if (host->caps & MMC_CAP_NEEDS_POLL) + mmc_schedule_delayed_work(&host->detect, HZ); +} + +#else void mmc_rescan(struct work_struct *work) { struct mmc_host *host = @@ -1436,6 +1589,20 @@ void mmc_rescan(struct work_struct *work) int err; unsigned long flags; int extend_wakelock = 0; + +#if defined(CONFIG_SDMMC_RK29) && defined(CONFIG_SDMMC_RK29_OLD) + unsigned long flags; + + spin_lock_irqsave(&host->lock, flags); + + if (host->rescan_disable) { + spin_unlock_irqrestore(&host->lock, flags); + return; + } + + spin_unlock_irqrestore(&host->lock, flags); +#endif + spin_lock_irqsave(&host->lock, flags); @@ -1542,6 +1709,7 @@ out: if (host->caps & MMC_CAP_NEEDS_POLL) mmc_schedule_delayed_work(&host->detect, HZ); } +#endif void mmc_start_host(struct mmc_host *host) { @@ -1680,6 +1848,10 @@ int mmc_suspend_host(struct mmc_host *host) if (host->bus_ops && !host->bus_dead) { if (host->bus_ops->suspend) err = host->bus_ops->suspend(host); + +#if defined(CONFIG_SDMMC_RK29) && defined(CONFIG_SDMMC_RK29_OLD) + //deleted all detail code. +#else if (err == -ENOSYS || !host->bus_ops->resume) { /* * We simply "remove" the card in this case. @@ -1693,6 +1865,7 @@ int mmc_suspend_host(struct mmc_host *host) host->pm_flags = 0; err = 0; } +#endif } mmc_bus_put(host); @@ -1725,6 +1898,8 @@ int mmc_resume_host(struct mmc_host *host) mmc_select_voltage(host, host->ocr); } BUG_ON(!host->bus_ops->resume); + +#if defined(CONFIG_SDMMC_RK29) && defined(CONFIG_SDMMC_RK29_OLD) err = host->bus_ops->resume(host); if (err) { printk(KERN_WARNING "%s: error %d during resume " @@ -1732,6 +1907,20 @@ int mmc_resume_host(struct mmc_host *host) mmc_hostname(host), err); err = 0; } + +#elif defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) + //panic if the card is being removed during the resume, deleted by xbw at 2011-06-20 + host->bus_ops->resume(host); + +#else + err = host->bus_ops->resume(host); + if (err) { + printk(KERN_WARNING "%s: error %d during resume " + "(card was removed?)\n", + mmc_hostname(host), err); + err = 0; + } +#endif } mmc_bus_put(host); @@ -1739,6 +1928,8 @@ int mmc_resume_host(struct mmc_host *host) } EXPORT_SYMBOL(mmc_resume_host); +///old driver add the function reforming to kernel2.6.38 +#if defined(CONFIG_SDMMC_RK29) && defined(CONFIG_SDMMC_RK29_OLD) /* Do the card removal on suspend if card is assumed removeable * Do that in pm notifier while userspace isn't yet frozen, so we will be able to sync the card. @@ -1794,6 +1985,8 @@ int mmc_pm_notify(struct notifier_block *notify_block, return 0; } +#endif// endif---defined(CONFIG_SDMMC_RK29) && defined(CONFIG_SDMMC_RK29_OLD) + #endif #ifdef CONFIG_MMC_EMBEDDED_SDIO diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index ba684e6d2b6b..04607b1604c8 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c @@ -86,8 +86,10 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev) init_waitqueue_head(&host->wq); INIT_DELAYED_WORK(&host->detect, mmc_rescan); INIT_DELAYED_WORK_DEFERRABLE(&host->disable, mmc_host_deeper_disable); +#if defined(CONFIG_SDMMC_RK29) && defined(CONFIG_SDMMC_RK29_OLD) // old driver, add pm reform to kernel2.6.38 #ifdef CONFIG_PM host->pm_notify.notifier_call = mmc_pm_notify; +#endif #endif /* @@ -140,6 +142,11 @@ int mmc_add_host(struct mmc_host *host) if (!(host->pm_flags & MMC_PM_IGNORE_PM_NOTIFY)) register_pm_notifier(&host->pm_notify); +#if defined(CONFIG_SDMMC_RK29) && defined(CONFIG_SDMMC_RK29_OLD) // old driver, add pm reform to kernel2.6.38 + if (!(host->pm_flags & MMC_PM_IGNORE_PM_NOTIFY)) + register_pm_notifier(&host->pm_notify); +#endif + return 0; } @@ -155,8 +162,10 @@ EXPORT_SYMBOL(mmc_add_host); */ void mmc_remove_host(struct mmc_host *host) { +#if defined(CONFIG_SDMMC_RK29) && defined(CONFIG_SDMMC_RK29_OLD) // old driver, add pm reform to kernel2.6.38 if (!(host->pm_flags & MMC_PM_IGNORE_PM_NOTIFY)) unregister_pm_notifier(&host->pm_notify); +#endif mmc_stop_host(host); diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 6909a54c39be..1f4fd781ef29 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -378,7 +378,13 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, /* The extra bit indicates that we support high capacity */ err = mmc_send_op_cond(host, ocr | (1 << 30), NULL); if (err) + { +#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) + printk("%s..%d.. ====*Identify the card as MMC , but OCR error, so fail to initialize.===xbw[%s]===\n",\ + __FUNCTION__, __LINE__, mmc_hostname(host)); +#endif goto err; + } /* * For SPI, enable CRC as appropriate. @@ -497,6 +503,10 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, if (max_dtr > card->ext_csd.hs_max_dtr) max_dtr = card->ext_csd.hs_max_dtr; } else if (max_dtr > card->csd.max_dtr) { +#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) + //in order to expand the compatibility of card. Added by xbw@2011-03-21 + card->csd.max_dtr = (card->csd.max_dtr > MMC_FPP_FREQ) ? MMC_FPP_FREQ : (card->csd.max_dtr); +#endif max_dtr = card->csd.max_dtr; } @@ -698,6 +708,9 @@ static void mmc_attach_bus_ops(struct mmc_host *host) int mmc_attach_mmc(struct mmc_host *host, u32 ocr) { int err; +#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) + int retry_times = 3; +#endif BUG_ON(!host); WARN_ON(!host->claimed); @@ -742,10 +755,33 @@ int mmc_attach_mmc(struct mmc_host *host, u32 ocr) goto err; mmc_release_host(host); - + +#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) +//modifyed by xbw at 2011--04-11 +Retry_add: err = mmc_add_card(host->card); + if (err) + { + //retry add the card; Added by xbw + if((--retry_times >= 0)) + { + printk("\n%s..%s..%d ****error in add partition, so retry. ===xbw[%s]===\n",__FUNCTION__,__FILE__,__LINE__, mmc_hostname(host)); + /* sleep some time */ + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ/2); + + goto Retry_add; + } + + goto remove_card; + + } +#else + err = mmc_add_card(host->card); if (err) goto remove_card; +#endif + return 0; diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 7ab8fdc61c77..52da7745b98f 100755 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -422,8 +422,13 @@ int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid) ocr |= 1 << 30; err = mmc_send_app_op_cond(host, ocr, NULL); - if (err) + if (err) { +#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) + printk("%s..%d.. ====*Identify the card as SD , but OCR error, so fail to initialize.===xbw[%s]===\n", \ + __FUNCTION__, __LINE__, mmc_hostname(host)); +#endif return err; + } if (mmc_host_is_spi(host)) err = mmc_send_cid(host, cid); @@ -498,6 +503,13 @@ int mmc_sd_setup_card(struct mmc_host *host, struct mmc_card *card, printk(KERN_WARNING "%s: read switch failed (attempt %d)\n", mmc_hostname(host), retries); + +#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) + if(0 == host->re_initialized_flags) + { + break; //Added by xbw at 2011-06-21 + } +#endif } } #else @@ -550,6 +562,11 @@ unsigned mmc_sd_get_max_clock(struct mmc_card *card) if (max_dtr > card->sw_caps.hs_max_dtr) max_dtr = card->sw_caps.hs_max_dtr; } else if (max_dtr > card->csd.max_dtr) { + +#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) + //in order to expand the compatibility of card. Added by xbw@2011-03-21 + card->csd.max_dtr = (card->csd.max_dtr > SD_FPP_FREQ) ? SD_FPP_FREQ : (card->csd.max_dtr); +#endif max_dtr = card->csd.max_dtr; } @@ -702,6 +719,15 @@ static void mmc_sd_detect(struct mmc_host *host) err = mmc_send_status(host->card, NULL); if (err) { retries--; + +#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) + if(0 == host->re_initialized_flags) + { + retries = 0; + break; //Added by xbw at 2011-06-21 + } +#endif + udelay(5); continue; } @@ -769,6 +795,13 @@ static int mmc_sd_resume(struct mmc_host *host) mmc_hostname(host), err, retries); mdelay(5); retries--; + +#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) + if(0 == host->re_initialized_flags) + { + break; //Added by xbw at 2011-06-21 + } +#endif continue; } break; @@ -822,6 +855,10 @@ static void mmc_sd_attach_bus_ops(struct mmc_host *host) int mmc_attach_sd(struct mmc_host *host, u32 ocr) { int err; +#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) + int retry_times = 3; +#endif + #ifdef CONFIG_MMC_PARANOID_SD_INIT int retries; #endif @@ -879,6 +916,14 @@ int mmc_attach_sd(struct mmc_host *host, u32 ocr) err = mmc_sd_init_card(host, host->ocr, NULL); if (err) { retries--; + + #if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) + if(0 == host->re_initialized_flags) + { + retries = 0; + break; //Added by xbw at 2011-06-21 + } + #endif continue; } break; @@ -897,9 +942,31 @@ int mmc_attach_sd(struct mmc_host *host, u32 ocr) mmc_release_host(host); +#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) +//modifyed by xbw at 2011--04-11 +Retry_add: err = mmc_add_card(host->card); + if (err) + { + //retry add the card; Added by xbw + if((--retry_times >= 0)) + { + printk("\n%s..%s..%d ****error in add partition, so retry. ===xbw[%s]===\n",__FUNCTION__,__FILE__,__LINE__, mmc_hostname(host)); + /* sleep some time */ + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ/2); + + goto Retry_add; + } + + goto remove_card; + + } +#else + err = mmc_add_card(host->card); if (err) goto remove_card; +#endif return 0; diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index d3ec4dc18d14..b81f07ce69ab 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -346,8 +346,13 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, */ if (!powered_resume) { err = mmc_send_io_op_cond(host, host->ocr, &ocr); - if (err) + if (err) { +#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) + printk("%s..%d.. ====*Identify the card as SDIO , but OCR error, so fail to initialize.===xbw[%s]===\n", \ + __FUNCTION__, __LINE__, mmc_hostname(host)); +#endif goto err; + } } /* @@ -400,6 +405,16 @@ 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) //old driver add the code ,reform to kernel2.6.38 + /* + * Update oldcard with the new RCA received from the SDIO + * device -- we're doing this so that it's updated in the + * "card" struct when oldcard overwrites that later. + */ + if (oldcard) + oldcard->rca = card->rca; +#endif + mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); } -- 2.34.1