[PATCH 2/3] mmc: omap_hsmmc: Errata: Fix SD card removal detection

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxx>
Signed-off-by: Semen Protsenko <semen.protsenko@xxxxxx>
---
 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 61d830f..49a1a03 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -1180,12 +1180,20 @@ 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);
 	}
 	return IRQ_HANDLED;
@@ -1500,6 +1508,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;
 	err = omap_hsmmc_prepare_data(host, req);
 	if (err) {
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux USB Devel]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux