From 48686b39b3779cbca52a4fbd539026de2d1c7a98 Mon Sep 17 00:00:00 2001 From: Sarthak Garg Date: Mon, 21 Sep 2020 10:02:48 +0530 Subject: [PATCH] mmc: core: Remove SD card upon recovery failure In case of bad SD card recovery fails everytime. Also some SD cards fail on Read/writes but can get initialized successfully. Mark card as removed and gracefully remove by calling mmc_detect_change. Also mark the card as corrupted and return to avoid reinitialization as sdhci_get_cd will return non zero as the card is physically present and avoid mmc_rescan from proceeding ahead. Change-Id: Id4c99d4608ef2b5f49cf5ac796a2aaf6d12a56c2 Signed-off-by: Sarthak Garg --- drivers/mmc/core/block.c | 9 +++++++++ drivers/mmc/core/core.c | 5 +++++ drivers/mmc/core/slot-gpio.c | 5 +++++ include/linux/mmc/host.h | 4 +++- 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index f30bd7d5f99a..20e3632af5ce 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -1840,6 +1840,15 @@ static void mmc_blk_mq_rw_recovery(struct mmc_queue *mq, struct request *req) err && mmc_blk_reset(md, card->host, type)) { pr_err("%s: recovery failed!\n", req->rq_disk->disk_name); mqrq->retries = MMC_NO_RETRIES; + +#if defined(CONFIG_SDC_QTI) + /* Completely remove the non-recoverable card */ + if (mmc_card_sd(card)) { + mmc_card_set_removed(card); + card->host->corrupted_card = true; + mmc_detect_change(card->host, msecs_to_jiffies(200)); + } +#endif return; } diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index fffd6d6470a1..f718426fd45d 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -2997,6 +2997,11 @@ void mmc_rescan(struct work_struct *work) if (host->bus_ops && !host->bus_dead) host->bus_ops->detect(host); +#if defined(CONFIG_SDC_QTI) + if (host->corrupted_card) + return; +#endif + host->detect_change = 0; /* diff --git a/drivers/mmc/core/slot-gpio.c b/drivers/mmc/core/slot-gpio.c index 582ec3d720f6..86c34eb22e10 100644 --- a/drivers/mmc/core/slot-gpio.c +++ b/drivers/mmc/core/slot-gpio.c @@ -32,6 +32,11 @@ static irqreturn_t mmc_gpio_cd_irqt(int irq, void *dev_id) struct mmc_host *host = dev_id; struct mmc_gpio *ctx = host->slot.handler_priv; +#if defined(CONFIG_SDC_QTI) + /* New card is not corrupted */ + host->corrupted_card = false; +#endif + host->trigger_card_event = true; mmc_detect_change(host, msecs_to_jiffies(ctx->cd_debounce_delay_ms)); diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index d2cdcc41f7c1..c8ad4e5ffe28 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -499,7 +499,9 @@ struct mmc_host { int rescan_disable; /* disable card detection */ int rescan_entered; /* used with nonremovable devices */ - +#if defined(CONFIG_SDC_QTI) + bool corrupted_card; /* good/bad associated card */ +#endif int need_retune; /* re-tuning is needed */ int hold_retune; /* hold off re-tuning */ unsigned int retune_period; /* re-tuning period in secs */