sdhci: support for ADMA only hosts
authorRichard Röjfors <richard.rojfors@mocean-labs.com>
Tue, 22 Sep 2009 23:45:30 +0000 (16:45 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 23 Sep 2009 14:39:38 +0000 (07:39 -0700)
Add support for ADMA on SDHCI hosts, not supporting SDMA.

According to the SDHCI specifications a host can support ADMA but not SDMA

Signed-off-by: Richard Röjfors <richard.rojfors@mocean-labs.com>
Cc: <linux-mmc@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
drivers/mmc/host/sdhci-pci.c
drivers/mmc/host/sdhci.c
drivers/mmc/host/sdhci.h

index 63b9d2a6a452a9eb0801d9baaf4980b73a12881f..e0356644d1aa4592faa28ccccb485d5cab944087 100644 (file)
@@ -396,7 +396,7 @@ static int sdhci_pci_enable_dma(struct sdhci_host *host)
 
        if (((pdev->class & 0xFFFF00) == (PCI_CLASS_SYSTEM_SDHCI << 8)) &&
                ((pdev->class & 0x0000FF) != PCI_SDHCI_IFDMA) &&
-               (host->flags & SDHCI_USE_DMA)) {
+               (host->flags & SDHCI_USE_SDMA)) {
                dev_warn(&pdev->dev, "Will use DMA mode even though HW "
                        "doesn't fully claim to support it.\n");
        }
index 38a78743fc51b9640bea4432ee585745dd4797fa..9d0767687e12660b8186a08dbb5c16e0ac64ba6c 100644 (file)
@@ -655,7 +655,7 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
        count = sdhci_calc_timeout(host, data);
        sdhci_writeb(host, count, SDHCI_TIMEOUT_CONTROL);
 
-       if (host->flags & SDHCI_USE_DMA)
+       if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA))
                host->flags |= SDHCI_REQ_USE_DMA;
 
        /*
@@ -1600,7 +1600,7 @@ int sdhci_resume_host(struct sdhci_host *host)
 {
        int ret;
 
-       if (host->flags & SDHCI_USE_DMA) {
+       if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
                if (host->ops->enable_dma)
                        host->ops->enable_dma(host);
        }
@@ -1681,23 +1681,20 @@ int sdhci_add_host(struct sdhci_host *host)
        caps = sdhci_readl(host, SDHCI_CAPABILITIES);
 
        if (host->quirks & SDHCI_QUIRK_FORCE_DMA)
-               host->flags |= SDHCI_USE_DMA;
-       else if (!(caps & SDHCI_CAN_DO_DMA))
-               DBG("Controller doesn't have DMA capability\n");
+               host->flags |= SDHCI_USE_SDMA;
+       else if (!(caps & SDHCI_CAN_DO_SDMA))
+               DBG("Controller doesn't have SDMA capability\n");
        else
-               host->flags |= SDHCI_USE_DMA;
+               host->flags |= SDHCI_USE_SDMA;
 
        if ((host->quirks & SDHCI_QUIRK_BROKEN_DMA) &&
-               (host->flags & SDHCI_USE_DMA)) {
+               (host->flags & SDHCI_USE_SDMA)) {
                DBG("Disabling DMA as it is marked broken\n");
-               host->flags &= ~SDHCI_USE_DMA;
+               host->flags &= ~SDHCI_USE_SDMA;
        }
 
-       if (host->flags & SDHCI_USE_DMA) {
-               if ((host->version >= SDHCI_SPEC_200) &&
-                               (caps & SDHCI_CAN_DO_ADMA2))
-                       host->flags |= SDHCI_USE_ADMA;
-       }
+       if ((host->version >= SDHCI_SPEC_200) && (caps & SDHCI_CAN_DO_ADMA2))
+               host->flags |= SDHCI_USE_ADMA;
 
        if ((host->quirks & SDHCI_QUIRK_BROKEN_ADMA) &&
                (host->flags & SDHCI_USE_ADMA)) {
@@ -1705,13 +1702,14 @@ int sdhci_add_host(struct sdhci_host *host)
                host->flags &= ~SDHCI_USE_ADMA;
        }
 
-       if (host->flags & SDHCI_USE_DMA) {
+       if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
                if (host->ops->enable_dma) {
                        if (host->ops->enable_dma(host)) {
                                printk(KERN_WARNING "%s: No suitable DMA "
                                        "available. Falling back to PIO.\n",
                                        mmc_hostname(mmc));
-                               host->flags &= ~(SDHCI_USE_DMA | SDHCI_USE_ADMA);
+                               host->flags &=
+                                       ~(SDHCI_USE_SDMA | SDHCI_USE_ADMA);
                        }
                }
        }
@@ -1739,7 +1737,7 @@ int sdhci_add_host(struct sdhci_host *host)
         * mask, but PIO does not need the hw shim so we set a new
         * mask here in that case.
         */
-       if (!(host->flags & SDHCI_USE_DMA)) {
+       if (!(host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA))) {
                host->dma_mask = DMA_BIT_MASK(64);
                mmc_dev(host->mmc)->dma_mask = &host->dma_mask;
        }
@@ -1816,7 +1814,7 @@ int sdhci_add_host(struct sdhci_host *host)
         */
        if (host->flags & SDHCI_USE_ADMA)
                mmc->max_hw_segs = 128;
-       else if (host->flags & SDHCI_USE_DMA)
+       else if (host->flags & SDHCI_USE_SDMA)
                mmc->max_hw_segs = 1;
        else /* PIO */
                mmc->max_hw_segs = 128;
@@ -1899,10 +1897,10 @@ int sdhci_add_host(struct sdhci_host *host)
 
        mmc_add_host(mmc);
 
-       printk(KERN_INFO "%s: SDHCI controller on %s [%s] using %s%s\n",
+       printk(KERN_INFO "%s: SDHCI controller on %s [%s] using %s\n",
                mmc_hostname(mmc), host->hw_name, dev_name(mmc_dev(mmc)),
-               (host->flags & SDHCI_USE_ADMA)?"A":"",
-               (host->flags & SDHCI_USE_DMA)?"DMA":"PIO");
+               (host->flags & SDHCI_USE_ADMA) ? "ADMA" :
+               (host->flags & SDHCI_USE_SDMA) ? "DMA" : "PIO");
 
        sdhci_enable_card_detection(host);
 
index afda7f126e0de6cc096e54224b1ac03cbe27feaf..ce5f1d73dc04667841c6da99973500e9e3c96e7f 100644 (file)
 #define  SDHCI_CAN_DO_ADMA2    0x00080000
 #define  SDHCI_CAN_DO_ADMA1    0x00100000
 #define  SDHCI_CAN_DO_HISPD    0x00200000
-#define  SDHCI_CAN_DO_DMA      0x00400000
+#define  SDHCI_CAN_DO_SDMA     0x00400000
 #define  SDHCI_CAN_VDD_330     0x01000000
 #define  SDHCI_CAN_VDD_300     0x02000000
 #define  SDHCI_CAN_VDD_180     0x04000000
@@ -252,7 +252,7 @@ struct sdhci_host {
        spinlock_t              lock;           /* Mutex */
 
        int                     flags;          /* Host attributes */
-#define SDHCI_USE_DMA          (1<<0)          /* Host is DMA capable */
+#define SDHCI_USE_SDMA         (1<<0)          /* Host is SDMA capable */
 #define SDHCI_USE_ADMA         (1<<1)          /* Host is ADMA capable */
 #define SDHCI_REQ_USE_DMA      (1<<2)          /* Use DMA for this req. */
 #define SDHCI_DEVICE_DEAD      (1<<3)          /* Device unresponsive */