diff options
author | Russell King <rmk@dyn-67.arm.linux.org.uk> | 2006-09-07 10:57:12 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2006-09-07 10:57:12 -0400 |
commit | d773d7255199a6c8934e197756f54a1115dd127b (patch) | |
tree | 940cb1f15be1d27508927ad40d0262fbec462437 | |
parent | 148f93d59cc9bb5e0f9a04d36a6f91d435e1a3f7 (diff) |
[MMC] Cleanup 385e3227d4d83ab13d7767c4bb3593b0256bf246
Rather than having two places which independently calculate the
timeout for data transfers, make it a library function instead.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Acked-by: Pierre Ossman <drzeus@drzeus.cx>
-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) |