mmc: core: fix power class selection
[pandora-kernel.git] / drivers / mmc / core / mmc.c
index 2b9ed14..54df5ad 100644 (file)
@@ -519,6 +519,20 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
                        ext_csd[EXT_CSD_CACHE_SIZE + 1] << 8 |
                        ext_csd[EXT_CSD_CACHE_SIZE + 2] << 16 |
                        ext_csd[EXT_CSD_CACHE_SIZE + 3] << 24;
+
+               if (ext_csd[EXT_CSD_DATA_SECTOR_SIZE] == 1)
+                       card->ext_csd.data_sector_size = 4096;
+               else
+                       card->ext_csd.data_sector_size = 512;
+
+               if ((ext_csd[EXT_CSD_DATA_TAG_SUPPORT] & 1) &&
+                   (ext_csd[EXT_CSD_TAG_UNIT_SIZE] <= 8)) {
+                       card->ext_csd.data_tag_unit_size =
+                       ((unsigned int) 1 << ext_csd[EXT_CSD_TAG_UNIT_SIZE]) *
+                       (card->ext_csd.data_sector_size);
+               } else {
+                       card->ext_csd.data_tag_unit_size = 0;
+               }
        }
 
 out:
@@ -681,6 +695,11 @@ static int mmc_select_powerclass(struct mmc_card *card,
                else if (host->ios.clock <= 200000000)
                        index = EXT_CSD_PWR_CL_200_195;
                break;
+       case MMC_VDD_27_28:
+       case MMC_VDD_28_29:
+       case MMC_VDD_29_30:
+       case MMC_VDD_30_31:
+       case MMC_VDD_31_32:
        case MMC_VDD_32_33:
        case MMC_VDD_33_34:
        case MMC_VDD_34_35:
@@ -938,7 +957,8 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
         * If enhanced_area_en is TRUE, host needs to enable ERASE_GRP_DEF
         * bit.  This bit will be lost every time after a reset or power off.
         */
-       if (card->ext_csd.enhanced_area_en) {
+       if (card->ext_csd.enhanced_area_en ||
+           (card->ext_csd.rev >= 3 && (host->caps2 & MMC_CAP2_HC_ERASE_SZ))) {
                err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
                                 EXT_CSD_ERASE_GROUP_DEF, 1,
                                 card->ext_csd.generic_cmd6_time);
@@ -1032,22 +1052,6 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
                }
        }
 
-       /*
-        * Enable HPI feature (if supported)
-        */
-       if (card->ext_csd.hpi) {
-               err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-                       EXT_CSD_HPI_MGMT, 1, 0);
-               if (err && err != -EBADMSG)
-                       goto free_card;
-               if (err) {
-                       pr_warning("%s: Enabling HPI failed\n",
-                                  mmc_hostname(card->host));
-                       err = 0;
-               } else
-                       card->ext_csd.hpi_en = 1;
-       }
-
        /*
         * Compute bus speed.
         */
@@ -1097,9 +1101,12 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
                 * 4. execute tuning for HS200
                 */
                if ((host->caps2 & MMC_CAP2_HS200) &&
-                   card->host->ops->execute_tuning)
+                   card->host->ops->execute_tuning) {
+                       mmc_host_clk_hold(card->host);
                        err = card->host->ops->execute_tuning(card->host,
                                MMC_SEND_TUNING_BLOCK_HS200);
+                       mmc_host_clk_release(card->host);
+               }
                if (err) {
                        pr_warning("%s: tuning execution failed\n",
                                   mmc_hostname(card->host));
@@ -1109,11 +1116,10 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
                ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ?
                                EXT_CSD_BUS_WIDTH_8 : EXT_CSD_BUS_WIDTH_4;
                err = mmc_select_powerclass(card, ext_csd_bits, ext_csd);
-               if (err) {
-                       pr_err("%s: power class selection to bus width %d failed\n",
-                               mmc_hostname(card->host), 1 << bus_width);
-                       goto err;
-               }
+               if (err)
+                       pr_warning("%s: power class selection to bus width %d"
+                                  " failed\n", mmc_hostname(card->host),
+                                  1 << bus_width);
        }
 
        /*
@@ -1145,10 +1151,10 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
                        err = mmc_select_powerclass(card, ext_csd_bits[idx][0],
                                                    ext_csd);
                        if (err)
-                               pr_err("%s: power class selection to "
-                                      "bus width %d failed\n",
-                                      mmc_hostname(card->host),
-                                      1 << bus_width);
+                               pr_warning("%s: power class selection to "
+                                          "bus width %d failed\n",
+                                          mmc_hostname(card->host),
+                                          1 << bus_width);
 
                        err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
                                         EXT_CSD_BUS_WIDTH,
@@ -1176,10 +1182,10 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
                        err = mmc_select_powerclass(card, ext_csd_bits[idx][1],
                                                    ext_csd);
                        if (err)
-                               pr_err("%s: power class selection to "
-                                      "bus width %d ddr %d failed\n",
-                                      mmc_hostname(card->host),
-                                      1 << bus_width, ddr);
+                               pr_warning("%s: power class selection to "
+                                          "bus width %d ddr %d failed\n",
+                                          mmc_hostname(card->host),
+                                          1 << bus_width, ddr);
 
                        err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
                                         EXT_CSD_BUS_WIDTH,
@@ -1218,6 +1224,23 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
                }
        }
 
+       /*
+        * Enable HPI feature (if supported)
+        */
+       if (card->ext_csd.hpi) {
+               err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+                               EXT_CSD_HPI_MGMT, 1,
+                               card->ext_csd.generic_cmd6_time);
+               if (err && err != -EBADMSG)
+                       goto free_card;
+               if (err) {
+                       pr_warning("%s: Enabling HPI failed\n",
+                                  mmc_hostname(card->host));
+                       err = 0;
+               } else
+                       card->ext_csd.hpi_en = 1;
+       }
+
        /*
         * If cache size is higher than 0, this indicates
         * the existence of cache and it can be turned on.