aboutsummaryrefslogtreecommitdiff
path: root/drivers/mmc/core/mmc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/core/mmc.c')
-rw-r--r--drivers/mmc/core/mmc.c35
1 files changed, 15 insertions, 20 deletions
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index a301a78a2bd1..449aa7a4227d 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -388,6 +388,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.
*/
@@ -450,6 +453,10 @@ static int mmc_read_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)
@@ -998,7 +1005,7 @@ static int mmc_select_hs_ddr(struct mmc_card *card)
ext_csd_bits,
card->ext_csd.generic_cmd6_time);
if (err) {
- pr_warn("%s: switch to bus width %d ddr failed\n",
+ pr_err("%s: switch to bus width %d ddr failed\n",
mmc_hostname(host), 1 << bus_width);
return err;
}
@@ -1069,7 +1076,7 @@ static int mmc_select_hs400(struct mmc_card *card)
card->ext_csd.generic_cmd6_time,
true, true, true);
if (err) {
- pr_warn("%s: switch to high-speed from hs200 failed, err:%d\n",
+ pr_err("%s: switch to high-speed from hs200 failed, err:%d\n",
mmc_hostname(host), err);
return err;
}
@@ -1079,7 +1086,7 @@ static int mmc_select_hs400(struct mmc_card *card)
EXT_CSD_DDR_BUS_WIDTH_8,
card->ext_csd.generic_cmd6_time);
if (err) {
- pr_warn("%s: switch to bus width for hs400 failed, err:%d\n",
+ pr_err("%s: switch to bus width for hs400 failed, err:%d\n",
mmc_hostname(host), err);
return err;
}
@@ -1089,7 +1096,7 @@ static int mmc_select_hs400(struct mmc_card *card)
card->ext_csd.generic_cmd6_time,
true, true, true);
if (err) {
- pr_warn("%s: switch to hs400 failed, err:%d\n",
+ pr_err("%s: switch to hs400 failed, err:%d\n",
mmc_hostname(host), err);
return err;
}
@@ -1214,7 +1221,6 @@ EXPORT_SYMBOL(tuning_blk_pattern_8bit);
static int mmc_hs200_tuning(struct mmc_card *card)
{
struct mmc_host *host = card->host;
- int err = 0;
/*
* Timing should be adjusted to the HS400 target
@@ -1225,18 +1231,7 @@ static int mmc_hs200_tuning(struct mmc_card *card)
if (host->ops->prepare_hs400_tuning)
host->ops->prepare_hs400_tuning(host, &host->ios);
- if (host->ops->execute_tuning) {
- mmc_host_clk_hold(host);
- err = host->ops->execute_tuning(host,
- MMC_SEND_TUNING_BLOCK_HS200);
- mmc_host_clk_release(host);
-
- if (err)
- pr_warn("%s: tuning execution failed\n",
- mmc_hostname(host));
- }
-
- return err;
+ return mmc_execute_tuning(card);
}
/*
@@ -1458,18 +1453,18 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
if (mmc_card_hs200(card)) {
err = mmc_hs200_tuning(card);
if (err)
- goto err;
+ goto free_card;
err = mmc_select_hs400(card);
if (err)
- goto err;
+ goto free_card;
} else if (mmc_card_hs(card)) {
/* Select the desired bus width optionally */
err = mmc_select_bus_width(card);
if (!IS_ERR_VALUE(err)) {
err = mmc_select_hs_ddr(card);
if (err)
- goto err;
+ goto free_card;
}
}