diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c index 7503b81..2818837 100644 --- a/drivers/mmc/host/mmc_spi.c +++ b/drivers/mmc/host/mmc_spi.c @@ -34,6 +34,7 @@ #include #include /* for R1_SPI_* bit values */ +#include #include #include @@ -96,7 +97,6 @@ * 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) @@ -225,6 +225,20 @@ static int mmc_spi_readtoken(struct mmc_spi_host *host) return mmc_spi_skip(host, readblock_timeout, 1, 0xff); } +/* + * Return the write timeout value (in nanoseconds) for this card. + */ +static inline unsigned int +mmc_get_write_timeout(struct mmc_spi_host *host, struct mmc_data *data) +{ + unsigned int timeout_ns; + + timeout_ns = data->timeout_ns; + timeout_ns += data->timeout_clks * 1000 * 1000 / + (host->mmc->card->host->ios.clock); + + return timeout_ns; +} /* * Note that for SPI, cmd->resp[0] is not the same data as "native" protocol @@ -605,11 +619,13 @@ 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, + struct mmc_data *data) { struct spi_device *spi = host->spi; int status, i; struct scratch *scratch = host->data; + unsigned int timeout_ns; if (host->mmc->use_spi_crc) scratch->crc_val = cpu_to_be16( @@ -673,7 +689,11 @@ mmc_spi_writeblock(struct mmc_spi_host *host, struct spi_transfer *t) if (scratch->status[i] != 0) return 0; } - return mmc_spi_wait_unbusy(host, writeblock_timeout); + + timeout_ns = mmc_get_write_timeout(host, data); + + return mmc_spi_wait_unbusy(host, + ktime_add_ns(ktime_set(0, 0), timeout_ns)); } /* @@ -832,7 +852,7 @@ 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); else status = mmc_spi_readblock(host, t); if (status < 0) @@ -872,6 +892,7 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd, struct scratch *scratch = host->data; int tmp; const unsigned statlen = sizeof(scratch->status); + unsigned int timeout_ns; dev_dbg(&spi->dev, " mmc_spi: STOP_TRAN\n"); @@ -917,7 +938,9 @@ 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); + timeout_ns = mmc_get_write_timeout(host, data); + tmp = mmc_spi_wait_unbusy(host, + ktime_add_ns(ktime_set(0, 0), timeout_ns)); if (tmp < 0 && !data->error) data->error = tmp; }