Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/drzeus/mmc
authorLinus Torvalds <torvalds@woody.linux-foundation.org>
Mon, 14 May 2007 19:29:14 +0000 (12:29 -0700)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Mon, 14 May 2007 19:29:14 +0000 (12:29 -0700)
* '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

drivers/mmc/card/block.c
drivers/mmc/host/au1xmmc.c
drivers/mmc/host/pxamci.c
drivers/mmc/host/sdhci.c
include/linux/major.h

index d24ab23..a7562f7 100644 (file)
@@ -45,8 +45,6 @@
  */
 #define MMC_SHIFT      3
 
-static int major;
-
 /*
  * There is one mmc_blk_data per slot.
  */
@@ -466,7 +464,7 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card)
        md->queue.issue_fn = mmc_blk_issue_rq;
        md->queue.data = md;
 
-       md->disk->major = major;
+       md->disk->major = MMC_BLOCK_MAJOR;
        md->disk->first_minor = devidx << MMC_SHIFT;
        md->disk->fops = &mmc_bdops;
        md->disk->private_data = md;
@@ -634,14 +632,9 @@ static int __init mmc_blk_init(void)
 {
        int res = -ENOMEM;
 
-       res = register_blkdev(major, "mmc");
-       if (res < 0) {
-               printk(KERN_WARNING "Unable to get major %d for MMC media: %d\n",
-                      major, res);
+       res = register_blkdev(MMC_BLOCK_MAJOR, "mmc");
+       if (res)
                goto out;
-       }
-       if (major == 0)
-               major = res;
 
        return mmc_register_driver(&mmc_driver);
 
@@ -652,7 +645,7 @@ static int __init mmc_blk_init(void)
 static void __exit mmc_blk_exit(void)
 {
        mmc_unregister_driver(&mmc_driver);
-       unregister_blkdev(major, "mmc");
+       unregister_blkdev(MMC_BLOCK_MAJOR, "mmc");
 }
 
 module_init(mmc_blk_init);
@@ -661,5 +654,3 @@ module_exit(mmc_blk_exit);
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Multimedia Card (MMC) block device driver");
 
-module_param(major, int, 0444);
-MODULE_PARM_DESC(major, "specify the major device number for MMC block driver");
index b7156a4..f967226 100644 (file)
@@ -187,9 +187,8 @@ static void au1xmmc_tasklet_finish(unsigned long param)
 }
 
 static int au1xmmc_send_command(struct au1xmmc_host *host, int wait,
-                               struct mmc_command *cmd)
+                               struct mmc_command *cmd, unsigned int flags)
 {
-
        u32 mmccmd = (cmd->opcode << SD_CMD_CI_SHIFT);
 
        switch (mmc_resp_type(cmd)) {
@@ -213,24 +212,16 @@ static int au1xmmc_send_command(struct au1xmmc_host *host, int wait,
                return MMC_ERR_INVALID;
        }
 
-       switch(cmd->opcode) {
-       case MMC_READ_SINGLE_BLOCK:
-       case SD_APP_SEND_SCR:
-               mmccmd |= SD_CMD_CT_2;
-               break;
-       case MMC_READ_MULTIPLE_BLOCK:
-               mmccmd |= SD_CMD_CT_4;
-               break;
-       case MMC_WRITE_BLOCK:
-               mmccmd |= SD_CMD_CT_1;
-               break;
-
-       case MMC_WRITE_MULTIPLE_BLOCK:
-               mmccmd |= SD_CMD_CT_3;
-               break;
-       case MMC_STOP_TRANSMISSION:
-               mmccmd |= SD_CMD_CT_7;
-               break;
+       if (flags & MMC_DATA_READ) {
+               if (flags & MMC_DATA_MULTI)
+                       mmccmd |= SD_CMD_CT_4;
+               else
+                       mmccmd |= SD_CMD_CT_2;
+       } else if (flags & MMC_DATA_WRITE) {
+               if (flags & MMC_DATA_MULTI)
+                       mmccmd |= SD_CMD_CT_3;
+               else
+                       mmccmd |= SD_CMD_CT_1;
        }
 
        au_writel(cmd->arg, HOST_CMDARG(host));
@@ -665,6 +656,7 @@ static void au1xmmc_request(struct mmc_host* mmc, struct mmc_request* mrq)
 {
 
        struct au1xmmc_host *host = mmc_priv(mmc);
+       unsigned int flags = 0;
        int ret = MMC_ERR_NONE;
 
        WARN_ON(irqs_disabled());
@@ -677,11 +669,12 @@ static void au1xmmc_request(struct mmc_host* mmc, struct mmc_request* mrq)
 
        if (mrq->data) {
                FLUSH_FIFO(host);
+               flags = mrq->data->flags;
                ret = au1xmmc_prepare_data(host, mrq->data);
        }
 
        if (ret == MMC_ERR_NONE)
-               ret = au1xmmc_send_command(host, 0, mrq->cmd);
+               ret = au1xmmc_send_command(host, 0, mrq->cmd, flags);
 
        if (ret != MMC_ERR_NONE) {
                mrq->cmd->error = ret;
index d97d386..f8985c5 100644 (file)
@@ -232,20 +232,14 @@ static int pxamci_cmd_done(struct pxamci_host *host, unsigned int stat)
                /*
                 * workaround for erratum #42:
                 * Intel PXA27x Family Processor Specification Update Rev 001
+                * A bogus CRC error can appear if the msb of a 136 bit
+                * response is a one.
                 */
-               if (cmd->opcode == MMC_ALL_SEND_CID ||
-                   cmd->opcode == MMC_SEND_CSD ||
-                   cmd->opcode == MMC_SEND_CID) {
-                       /* a bogus CRC error can appear if the msb of
-                          the 15 byte response is a one */
-                       if ((cmd->resp[0] & 0x80000000) == 0)
-                               cmd->error = MMC_ERR_BADCRC;
-               } else {
-                       pr_debug("ignoring CRC from command %d - *risky*\n",cmd->opcode);
-               }
-#else
-               cmd->error = MMC_ERR_BADCRC;
+               if (cmd->flags & MMC_RSP_136 && cmd->resp[0] & 0x80000000) {
+                       pr_debug("ignoring CRC from command %d - *risky*\n", cmd->opcode);
+               } else
 #endif
+               cmd->error = MMC_ERR_BADCRC;
        }
 
        pxamci_disable_irq(host, END_CMD_RES);
index ff5bf73..a359efd 100644 (file)
@@ -963,6 +963,15 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
                if (intmask & (SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL))
                        sdhci_transfer_pio(host);
 
+               /*
+                * We currently don't do anything fancy with DMA
+                * boundaries, but as we can't disable the feature
+                * we need to at least restart the transfer.
+                */
+               if (intmask & SDHCI_INT_DMA_END)
+                       writel(readl(host->ioaddr + SDHCI_DMA_ADDRESS),
+                               host->ioaddr + SDHCI_DMA_ADDRESS);
+
                if (intmask & SDHCI_INT_DATA_END)
                        sdhci_finish_data(host);
        }
index 0a74c52..7e7c909 100644 (file)
 #define USB_ACM_AUX_MAJOR      167
 #define USB_CHAR_MAJOR         180
 
+#define MMC_BLOCK_MAJOR                179
+
 #define VXVM_MAJOR             199     /* VERITAS volume i/o driver    */
 #define VXSPEC_MAJOR           200     /* VERITAS volume config driver */
 #define VXDMP_MAJOR            201     /* VERITAS volume multipath driver */