diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-14 15:29:14 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-14 15:29:14 -0400 |
commit | 3ec2ab5514dbd6b5c4c3437c6a3cd9e5a90e84ef (patch) | |
tree | 44225691130bac645c033db1f80cc083597f1bb3 /drivers | |
parent | 200cfbb36ce360f7943c62b6c09885c215bfc1f5 (diff) | |
parent | 90e07d9f54c61449dd48eff82e2354d0124d4f7e (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/drzeus/mmc
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/drzeus/mmc:
pxamci: fix PXA27x MMC workaround for bad CRC with 136 bit response
mmc: use assigned major for block device
sdhci: handle dma boundary interrupts
mmc: au1xmmc command types check from data flags
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mmc/card/block.c | 17 | ||||
-rw-r--r-- | drivers/mmc/host/au1xmmc.c | 35 | ||||
-rw-r--r-- | drivers/mmc/host/pxamci.c | 18 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci.c | 9 |
4 files changed, 33 insertions, 46 deletions
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index d24ab234394c..a7562f7fc0b3 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c | |||
@@ -45,8 +45,6 @@ | |||
45 | */ | 45 | */ |
46 | #define MMC_SHIFT 3 | 46 | #define MMC_SHIFT 3 |
47 | 47 | ||
48 | static int major; | ||
49 | |||
50 | /* | 48 | /* |
51 | * There is one mmc_blk_data per slot. | 49 | * There is one mmc_blk_data per slot. |
52 | */ | 50 | */ |
@@ -466,7 +464,7 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) | |||
466 | md->queue.issue_fn = mmc_blk_issue_rq; | 464 | md->queue.issue_fn = mmc_blk_issue_rq; |
467 | md->queue.data = md; | 465 | md->queue.data = md; |
468 | 466 | ||
469 | md->disk->major = major; | 467 | md->disk->major = MMC_BLOCK_MAJOR; |
470 | md->disk->first_minor = devidx << MMC_SHIFT; | 468 | md->disk->first_minor = devidx << MMC_SHIFT; |
471 | md->disk->fops = &mmc_bdops; | 469 | md->disk->fops = &mmc_bdops; |
472 | md->disk->private_data = md; | 470 | md->disk->private_data = md; |
@@ -634,14 +632,9 @@ static int __init mmc_blk_init(void) | |||
634 | { | 632 | { |
635 | int res = -ENOMEM; | 633 | int res = -ENOMEM; |
636 | 634 | ||
637 | res = register_blkdev(major, "mmc"); | 635 | res = register_blkdev(MMC_BLOCK_MAJOR, "mmc"); |
638 | if (res < 0) { | 636 | if (res) |
639 | printk(KERN_WARNING "Unable to get major %d for MMC media: %d\n", | ||
640 | major, res); | ||
641 | goto out; | 637 | goto out; |
642 | } | ||
643 | if (major == 0) | ||
644 | major = res; | ||
645 | 638 | ||
646 | return mmc_register_driver(&mmc_driver); | 639 | return mmc_register_driver(&mmc_driver); |
647 | 640 | ||
@@ -652,7 +645,7 @@ static int __init mmc_blk_init(void) | |||
652 | static void __exit mmc_blk_exit(void) | 645 | static void __exit mmc_blk_exit(void) |
653 | { | 646 | { |
654 | mmc_unregister_driver(&mmc_driver); | 647 | mmc_unregister_driver(&mmc_driver); |
655 | unregister_blkdev(major, "mmc"); | 648 | unregister_blkdev(MMC_BLOCK_MAJOR, "mmc"); |
656 | } | 649 | } |
657 | 650 | ||
658 | module_init(mmc_blk_init); | 651 | module_init(mmc_blk_init); |
@@ -661,5 +654,3 @@ module_exit(mmc_blk_exit); | |||
661 | MODULE_LICENSE("GPL"); | 654 | MODULE_LICENSE("GPL"); |
662 | MODULE_DESCRIPTION("Multimedia Card (MMC) block device driver"); | 655 | MODULE_DESCRIPTION("Multimedia Card (MMC) block device driver"); |
663 | 656 | ||
664 | module_param(major, int, 0444); | ||
665 | MODULE_PARM_DESC(major, "specify the major device number for MMC block driver"); | ||
diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c index b7156a4555b5..f967226d7505 100644 --- a/drivers/mmc/host/au1xmmc.c +++ b/drivers/mmc/host/au1xmmc.c | |||
@@ -187,9 +187,8 @@ static void au1xmmc_tasklet_finish(unsigned long param) | |||
187 | } | 187 | } |
188 | 188 | ||
189 | static int au1xmmc_send_command(struct au1xmmc_host *host, int wait, | 189 | static int au1xmmc_send_command(struct au1xmmc_host *host, int wait, |
190 | struct mmc_command *cmd) | 190 | struct mmc_command *cmd, unsigned int flags) |
191 | { | 191 | { |
192 | |||
193 | u32 mmccmd = (cmd->opcode << SD_CMD_CI_SHIFT); | 192 | u32 mmccmd = (cmd->opcode << SD_CMD_CI_SHIFT); |
194 | 193 | ||
195 | switch (mmc_resp_type(cmd)) { | 194 | switch (mmc_resp_type(cmd)) { |
@@ -213,24 +212,16 @@ static int au1xmmc_send_command(struct au1xmmc_host *host, int wait, | |||
213 | return MMC_ERR_INVALID; | 212 | return MMC_ERR_INVALID; |
214 | } | 213 | } |
215 | 214 | ||
216 | switch(cmd->opcode) { | 215 | if (flags & MMC_DATA_READ) { |
217 | case MMC_READ_SINGLE_BLOCK: | 216 | if (flags & MMC_DATA_MULTI) |
218 | case SD_APP_SEND_SCR: | 217 | mmccmd |= SD_CMD_CT_4; |
219 | mmccmd |= SD_CMD_CT_2; | 218 | else |
220 | break; | 219 | mmccmd |= SD_CMD_CT_2; |
221 | case MMC_READ_MULTIPLE_BLOCK: | 220 | } else if (flags & MMC_DATA_WRITE) { |
222 | mmccmd |= SD_CMD_CT_4; | 221 | if (flags & MMC_DATA_MULTI) |
223 | break; | 222 | mmccmd |= SD_CMD_CT_3; |
224 | case MMC_WRITE_BLOCK: | 223 | else |
225 | mmccmd |= SD_CMD_CT_1; | 224 | mmccmd |= SD_CMD_CT_1; |
226 | break; | ||
227 | |||
228 | case MMC_WRITE_MULTIPLE_BLOCK: | ||
229 | mmccmd |= SD_CMD_CT_3; | ||
230 | break; | ||
231 | case MMC_STOP_TRANSMISSION: | ||
232 | mmccmd |= SD_CMD_CT_7; | ||
233 | break; | ||
234 | } | 225 | } |
235 | 226 | ||
236 | au_writel(cmd->arg, HOST_CMDARG(host)); | 227 | au_writel(cmd->arg, HOST_CMDARG(host)); |
@@ -665,6 +656,7 @@ static void au1xmmc_request(struct mmc_host* mmc, struct mmc_request* mrq) | |||
665 | { | 656 | { |
666 | 657 | ||
667 | struct au1xmmc_host *host = mmc_priv(mmc); | 658 | struct au1xmmc_host *host = mmc_priv(mmc); |
659 | unsigned int flags = 0; | ||
668 | int ret = MMC_ERR_NONE; | 660 | int ret = MMC_ERR_NONE; |
669 | 661 | ||
670 | WARN_ON(irqs_disabled()); | 662 | WARN_ON(irqs_disabled()); |
@@ -677,11 +669,12 @@ static void au1xmmc_request(struct mmc_host* mmc, struct mmc_request* mrq) | |||
677 | 669 | ||
678 | if (mrq->data) { | 670 | if (mrq->data) { |
679 | FLUSH_FIFO(host); | 671 | FLUSH_FIFO(host); |
672 | flags = mrq->data->flags; | ||
680 | ret = au1xmmc_prepare_data(host, mrq->data); | 673 | ret = au1xmmc_prepare_data(host, mrq->data); |
681 | } | 674 | } |
682 | 675 | ||
683 | if (ret == MMC_ERR_NONE) | 676 | if (ret == MMC_ERR_NONE) |
684 | ret = au1xmmc_send_command(host, 0, mrq->cmd); | 677 | ret = au1xmmc_send_command(host, 0, mrq->cmd, flags); |
685 | 678 | ||
686 | if (ret != MMC_ERR_NONE) { | 679 | if (ret != MMC_ERR_NONE) { |
687 | mrq->cmd->error = ret; | 680 | mrq->cmd->error = ret; |
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c index d97d3864b57f..f8985c508bb9 100644 --- a/drivers/mmc/host/pxamci.c +++ b/drivers/mmc/host/pxamci.c | |||
@@ -232,20 +232,14 @@ static int pxamci_cmd_done(struct pxamci_host *host, unsigned int stat) | |||
232 | /* | 232 | /* |
233 | * workaround for erratum #42: | 233 | * workaround for erratum #42: |
234 | * Intel PXA27x Family Processor Specification Update Rev 001 | 234 | * Intel PXA27x Family Processor Specification Update Rev 001 |
235 | * A bogus CRC error can appear if the msb of a 136 bit | ||
236 | * response is a one. | ||
235 | */ | 237 | */ |
236 | if (cmd->opcode == MMC_ALL_SEND_CID || | 238 | if (cmd->flags & MMC_RSP_136 && cmd->resp[0] & 0x80000000) { |
237 | cmd->opcode == MMC_SEND_CSD || | 239 | pr_debug("ignoring CRC from command %d - *risky*\n", cmd->opcode); |
238 | cmd->opcode == MMC_SEND_CID) { | 240 | } else |
239 | /* a bogus CRC error can appear if the msb of | ||
240 | the 15 byte response is a one */ | ||
241 | if ((cmd->resp[0] & 0x80000000) == 0) | ||
242 | cmd->error = MMC_ERR_BADCRC; | ||
243 | } else { | ||
244 | pr_debug("ignoring CRC from command %d - *risky*\n",cmd->opcode); | ||
245 | } | ||
246 | #else | ||
247 | cmd->error = MMC_ERR_BADCRC; | ||
248 | #endif | 241 | #endif |
242 | cmd->error = MMC_ERR_BADCRC; | ||
249 | } | 243 | } |
250 | 244 | ||
251 | pxamci_disable_irq(host, END_CMD_RES); | 245 | pxamci_disable_irq(host, END_CMD_RES); |
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index ff5bf73cdd25..a359efdd77eb 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
@@ -963,6 +963,15 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) | |||
963 | if (intmask & (SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL)) | 963 | if (intmask & (SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL)) |
964 | sdhci_transfer_pio(host); | 964 | sdhci_transfer_pio(host); |
965 | 965 | ||
966 | /* | ||
967 | * We currently don't do anything fancy with DMA | ||
968 | * boundaries, but as we can't disable the feature | ||
969 | * we need to at least restart the transfer. | ||
970 | */ | ||
971 | if (intmask & SDHCI_INT_DMA_END) | ||
972 | writel(readl(host->ioaddr + SDHCI_DMA_ADDRESS), | ||
973 | host->ioaddr + SDHCI_DMA_ADDRESS); | ||
974 | |||
966 | if (intmask & SDHCI_INT_DATA_END) | 975 | if (intmask & SDHCI_INT_DATA_END) |
967 | sdhci_finish_data(host); | 976 | sdhci_finish_data(host); |
968 | } | 977 | } |