aboutsummaryrefslogtreecommitdiff
path: root/drivers/mmc/core/block.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/core/block.c')
-rw-r--r--drivers/mmc/core/block.c69
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