diff options
author | David Yu <davyu@nvidia.com> | 2013-12-12 11:36:40 +0900 |
---|---|---|
committer | Harry Hong <hhong@nvidia.com> | 2013-12-12 20:12:00 -0800 |
commit | 9a1bc99f0448ac515f334cdf31717dbf41e307a9 (patch) | |
tree | 2b8ad19592366eca499f0cbf0298a2e0c4b7de3f | |
parent | be06df21db5747aee304696004e1a0e31afd8f26 (diff) |
mmc: tegra: error handling if no card
if sd card removed during tap_delay tuning,
don't exit until trying MAX_TAP_VALUES.
it makes the system un-responsive for 2 sec.
Therefore, adding to check card_present before starting
freq_tuning.
if card is not present, return error
and then exit tuning procedure.
Bug 1422437
Bug 1364449
Change-Id: Ib8dff29a1c1faade2acaa93c3e97ea23d3e3041c
Reviewed-on: http://git-master/r/272902
Signed-off-by: David Yu <davyu@nvidia.com>
Reviewed-on: http://git-master/r/344556
(cherry picked from commit 7a0bd79cb7d672356f5010c3c06c8ff1c1f5a10b)
Reviewed-on: http://git-master/r/345037
Reviewed-by: Harry Hong <hhong@nvidia.com>
Tested-by: Harry Hong <hhong@nvidia.com>
-rw-r--r-- | drivers/mmc/host/sdhci-tegra.c | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c index 571962446e9d..8b9c89673e81 100644 --- a/drivers/mmc/host/sdhci-tegra.c +++ b/drivers/mmc/host/sdhci-tegra.c @@ -1679,6 +1679,7 @@ static int sdhci_tegra_issue_tuning_cmd(struct sdhci_host *sdhci) { struct sdhci_pltfm_host *pltfm_host = sdhci_priv(sdhci); struct sdhci_tegra *tegra_host = pltfm_host->priv; + const struct tegra_sdhci_platform_data *plat = tegra_host->plat; int err = 0; u8 ctrl; u32 mask; @@ -1686,6 +1687,10 @@ static int sdhci_tegra_issue_tuning_cmd(struct sdhci_host *sdhci) int flags; u32 intstatus; + if (gpio_is_valid(plat->cd_gpio) + && (gpio_get_value(plat->cd_gpio) != 0)) + return -ENODEV; + mask = SDHCI_CMD_INHIBIT | SDHCI_DATA_INHIBIT; while (sdhci_readl(sdhci, SDHCI_PRESENT_STATE) & mask) { if (timeout == 0) { @@ -1747,7 +1752,7 @@ static int sdhci_tegra_issue_tuning_cmd(struct sdhci_host *sdhci) } else { tegra_sdhci_reset(sdhci, SDHCI_RESET_CMD); tegra_sdhci_reset(sdhci, SDHCI_RESET_DATA); - err = -EIO; + err = -EAGAIN; } if (sdhci->tuning_done) { @@ -1757,7 +1762,7 @@ static int sdhci_tegra_issue_tuning_cmd(struct sdhci_host *sdhci) (ctrl & SDHCI_CTRL_TUNED_CLK)) err = 0; else - err = -EIO; + err = -EAGAIN; } mdelay(1); out: @@ -1777,6 +1782,8 @@ static int sdhci_tegra_scan_tap_values(struct sdhci_host *sdhci, /* Run frequency tuning */ err = sdhci_tegra_issue_tuning_cmd(sdhci); + if (err == -ENODEV) + return err; if (err && retry) { retry--; continue; @@ -1813,7 +1820,10 @@ static int sdhci_tegra_get_tap_window_data(struct sdhci_host *sdhci, /* Get the partial window data */ tap_value = 0; tap_value = sdhci_tegra_scan_tap_values(sdhci, tap_value, false); - if (!tap_value) { + if (tap_value < 0) { + err = -EIO; + goto out; + } else if (!tap_value) { tap_data->abandon_partial_win = true; tap_data->partial_win = 0; } else if (tap_value > MAX_TAP_VALUES) { @@ -1838,7 +1848,10 @@ static int sdhci_tegra_get_tap_window_data(struct sdhci_host *sdhci, /* Get the full window start */ tap_value++; tap_value = sdhci_tegra_scan_tap_values(sdhci, tap_value, true); - if (tap_value > MAX_TAP_VALUES) { + if (tap_value < 0) { + err = -EIO; + goto out; + } else if (tap_value > MAX_TAP_VALUES) { /* All tap values exhausted. No full window */ tap_data->abandon_full_win = true; goto out; |