diff options
| -rw-r--r-- | drivers/mmc/mmc.c | 64 | ||||
| -rw-r--r-- | drivers/mmc/mmc_block.c | 35 | ||||
| -rw-r--r-- | include/linux/mmc/mmc.h | 2 |
3 files changed, 53 insertions, 48 deletions
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index c0c7ef2a8b28..74eaaee66de0 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, | |||
| 247 | 247 | ||
| 248 | EXPORT_SYMBOL(mmc_wait_for_app_cmd); | 248 | EXPORT_SYMBOL(mmc_wait_for_app_cmd); |
| 249 | 249 | ||
| 250 | /** | ||
| 251 | * mmc_set_data_timeout - set the timeout for a data command | ||
| 252 | * @data: data phase for command | ||
| 253 | * @card: the MMC card associated with the data transfer | ||
| 254 | * @write: flag to differentiate reads from writes | ||
| 255 | */ | ||
| 256 | void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card, | ||
| 257 | int write) | ||
| 258 | { | ||
| 259 | unsigned int mult; | ||
| 260 | |||
| 261 | /* | ||
| 262 | * SD cards use a 100 multiplier rather than 10 | ||
| 263 | */ | ||
| 264 | mult = mmc_card_sd(card) ? 100 : 10; | ||
| 265 | |||
| 266 | /* | ||
| 267 | * Scale up the multiplier (and therefore the timeout) by | ||
| 268 | * the r2w factor for writes. | ||
| 269 | */ | ||
| 270 | if (write) | ||
| 271 | mult <<= card->csd.r2w_factor; | ||
| 272 | |||
| 273 | data->timeout_ns = card->csd.tacc_ns * mult; | ||
| 274 | data->timeout_clks = card->csd.tacc_clks * mult; | ||
| 275 | |||
| 276 | /* | ||
| 277 | * SD cards also have an upper limit on the timeout. | ||
| 278 | */ | ||
| 279 | if (mmc_card_sd(card)) { | ||
| 280 | unsigned int timeout_us, limit_us; | ||
| 281 | |||
| 282 | timeout_us = data->timeout_ns / 1000; | ||
| 283 | timeout_us += data->timeout_clks * 1000 / | ||
| 284 | (card->host->ios.clock / 1000); | ||
| 285 | |||
| 286 | if (write) | ||
| 287 | limit_us = 250000; | ||
| 288 | else | ||
| 289 | limit_us = 100000; | ||
| 290 | |||
| 291 | if (timeout_us > limit_us) { | ||
| 292 | data->timeout_ns = limit_us * 1000; | ||
| 293 | data->timeout_clks = 0; | ||
| 294 | } | ||
| 295 | } | ||
| 296 | } | ||
| 297 | EXPORT_SYMBOL(mmc_set_data_timeout); | ||
| 298 | |||
| 250 | static int mmc_select_card(struct mmc_host *host, struct mmc_card *card); | 299 | static int mmc_select_card(struct mmc_host *host, struct mmc_card *card); |
| 251 | 300 | ||
| 252 | /** | 301 | /** |
| @@ -908,12 +957,9 @@ static void mmc_read_scrs(struct mmc_host *host) | |||
| 908 | { | 957 | { |
| 909 | int err; | 958 | int err; |
| 910 | struct mmc_card *card; | 959 | struct mmc_card *card; |
| 911 | |||
| 912 | struct mmc_request mrq; | 960 | struct mmc_request mrq; |
| 913 | struct mmc_command cmd; | 961 | struct mmc_command cmd; |
| 914 | struct mmc_data data; | 962 | struct mmc_data data; |
| 915 | unsigned int timeout_us; | ||
| 916 | |||
| 917 | struct scatterlist sg; | 963 | struct scatterlist sg; |
| 918 | 964 | ||
| 919 | list_for_each_entry(card, &host->cards, node) { | 965 | list_for_each_entry(card, &host->cards, node) { |
| @@ -948,17 +994,7 @@ static void mmc_read_scrs(struct mmc_host *host) | |||
| 948 | 994 | ||
| 949 | memset(&data, 0, sizeof(struct mmc_data)); | 995 | memset(&data, 0, sizeof(struct mmc_data)); |
| 950 | 996 | ||
| 951 | data.timeout_ns = card->csd.tacc_ns * 100; | 997 | mmc_set_data_timeout(&data, card, 0); |
| 952 | data.timeout_clks = card->csd.tacc_clks * 100; | ||
| 953 | |||
| 954 | timeout_us = data.timeout_ns / 1000; | ||
| 955 | timeout_us += data.timeout_clks * 1000 / | ||
| 956 | (host->ios.clock / 1000); | ||
| 957 | |||
| 958 | if (timeout_us > 100000) { | ||
| 959 | data.timeout_ns = 100000000; | ||
| 960 | data.timeout_clks = 0; | ||
| 961 | } | ||
| 962 | 998 | ||
| 963 | data.blksz_bits = 3; | 999 | data.blksz_bits = 3; |
| 964 | data.blksz = 1 << 3; | 1000 | data.blksz = 1 << 3; |
diff --git a/drivers/mmc/mmc_block.c b/drivers/mmc/mmc_block.c index 515fb227eba7..d6fcc467b503 100644 --- a/drivers/mmc/mmc_block.c +++ b/drivers/mmc/mmc_block.c | |||
| @@ -179,40 +179,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | |||
| 179 | brq.stop.arg = 0; | 179 | brq.stop.arg = 0; |
| 180 | brq.stop.flags = MMC_RSP_R1B | MMC_CMD_AC; | 180 | brq.stop.flags = MMC_RSP_R1B | MMC_CMD_AC; |
| 181 | 181 | ||
| 182 | brq.data.timeout_ns = card->csd.tacc_ns * 10; | 182 | mmc_set_data_timeout(&brq.data, card, rq_data_dir(req) != READ); |
| 183 | brq.data.timeout_clks = card->csd.tacc_clks * 10; | ||
| 184 | |||
| 185 | /* | ||
| 186 | * Scale up the timeout by the r2w factor | ||
| 187 | */ | ||
| 188 | if (rq_data_dir(req) == WRITE) { | ||
| 189 | brq.data.timeout_ns <<= card->csd.r2w_factor; | ||
| 190 | brq.data.timeout_clks <<= card->csd.r2w_factor; | ||
| 191 | } | ||
| 192 | |||
| 193 | /* | ||
| 194 | * SD cards use a 100 multiplier and has a upper limit | ||
| 195 | */ | ||
| 196 | if (mmc_card_sd(card)) { | ||
| 197 | unsigned int limit_us, timeout_us; | ||
| 198 | |||
| 199 | brq.data.timeout_ns *= 10; | ||
| 200 | brq.data.timeout_clks *= 10; | ||
| 201 | |||
| 202 | if (rq_data_dir(req) == READ) | ||
| 203 | limit_us = 100000; | ||
| 204 | else | ||
| 205 | limit_us = 250000; | ||
| 206 | |||
| 207 | timeout_us = brq.data.timeout_ns / 1000; | ||
| 208 | timeout_us += brq.data.timeout_clks * 1000 / | ||
| 209 | (card->host->ios.clock / 1000); | ||
| 210 | |||
| 211 | if (timeout_us > limit_us) { | ||
| 212 | brq.data.timeout_ns = limit_us * 1000; | ||
| 213 | brq.data.timeout_clks = 0; | ||
| 214 | } | ||
| 215 | } | ||
| 216 | 183 | ||
| 217 | if (rq_data_dir(req) == READ) { | 184 | if (rq_data_dir(req) == READ) { |
| 218 | brq.cmd.opcode = brq.data.blocks > 1 ? MMC_READ_MULTIPLE_BLOCK : MMC_READ_SINGLE_BLOCK; | 185 | brq.cmd.opcode = brq.data.blocks > 1 ? MMC_READ_MULTIPLE_BLOCK : MMC_READ_SINGLE_BLOCK; |
diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h index 03a14a30c46a..627e2c08ce41 100644 --- a/include/linux/mmc/mmc.h +++ b/include/linux/mmc/mmc.h | |||
| @@ -105,6 +105,8 @@ extern int mmc_wait_for_cmd(struct mmc_host *, struct mmc_command *, int); | |||
| 105 | extern int mmc_wait_for_app_cmd(struct mmc_host *, unsigned int, | 105 | extern int mmc_wait_for_app_cmd(struct mmc_host *, unsigned int, |
| 106 | struct mmc_command *, int); | 106 | struct mmc_command *, int); |
| 107 | 107 | ||
| 108 | extern void mmc_set_data_timeout(struct mmc_data *, const struct mmc_card *, int); | ||
| 109 | |||
| 108 | extern int __mmc_claim_host(struct mmc_host *host, struct mmc_card *card); | 110 | extern int __mmc_claim_host(struct mmc_host *host, struct mmc_card *card); |
| 109 | 111 | ||
| 110 | static inline void mmc_claim_host(struct mmc_host *host) | 112 | static inline void mmc_claim_host(struct mmc_host *host) |
