Merge commit drm-intel-fixes into topic/ppgtt
[firefly-linux-kernel-4.4.55.git] / drivers / mmc / host / sdhci.c
index 7a7fb4f0d5a43a4829fa1e258afbf112f4dd9b82..bd8a0982aec33ec99b95b97fbcbdd65dee642770 100644 (file)
@@ -49,7 +49,6 @@ static unsigned int debug_quirks2;
 
 static void sdhci_finish_data(struct sdhci_host *);
 
-static void sdhci_send_command(struct sdhci_host *, struct mmc_command *);
 static void sdhci_finish_command(struct sdhci_host *);
 static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode);
 static void sdhci_tuning_timer(unsigned long data);
@@ -981,7 +980,7 @@ static void sdhci_finish_data(struct sdhci_host *host)
                tasklet_schedule(&host->finish_tasklet);
 }
 
-static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
+void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
 {
        int flags;
        u32 mask;
@@ -1053,6 +1052,7 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
 
        sdhci_writew(host, SDHCI_MAKE_CMD(cmd->opcode, flags), SDHCI_COMMAND);
 }
+EXPORT_SYMBOL_GPL(sdhci_send_command);
 
 static void sdhci_finish_command(struct sdhci_host *host)
 {
@@ -1435,7 +1435,8 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
        }
 
        if (host->version >= SDHCI_SPEC_300 &&
-               (ios->power_mode == MMC_POWER_UP))
+               (ios->power_mode == MMC_POWER_UP) &&
+               !(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN))
                sdhci_enable_preset_value(host, false);
 
        sdhci_set_clock(host, ios->clock);
@@ -1875,6 +1876,14 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
                return 0;
        }
 
+       if (host->ops->platform_execute_tuning) {
+               spin_unlock(&host->lock);
+               enable_irq(host->irq);
+               err = host->ops->platform_execute_tuning(host, opcode);
+               sdhci_runtime_pm_put(host);
+               return err;
+       }
+
        sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
 
        /*
@@ -1981,6 +1990,7 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
        if (!tuning_loop_counter || !timeout) {
                ctrl &= ~SDHCI_CTRL_TUNED_CLK;
                sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
+               err = -EIO;
        } else {
                if (!(ctrl & SDHCI_CTRL_TUNED_CLK)) {
                        pr_info(DRIVER_NAME ": Tuning procedure"
@@ -2491,6 +2501,14 @@ again:
        result = IRQ_HANDLED;
 
        intmask = sdhci_readl(host, SDHCI_INT_STATUS);
+
+       /*
+        * If we know we'll call the driver to signal SDIO IRQ, disregard
+        * further indications of Card Interrupt in the status to avoid a
+        * needless loop.
+        */
+       if (cardint)
+               intmask &= ~SDHCI_INT_CARD_INT;
        if (intmask && --max_loops)
                goto again;
 out:
@@ -2546,8 +2564,6 @@ EXPORT_SYMBOL_GPL(sdhci_disable_irq_wakeups);
 
 int sdhci_suspend_host(struct sdhci_host *host)
 {
-       int ret;
-
        if (host->ops->platform_suspend)
                host->ops->platform_suspend(host);
 
@@ -2559,19 +2575,6 @@ int sdhci_suspend_host(struct sdhci_host *host)
                host->flags &= ~SDHCI_NEEDS_RETUNING;
        }
 
-       ret = mmc_suspend_host(host->mmc);
-       if (ret) {
-               if (host->flags & SDHCI_USING_RETUNING_TIMER) {
-                       host->flags |= SDHCI_NEEDS_RETUNING;
-                       mod_timer(&host->tuning_timer, jiffies +
-                                       host->tuning_count * HZ);
-               }
-
-               sdhci_enable_card_detection(host);
-
-               return ret;
-       }
-
        if (!device_may_wakeup(mmc_dev(host->mmc))) {
                sdhci_mask_irqs(host, SDHCI_INT_ALL_MASK);
                free_irq(host->irq, host);
@@ -2579,14 +2582,14 @@ int sdhci_suspend_host(struct sdhci_host *host)
                sdhci_enable_irq_wakeups(host);
                enable_irq_wake(host->irq);
        }
-       return ret;
+       return 0;
 }
 
 EXPORT_SYMBOL_GPL(sdhci_suspend_host);
 
 int sdhci_resume_host(struct sdhci_host *host)
 {
-       int ret;
+       int ret = 0;
 
        if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
                if (host->ops->enable_dma)
@@ -2615,7 +2618,6 @@ int sdhci_resume_host(struct sdhci_host *host)
                mmiowb();
        }
 
-       ret = mmc_resume_host(host->mmc);
        sdhci_enable_card_detection(host);
 
        if (host->ops->platform_resume)