summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Yu <davyu@nvidia.com>2013-12-12 11:36:40 +0900
committerHarry Hong <hhong@nvidia.com>2013-12-12 20:12:00 -0800
commit9a1bc99f0448ac515f334cdf31717dbf41e307a9 (patch)
tree2b8ad19592366eca499f0cbf0298a2e0c4b7de3f
parentbe06df21db5747aee304696004e1a0e31afd8f26 (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.c21
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;