diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-09-11 07:56:38 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-09-11 07:56:38 -0700 |
commit | e004876c3b0b6a71406069b0e55368cb9bbdc920 (patch) | |
tree | 43f95e14b282cbc683ec66539de25e0e94649f65 /drivers/mmc/mmc.c | |
parent | 5a05e5bf204e729b79e9462785f2fa09d5126855 (diff) | |
parent | 6fe9febb8af2f82f9caace1aa1c00cd8de7469ac (diff) |
Merge master.kernel.org:/home/rmk/linux-2.6-mmc
* master.kernel.org:/home/rmk/linux-2.6-mmc:
[MMC] Always use a sector size of 512 bytes
[MMC] Cleanup 385e3227d4d83ab13d7767c4bb3593b0256bf246
[ARM] 3751/1: i.MX/MX1 SD/MMC use 512 bytes request for SCR read
[MMC] Fix SD timeout calculation
[MMC] constify mmc_host_ops
Diffstat (limited to 'drivers/mmc/mmc.c')
-rw-r--r-- | drivers/mmc/mmc.c | 55 |
1 files changed, 51 insertions, 4 deletions
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 33525bdf2ab..74eaaee66de 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -247,6 +247,55 @@ int mmc_wait_for_app_cmd(struct mmc_host *host, unsigned int rca, EXPORT_SYMBOL(mmc_wait_for_app_cmd); +/** + * mmc_set_data_timeout - set the timeout for a data command + * @data: data phase for command + * @card: the MMC card associated with the data transfer + * @write: flag to differentiate reads from writes + */ +void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card, + int write) +{ + unsigned int mult; + + /* + * SD cards use a 100 multiplier rather than 10 + */ + mult = mmc_card_sd(card) ? 100 : 10; + + /* + * Scale up the multiplier (and therefore the timeout) by + * the r2w factor for writes. + */ + if (write) + mult <<= card->csd.r2w_factor; + + data->timeout_ns = card->csd.tacc_ns * mult; + data->timeout_clks = card->csd.tacc_clks * mult; + + /* + * SD cards also have an upper limit on the timeout. + */ + if (mmc_card_sd(card)) { + unsigned int timeout_us, limit_us; + + timeout_us = data->timeout_ns / 1000; + timeout_us += data->timeout_clks * 1000 / + (card->host->ios.clock / 1000); + + if (write) + limit_us = 250000; + else + limit_us = 100000; + + if (timeout_us > limit_us) { + data->timeout_ns = limit_us * 1000; + data->timeout_clks = 0; + } + } +} +EXPORT_SYMBOL(mmc_set_data_timeout); + static int mmc_select_card(struct mmc_host *host, struct mmc_card *card); /** @@ -908,11 +957,9 @@ static void mmc_read_scrs(struct mmc_host *host) { int err; struct mmc_card *card; - struct mmc_request mrq; struct mmc_command cmd; struct mmc_data data; - struct scatterlist sg; list_for_each_entry(card, &host->cards, node) { @@ -947,8 +994,8 @@ static void mmc_read_scrs(struct mmc_host *host) memset(&data, 0, sizeof(struct mmc_data)); - data.timeout_ns = card->csd.tacc_ns * 10; - data.timeout_clks = card->csd.tacc_clks * 10; + mmc_set_data_timeout(&data, card, 0); + data.blksz_bits = 3; data.blksz = 1 << 3; data.blocks = 1; |