diff options
author | Russell King <rmk@dyn-67.arm.linux.org.uk> | 2008-08-07 04:55:03 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2008-08-07 04:55:03 -0400 |
commit | 4fb8af10d0fd09372d52966b76922b9e82bbc950 (patch) | |
tree | d240e4d40357583e3f3eb228dccf20122a5b31ed /drivers/mmc | |
parent | f44f82e8a20b98558486eb14497b2f71c78fa325 (diff) | |
parent | 64a99d2a8c3ed5c4e39f3ae1cc682aa8fd3977fc (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild-fixes
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/card/block.c | 17 | ||||
-rw-r--r-- | drivers/mmc/card/mmc_test.c | 85 | ||||
-rw-r--r-- | drivers/mmc/core/core.c | 5 | ||||
-rw-r--r-- | drivers/mmc/host/au1xmmc.c | 8 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci-pci.c | 3 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci.c | 15 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci.h | 2 |
7 files changed, 40 insertions, 95 deletions
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 66e5a5487c20..86dbb366415a 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c | |||
@@ -213,7 +213,8 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | |||
213 | struct mmc_blk_data *md = mq->data; | 213 | struct mmc_blk_data *md = mq->data; |
214 | struct mmc_card *card = md->queue.card; | 214 | struct mmc_card *card = md->queue.card; |
215 | struct mmc_blk_request brq; | 215 | struct mmc_blk_request brq; |
216 | int ret = 1, sg_pos, data_size; | 216 | int ret = 1, data_size, i; |
217 | struct scatterlist *sg; | ||
217 | 218 | ||
218 | mmc_claim_host(card->host); | 219 | mmc_claim_host(card->host); |
219 | 220 | ||
@@ -267,18 +268,22 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | |||
267 | 268 | ||
268 | mmc_queue_bounce_pre(mq); | 269 | mmc_queue_bounce_pre(mq); |
269 | 270 | ||
271 | /* | ||
272 | * Adjust the sg list so it is the same size as the | ||
273 | * request. | ||
274 | */ | ||
270 | if (brq.data.blocks != | 275 | if (brq.data.blocks != |
271 | (req->nr_sectors >> (md->block_bits - 9))) { | 276 | (req->nr_sectors >> (md->block_bits - 9))) { |
272 | data_size = brq.data.blocks * brq.data.blksz; | 277 | data_size = brq.data.blocks * brq.data.blksz; |
273 | for (sg_pos = 0; sg_pos < brq.data.sg_len; sg_pos++) { | 278 | for_each_sg(brq.data.sg, sg, brq.data.sg_len, i) { |
274 | data_size -= mq->sg[sg_pos].length; | 279 | data_size -= sg->length; |
275 | if (data_size <= 0) { | 280 | if (data_size <= 0) { |
276 | mq->sg[sg_pos].length += data_size; | 281 | sg->length += data_size; |
277 | sg_pos++; | 282 | i++; |
278 | break; | 283 | break; |
279 | } | 284 | } |
280 | } | 285 | } |
281 | brq.data.sg_len = sg_pos; | 286 | brq.data.sg_len = i; |
282 | } | 287 | } |
283 | 288 | ||
284 | mmc_wait_for_req(card->host, &brq.mrq); | 289 | mmc_wait_for_req(card->host, &brq.mrq); |
diff --git a/drivers/mmc/card/mmc_test.c b/drivers/mmc/card/mmc_test.c index a067fe436301..f26b01d811ae 100644 --- a/drivers/mmc/card/mmc_test.c +++ b/drivers/mmc/card/mmc_test.c | |||
@@ -388,16 +388,14 @@ static int mmc_test_transfer(struct mmc_test_card *test, | |||
388 | int ret, i; | 388 | int ret, i; |
389 | unsigned long flags; | 389 | unsigned long flags; |
390 | 390 | ||
391 | BUG_ON(blocks * blksz > BUFFER_SIZE); | ||
392 | |||
393 | if (write) { | 391 | if (write) { |
394 | for (i = 0;i < blocks * blksz;i++) | 392 | for (i = 0;i < blocks * blksz;i++) |
395 | test->scratch[i] = i; | 393 | test->scratch[i] = i; |
396 | } else { | 394 | } else { |
397 | memset(test->scratch, 0, blocks * blksz); | 395 | memset(test->scratch, 0, BUFFER_SIZE); |
398 | } | 396 | } |
399 | local_irq_save(flags); | 397 | local_irq_save(flags); |
400 | sg_copy_from_buffer(sg, sg_len, test->scratch, blocks * blksz); | 398 | sg_copy_from_buffer(sg, sg_len, test->scratch, BUFFER_SIZE); |
401 | local_irq_restore(flags); | 399 | local_irq_restore(flags); |
402 | 400 | ||
403 | ret = mmc_test_set_blksize(test, blksz); | 401 | ret = mmc_test_set_blksize(test, blksz); |
@@ -444,7 +442,7 @@ static int mmc_test_transfer(struct mmc_test_card *test, | |||
444 | } | 442 | } |
445 | } else { | 443 | } else { |
446 | local_irq_save(flags); | 444 | local_irq_save(flags); |
447 | sg_copy_to_buffer(sg, sg_len, test->scratch, blocks * blksz); | 445 | sg_copy_to_buffer(sg, sg_len, test->scratch, BUFFER_SIZE); |
448 | local_irq_restore(flags); | 446 | local_irq_restore(flags); |
449 | for (i = 0;i < blocks * blksz;i++) { | 447 | for (i = 0;i < blocks * blksz;i++) { |
450 | if (test->scratch[i] != (u8)i) | 448 | if (test->scratch[i] != (u8)i) |
@@ -805,69 +803,6 @@ static int mmc_test_multi_xfersize_read(struct mmc_test_card *test) | |||
805 | return 0; | 803 | return 0; |
806 | } | 804 | } |
807 | 805 | ||
808 | static int mmc_test_bigsg_write(struct mmc_test_card *test) | ||
809 | { | ||
810 | int ret; | ||
811 | unsigned int size; | ||
812 | struct scatterlist sg; | ||
813 | |||
814 | if (test->card->host->max_blk_count == 1) | ||
815 | return RESULT_UNSUP_HOST; | ||
816 | |||
817 | size = PAGE_SIZE * 2; | ||
818 | size = min(size, test->card->host->max_req_size); | ||
819 | size = min(size, test->card->host->max_seg_size); | ||
820 | size = min(size, test->card->host->max_blk_count * 512); | ||
821 | |||
822 | memset(test->buffer, 0, BUFFER_SIZE); | ||
823 | |||
824 | if (size < 1024) | ||
825 | return RESULT_UNSUP_HOST; | ||
826 | |||
827 | sg_init_table(&sg, 1); | ||
828 | sg_init_one(&sg, test->buffer, BUFFER_SIZE); | ||
829 | |||
830 | ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 1); | ||
831 | if (ret) | ||
832 | return ret; | ||
833 | |||
834 | return 0; | ||
835 | } | ||
836 | |||
837 | static int mmc_test_bigsg_read(struct mmc_test_card *test) | ||
838 | { | ||
839 | int ret, i; | ||
840 | unsigned int size; | ||
841 | struct scatterlist sg; | ||
842 | |||
843 | if (test->card->host->max_blk_count == 1) | ||
844 | return RESULT_UNSUP_HOST; | ||
845 | |||
846 | size = PAGE_SIZE * 2; | ||
847 | size = min(size, test->card->host->max_req_size); | ||
848 | size = min(size, test->card->host->max_seg_size); | ||
849 | size = min(size, test->card->host->max_blk_count * 512); | ||
850 | |||
851 | if (size < 1024) | ||
852 | return RESULT_UNSUP_HOST; | ||
853 | |||
854 | memset(test->buffer, 0xCD, BUFFER_SIZE); | ||
855 | |||
856 | sg_init_table(&sg, 1); | ||
857 | sg_init_one(&sg, test->buffer, BUFFER_SIZE); | ||
858 | ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 0); | ||
859 | if (ret) | ||
860 | return ret; | ||
861 | |||
862 | /* mmc_test_transfer() doesn't check for read overflows */ | ||
863 | for (i = size;i < BUFFER_SIZE;i++) { | ||
864 | if (test->buffer[i] != 0xCD) | ||
865 | return RESULT_FAIL; | ||
866 | } | ||
867 | |||
868 | return 0; | ||
869 | } | ||
870 | |||
871 | #ifdef CONFIG_HIGHMEM | 806 | #ifdef CONFIG_HIGHMEM |
872 | 807 | ||
873 | static int mmc_test_write_high(struct mmc_test_card *test) | 808 | static int mmc_test_write_high(struct mmc_test_card *test) |
@@ -1071,20 +1006,6 @@ static const struct mmc_test_case mmc_test_cases[] = { | |||
1071 | .run = mmc_test_multi_xfersize_read, | 1006 | .run = mmc_test_multi_xfersize_read, |
1072 | }, | 1007 | }, |
1073 | 1008 | ||
1074 | { | ||
1075 | .name = "Over-sized SG list write", | ||
1076 | .prepare = mmc_test_prepare_write, | ||
1077 | .run = mmc_test_bigsg_write, | ||
1078 | .cleanup = mmc_test_cleanup, | ||
1079 | }, | ||
1080 | |||
1081 | { | ||
1082 | .name = "Over-sized SG list read", | ||
1083 | .prepare = mmc_test_prepare_read, | ||
1084 | .run = mmc_test_bigsg_read, | ||
1085 | .cleanup = mmc_test_cleanup, | ||
1086 | }, | ||
1087 | |||
1088 | #ifdef CONFIG_HIGHMEM | 1009 | #ifdef CONFIG_HIGHMEM |
1089 | 1010 | ||
1090 | { | 1011 | { |
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 3ee5b8c3b5ce..044d84eeed7c 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c | |||
@@ -121,6 +121,7 @@ mmc_start_request(struct mmc_host *host, struct mmc_request *mrq) | |||
121 | { | 121 | { |
122 | #ifdef CONFIG_MMC_DEBUG | 122 | #ifdef CONFIG_MMC_DEBUG |
123 | unsigned int i, sz; | 123 | unsigned int i, sz; |
124 | struct scatterlist *sg; | ||
124 | #endif | 125 | #endif |
125 | 126 | ||
126 | pr_debug("%s: starting CMD%u arg %08x flags %08x\n", | 127 | pr_debug("%s: starting CMD%u arg %08x flags %08x\n", |
@@ -156,8 +157,8 @@ mmc_start_request(struct mmc_host *host, struct mmc_request *mrq) | |||
156 | 157 | ||
157 | #ifdef CONFIG_MMC_DEBUG | 158 | #ifdef CONFIG_MMC_DEBUG |
158 | sz = 0; | 159 | sz = 0; |
159 | for (i = 0;i < mrq->data->sg_len;i++) | 160 | for_each_sg(mrq->data->sg, sg, mrq->data->sg_len, i) |
160 | sz += mrq->data->sg[i].length; | 161 | sz += sg->length; |
161 | BUG_ON(sz != mrq->data->blocks * mrq->data->blksz); | 162 | BUG_ON(sz != mrq->data->blocks * mrq->data->blksz); |
162 | #endif | 163 | #endif |
163 | 164 | ||
diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c index 99b20917cc0f..d3f55615c099 100644 --- a/drivers/mmc/host/au1xmmc.c +++ b/drivers/mmc/host/au1xmmc.c | |||
@@ -61,7 +61,13 @@ | |||
61 | 61 | ||
62 | /* Hardware definitions */ | 62 | /* Hardware definitions */ |
63 | #define AU1XMMC_DESCRIPTOR_COUNT 1 | 63 | #define AU1XMMC_DESCRIPTOR_COUNT 1 |
64 | #define AU1XMMC_DESCRIPTOR_SIZE 2048 | 64 | |
65 | /* max DMA seg size: 64KB on Au1100, 4MB on Au1200 */ | ||
66 | #ifdef CONFIG_SOC_AU1100 | ||
67 | #define AU1XMMC_DESCRIPTOR_SIZE 0x0000ffff | ||
68 | #else /* Au1200 */ | ||
69 | #define AU1XMMC_DESCRIPTOR_SIZE 0x003fffff | ||
70 | #endif | ||
65 | 71 | ||
66 | #define AU1XMMC_OCR (MMC_VDD_27_28 | MMC_VDD_28_29 | MMC_VDD_29_30 | \ | 72 | #define AU1XMMC_OCR (MMC_VDD_27_28 | MMC_VDD_28_29 | MMC_VDD_29_30 | \ |
67 | MMC_VDD_30_31 | MMC_VDD_31_32 | MMC_VDD_32_33 | \ | 73 | MMC_VDD_30_31 | MMC_VDD_31_32 | MMC_VDD_32_33 | \ |
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index deb607c52c0d..fcb14c2346cc 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c | |||
@@ -143,7 +143,8 @@ static int jmicron_probe(struct sdhci_pci_chip *chip) | |||
143 | chip->quirks |= SDHCI_QUIRK_32BIT_DMA_ADDR | | 143 | chip->quirks |= SDHCI_QUIRK_32BIT_DMA_ADDR | |
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 | } | 148 | } |
148 | 149 | ||
149 | /* | 150 | /* |
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 5f95e10229b5..e3a8133560a2 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
@@ -278,6 +278,15 @@ static void sdhci_transfer_pio(struct sdhci_host *host) | |||
278 | else | 278 | else |
279 | mask = SDHCI_SPACE_AVAILABLE; | 279 | mask = SDHCI_SPACE_AVAILABLE; |
280 | 280 | ||
281 | /* | ||
282 | * Some controllers (JMicron JMB38x) mess up the buffer bits | ||
283 | * for transfers < 4 bytes. As long as it is just one block, | ||
284 | * we can ignore the bits. | ||
285 | */ | ||
286 | if ((host->quirks & SDHCI_QUIRK_BROKEN_SMALL_PIO) && | ||
287 | (host->data->blocks == 1)) | ||
288 | mask = ~0; | ||
289 | |||
281 | while (readl(host->ioaddr + SDHCI_PRESENT_STATE) & mask) { | 290 | while (readl(host->ioaddr + SDHCI_PRESENT_STATE) & mask) { |
282 | if (host->data->flags & MMC_DATA_READ) | 291 | if (host->data->flags & MMC_DATA_READ) |
283 | sdhci_read_block_pio(host); | 292 | sdhci_read_block_pio(host); |
@@ -439,7 +448,7 @@ static int sdhci_adma_table_pre(struct sdhci_host *host, | |||
439 | 448 | ||
440 | host->adma_addr = dma_map_single(mmc_dev(host->mmc), | 449 | host->adma_addr = dma_map_single(mmc_dev(host->mmc), |
441 | host->adma_desc, (128 * 2 + 1) * 4, DMA_TO_DEVICE); | 450 | host->adma_desc, (128 * 2 + 1) * 4, DMA_TO_DEVICE); |
442 | if (dma_mapping_error(mmc_dev(host->mmc), host->align_addr)) | 451 | if (dma_mapping_error(mmc_dev(host->mmc), host->adma_addr)) |
443 | goto unmap_entries; | 452 | goto unmap_entries; |
444 | BUG_ON(host->adma_addr & 0x3); | 453 | BUG_ON(host->adma_addr & 0x3); |
445 | 454 | ||
@@ -645,7 +654,7 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data) | |||
645 | * us an invalid request. | 654 | * us an invalid request. |
646 | */ | 655 | */ |
647 | WARN_ON(1); | 656 | WARN_ON(1); |
648 | host->flags &= ~SDHCI_USE_DMA; | 657 | host->flags &= ~SDHCI_REQ_USE_DMA; |
649 | } else { | 658 | } else { |
650 | writel(host->adma_addr, | 659 | writel(host->adma_addr, |
651 | host->ioaddr + SDHCI_ADMA_ADDRESS); | 660 | host->ioaddr + SDHCI_ADMA_ADDRESS); |
@@ -664,7 +673,7 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data) | |||
664 | * us an invalid request. | 673 | * us an invalid request. |
665 | */ | 674 | */ |
666 | WARN_ON(1); | 675 | WARN_ON(1); |
667 | host->flags &= ~SDHCI_USE_DMA; | 676 | host->flags &= ~SDHCI_REQ_USE_DMA; |
668 | } else { | 677 | } else { |
669 | WARN_ON(sg_cnt != 1); | 678 | WARN_ON(sg_cnt != 1); |
670 | writel(sg_dma_address(data->sg), | 679 | writel(sg_dma_address(data->sg), |
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index e354faee5df0..197d4a05f4ae 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h | |||
@@ -206,6 +206,8 @@ struct sdhci_host { | |||
206 | #define SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER (1<<11) | 206 | #define SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER (1<<11) |
207 | /* Controller provides an incorrect timeout value for transfers */ | 207 | /* Controller provides an incorrect timeout value for transfers */ |
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 */ | ||
210 | #define SDHCI_QUIRK_BROKEN_SMALL_PIO (1<<13) | ||
209 | 211 | ||
210 | int irq; /* Device IRQ */ | 212 | int irq; /* Device IRQ */ |
211 | void __iomem * ioaddr; /* Mapped address */ | 213 | void __iomem * ioaddr; /* Mapped address */ |