summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorViswanath Puttagunta <vishp@ti.com>2011-12-12 19:06:46 -0600
committerAndy Green <andy.green@linaro.org>2012-09-07 13:06:13 +0800
commit33a9324ad147bf3d7cdac7ce34d5d12cb313ebb7 (patch)
tree0cffdaf4a2d671536e0ce6263f02740045d84692 /drivers
parent5fa0fe4e45d30fe16de77062396655967f4c0a94 (diff)
omap_hsmmc: Errata: Fix SD card removal detection
Because of OMAP4 Silicon errata (i705), we have to turn off the PBIAS and VMMC for SD card as soon as we get card disconnect interrupt. Because of this, we don't wait for all higher layer structures to be dismantled before turning off power. As a side effect of this, we might end up getting a mmc_request even after SD is removed and VMMC and PBIAS are turned off. In that case, just fail the mmc_request and return immediately Signed-off-by: Viswanath Puttagunta <vishp@ti.com> Signed-off-by: Sebastien Jan <s-jan@ti.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mmc/host/omap_hsmmc.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 79fa155cef9e..cb95f2c747c4 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -1312,11 +1312,19 @@ static irqreturn_t omap_hsmmc_detect(int irq, void *dev_id)
if (carddetect) {
mmc_detect_change(host->mmc, (HZ * 200) / 1000);
} else {
+ /*
+ * Because of OMAP4 Silicon errata (i705), we have to turn off the
+ * PBIAS and VMMC for SD card as soon as we get card disconnect
+ * interrupt. Because of this, we don't wait for all higher layer
+ * structures to be dismantled before turning off power
+ */
+ mmc_claim_host(host->mmc);
if ((MMC_POWER_OFF != host->power_mode) &&
(mmc_slot(host).set_power != NULL)) {
mmc_slot(host).set_power(host->dev, host->slot_id, 0, 0);
host->power_mode = MMC_POWER_OFF;
}
+ mmc_release_host(host->mmc);
mmc_detect_change(host->mmc, 0);
}
@@ -1632,6 +1640,26 @@ static void omap_hsmmc_request(struct mmc_host *mmc, struct mmc_request *req)
} else if (host->reqs_blocked)
host->reqs_blocked = 0;
WARN_ON(host->mrq != NULL);
+
+ /*
+ * Because of OMAP4 Silicon errata (i705), we have to turn off the
+ * PBIAS and VMMC for SD card as soon as we get card disconnect
+ * interrupt. Because of this, we don't wait for all higher layer
+ * structures to be dismantled before turning off power. Because
+ * of this, we might end up here even after SD card is removed
+ * and VMMC and PBIAS are turned off. In that case, just fail
+ * the commands immediately
+ */
+ if (host->power_mode == MMC_POWER_OFF) {
+ req->cmd->error = EIO;
+ if (req->data)
+ req->data->error = -EIO;
+ dev_warn(mmc_dev(host->mmc),
+ "Card is no longer present\n");
+ mmc_request_done(mmc, req);
+ return;
+ }
+
host->mrq = req;
if (req->sbc) {
omap_hsmmc_start_command(host, req->sbc, NULL, 0);