diff options
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/Kconfig | 9 | ||||
-rw-r--r-- | drivers/mmc/card/Kconfig | 3 | ||||
-rw-r--r-- | drivers/mmc/card/block.c | 46 | ||||
-rw-r--r-- | drivers/mmc/card/queue.c | 23 | ||||
-rw-r--r-- | drivers/mmc/core/mmc_ops.c | 8 | ||||
-rw-r--r-- | drivers/mmc/core/sdio.c | 52 | ||||
-rw-r--r-- | drivers/mmc/core/sdio_irq.c | 16 | ||||
-rw-r--r-- | drivers/mmc/host/Kconfig | 19 | ||||
-rw-r--r-- | drivers/mmc/host/mmc_spi.c | 32 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci-pci.c | 3 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci.c | 46 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci.h | 2 |
12 files changed, 166 insertions, 93 deletions
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index c0b41e8bcd9d..f2eeb38efa65 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig | |||
@@ -3,13 +3,14 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | menuconfig MMC | 5 | menuconfig MMC |
6 | tristate "MMC/SD card support" | 6 | tristate "MMC/SD/SDIO card support" |
7 | depends on HAS_IOMEM | 7 | depends on HAS_IOMEM |
8 | help | 8 | help |
9 | MMC is the "multi-media card" bus protocol. | 9 | This selects MultiMediaCard, Secure Digital and Secure |
10 | Digital I/O support. | ||
10 | 11 | ||
11 | If you want MMC support, you should say Y here and also | 12 | If you want MMC/SD/SDIO support, you should say Y here and |
12 | to the specific driver for your MMC interface. | 13 | also to your specific host controller driver. |
13 | 14 | ||
14 | config MMC_DEBUG | 15 | config MMC_DEBUG |
15 | bool "MMC debugging" | 16 | bool "MMC debugging" |
diff --git a/drivers/mmc/card/Kconfig b/drivers/mmc/card/Kconfig index dd0f398ee2f5..3f2a912659af 100644 --- a/drivers/mmc/card/Kconfig +++ b/drivers/mmc/card/Kconfig | |||
@@ -2,7 +2,7 @@ | |||
2 | # MMC/SD card drivers | 2 | # MMC/SD card drivers |
3 | # | 3 | # |
4 | 4 | ||
5 | comment "MMC/SD Card Drivers" | 5 | comment "MMC/SD/SDIO Card Drivers" |
6 | 6 | ||
7 | config MMC_BLOCK | 7 | config MMC_BLOCK |
8 | tristate "MMC block device driver" | 8 | tristate "MMC block device driver" |
@@ -34,7 +34,6 @@ config MMC_BLOCK_BOUNCE | |||
34 | 34 | ||
35 | config SDIO_UART | 35 | config SDIO_UART |
36 | tristate "SDIO UART/GPS class support" | 36 | tristate "SDIO UART/GPS class support" |
37 | depends on MMC | ||
38 | help | 37 | help |
39 | SDIO function driver for SDIO cards that implements the UART | 38 | SDIO function driver for SDIO cards that implements the UART |
40 | class, as well as the GPS class which appears like a UART. | 39 | class, as well as the GPS class which appears like a UART. |
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index ebc8b9d77613..1d1e469e08ea 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c | |||
@@ -57,7 +57,6 @@ struct mmc_blk_data { | |||
57 | struct mmc_queue queue; | 57 | struct mmc_queue queue; |
58 | 58 | ||
59 | unsigned int usage; | 59 | unsigned int usage; |
60 | unsigned int block_bits; | ||
61 | unsigned int read_only; | 60 | unsigned int read_only; |
62 | }; | 61 | }; |
63 | 62 | ||
@@ -215,8 +214,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | |||
215 | struct mmc_blk_data *md = mq->data; | 214 | struct mmc_blk_data *md = mq->data; |
216 | struct mmc_card *card = md->queue.card; | 215 | struct mmc_card *card = md->queue.card; |
217 | struct mmc_blk_request brq; | 216 | struct mmc_blk_request brq; |
218 | int ret = 1, data_size, i; | 217 | int ret = 1; |
219 | struct scatterlist *sg; | ||
220 | 218 | ||
221 | mmc_claim_host(card->host); | 219 | mmc_claim_host(card->host); |
222 | 220 | ||
@@ -232,13 +230,11 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | |||
232 | if (!mmc_card_blockaddr(card)) | 230 | if (!mmc_card_blockaddr(card)) |
233 | brq.cmd.arg <<= 9; | 231 | brq.cmd.arg <<= 9; |
234 | brq.cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC; | 232 | brq.cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC; |
235 | brq.data.blksz = 1 << md->block_bits; | 233 | brq.data.blksz = 512; |
236 | brq.stop.opcode = MMC_STOP_TRANSMISSION; | 234 | brq.stop.opcode = MMC_STOP_TRANSMISSION; |
237 | brq.stop.arg = 0; | 235 | brq.stop.arg = 0; |
238 | brq.stop.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; | 236 | brq.stop.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; |
239 | brq.data.blocks = req->nr_sectors >> (md->block_bits - 9); | 237 | brq.data.blocks = req->nr_sectors; |
240 | if (brq.data.blocks > card->host->max_blk_count) | ||
241 | brq.data.blocks = card->host->max_blk_count; | ||
242 | 238 | ||
243 | if (brq.data.blocks > 1) { | 239 | if (brq.data.blocks > 1) { |
244 | /* SPI multiblock writes terminate using a special | 240 | /* SPI multiblock writes terminate using a special |
@@ -270,24 +266,6 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | |||
270 | 266 | ||
271 | mmc_queue_bounce_pre(mq); | 267 | mmc_queue_bounce_pre(mq); |
272 | 268 | ||
273 | /* | ||
274 | * Adjust the sg list so it is the same size as the | ||
275 | * request. | ||
276 | */ | ||
277 | if (brq.data.blocks != | ||
278 | (req->nr_sectors >> (md->block_bits - 9))) { | ||
279 | data_size = brq.data.blocks * brq.data.blksz; | ||
280 | for_each_sg(brq.data.sg, sg, brq.data.sg_len, i) { | ||
281 | data_size -= sg->length; | ||
282 | if (data_size <= 0) { | ||
283 | sg->length += data_size; | ||
284 | i++; | ||
285 | break; | ||
286 | } | ||
287 | } | ||
288 | brq.data.sg_len = i; | ||
289 | } | ||
290 | |||
291 | mmc_wait_for_req(card->host, &brq.mrq); | 269 | mmc_wait_for_req(card->host, &brq.mrq); |
292 | 270 | ||
293 | mmc_queue_bounce_post(mq); | 271 | mmc_queue_bounce_post(mq); |
@@ -372,16 +350,11 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | |||
372 | if (rq_data_dir(req) != READ) { | 350 | if (rq_data_dir(req) != READ) { |
373 | if (mmc_card_sd(card)) { | 351 | if (mmc_card_sd(card)) { |
374 | u32 blocks; | 352 | u32 blocks; |
375 | unsigned int bytes; | ||
376 | 353 | ||
377 | blocks = mmc_sd_num_wr_blocks(card); | 354 | blocks = mmc_sd_num_wr_blocks(card); |
378 | if (blocks != (u32)-1) { | 355 | if (blocks != (u32)-1) { |
379 | if (card->csd.write_partial) | ||
380 | bytes = blocks << md->block_bits; | ||
381 | else | ||
382 | bytes = blocks << 9; | ||
383 | spin_lock_irq(&md->lock); | 356 | spin_lock_irq(&md->lock); |
384 | ret = __blk_end_request(req, 0, bytes); | 357 | ret = __blk_end_request(req, 0, blocks << 9); |
385 | spin_unlock_irq(&md->lock); | 358 | spin_unlock_irq(&md->lock); |
386 | } | 359 | } |
387 | } else { | 360 | } else { |
@@ -431,13 +404,6 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) | |||
431 | */ | 404 | */ |
432 | md->read_only = mmc_blk_readonly(card); | 405 | md->read_only = mmc_blk_readonly(card); |
433 | 406 | ||
434 | /* | ||
435 | * Both SD and MMC specifications state (although a bit | ||
436 | * unclearly in the MMC case) that a block size of 512 | ||
437 | * bytes must always be supported by the card. | ||
438 | */ | ||
439 | md->block_bits = 9; | ||
440 | |||
441 | md->disk = alloc_disk(1 << MMC_SHIFT); | 407 | md->disk = alloc_disk(1 << MMC_SHIFT); |
442 | if (md->disk == NULL) { | 408 | if (md->disk == NULL) { |
443 | ret = -ENOMEM; | 409 | ret = -ENOMEM; |
@@ -475,7 +441,7 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) | |||
475 | 441 | ||
476 | sprintf(md->disk->disk_name, "mmcblk%d", devidx); | 442 | sprintf(md->disk->disk_name, "mmcblk%d", devidx); |
477 | 443 | ||
478 | blk_queue_hardsect_size(md->queue.queue, 1 << md->block_bits); | 444 | blk_queue_hardsect_size(md->queue.queue, 512); |
479 | 445 | ||
480 | if (!mmc_card_sd(card) && mmc_card_blockaddr(card)) { | 446 | if (!mmc_card_sd(card) && mmc_card_blockaddr(card)) { |
481 | /* | 447 | /* |
@@ -513,7 +479,7 @@ mmc_blk_set_blksize(struct mmc_blk_data *md, struct mmc_card *card) | |||
513 | 479 | ||
514 | mmc_claim_host(card->host); | 480 | mmc_claim_host(card->host); |
515 | cmd.opcode = MMC_SET_BLOCKLEN; | 481 | cmd.opcode = MMC_SET_BLOCKLEN; |
516 | cmd.arg = 1 << md->block_bits; | 482 | cmd.arg = 512; |
517 | cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC; | 483 | cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC; |
518 | err = mmc_wait_for_cmd(card->host, &cmd, 5); | 484 | err = mmc_wait_for_cmd(card->host, &cmd, 5); |
519 | mmc_release_host(card->host); | 485 | mmc_release_host(card->host); |
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index 3dee97e7d165..406989e992ba 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c | |||
@@ -31,7 +31,7 @@ static int mmc_prep_request(struct request_queue *q, struct request *req) | |||
31 | /* | 31 | /* |
32 | * We only like normal block requests. | 32 | * We only like normal block requests. |
33 | */ | 33 | */ |
34 | if (!blk_fs_request(req) && !blk_pc_request(req)) { | 34 | if (!blk_fs_request(req)) { |
35 | blk_dump_rq_flags(req, "MMC bad request"); | 35 | blk_dump_rq_flags(req, "MMC bad request"); |
36 | return BLKPREP_KILL; | 36 | return BLKPREP_KILL; |
37 | } | 37 | } |
@@ -131,6 +131,7 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock | |||
131 | mq->req = NULL; | 131 | mq->req = NULL; |
132 | 132 | ||
133 | blk_queue_prep_rq(mq->queue, mmc_prep_request); | 133 | blk_queue_prep_rq(mq->queue, mmc_prep_request); |
134 | blk_queue_ordered(mq->queue, QUEUE_ORDERED_DRAIN, NULL); | ||
134 | 135 | ||
135 | #ifdef CONFIG_MMC_BLOCK_BOUNCE | 136 | #ifdef CONFIG_MMC_BLOCK_BOUNCE |
136 | if (host->max_hw_segs == 1) { | 137 | if (host->max_hw_segs == 1) { |
@@ -142,12 +143,19 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock | |||
142 | bouncesz = host->max_req_size; | 143 | bouncesz = host->max_req_size; |
143 | if (bouncesz > host->max_seg_size) | 144 | if (bouncesz > host->max_seg_size) |
144 | bouncesz = host->max_seg_size; | 145 | bouncesz = host->max_seg_size; |
146 | if (bouncesz > (host->max_blk_count * 512)) | ||
147 | bouncesz = host->max_blk_count * 512; | ||
148 | |||
149 | if (bouncesz > 512) { | ||
150 | mq->bounce_buf = kmalloc(bouncesz, GFP_KERNEL); | ||
151 | if (!mq->bounce_buf) { | ||
152 | printk(KERN_WARNING "%s: unable to " | ||
153 | "allocate bounce buffer\n", | ||
154 | mmc_card_name(card)); | ||
155 | } | ||
156 | } | ||
145 | 157 | ||
146 | mq->bounce_buf = kmalloc(bouncesz, GFP_KERNEL); | 158 | if (mq->bounce_buf) { |
147 | if (!mq->bounce_buf) { | ||
148 | printk(KERN_WARNING "%s: unable to allocate " | ||
149 | "bounce buffer\n", mmc_card_name(card)); | ||
150 | } else { | ||
151 | blk_queue_bounce_limit(mq->queue, BLK_BOUNCE_ANY); | 159 | blk_queue_bounce_limit(mq->queue, BLK_BOUNCE_ANY); |
152 | blk_queue_max_sectors(mq->queue, bouncesz / 512); | 160 | blk_queue_max_sectors(mq->queue, bouncesz / 512); |
153 | blk_queue_max_phys_segments(mq->queue, bouncesz / 512); | 161 | blk_queue_max_phys_segments(mq->queue, bouncesz / 512); |
@@ -175,7 +183,8 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock | |||
175 | 183 | ||
176 | if (!mq->bounce_buf) { | 184 | if (!mq->bounce_buf) { |
177 | blk_queue_bounce_limit(mq->queue, limit); | 185 | blk_queue_bounce_limit(mq->queue, limit); |
178 | blk_queue_max_sectors(mq->queue, host->max_req_size / 512); | 186 | blk_queue_max_sectors(mq->queue, |
187 | min(host->max_blk_count, host->max_req_size / 512)); | ||
179 | blk_queue_max_phys_segments(mq->queue, host->max_phys_segs); | 188 | blk_queue_max_phys_segments(mq->queue, host->max_phys_segs); |
180 | blk_queue_max_hw_segments(mq->queue, host->max_hw_segs); | 189 | blk_queue_max_hw_segments(mq->queue, host->max_hw_segs); |
181 | blk_queue_max_segment_size(mq->queue, host->max_seg_size); | 190 | blk_queue_max_segment_size(mq->queue, host->max_seg_size); |
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c index 64b05c6270f2..9c50e6f1c236 100644 --- a/drivers/mmc/core/mmc_ops.c +++ b/drivers/mmc/core/mmc_ops.c | |||
@@ -248,8 +248,12 @@ mmc_send_cxd_data(struct mmc_card *card, struct mmc_host *host, | |||
248 | 248 | ||
249 | sg_init_one(&sg, data_buf, len); | 249 | sg_init_one(&sg, data_buf, len); |
250 | 250 | ||
251 | if (card) | 251 | /* |
252 | mmc_set_data_timeout(&data, card); | 252 | * The spec states that CSR and CID accesses have a timeout |
253 | * of 64 clock cycles. | ||
254 | */ | ||
255 | data.timeout_ns = 0; | ||
256 | data.timeout_clks = 64; | ||
253 | 257 | ||
254 | mmc_wait_for_req(host, &mrq); | 258 | mmc_wait_for_req(host, &mrq); |
255 | 259 | ||
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 4eab79e09ccc..fb99ccff9080 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c | |||
@@ -165,6 +165,36 @@ static int sdio_enable_wide(struct mmc_card *card) | |||
165 | } | 165 | } |
166 | 166 | ||
167 | /* | 167 | /* |
168 | * Test if the card supports high-speed mode and, if so, switch to it. | ||
169 | */ | ||
170 | static int sdio_enable_hs(struct mmc_card *card) | ||
171 | { | ||
172 | int ret; | ||
173 | u8 speed; | ||
174 | |||
175 | if (!(card->host->caps & MMC_CAP_SD_HIGHSPEED)) | ||
176 | return 0; | ||
177 | |||
178 | if (!card->cccr.high_speed) | ||
179 | return 0; | ||
180 | |||
181 | ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &speed); | ||
182 | if (ret) | ||
183 | return ret; | ||
184 | |||
185 | speed |= SDIO_SPEED_EHS; | ||
186 | |||
187 | ret = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_SPEED, speed, NULL); | ||
188 | if (ret) | ||
189 | return ret; | ||
190 | |||
191 | mmc_card_set_highspeed(card); | ||
192 | mmc_set_timing(card->host, MMC_TIMING_SD_HS); | ||
193 | |||
194 | return 0; | ||
195 | } | ||
196 | |||
197 | /* | ||
168 | * Host is being removed. Free up the current card. | 198 | * Host is being removed. Free up the current card. |
169 | */ | 199 | */ |
170 | static void mmc_sdio_remove(struct mmc_host *host) | 200 | static void mmc_sdio_remove(struct mmc_host *host) |
@@ -333,10 +363,26 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr) | |||
333 | goto remove; | 363 | goto remove; |
334 | 364 | ||
335 | /* | 365 | /* |
336 | * No support for high-speed yet, so just set | 366 | * Switch to high-speed (if supported). |
337 | * the card's maximum speed. | ||
338 | */ | 367 | */ |
339 | mmc_set_clock(host, card->cis.max_dtr); | 368 | err = sdio_enable_hs(card); |
369 | if (err) | ||
370 | goto remove; | ||
371 | |||
372 | /* | ||
373 | * Change to the card's maximum speed. | ||
374 | */ | ||
375 | if (mmc_card_highspeed(card)) { | ||
376 | /* | ||
377 | * The SDIO specification doesn't mention how | ||
378 | * the CIS transfer speed register relates to | ||
379 | * high-speed, but it seems that 50 MHz is | ||
380 | * mandatory. | ||
381 | */ | ||
382 | mmc_set_clock(host, 50000000); | ||
383 | } else { | ||
384 | mmc_set_clock(host, card->cis.max_dtr); | ||
385 | } | ||
340 | 386 | ||
341 | /* | 387 | /* |
342 | * Switch to wider bus (if supported). | 388 | * Switch to wider bus (if supported). |
diff --git a/drivers/mmc/core/sdio_irq.c b/drivers/mmc/core/sdio_irq.c index c292e124107a..bb192f90e8e9 100644 --- a/drivers/mmc/core/sdio_irq.c +++ b/drivers/mmc/core/sdio_irq.c | |||
@@ -5,6 +5,8 @@ | |||
5 | * Created: June 18, 2007 | 5 | * Created: June 18, 2007 |
6 | * Copyright: MontaVista Software Inc. | 6 | * Copyright: MontaVista Software Inc. |
7 | * | 7 | * |
8 | * Copyright 2008 Pierre Ossman | ||
9 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published by | 11 | * it under the terms of the GNU General Public License as published by |
10 | * the Free Software Foundation; either version 2 of the License, or (at | 12 | * the Free Software Foundation; either version 2 of the License, or (at |
@@ -107,11 +109,14 @@ static int sdio_irq_thread(void *_host) | |||
107 | 109 | ||
108 | /* | 110 | /* |
109 | * Give other threads a chance to run in the presence of | 111 | * Give other threads a chance to run in the presence of |
110 | * errors. FIXME: determine if due to card removal and | 112 | * errors. |
111 | * possibly exit this thread if so. | ||
112 | */ | 113 | */ |
113 | if (ret < 0) | 114 | if (ret < 0) { |
114 | ssleep(1); | 115 | set_current_state(TASK_INTERRUPTIBLE); |
116 | if (!kthread_should_stop()) | ||
117 | schedule_timeout(HZ); | ||
118 | set_current_state(TASK_RUNNING); | ||
119 | } | ||
115 | 120 | ||
116 | /* | 121 | /* |
117 | * Adaptive polling frequency based on the assumption | 122 | * Adaptive polling frequency based on the assumption |
@@ -154,7 +159,8 @@ static int sdio_card_irq_get(struct mmc_card *card) | |||
154 | if (!host->sdio_irqs++) { | 159 | if (!host->sdio_irqs++) { |
155 | atomic_set(&host->sdio_irq_thread_abort, 0); | 160 | atomic_set(&host->sdio_irq_thread_abort, 0); |
156 | host->sdio_irq_thread = | 161 | host->sdio_irq_thread = |
157 | kthread_run(sdio_irq_thread, host, "ksdiorqd"); | 162 | kthread_run(sdio_irq_thread, host, "ksdioirqd/%s", |
163 | mmc_hostname(host)); | ||
158 | if (IS_ERR(host->sdio_irq_thread)) { | 164 | if (IS_ERR(host->sdio_irq_thread)) { |
159 | int err = PTR_ERR(host->sdio_irq_thread); | 165 | int err = PTR_ERR(host->sdio_irq_thread); |
160 | host->sdio_irqs--; | 166 | host->sdio_irqs--; |
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 1ce21d4c8608..dfa585f7feaf 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig | |||
@@ -2,7 +2,7 @@ | |||
2 | # MMC/SD host controller drivers | 2 | # MMC/SD host controller drivers |
3 | # | 3 | # |
4 | 4 | ||
5 | comment "MMC/SD Host Controller Drivers" | 5 | comment "MMC/SD/SDIO Host Controller Drivers" |
6 | 6 | ||
7 | config MMC_ARMMMCI | 7 | config MMC_ARMMMCI |
8 | tristate "ARM AMBA Multimedia Card Interface support" | 8 | tristate "ARM AMBA Multimedia Card Interface support" |
@@ -152,21 +152,22 @@ config MMC_TIFM_SD | |||
152 | module will be called tifm_sd. | 152 | module will be called tifm_sd. |
153 | 153 | ||
154 | config MMC_SPI | 154 | config MMC_SPI |
155 | tristate "MMC/SD over SPI" | 155 | tristate "MMC/SD/SDIO over SPI" |
156 | depends on MMC && SPI_MASTER && !HIGHMEM && HAS_DMA | 156 | depends on SPI_MASTER && !HIGHMEM && HAS_DMA |
157 | select CRC7 | 157 | select CRC7 |
158 | select CRC_ITU_T | 158 | select CRC_ITU_T |
159 | help | 159 | help |
160 | Some systems accss MMC/SD cards using a SPI controller instead of | 160 | Some systems accss MMC/SD/SDIO cards using a SPI controller |
161 | using a "native" MMC/SD controller. This has a disadvantage of | 161 | instead of using a "native" MMC/SD/SDIO controller. This has a |
162 | being relatively high overhead, but a compensating advantage of | 162 | disadvantage of being relatively high overhead, but a compensating |
163 | working on many systems without dedicated MMC/SD controllers. | 163 | advantage of working on many systems without dedicated MMC/SD/SDIO |
164 | controllers. | ||
164 | 165 | ||
165 | If unsure, or if your system has no SPI master driver, say N. | 166 | If unsure, or if your system has no SPI master driver, say N. |
166 | 167 | ||
167 | config MMC_S3C | 168 | config MMC_S3C |
168 | tristate "Samsung S3C SD/MMC Card Interface support" | 169 | tristate "Samsung S3C SD/MMC Card Interface support" |
169 | depends on ARCH_S3C2410 && MMC | 170 | depends on ARCH_S3C2410 |
170 | help | 171 | help |
171 | This selects a driver for the MCI interface found in | 172 | This selects a driver for the MCI interface found in |
172 | Samsung's S3C2410, S3C2412, S3C2440, S3C2442 CPUs. | 173 | Samsung's S3C2410, S3C2412, S3C2440, S3C2442 CPUs. |
@@ -177,7 +178,7 @@ config MMC_S3C | |||
177 | 178 | ||
178 | config MMC_SDRICOH_CS | 179 | config MMC_SDRICOH_CS |
179 | tristate "MMC/SD driver for Ricoh Bay1Controllers (EXPERIMENTAL)" | 180 | tristate "MMC/SD driver for Ricoh Bay1Controllers (EXPERIMENTAL)" |
180 | depends on EXPERIMENTAL && MMC && PCI && PCMCIA | 181 | depends on EXPERIMENTAL && PCI && PCMCIA |
181 | help | 182 | help |
182 | Say Y here if your Notebook reports a Ricoh Bay1Controller PCMCIA | 183 | Say Y here if your Notebook reports a Ricoh Bay1Controller PCMCIA |
183 | card whenever you insert a MMC or SD card into the card slot. | 184 | card whenever you insert a MMC or SD card into the card slot. |
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c index 7503b81374e0..07faf5412a1f 100644 --- a/drivers/mmc/host/mmc_spi.c +++ b/drivers/mmc/host/mmc_spi.c | |||
@@ -95,8 +95,6 @@ | |||
95 | * reads which takes nowhere near that long. Older cards may be able to use | 95 | * reads which takes nowhere near that long. Older cards may be able to use |
96 | * shorter timeouts ... but why bother? | 96 | * shorter timeouts ... but why bother? |
97 | */ | 97 | */ |
98 | #define readblock_timeout ktime_set(0, 100 * 1000 * 1000) | ||
99 | #define writeblock_timeout ktime_set(0, 250 * 1000 * 1000) | ||
100 | #define r1b_timeout ktime_set(3, 0) | 98 | #define r1b_timeout ktime_set(3, 0) |
101 | 99 | ||
102 | 100 | ||
@@ -220,9 +218,9 @@ mmc_spi_wait_unbusy(struct mmc_spi_host *host, ktime_t timeout) | |||
220 | return mmc_spi_skip(host, timeout, sizeof(host->data->status), 0); | 218 | return mmc_spi_skip(host, timeout, sizeof(host->data->status), 0); |
221 | } | 219 | } |
222 | 220 | ||
223 | static int mmc_spi_readtoken(struct mmc_spi_host *host) | 221 | static int mmc_spi_readtoken(struct mmc_spi_host *host, ktime_t timeout) |
224 | { | 222 | { |
225 | return mmc_spi_skip(host, readblock_timeout, 1, 0xff); | 223 | return mmc_spi_skip(host, timeout, 1, 0xff); |
226 | } | 224 | } |
227 | 225 | ||
228 | 226 | ||
@@ -605,7 +603,8 @@ mmc_spi_setup_data_message( | |||
605 | * Return negative errno, else success. | 603 | * Return negative errno, else success. |
606 | */ | 604 | */ |
607 | static int | 605 | static int |
608 | mmc_spi_writeblock(struct mmc_spi_host *host, struct spi_transfer *t) | 606 | mmc_spi_writeblock(struct mmc_spi_host *host, struct spi_transfer *t, |
607 | ktime_t timeout) | ||
609 | { | 608 | { |
610 | struct spi_device *spi = host->spi; | 609 | struct spi_device *spi = host->spi; |
611 | int status, i; | 610 | int status, i; |
@@ -673,7 +672,7 @@ mmc_spi_writeblock(struct mmc_spi_host *host, struct spi_transfer *t) | |||
673 | if (scratch->status[i] != 0) | 672 | if (scratch->status[i] != 0) |
674 | return 0; | 673 | return 0; |
675 | } | 674 | } |
676 | return mmc_spi_wait_unbusy(host, writeblock_timeout); | 675 | return mmc_spi_wait_unbusy(host, timeout); |
677 | } | 676 | } |
678 | 677 | ||
679 | /* | 678 | /* |
@@ -693,7 +692,8 @@ mmc_spi_writeblock(struct mmc_spi_host *host, struct spi_transfer *t) | |||
693 | * STOP_TRANSMISSION command. | 692 | * STOP_TRANSMISSION command. |
694 | */ | 693 | */ |
695 | static int | 694 | static int |
696 | mmc_spi_readblock(struct mmc_spi_host *host, struct spi_transfer *t) | 695 | mmc_spi_readblock(struct mmc_spi_host *host, struct spi_transfer *t, |
696 | ktime_t timeout) | ||
697 | { | 697 | { |
698 | struct spi_device *spi = host->spi; | 698 | struct spi_device *spi = host->spi; |
699 | int status; | 699 | int status; |
@@ -707,7 +707,7 @@ mmc_spi_readblock(struct mmc_spi_host *host, struct spi_transfer *t) | |||
707 | return status; | 707 | return status; |
708 | status = scratch->status[0]; | 708 | status = scratch->status[0]; |
709 | if (status == 0xff || status == 0) | 709 | if (status == 0xff || status == 0) |
710 | status = mmc_spi_readtoken(host); | 710 | status = mmc_spi_readtoken(host, timeout); |
711 | 711 | ||
712 | if (status == SPI_TOKEN_SINGLE) { | 712 | if (status == SPI_TOKEN_SINGLE) { |
713 | if (host->dma_dev) { | 713 | if (host->dma_dev) { |
@@ -778,6 +778,8 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd, | |||
778 | struct scatterlist *sg; | 778 | struct scatterlist *sg; |
779 | unsigned n_sg; | 779 | unsigned n_sg; |
780 | int multiple = (data->blocks > 1); | 780 | int multiple = (data->blocks > 1); |
781 | u32 clock_rate; | ||
782 | ktime_t timeout; | ||
781 | 783 | ||
782 | if (data->flags & MMC_DATA_READ) | 784 | if (data->flags & MMC_DATA_READ) |
783 | direction = DMA_FROM_DEVICE; | 785 | direction = DMA_FROM_DEVICE; |
@@ -786,6 +788,14 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd, | |||
786 | mmc_spi_setup_data_message(host, multiple, direction); | 788 | mmc_spi_setup_data_message(host, multiple, direction); |
787 | t = &host->t; | 789 | t = &host->t; |
788 | 790 | ||
791 | if (t->speed_hz) | ||
792 | clock_rate = t->speed_hz; | ||
793 | else | ||
794 | clock_rate = spi->max_speed_hz; | ||
795 | |||
796 | timeout = ktime_add_ns(ktime_set(0, 0), data->timeout_ns + | ||
797 | data->timeout_clks * 1000000 / clock_rate); | ||
798 | |||
789 | /* Handle scatterlist segments one at a time, with synch for | 799 | /* Handle scatterlist segments one at a time, with synch for |
790 | * each 512-byte block | 800 | * each 512-byte block |
791 | */ | 801 | */ |
@@ -832,9 +842,9 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd, | |||
832 | t->len); | 842 | t->len); |
833 | 843 | ||
834 | if (direction == DMA_TO_DEVICE) | 844 | if (direction == DMA_TO_DEVICE) |
835 | status = mmc_spi_writeblock(host, t); | 845 | status = mmc_spi_writeblock(host, t, timeout); |
836 | else | 846 | else |
837 | status = mmc_spi_readblock(host, t); | 847 | status = mmc_spi_readblock(host, t, timeout); |
838 | if (status < 0) | 848 | if (status < 0) |
839 | break; | 849 | break; |
840 | 850 | ||
@@ -917,7 +927,7 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd, | |||
917 | if (scratch->status[tmp] != 0) | 927 | if (scratch->status[tmp] != 0) |
918 | return; | 928 | return; |
919 | } | 929 | } |
920 | tmp = mmc_spi_wait_unbusy(host, writeblock_timeout); | 930 | tmp = mmc_spi_wait_unbusy(host, timeout); |
921 | if (tmp < 0 && !data->error) | 931 | if (tmp < 0 && !data->error) |
922 | data->error = tmp; | 932 | data->error = tmp; |
923 | } | 933 | } |
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index fcb14c2346cc..0a84f10d719c 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c | |||
@@ -144,7 +144,8 @@ static int jmicron_probe(struct sdhci_pci_chip *chip) | |||
144 | SDHCI_QUIRK_32BIT_DMA_SIZE | | 144 | SDHCI_QUIRK_32BIT_DMA_SIZE | |
145 | SDHCI_QUIRK_32BIT_ADMA_SIZE | | 145 | SDHCI_QUIRK_32BIT_ADMA_SIZE | |
146 | SDHCI_QUIRK_RESET_AFTER_REQUEST | | 146 | SDHCI_QUIRK_RESET_AFTER_REQUEST | |
147 | SDHCI_QUIRK_BROKEN_SMALL_PIO; | 147 | SDHCI_QUIRK_BROKEN_SMALL_PIO | |
148 | SDHCI_QUIRK_FORCE_HIGHSPEED; | ||
148 | } | 149 | } |
149 | 150 | ||
150 | /* | 151 | /* |
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index e3a8133560a2..30f64b1f2354 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
@@ -177,7 +177,7 @@ static void sdhci_read_block_pio(struct sdhci_host *host) | |||
177 | { | 177 | { |
178 | unsigned long flags; | 178 | unsigned long flags; |
179 | size_t blksize, len, chunk; | 179 | size_t blksize, len, chunk; |
180 | u32 scratch; | 180 | u32 uninitialized_var(scratch); |
181 | u8 *buf; | 181 | u8 *buf; |
182 | 182 | ||
183 | DBG("PIO reading\n"); | 183 | DBG("PIO reading\n"); |
@@ -1154,7 +1154,7 @@ static void sdhci_tasklet_card(unsigned long param) | |||
1154 | 1154 | ||
1155 | spin_unlock_irqrestore(&host->lock, flags); | 1155 | spin_unlock_irqrestore(&host->lock, flags); |
1156 | 1156 | ||
1157 | mmc_detect_change(host->mmc, msecs_to_jiffies(500)); | 1157 | mmc_detect_change(host->mmc, msecs_to_jiffies(200)); |
1158 | } | 1158 | } |
1159 | 1159 | ||
1160 | static void sdhci_tasklet_finish(unsigned long param) | 1160 | static void sdhci_tasklet_finish(unsigned long param) |
@@ -1266,9 +1266,31 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask) | |||
1266 | SDHCI_INT_INDEX)) | 1266 | SDHCI_INT_INDEX)) |
1267 | host->cmd->error = -EILSEQ; | 1267 | host->cmd->error = -EILSEQ; |
1268 | 1268 | ||
1269 | if (host->cmd->error) | 1269 | if (host->cmd->error) { |
1270 | tasklet_schedule(&host->finish_tasklet); | 1270 | tasklet_schedule(&host->finish_tasklet); |
1271 | else if (intmask & SDHCI_INT_RESPONSE) | 1271 | return; |
1272 | } | ||
1273 | |||
1274 | /* | ||
1275 | * The host can send and interrupt when the busy state has | ||
1276 | * ended, allowing us to wait without wasting CPU cycles. | ||
1277 | * Unfortunately this is overloaded on the "data complete" | ||
1278 | * interrupt, so we need to take some care when handling | ||
1279 | * it. | ||
1280 | * | ||
1281 | * Note: The 1.0 specification is a bit ambiguous about this | ||
1282 | * feature so there might be some problems with older | ||
1283 | * controllers. | ||
1284 | */ | ||
1285 | if (host->cmd->flags & MMC_RSP_BUSY) { | ||
1286 | if (host->cmd->data) | ||
1287 | DBG("Cannot wait for busy signal when also " | ||
1288 | "doing a data transfer"); | ||
1289 | else | ||
1290 | return; | ||
1291 | } | ||
1292 | |||
1293 | if (intmask & SDHCI_INT_RESPONSE) | ||
1272 | sdhci_finish_command(host); | 1294 | sdhci_finish_command(host); |
1273 | } | 1295 | } |
1274 | 1296 | ||
@@ -1278,11 +1300,16 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) | |||
1278 | 1300 | ||
1279 | if (!host->data) { | 1301 | if (!host->data) { |
1280 | /* | 1302 | /* |
1281 | * A data end interrupt is sent together with the response | 1303 | * The "data complete" interrupt is also used to |
1282 | * for the stop command. | 1304 | * indicate that a busy state has ended. See comment |
1305 | * above in sdhci_cmd_irq(). | ||
1283 | */ | 1306 | */ |
1284 | if (intmask & SDHCI_INT_DATA_END) | 1307 | if (host->cmd && (host->cmd->flags & MMC_RSP_BUSY)) { |
1285 | return; | 1308 | if (intmask & SDHCI_INT_DATA_END) { |
1309 | sdhci_finish_command(host); | ||
1310 | return; | ||
1311 | } | ||
1312 | } | ||
1286 | 1313 | ||
1287 | printk(KERN_ERR "%s: Got data interrupt 0x%08x even " | 1314 | printk(KERN_ERR "%s: Got data interrupt 0x%08x even " |
1288 | "though no data operation was in progress.\n", | 1315 | "though no data operation was in progress.\n", |
@@ -1604,7 +1631,8 @@ int sdhci_add_host(struct sdhci_host *host) | |||
1604 | mmc->f_max = host->max_clk; | 1631 | mmc->f_max = host->max_clk; |
1605 | mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ; | 1632 | mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ; |
1606 | 1633 | ||
1607 | if (caps & SDHCI_CAN_DO_HISPD) | 1634 | if ((caps & SDHCI_CAN_DO_HISPD) || |
1635 | (host->quirks & SDHCI_QUIRK_FORCE_HIGHSPEED)) | ||
1608 | mmc->caps |= MMC_CAP_SD_HIGHSPEED; | 1636 | mmc->caps |= MMC_CAP_SD_HIGHSPEED; |
1609 | 1637 | ||
1610 | mmc->ocr_avail = 0; | 1638 | mmc->ocr_avail = 0; |
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 197d4a05f4ae..31f4b1528e76 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h | |||
@@ -208,6 +208,8 @@ struct sdhci_host { | |||
208 | #define SDHCI_QUIRK_BROKEN_TIMEOUT_VAL (1<<12) | 208 | #define SDHCI_QUIRK_BROKEN_TIMEOUT_VAL (1<<12) |
209 | /* Controller has an issue with buffer bits for small transfers */ | 209 | /* Controller has an issue with buffer bits for small transfers */ |
210 | #define SDHCI_QUIRK_BROKEN_SMALL_PIO (1<<13) | 210 | #define SDHCI_QUIRK_BROKEN_SMALL_PIO (1<<13) |
211 | /* Controller supports high speed but doesn't have the caps bit set */ | ||
212 | #define SDHCI_QUIRK_FORCE_HIGHSPEED (1<<14) | ||
211 | 213 | ||
212 | int irq; /* Device IRQ */ | 214 | int irq; /* Device IRQ */ |
213 | void __iomem * ioaddr; /* Mapped address */ | 215 | void __iomem * ioaddr; /* Mapped address */ |