Merge branch 'fixes' into next
[linux-2.6-block.git] / drivers / mmc / host / sdhci.c
index 6cc72177f85388b4e0c50007dba93b51c53e8bfd..37b1158c1c0c9427d272b45a24c4049de5ff702e 100644 (file)
@@ -111,6 +111,9 @@ void sdhci_dumpregs(struct sdhci_host *host)
                }
        }
 
+       if (host->ops->dump_vendor_regs)
+               host->ops->dump_vendor_regs(host);
+
        SDHCI_DUMP("============================================\n");
 }
 EXPORT_SYMBOL_GPL(sdhci_dumpregs);
@@ -317,6 +320,7 @@ out:
 static void sdhci_init(struct sdhci_host *host, int soft)
 {
        struct mmc_host *mmc = host->mmc;
+       unsigned long flags;
 
        if (soft)
                sdhci_do_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
@@ -326,7 +330,9 @@ static void sdhci_init(struct sdhci_host *host, int soft)
        if (host->v4_mode)
                sdhci_do_enable_v4_mode(host);
 
+       spin_lock_irqsave(&host->lock, flags);
        sdhci_set_default_irqs(host);
+       spin_unlock_irqrestore(&host->lock, flags);
 
        host->cqe_on = false;
 
@@ -634,9 +640,13 @@ static int sdhci_pre_dma_transfer(struct sdhci_host *host,
                }
                if (mmc_get_dma_dir(data) == DMA_TO_DEVICE) {
                        /* Copy the data to the bounce buffer */
-                       sg_copy_to_buffer(data->sg, data->sg_len,
-                                         host->bounce_buffer,
-                                         length);
+                       if (host->ops->copy_to_bounce_buffer) {
+                               host->ops->copy_to_bounce_buffer(host,
+                                                                data, length);
+                       } else {
+                               sg_copy_to_buffer(data->sg, data->sg_len,
+                                                 host->bounce_buffer, length);
+                       }
                }
                /* Switch ownership to the DMA */
                dma_sync_single_for_device(host->mmc->parent,
@@ -4128,9 +4138,6 @@ int sdhci_setup_host(struct sdhci_host *host)
                       mmc_hostname(mmc), host->version);
        }
 
-       if (host->quirks & SDHCI_QUIRK_BROKEN_CQE)
-               mmc->caps2 &= ~MMC_CAP2_CQE;
-
        if (host->quirks & SDHCI_QUIRK_FORCE_DMA)
                host->flags |= SDHCI_USE_SDMA;
        else if (!(host->caps & SDHCI_CAN_DO_SDMA))
@@ -4328,7 +4335,7 @@ int sdhci_setup_host(struct sdhci_host *host)
            !host->ops->get_max_timeout_count)
                mmc->max_busy_timeout = 0;
 
-       mmc->caps |= MMC_CAP_SDIO_IRQ | MMC_CAP_ERASE | MMC_CAP_CMD23;
+       mmc->caps |= MMC_CAP_SDIO_IRQ | MMC_CAP_CMD23;
        mmc->caps2 |= MMC_CAP2_SDIO_IRQ_NOTHREAD;
 
        if (host->quirks & SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12)
@@ -4483,35 +4490,32 @@ int sdhci_setup_host(struct sdhci_host *host)
 
                        curr = min_t(u32, curr, SDHCI_MAX_CURRENT_LIMIT);
                        max_current_caps =
-                               (curr << SDHCI_MAX_CURRENT_330_SHIFT) |
-                               (curr << SDHCI_MAX_CURRENT_300_SHIFT) |
-                               (curr << SDHCI_MAX_CURRENT_180_SHIFT);
+                               FIELD_PREP(SDHCI_MAX_CURRENT_330_MASK, curr) |
+                               FIELD_PREP(SDHCI_MAX_CURRENT_300_MASK, curr) |
+                               FIELD_PREP(SDHCI_MAX_CURRENT_180_MASK, curr);
                }
        }
 
        if (host->caps & SDHCI_CAN_VDD_330) {
                ocr_avail |= MMC_VDD_32_33 | MMC_VDD_33_34;
 
-               mmc->max_current_330 = ((max_current_caps &
-                                  SDHCI_MAX_CURRENT_330_MASK) >>
-                                  SDHCI_MAX_CURRENT_330_SHIFT) *
-                                  SDHCI_MAX_CURRENT_MULTIPLIER;
+               mmc->max_current_330 = FIELD_GET(SDHCI_MAX_CURRENT_330_MASK,
+                                                max_current_caps) *
+                                               SDHCI_MAX_CURRENT_MULTIPLIER;
        }
        if (host->caps & SDHCI_CAN_VDD_300) {
                ocr_avail |= MMC_VDD_29_30 | MMC_VDD_30_31;
 
-               mmc->max_current_300 = ((max_current_caps &
-                                  SDHCI_MAX_CURRENT_300_MASK) >>
-                                  SDHCI_MAX_CURRENT_300_SHIFT) *
-                                  SDHCI_MAX_CURRENT_MULTIPLIER;
+               mmc->max_current_300 = FIELD_GET(SDHCI_MAX_CURRENT_300_MASK,
+                                                max_current_caps) *
+                                               SDHCI_MAX_CURRENT_MULTIPLIER;
        }
        if (host->caps & SDHCI_CAN_VDD_180) {
                ocr_avail |= MMC_VDD_165_195;
 
-               mmc->max_current_180 = ((max_current_caps &
-                                  SDHCI_MAX_CURRENT_180_MASK) >>
-                                  SDHCI_MAX_CURRENT_180_SHIFT) *
-                                  SDHCI_MAX_CURRENT_MULTIPLIER;
+               mmc->max_current_180 = FIELD_GET(SDHCI_MAX_CURRENT_180_MASK,
+                                                max_current_caps) *
+                                               SDHCI_MAX_CURRENT_MULTIPLIER;
        }
 
        /* If OCR set by host, use it instead. */
@@ -4662,6 +4666,12 @@ int __sdhci_add_host(struct sdhci_host *host)
        struct mmc_host *mmc = host->mmc;
        int ret;
 
+       if ((mmc->caps2 & MMC_CAP2_CQE) &&
+           (host->quirks & SDHCI_QUIRK_BROKEN_CQE)) {
+               mmc->caps2 &= ~MMC_CAP2_CQE;
+               mmc->cqe_ops = NULL;
+       }
+
        host->complete_wq = alloc_workqueue("sdhci", flags, 0);
        if (!host->complete_wq)
                return -ENOMEM;