import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / mmc / core / sd.c
index 9e645e19cec6c791151c4d6cb7672aa364641dac..b73849148d7ea4a00ea76938975da9b023faf864 100644 (file)
@@ -25,6 +25,7 @@
 #include "sd.h"
 #include "sd_ops.h"
 
+u32 g_u32_cid[4]={0};
 static const unsigned int tran_exp[] = {
        10000,          100000,         1000000,        10000000,
        0,              0,              0,              0
@@ -475,6 +476,7 @@ static int sd_set_bus_speed_mode(struct mmc_card *card, u8 *status)
 {
        int err;
        unsigned int timing = 0;
+       int retry = 3; //[ss6]for switch mode failed.
 
        switch (card->sd_bus_speed) {
        case UHS_SDR104_BUS_SPEED:
@@ -500,14 +502,18 @@ static int sd_set_bus_speed_mode(struct mmc_card *card, u8 *status)
        default:
                return 0;
        }
-
+reswitch:
        err = mmc_sd_switch(card, 1, 0, card->sd_bus_speed, status);
        if (err)
                return err;
+       printk(KERN_WARNING "msdc status[16] & 0xF = 0x%x bus_speed = 0x%x\n",(status[16] & 0xF),card->sd_bus_speed);
 
-       if ((status[16] & 0xF) != card->sd_bus_speed)
+       if ((status[16] & 0xF) != card->sd_bus_speed){
                pr_warning("%s: Problem setting bus speed mode!\n",
                        mmc_hostname(card->host));
+               if(retry--)
+                       goto reswitch;
+       }
        else {
                mmc_set_timing(card->host, timing);
                mmc_set_clock(card->host, card->sw_caps.uhs_max_dtr);
@@ -805,6 +811,9 @@ int mmc_sd_setup_card(struct mmc_host *host, struct mmc_card *card,
        bool reinit)
 {
        int err;
+#ifdef CONFIG_MMC_PARANOID_SD_INIT
+       int retries;
+#endif
 
        if (!reinit) {
                /*
@@ -831,7 +840,26 @@ int mmc_sd_setup_card(struct mmc_host *host, struct mmc_card *card,
                /*
                 * Fetch switch information from card.
                 */
+#ifdef CONFIG_MMC_PARANOID_SD_INIT
+               for (retries = 1; retries <= 3; retries++) {
+                       err = mmc_read_switch(card);
+                       if (!err) {
+                               if (retries > 1) {
+                                       printk(KERN_WARNING
+                                              "%s: recovered\n", 
+                                              mmc_hostname(host));
+                               }
+                               break;
+                       } else {
+                               printk(KERN_WARNING
+                                      "%s: read switch failed (attempt %d)\n",
+                                      mmc_hostname(host), retries);
+                       }
+               }
+#else
                err = mmc_read_switch(card);
+#endif
+
                if (err)
                        return err;
        }
@@ -903,7 +931,7 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
        struct mmc_card *oldcard)
 {
        struct mmc_card *card;
-       int err;
+       int err, i;
        u32 cid[4];
        u32 rocr = 0;
 
@@ -913,6 +941,8 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
        err = mmc_sd_get_cid(host, ocr, cid, &rocr);
        if (err)
                return err;
+       for (i=0; i<4; i++)
+               g_u32_cid[i] = cid[i];
 
        if (oldcard) {
                if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0)
@@ -1032,7 +1062,10 @@ static int mmc_sd_alive(struct mmc_host *host)
  */
 static void mmc_sd_detect(struct mmc_host *host)
 {
-       int err;
+       int err = 0;
+#ifdef CONFIG_MMC_PARANOID_SD_INIT
+       int retries = 5;
+#endif
 
        BUG_ON(!host);
        BUG_ON(!host->card);
@@ -1042,7 +1075,23 @@ static void mmc_sd_detect(struct mmc_host *host)
        /*
         * Just check if our card has been removed.
         */
+#ifdef CONFIG_MMC_PARANOID_SD_INIT
+       while(retries) {
+               err = mmc_send_status(host->card, NULL);
+               if (err) {
+                       retries--;
+                       udelay(5);
+                       continue;
+               }
+               break;
+       }
+       if (!retries) {
+               printk(KERN_ERR "%s(%s): Unable to re-detect card (%d)\n",
+                      __func__, mmc_hostname(host), err);
+       }
+#else
        err = _mmc_detect_card_removed(host);
+#endif
 
        mmc_release_host(host);
 
@@ -1084,17 +1133,39 @@ static int mmc_sd_suspend(struct mmc_host *host)
 static int mmc_sd_resume(struct mmc_host *host)
 {
        int err;
+#ifdef CONFIG_MMC_PARANOID_SD_INIT
+       int retries;
+#endif
 
        BUG_ON(!host);
        BUG_ON(!host->card);
 
        mmc_claim_host(host);
+#ifdef CONFIG_MMC_PARANOID_SD_INIT
+       retries = 5;
+       while (retries) {
+               err = mmc_sd_init_card(host, host->ocr, host->card);
+
+               if (err) {
+                       printk(KERN_ERR "%s: Re-init card rc = %d (retries = %d)\n",
+                              mmc_hostname(host), err, retries);
+                       mdelay(5);
+                       retries--;
+                       continue;
+               }
+               break;
+       }
+#else
        err = mmc_sd_init_card(host, host->ocr, host->card);
+#endif
        mmc_release_host(host);
 
        return err;
 }
-
+int mmc_sd_power_cycle(struct mmc_host *host,u32 ocr,struct mmc_card *card)
+{
+       return mmc_sd_init_card(host,ocr,card);
+}
 static int mmc_sd_power_restore(struct mmc_host *host)
 {
        int ret;
@@ -1143,6 +1214,9 @@ int mmc_attach_sd(struct mmc_host *host)
 {
        int err;
        u32 ocr;
+#ifdef CONFIG_MMC_PARANOID_SD_INIT
+       int retries;
+#endif
 
        BUG_ON(!host);
        WARN_ON(!host->claimed);
@@ -1198,9 +1272,27 @@ int mmc_attach_sd(struct mmc_host *host)
        /*
         * Detect and init the card.
         */
+#ifdef CONFIG_MMC_PARANOID_SD_INIT
+       retries = 5;
+       while (retries) {
+               err = mmc_sd_init_card(host, host->ocr, NULL);
+               if (err) {
+                       retries--;
+                       continue;
+               }
+               break;
+       }
+
+       if (!retries) {
+               printk(KERN_ERR "%s: mmc_sd_init_card() failure (err = %d)\n",
+                      mmc_hostname(host), err);
+               goto err;
+       }
+#else
        err = mmc_sd_init_card(host, host->ocr, NULL);
        if (err)
                goto err;
+#endif
 
        mmc_release_host(host);
        err = mmc_add_card(host->card);