diff options
Diffstat (limited to 'drivers/mmc/core/block.c')
-rw-r--r-- | drivers/mmc/core/block.c | 69 |
1 files changed, 22 insertions, 47 deletions
diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index 20da7ed43e6d..2fab95b9c668 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -947,34 +947,6 @@ static int mmc_sd_num_wr_blocks(struct mmc_card *card, u32 *written_blocks) return 0; } -static unsigned int mmc_blk_clock_khz(struct mmc_host *host) -{ - if (host->actual_clock) - return host->actual_clock / 1000; - - /* Clock may be subject to a divisor, fudge it by a factor of 2. */ - if (host->ios.clock) - return host->ios.clock / 2000; - - /* How can there be no clock */ - WARN_ON_ONCE(1); - return 100; /* 100 kHz is minimum possible value */ -} - -static unsigned int mmc_blk_data_timeout_ms(struct mmc_host *host, - struct mmc_data *data) -{ - unsigned int ms = DIV_ROUND_UP(data->timeout_ns, 1000000); - unsigned int khz; - - if (data->timeout_clks) { - khz = mmc_blk_clock_khz(host); - ms += DIV_ROUND_UP(data->timeout_clks, khz); - } - - return ms; -} - /* * Attempts to reset the card and get back to the requested partition. * Therefore any error here must result in cancelling the block layer @@ -1656,31 +1628,34 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq, #define MMC_DATA_RETRIES 2 #define MMC_NO_RETRIES (MMC_MAX_RETRIES + 1) -static int mmc_blk_send_stop(struct mmc_card *card, unsigned int timeout) +static int mmc_blk_send_stop(struct mmc_card *card) { - struct mmc_command cmd = { - .opcode = MMC_STOP_TRANSMISSION, - .flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC, - /* Some hosts wait for busy anyway, so provide a busy timeout */ - .busy_timeout = timeout, - }; + unsigned int timeout_ms = MMC_BLK_TIMEOUT_MS; + struct mmc_host *host = card->host; + struct mmc_command cmd = {}; + bool use_r1b_resp; + int err; + + cmd.opcode = MMC_STOP_TRANSMISSION; + use_r1b_resp = mmc_prepare_busy_cmd(host, &cmd, timeout_ms); + + err = mmc_wait_for_cmd(host, &cmd, 0); + if (err) + return err; + + /* No need to poll when using HW busy detection. */ + if (host->caps & MMC_CAP_WAIT_WHILE_BUSY && use_r1b_resp) + return 0; - return mmc_wait_for_cmd(card->host, &cmd, 5); + return mmc_poll_for_busy(card, timeout_ms, false, MMC_BUSY_IO); } -static int mmc_blk_fix_state(struct mmc_card *card, struct request *req) +static int mmc_blk_fix_state(struct mmc_card *card) { - struct mmc_queue_req *mqrq = req_to_mmc_queue_req(req); - struct mmc_blk_request *brq = &mqrq->brq; - unsigned int timeout = mmc_blk_data_timeout_ms(card->host, &brq->data); int err; mmc_retune_hold_now(card->host); - - mmc_blk_send_stop(card, timeout); - - err = mmc_poll_for_busy(card, timeout, false, MMC_BUSY_IO); - + err = mmc_blk_send_stop(card); mmc_retune_release(card->host); return err; @@ -1714,7 +1689,7 @@ static void mmc_blk_read_single(struct mmc_queue *mq, struct request *req) if (!mmc_host_is_spi(host) && !mmc_ready_for_data(status)) { - err = mmc_blk_fix_state(card, req); + err = mmc_blk_fix_state(card); if (err) goto error_exit; } @@ -1835,7 +1810,7 @@ static void mmc_blk_mq_rw_recovery(struct mmc_queue *mq, struct request *req) /* Try to get back to "tran" state */ if (!mmc_host_is_spi(mq->card->host) && (err || !mmc_ready_for_data(status))) - err = mmc_blk_fix_state(mq->card, req); + err = mmc_blk_fix_state(mq->card); /* * Special case for SD cards where the card might record the number of |