diff options
author | Viswanath Puttagunta <vishp@ti.com> | 2011-12-12 19:06:46 -0600 |
---|---|---|
committer | Andy Green <andy.green@linaro.org> | 2012-09-07 13:06:13 +0800 |
commit | 33a9324ad147bf3d7cdac7ce34d5d12cb313ebb7 (patch) | |
tree | 0cffdaf4a2d671536e0ce6263f02740045d84692 /drivers | |
parent | 5fa0fe4e45d30fe16de77062396655967f4c0a94 (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.c | 28 |
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); |