diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 044d84e..b5c6f5f 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -249,8 +249,10 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card) * SDIO cards only define an upper 1 s limit on access. */ if (mmc_card_sdio(card)) { - data->timeout_ns = 1000000000; - data->timeout_clks = 0; + if (data->timeout_ns > 1000000000) { + data->timeout_ns = 1000000000; + data->timeout_clks = 0; + } return; } @@ -269,6 +271,11 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card) data->timeout_ns = card->csd.tacc_ns * mult; data->timeout_clks = card->csd.tacc_clks * mult; + data->ktimeout = ktime_set(0, 0); + data->ktimeout = ktime_add_ns(data->ktimeout, data->timeout_ns); + data->ktimeout = ktime_add_ns(data->ktimeout, + data->timeout_clks * 1000000 / card->host->ios.clock); + /* * SD cards also have an upper limit on the timeout. */ @@ -290,6 +297,8 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card) if (timeout_us > limit_us || mmc_card_blockaddr(card)) { data->timeout_ns = limit_us * 1000; data->timeout_clks = 0; + data->ktimeout = ktime_add_ns(ktime_set(0, 0), + data->timeout_ns); } } } diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c index 7503b81..cdeb2e5 100644 --- a/drivers/mmc/host/mmc_spi.c +++ b/drivers/mmc/host/mmc_spi.c @@ -95,8 +95,6 @@ * reads which takes nowhere near that long. Older cards may be able to use * shorter timeouts ... but why bother? */ -#define readblock_timeout ktime_set(0, 100 * 1000 * 1000) -#define writeblock_timeout ktime_set(0, 250 * 1000 * 1000) #define r1b_timeout ktime_set(3, 0) @@ -220,9 +218,9 @@ mmc_spi_wait_unbusy(struct mmc_spi_host *host, ktime_t timeout) return mmc_spi_skip(host, timeout, sizeof(host->data->status), 0); } -static int mmc_spi_readtoken(struct mmc_spi_host *host) +static int mmc_spi_readtoken(struct mmc_spi_host *host, ktime_t timeout) { - return mmc_spi_skip(host, readblock_timeout, 1, 0xff); + return mmc_spi_skip(host, timeout, 1, 0xff); } @@ -605,7 +603,8 @@ mmc_spi_setup_data_message( * Return negative errno, else success. */ static int -mmc_spi_writeblock(struct mmc_spi_host *host, struct spi_transfer *t) +mmc_spi_writeblock(struct mmc_spi_host *host, struct spi_transfer *t, + ktime_t writeblock_timeout) { struct spi_device *spi = host->spi; int status, i; @@ -693,7 +692,8 @@ mmc_spi_writeblock(struct mmc_spi_host *host, struct spi_transfer *t) * STOP_TRANSMISSION command. */ static int -mmc_spi_readblock(struct mmc_spi_host *host, struct spi_transfer *t) +mmc_spi_readblock(struct mmc_spi_host *host, struct spi_transfer *t, + ktime_t readblock_timeout) { struct spi_device *spi = host->spi; int status; @@ -707,7 +707,7 @@ mmc_spi_readblock(struct mmc_spi_host *host, struct spi_transfer *t) return status; status = scratch->status[0]; if (status == 0xff || status == 0) - status = mmc_spi_readtoken(host); + status = mmc_spi_readtoken(host, readblock_timeout); if (status == SPI_TOKEN_SINGLE) { if (host->dma_dev) { @@ -832,9 +832,11 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd, t->len); if (direction == DMA_TO_DEVICE) - status = mmc_spi_writeblock(host, t); + status = mmc_spi_writeblock(host, t, + data->ktimeout); else - status = mmc_spi_readblock(host, t); + status = mmc_spi_readblock(host, t, + data->ktimeout); if (status < 0) break; @@ -917,7 +919,7 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd, if (scratch->status[tmp] != 0) return; } - tmp = mmc_spi_wait_unbusy(host, writeblock_timeout); + tmp = mmc_spi_wait_unbusy(host, data->ktimeout); if (tmp < 0 && !data->error) data->error = tmp; } diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index 143cebf..e518391 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h @@ -10,6 +10,7 @@ #include #include +#include struct request; struct mmc_data; @@ -99,6 +100,7 @@ struct mmc_command { struct mmc_data { unsigned int timeout_ns; /* data timeout (in ns, max 80ms) */ unsigned int timeout_clks; /* data timeout (in clocks) */ + ktime_t ktimeout; /* data timeout */ unsigned int blksz; /* data block size */ unsigned int blocks; /* number of blocks */ unsigned int error; /* data error */