mmc: mmc: Fix partition switch timeout for some eMMCs
[linux-2.6-block.git] / drivers / mmc / core / mmc.c
index 4dbe3df8024b2cf3ed9206f8d76cff1ba660dc7e..b81b08f81325721037362213997618b7ebfc1e10 100644 (file)
@@ -333,6 +333,9 @@ static void mmc_manage_gp_partitions(struct mmc_card *card, u8 *ext_csd)
        }
 }
 
+/* Minimum partition switch timeout in milliseconds */
+#define MMC_MIN_PART_SWITCH_TIME       300
+
 /*
  * Decode extended CSD.
  */
@@ -397,6 +400,10 @@ static int mmc_decode_ext_csd(struct mmc_card *card, u8 *ext_csd)
 
                /* EXT_CSD value is in units of 10ms, but we store in ms */
                card->ext_csd.part_time = 10 * ext_csd[EXT_CSD_PART_SWITCH_TIME];
+               /* Some eMMC set the value too low so set a minimum */
+               if (card->ext_csd.part_time &&
+                   card->ext_csd.part_time < MMC_MIN_PART_SWITCH_TIME)
+                       card->ext_csd.part_time = MMC_MIN_PART_SWITCH_TIME;
 
                /* Sleep / awake timeout in 100ns units */
                if (sa_shift > 0 && sa_shift <= 0x17)
@@ -1244,10 +1251,11 @@ static int mmc_select_hs200(struct mmc_card *card)
 {
        struct mmc_host *host = card->host;
        bool send_status = true;
-       unsigned int old_timing;
+       unsigned int old_timing, old_signal_voltage;
        int err = -EINVAL;
        u8 val;
 
+       old_signal_voltage = host->ios.signal_voltage;
        if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200_1_2V)
                err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120);
 
@@ -1256,7 +1264,7 @@ static int mmc_select_hs200(struct mmc_card *card)
 
        /* If fails try again during next card power cycle */
        if (err)
-               goto err;
+               return err;
 
        mmc_select_driver_type(card);
 
@@ -1290,9 +1298,14 @@ static int mmc_select_hs200(struct mmc_card *card)
                }
        }
 err:
-       if (err)
+       if (err) {
+               /* fall back to the old signal voltage, if fails report error */
+               if (__mmc_set_signal_voltage(host, old_signal_voltage))
+                       err = -EIO;
+
                pr_err("%s: %s failed, error %d\n", mmc_hostname(card->host),
                       __func__, err);
+       }
        return err;
 }
 
@@ -1314,21 +1327,13 @@ static int mmc_select_timing(struct mmc_card *card)
        if (err && err != -EBADMSG)
                return err;
 
-       if (err) {
-               pr_warn("%s: switch to %s failed\n",
-                       mmc_card_hs(card) ? "high-speed" :
-                       (mmc_card_hs200(card) ? "hs200" : ""),
-                       mmc_hostname(card->host));
-               err = 0;
-       }
-
 bus_speed:
        /*
         * Set the bus speed to the selected bus timing.
         * If timing is not selected, backward compatible is the default.
         */
        mmc_set_bus_speed(card);
-       return err;
+       return 0;
 }
 
 /*
@@ -1483,12 +1488,13 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
                if (err)
                        goto free_card;
 
-               /* If doing byte addressing, check if required to do sector
+               /*
+                * If doing byte addressing, check if required to do sector
                 * addressing.  Handle the case of <2GB cards needing sector
                 * addressing.  See section 8.1 JEDEC Standard JED84-A441;
                 * ocr register has bit 30 set for sector addressing.
                 */
-               if (!(mmc_card_blockaddr(card)) && (rocr & (1<<30)))
+               if (rocr & BIT(30))
                        mmc_card_set_blockaddr(card);
 
                /* Erase size depends on CSD and Extended CSD */
@@ -1957,19 +1963,23 @@ static int mmc_reset(struct mmc_host *host)
 {
        struct mmc_card *card = host->card;
 
-       if (!(host->caps & MMC_CAP_HW_RESET) || !host->ops->hw_reset)
-               return -EOPNOTSUPP;
-
-       if (!mmc_can_reset(card))
-               return -EOPNOTSUPP;
-
-       mmc_set_clock(host, host->f_init);
-
-       host->ops->hw_reset(host);
-
-       /* Set initial state and call mmc_set_ios */
-       mmc_set_initial_state(host);
-
+       /*
+        * In the case of recovery, we can't expect flushing the cache to work
+        * always, but we have a go and ignore errors.
+        */
+       mmc_flush_cache(host->card);
+
+       if ((host->caps & MMC_CAP_HW_RESET) && host->ops->hw_reset &&
+            mmc_can_reset(card)) {
+               /* If the card accept RST_n signal, send it. */
+               mmc_set_clock(host, host->f_init);
+               host->ops->hw_reset(host);
+               /* Set initial state and call mmc_set_ios */
+               mmc_set_initial_state(host);
+       } else {
+               /* Do a brute force power cycle */
+               mmc_power_cycle(host, card->ocr);
+       }
        return mmc_init_card(host, card->ocr, card);
 }