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 */