Skip to content

Commit 3446dae

Browse files
committed
mmc: Speed up reboot with an absent card
On devices with no card detect mechanism, the host ends up polling for the insertion of a card. This polling happens at multiple frequencies and with many steps (SDIO, SD, MMC), some of which involve timeouts. If a reboot is requested during one of those scans, it will stall, pointlessly, for up to a minute while it completes. Attempt to short circuit the rescan if the MMC interface is being removed, as happens during a reboot. See: #6647 Signed-off-by: Phil Elwell <[email protected]>
1 parent 5227282 commit 3446dae

File tree

3 files changed

+20
-1
lines changed

3 files changed

+20
-1
lines changed

drivers/mmc/core/core.c

+13-1
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,12 @@ void mmc_wait_for_req_done(struct mmc_host *host, struct mmc_request *mrq)
399399
struct mmc_command *cmd;
400400

401401
while (1) {
402-
wait_for_completion(&mrq->completion);
402+
if (!host->rescan_disable)
403+
wait_for_completion(&mrq->completion);
404+
if (host->rescan_disable) {
405+
cmd->error = -ENOENT;
406+
break;
407+
}
403408

404409
cmd = mrq->cmd;
405410

@@ -619,6 +624,11 @@ EXPORT_SYMBOL(mmc_is_req_done);
619624
*/
620625
void mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq)
621626
{
627+
if (host->rescan_disable) {
628+
mrq->cmd->error = -ENOENT;
629+
return;
630+
}
631+
622632
__mmc_start_req(host, mrq);
623633

624634
if (!mrq->cap_cmd_during_tfr)
@@ -2265,6 +2275,8 @@ void mmc_rescan(struct work_struct *work)
22652275

22662276
for (i = 0; i < ARRAY_SIZE(freqs); i++) {
22672277
unsigned int freq = freqs[i];
2278+
if (host->rescan_disable)
2279+
return;
22682280
if (freq > host->f_max) {
22692281
if (i + 1 < ARRAY_SIZE(freqs))
22702282
continue;

drivers/mmc/core/mmc_ops.c

+3
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,9 @@ int __mmc_poll_for_busy(struct mmc_host *host, unsigned int period_us,
512512

513513
timeout = jiffies + msecs_to_jiffies(timeout_ms) + 1;
514514
do {
515+
if (host->rescan_disable)
516+
return -ENOENT;
517+
515518
/*
516519
* Due to the possibility of being preempted while polling,
517520
* check the expiration time first.

drivers/mmc/core/sdio.c

+4
Original file line numberDiff line numberDiff line change
@@ -673,6 +673,10 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
673673
ocr |= R4_18V_PRESENT;
674674

675675
try_again:
676+
if (host->rescan_disable) {
677+
err = -ENOENT;
678+
goto remove;
679+
}
676680
if (!retries) {
677681
pr_warn("%s: Skipping voltage switch\n", mmc_hostname(host));
678682
ocr &= ~R4_18V_PRESENT;

0 commit comments

Comments
 (0)