X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=drivers%2Fmmc%2Fcore%2Fcore.c;h=3c7e63b416ef96c0b1bc3ee8fb62733fbac52ff8;hb=8680927736b7e032489eaccf591d45b42d9f2c94;hp=ad32bd77321f06524ee66f5a12237179e8134841;hpb=30ff24c355ab4cc4f4794f285e1486e90a771d26;p=firefly-linux-kernel-4.4.55.git diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index ad32bd77321f..3c7e63b416ef 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);