]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/mmc/host/sdhci.c
Merge git://git.infradead.org/iommu-2.6
[mv-sheeva.git] / drivers / mmc / host / sdhci.c
index 6779b4ecab185255d630e9c209ea032b979ec6de..c279fbc4c2e54059d3c06fcec327b59df287bb84 100644 (file)
@@ -591,6 +591,9 @@ static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_data *data)
        target_timeout = data->timeout_ns / 1000 +
                data->timeout_clks / host->clock;
 
+       if (host->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)
+               host->timeout_clk = host->clock / 1000;
+
        /*
         * Figure out needed cycles.
         * We do this in steps in order to fit inside a 32 bit int.
@@ -652,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;
 
        /*
@@ -773,8 +776,14 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
        }
 
        if (!(host->flags & SDHCI_REQ_USE_DMA)) {
-               sg_miter_start(&host->sg_miter,
-                       data->sg, data->sg_len, SG_MITER_ATOMIC);
+               int flags;
+
+               flags = SG_MITER_ATOMIC;
+               if (host->data->flags & MMC_DATA_READ)
+                       flags |= SG_MITER_TO_SG;
+               else
+                       flags |= SG_MITER_FROM_SG;
+               sg_miter_start(&host->sg_miter, data->sg, data->sg_len, flags);
                host->blocks = data->blocks;
        }
 
@@ -985,8 +994,8 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
        clk |= SDHCI_CLOCK_INT_EN;
        sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
 
-       /* Wait max 10 ms */
-       timeout = 10;
+       /* Wait max 20 ms */
+       timeout = 20;
        while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL))
                & SDHCI_CLOCK_INT_STABLE)) {
                if (timeout == 0) {
@@ -1591,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);
        }
@@ -1672,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)) {
@@ -1696,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);
                        }
                }
        }
@@ -1730,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;
        }
@@ -1751,13 +1758,15 @@ int sdhci_add_host(struct sdhci_host *host)
        host->timeout_clk =
                (caps & SDHCI_TIMEOUT_CLK_MASK) >> SDHCI_TIMEOUT_CLK_SHIFT;
        if (host->timeout_clk == 0) {
-               if (!host->ops->get_timeout_clock) {
+               if (host->ops->get_timeout_clock) {
+                       host->timeout_clk = host->ops->get_timeout_clock(host);
+               } else if (!(host->quirks &
+                               SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)) {
                        printk(KERN_ERR
                               "%s: Hardware doesn't specify timeout clock "
                               "frequency.\n", mmc_hostname(mmc));
                        return -ENODEV;
                }
-               host->timeout_clk = host->ops->get_timeout_clock(host);
        }
        if (caps & SDHCI_TIMEOUT_CLK_UNIT)
                host->timeout_clk *= 1000;
@@ -1766,7 +1775,11 @@ int sdhci_add_host(struct sdhci_host *host)
         * Set host parameters.
         */
        mmc->ops = &sdhci_ops;
-       mmc->f_min = host->max_clk / 256;
+       if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK &&
+                       host->ops->set_clock && host->ops->get_min_clock)
+               mmc->f_min = host->ops->get_min_clock(host);
+       else
+               mmc->f_min = host->max_clk / 256;
        mmc->f_max = host->max_clk;
        mmc->caps = MMC_CAP_SDIO_IRQ;
 
@@ -1801,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;
@@ -1884,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);