OSDN Git Service

Merge android-4.4.191 (6da3fbc) into msm-4.4
[sagit-ice-cold/kernel_xiaomi_msm8998.git] / drivers / mmc / core / sd.c
index bf896b6..f24c6ad 100644 (file)
@@ -33,6 +33,8 @@
 #define UHS_SDR25_MIN_DTR      (25 * 1000 * 1000)
 #define UHS_SDR12_MIN_DTR      (12.5 * 1000 * 1000)
 
+#define ENOCALLBACK 1
+
 static const unsigned int tran_exp[] = {
        10000,          100000,         1000000,        10000000,
        0,              0,              0,              0
@@ -222,6 +224,14 @@ static int mmc_decode_scr(struct mmc_card *card)
 
        if (scr->sda_spec3)
                scr->cmds = UNSTUFF_BITS(resp, 32, 2);
+
+       /* SD Spec says: any SD Card shall set at least bits 0 and 2 */
+       if (!(scr->bus_widths & SD_SCR_BUS_WIDTH_1) ||
+           !(scr->bus_widths & SD_SCR_BUS_WIDTH_4)) {
+               pr_err("%s: invalid bus width\n", mmc_hostname(card->host));
+               return -EINVAL;
+       }
+
        return 0;
 }
 
@@ -498,7 +508,11 @@ static int sd_set_bus_speed_mode(struct mmc_card *card, u8 *status)
                err = -EBUSY;
        } else {
                mmc_set_timing(card->host, timing);
-               mmc_set_clock(card->host, card->sw_caps.uhs_max_dtr);
+               if (card->host->ops->check_temp(card->host) &&
+                               timing == MMC_TIMING_UHS_SDR104)
+                       mmc_set_clock(card->host, UHS_SDR50_MAX_DTR);
+               else
+                       mmc_set_clock(card->host, card->sw_caps.uhs_max_dtr);
        }
 
        return err;
@@ -1122,6 +1136,34 @@ free_card:
        return err;
 }
 
+static int mmc_sd_init_temp_control_clk_scaling(struct mmc_host *host)
+{
+       int ret;
+
+       if (host->ops->reg_temp_callback) {
+               ret = host->ops->reg_temp_callback(host);
+       } else {
+               pr_err("%s: %s: couldn't find init temp control clk scaling cb\n",
+                       mmc_hostname(host), __func__);
+               ret = -ENOCALLBACK;
+       }
+       return ret;
+}
+
+static int mmc_sd_dereg_temp_control_clk_scaling(struct mmc_host *host)
+{
+       int ret;
+
+       if (host->ops->dereg_temp_callback) {
+               ret = host->ops->dereg_temp_callback(host);
+       } else {
+               pr_err("%s: %s: couldn't find dereg temp control clk scaling cb\n",
+                       mmc_hostname(host), __func__);
+               ret = -ENOCALLBACK;
+       }
+       return ret;
+}
+
 /*
  * Host is being removed. Free up the current card.
  */
@@ -1131,6 +1173,7 @@ static void mmc_sd_remove(struct mmc_host *host)
        BUG_ON(!host->card);
 
        mmc_exit_clk_scaling(host);
+       mmc_sd_dereg_temp_control_clk_scaling(host);
        mmc_remove_card(host->card);
 
        mmc_claim_host(host);
@@ -1448,6 +1491,12 @@ int mmc_attach_sd(struct mmc_host *host)
                        goto err;
        }
 
+       /*
+        * Some SD cards claims an out of spec VDD voltage range. Let's treat
+        * these bits as being in-valid and especially also bit7.
+        */
+       ocr &= ~0x7FFF;
+
        rocr = mmc_select_voltage(host, ocr);
 
        /*
@@ -1458,6 +1507,9 @@ int mmc_attach_sd(struct mmc_host *host)
                goto err;
        }
 
+       if (mmc_sd_init_temp_control_clk_scaling(host))
+               pr_err("%s: failed to init temp control clk scaling\n",
+                       mmc_hostname(host));
        /*
         * Detect and init the card.
         */