sdhci: Make sdhci_disable_irq_wakeups() static
[cascardo/linux.git] / drivers / mmc / host / sdhci.c
index 47055f3..b5e22b8 100644 (file)
@@ -707,19 +707,28 @@ static void sdhci_set_transfer_irqs(struct sdhci_host *host)
        sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
 }
 
-static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd)
+static void sdhci_set_timeout(struct sdhci_host *host, struct mmc_command *cmd)
 {
        u8 count;
+
+       if (host->ops->set_timeout) {
+               host->ops->set_timeout(host, cmd);
+       } else {
+               count = sdhci_calc_timeout(host, cmd);
+               sdhci_writeb(host, count, SDHCI_TIMEOUT_CONTROL);
+       }
+}
+
+static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd)
+{
        u8 ctrl;
        struct mmc_data *data = cmd->data;
        int ret;
 
        WARN_ON(host->data);
 
-       if (data || (cmd->flags & MMC_RSP_BUSY)) {
-               count = sdhci_calc_timeout(host, cmd);
-               sdhci_writeb(host, count, SDHCI_TIMEOUT_CONTROL);
-       }
+       if (data || (cmd->flags & MMC_RSP_BUSY))
+               sdhci_set_timeout(host, cmd);
 
        if (!data)
                return;
@@ -1194,7 +1203,6 @@ void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
 clock_set:
        if (real_div)
                host->mmc->actual_clock = (host->max_clk * clk_mul) / real_div;
-
        clk |= (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT;
        clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN)
                << SDHCI_DIVIDER_HI_SHIFT;
@@ -1223,8 +1231,16 @@ EXPORT_SYMBOL_GPL(sdhci_set_clock);
 static void sdhci_set_power(struct sdhci_host *host, unsigned char mode,
                            unsigned short vdd)
 {
+       struct mmc_host *mmc = host->mmc;
        u8 pwr = 0;
 
+       if (!IS_ERR(mmc->supply.vmmc)) {
+               spin_unlock_irq(&host->lock);
+               mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd);
+               spin_lock_irq(&host->lock);
+               return;
+       }
+
        if (mode != MMC_POWER_OFF) {
                switch (1 << vdd) {
                case MMC_VDD_165_195:
@@ -1283,12 +1299,6 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned char mode,
                if (host->quirks & SDHCI_QUIRK_DELAY_AFTER_POWER)
                        mdelay(10);
        }
-
-       if (host->vmmc) {
-               spin_unlock_irq(&host->lock);
-               mmc_regulator_set_ocr(host->mmc, host->vmmc, vdd);
-               spin_lock_irq(&host->lock);
-       }
 }
 
 /*****************************************************************************\
@@ -1440,13 +1450,15 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
 {
        unsigned long flags;
        u8 ctrl;
+       struct mmc_host *mmc = host->mmc;
 
        spin_lock_irqsave(&host->lock, flags);
 
        if (host->flags & SDHCI_DEVICE_DEAD) {
                spin_unlock_irqrestore(&host->lock, flags);
-               if (host->vmmc && ios->power_mode == MMC_POWER_OFF)
-                       mmc_regulator_set_ocr(host->mmc, host->vmmc, 0);
+               if (!IS_ERR(mmc->supply.vmmc) &&
+                   ios->power_mode == MMC_POWER_OFF)
+                       mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0);
                return;
        }
 
@@ -1467,6 +1479,18 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
        if (!ios->clock || ios->clock != host->clock) {
                host->ops->set_clock(host, ios->clock);
                host->clock = ios->clock;
+
+               if (host->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK &&
+                   host->clock) {
+                       host->timeout_clk = host->mmc->actual_clock ?
+                                               host->mmc->actual_clock / 1000 :
+                                               host->clock / 1000;
+                       host->mmc->max_busy_timeout =
+                               host->ops->get_max_timeout_count ?
+                               host->ops->get_max_timeout_count(host) :
+                               1 << 27;
+                       host->mmc->max_busy_timeout /= host->timeout_clk;
+               }
        }
 
        sdhci_set_power(host, ios->power_mode, ios->vdd);
@@ -1530,7 +1554,6 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
                        host->ops->set_clock(host, host->clock);
                }
 
-
                /* Reset SD Clock Enable */
                clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
                clk &= ~SDHCI_CLOCK_CARD_EN;
@@ -1707,6 +1730,7 @@ static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)
 static int sdhci_do_start_signal_voltage_switch(struct sdhci_host *host,
                                                struct mmc_ios *ios)
 {
+       struct mmc_host *mmc = host->mmc;
        u16 ctrl;
        int ret;
 
@@ -1725,11 +1749,12 @@ static int sdhci_do_start_signal_voltage_switch(struct sdhci_host *host,
                ctrl &= ~SDHCI_CTRL_VDD_180;
                sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
 
-               if (host->vqmmc) {
-                       ret = regulator_set_voltage(host->vqmmc, 2700000, 3600000);
+               if (!IS_ERR(mmc->supply.vqmmc)) {
+                       ret = regulator_set_voltage(mmc->supply.vqmmc, 2700000,
+                                                   3600000);
                        if (ret) {
                                pr_warning("%s: Switching to 3.3V signalling voltage "
-                                               " failed\n", mmc_hostname(host->mmc));
+                                               " failed\n", mmc_hostname(mmc));
                                return -EIO;
                        }
                }
@@ -1742,16 +1767,16 @@ static int sdhci_do_start_signal_voltage_switch(struct sdhci_host *host,
                        return 0;
 
                pr_warning("%s: 3.3V regulator output did not became stable\n",
-                               mmc_hostname(host->mmc));
+                               mmc_hostname(mmc));
 
                return -EAGAIN;
        case MMC_SIGNAL_VOLTAGE_180:
-               if (host->vqmmc) {
-                       ret = regulator_set_voltage(host->vqmmc,
+               if (!IS_ERR(mmc->supply.vqmmc)) {
+                       ret = regulator_set_voltage(mmc->supply.vqmmc,
                                        1700000, 1950000);
                        if (ret) {
                                pr_warning("%s: Switching to 1.8V signalling voltage "
-                                               " failed\n", mmc_hostname(host->mmc));
+                                               " failed\n", mmc_hostname(mmc));
                                return -EIO;
                        }
                }
@@ -1763,24 +1788,22 @@ static int sdhci_do_start_signal_voltage_switch(struct sdhci_host *host,
                ctrl |= SDHCI_CTRL_VDD_180;
                sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
 
-               /* Wait for 5ms */
-               usleep_range(5000, 5500);
-
                /* 1.8V regulator output should be stable within 5 ms */
                ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
                if (ctrl & SDHCI_CTRL_VDD_180)
                        return 0;
 
                pr_warning("%s: 1.8V regulator output did not became stable\n",
-                               mmc_hostname(host->mmc));
+                               mmc_hostname(mmc));
 
                return -EAGAIN;
        case MMC_SIGNAL_VOLTAGE_120:
-               if (host->vqmmc) {
-                       ret = regulator_set_voltage(host->vqmmc, 1100000, 1300000);
+               if (!IS_ERR(mmc->supply.vqmmc)) {
+                       ret = regulator_set_voltage(mmc->supply.vqmmc, 1100000,
+                                                   1300000);
                        if (ret) {
                                pr_warning("%s: Switching to 1.2V signalling voltage "
-                                               " failed\n", mmc_hostname(host->mmc));
+                                               " failed\n", mmc_hostname(mmc));
                                return -EIO;
                        }
                }
@@ -2301,6 +2324,11 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
                 * above in sdhci_cmd_irq().
                 */
                if (host->cmd && (host->cmd->flags & MMC_RSP_BUSY)) {
+                       if (intmask & SDHCI_INT_DATA_TIMEOUT) {
+                               host->cmd->error = -ETIMEDOUT;
+                               tasklet_schedule(&host->finish_tasklet);
+                               return;
+                       }
                        if (intmask & SDHCI_INT_DATA_END) {
                                sdhci_finish_command(host);
                                return;
@@ -2531,7 +2559,7 @@ void sdhci_enable_irq_wakeups(struct sdhci_host *host)
 }
 EXPORT_SYMBOL_GPL(sdhci_enable_irq_wakeups);
 
-void sdhci_disable_irq_wakeups(struct sdhci_host *host)
+static void sdhci_disable_irq_wakeups(struct sdhci_host *host)
 {
        u8 val;
        u8 mask = SDHCI_WAKE_ON_INSERT | SDHCI_WAKE_ON_REMOVE
@@ -2541,7 +2569,6 @@ void sdhci_disable_irq_wakeups(struct sdhci_host *host)
        val &= ~mask;
        sdhci_writeb(host, val, SDHCI_WAKE_UP_CONTROL);
 }
-EXPORT_SYMBOL_GPL(sdhci_disable_irq_wakeups);
 
 int sdhci_suspend_host(struct sdhci_host *host)
 {
@@ -2643,7 +2670,6 @@ static void sdhci_runtime_pm_bus_off(struct sdhci_host *host)
 int sdhci_runtime_suspend_host(struct sdhci_host *host)
 {
        unsigned long flags;
-       int ret = 0;
 
        /* Disable tuning since we are suspending */
        if (host->flags & SDHCI_USING_RETUNING_TIMER) {
@@ -2663,14 +2689,14 @@ int sdhci_runtime_suspend_host(struct sdhci_host *host)
        host->runtime_suspended = true;
        spin_unlock_irqrestore(&host->lock, flags);
 
-       return ret;
+       return 0;
 }
 EXPORT_SYMBOL_GPL(sdhci_runtime_suspend_host);
 
 int sdhci_runtime_resume_host(struct sdhci_host *host)
 {
        unsigned long flags;
-       int ret = 0, host_flags = host->flags;
+       int host_flags = host->flags;
 
        if (host_flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
                if (host->ops->enable_dma)
@@ -2709,7 +2735,7 @@ int sdhci_runtime_resume_host(struct sdhci_host *host)
 
        spin_unlock_irqrestore(&host->lock, flags);
 
-       return ret;
+       return 0;
 }
 EXPORT_SYMBOL_GPL(sdhci_runtime_resume_host);
 
@@ -2820,12 +2846,12 @@ int sdhci_add_host(struct sdhci_host *host)
                 * (128) and potentially one alignment transfer for
                 * each of those entries.
                 */
-               host->adma_desc = dma_alloc_coherent(mmc_dev(host->mmc),
+               host->adma_desc = dma_alloc_coherent(mmc_dev(mmc),
                                                     ADMA_SIZE, &host->adma_addr,
                                                     GFP_KERNEL);
                host->align_buffer = kmalloc(128 * 4, GFP_KERNEL);
                if (!host->adma_desc || !host->align_buffer) {
-                       dma_free_coherent(mmc_dev(host->mmc), ADMA_SIZE,
+                       dma_free_coherent(mmc_dev(mmc), ADMA_SIZE,
                                          host->adma_desc, host->adma_addr);
                        kfree(host->align_buffer);
                        pr_warning("%s: Unable to allocate ADMA "
@@ -2838,7 +2864,7 @@ int sdhci_add_host(struct sdhci_host *host)
                        pr_warning("%s: unable to allocate aligned ADMA descriptor\n",
                                   mmc_hostname(mmc));
                        host->flags &= ~SDHCI_USE_ADMA;
-                       dma_free_coherent(mmc_dev(host->mmc), ADMA_SIZE,
+                       dma_free_coherent(mmc_dev(mmc), ADMA_SIZE,
                                          host->adma_desc, host->adma_addr);
                        kfree(host->align_buffer);
                        host->adma_desc = NULL;
@@ -2853,7 +2879,7 @@ int sdhci_add_host(struct sdhci_host *host)
         */
        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;
+               mmc_dev(mmc)->dma_mask = &host->dma_mask;
        }
 
        if (host->version >= SDHCI_SPEC_300)
@@ -2906,25 +2932,27 @@ int sdhci_add_host(struct sdhci_host *host)
        } else
                mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_200;
 
-       host->timeout_clk =
-               (caps[0] & SDHCI_TIMEOUT_CLK_MASK) >> SDHCI_TIMEOUT_CLK_SHIFT;
-       if (host->timeout_clk == 0) {
-               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)) {
-                       pr_err("%s: Hardware doesn't specify timeout clock "
-                              "frequency.\n", mmc_hostname(mmc));
-                       return -ENODEV;
+       if (!(host->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)) {
+               host->timeout_clk = (caps[0] & SDHCI_TIMEOUT_CLK_MASK) >>
+                                       SDHCI_TIMEOUT_CLK_SHIFT;
+               if (host->timeout_clk == 0) {
+                       if (host->ops->get_timeout_clock) {
+                               host->timeout_clk =
+                                       host->ops->get_timeout_clock(host);
+                       } else {
+                               pr_err("%s: Hardware doesn't specify timeout clock frequency.\n",
+                                       mmc_hostname(mmc));
+                               return -ENODEV;
+                       }
                }
-       }
-       if (caps[0] & SDHCI_TIMEOUT_CLK_UNIT)
-               host->timeout_clk *= 1000;
 
-       if (host->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)
-               host->timeout_clk = mmc->f_max / 1000;
+               if (caps[0] & SDHCI_TIMEOUT_CLK_UNIT)
+                       host->timeout_clk *= 1000;
 
-       mmc->max_busy_timeout = (1 << 27) / host->timeout_clk;
+               mmc->max_busy_timeout = host->ops->get_max_timeout_count ?
+                       host->ops->get_max_timeout_count(host) : 1 << 27;
+               mmc->max_busy_timeout /= host->timeout_clk;
+       }
 
        mmc->caps |= MMC_CAP_SDIO_IRQ | MMC_CAP_ERASE | MMC_CAP_CMD23;
        mmc->caps2 |= MMC_CAP2_SDIO_IRQ_NOTHREAD;
@@ -2959,28 +2987,25 @@ int sdhci_add_host(struct sdhci_host *host)
                mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;
 
        if ((host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) &&
-           !(host->mmc->caps & MMC_CAP_NONREMOVABLE))
+           !(mmc->caps & MMC_CAP_NONREMOVABLE))
                mmc->caps |= MMC_CAP_NEEDS_POLL;
 
+       /* If there are external regulators, get them */
+       if (mmc_regulator_get_supply(mmc) == -EPROBE_DEFER)
+               return -EPROBE_DEFER;
+
        /* If vqmmc regulator and no 1.8V signalling, then there's no UHS */
-       host->vqmmc = regulator_get_optional(mmc_dev(mmc), "vqmmc");
-       if (IS_ERR_OR_NULL(host->vqmmc)) {
-               if (PTR_ERR(host->vqmmc) < 0) {
-                       pr_info("%s: no vqmmc regulator found\n",
-                               mmc_hostname(mmc));
-                       host->vqmmc = NULL;
-               }
-       } else {
-               ret = regulator_enable(host->vqmmc);
-               if (!regulator_is_supported_voltage(host->vqmmc, 1700000,
-                       1950000))
+       if (!IS_ERR(mmc->supply.vqmmc)) {
+               ret = regulator_enable(mmc->supply.vqmmc);
+               if (!regulator_is_supported_voltage(mmc->supply.vqmmc, 1700000,
+                                                   1950000))
                        caps[1] &= ~(SDHCI_SUPPORT_SDR104 |
                                        SDHCI_SUPPORT_SDR50 |
                                        SDHCI_SUPPORT_DDR50);
                if (ret) {
                        pr_warn("%s: Failed to enable vqmmc regulator: %d\n",
                                mmc_hostname(mmc), ret);
-                       host->vqmmc = NULL;
+                       mmc->supply.vqmmc = NULL;
                }
        }
 
@@ -3041,34 +3066,6 @@ int sdhci_add_host(struct sdhci_host *host)
 
        ocr_avail = 0;
 
-       host->vmmc = regulator_get_optional(mmc_dev(mmc), "vmmc");
-       if (IS_ERR_OR_NULL(host->vmmc)) {
-               if (PTR_ERR(host->vmmc) < 0) {
-                       pr_info("%s: no vmmc regulator found\n",
-                               mmc_hostname(mmc));
-                       host->vmmc = NULL;
-               }
-       }
-
-#ifdef CONFIG_REGULATOR
-       /*
-        * Voltage range check makes sense only if regulator reports
-        * any voltage value.
-        */
-       if (host->vmmc && regulator_get_voltage(host->vmmc) > 0) {
-               ret = regulator_is_supported_voltage(host->vmmc, 2700000,
-                       3600000);
-               if ((ret <= 0) || (!(caps[0] & SDHCI_CAN_VDD_330)))
-                       caps[0] &= ~SDHCI_CAN_VDD_330;
-               if ((ret <= 0) || (!(caps[0] & SDHCI_CAN_VDD_300)))
-                       caps[0] &= ~SDHCI_CAN_VDD_300;
-               ret = regulator_is_supported_voltage(host->vmmc, 1700000,
-                       1950000);
-               if ((ret <= 0) || (!(caps[0] & SDHCI_CAN_VDD_180)))
-                       caps[0] &= ~SDHCI_CAN_VDD_180;
-       }
-#endif /* CONFIG_REGULATOR */
-
        /*
         * According to SD Host Controller spec v3.00, if the Host System
         * can afford more than 150mA, Host Driver should set XPC to 1. Also
@@ -3077,8 +3074,8 @@ int sdhci_add_host(struct sdhci_host *host)
         * value.
         */
        max_current_caps = sdhci_readl(host, SDHCI_MAX_CURRENT);
-       if (!max_current_caps && host->vmmc) {
-               u32 curr = regulator_get_current_limit(host->vmmc);
+       if (!max_current_caps && !IS_ERR(mmc->supply.vmmc)) {
+               int curr = regulator_get_current_limit(mmc->supply.vmmc);
                if (curr > 0) {
 
                        /* convert to SDHCI_MAX_CURRENT format */
@@ -3118,8 +3115,12 @@ int sdhci_add_host(struct sdhci_host *host)
                                   SDHCI_MAX_CURRENT_MULTIPLIER;
        }
 
+       /* If OCR set by external regulators, use it instead */
+       if (mmc->ocr_avail)
+               ocr_avail = mmc->ocr_avail;
+
        if (host->ocr_mask)
-               ocr_avail = host->ocr_mask;
+               ocr_avail &= host->ocr_mask;
 
        mmc->ocr_avail = ocr_avail;
        mmc->ocr_avail_sdio = ocr_avail;
@@ -3273,6 +3274,7 @@ EXPORT_SYMBOL_GPL(sdhci_add_host);
 
 void sdhci_remove_host(struct sdhci_host *host, int dead)
 {
+       struct mmc_host *mmc = host->mmc;
        unsigned long flags;
 
        if (dead) {
@@ -3282,7 +3284,7 @@ void sdhci_remove_host(struct sdhci_host *host, int dead)
 
                if (host->mrq) {
                        pr_err("%s: Controller removed during "
-                               " transfer!\n", mmc_hostname(host->mmc));
+                               " transfer!\n", mmc_hostname(mmc));
 
                        host->mrq->cmd->error = -ENOMEDIUM;
                        tasklet_schedule(&host->finish_tasklet);
@@ -3293,7 +3295,7 @@ void sdhci_remove_host(struct sdhci_host *host, int dead)
 
        sdhci_disable_card_detection(host);
 
-       mmc_remove_host(host->mmc);
+       mmc_remove_host(mmc);
 
 #ifdef SDHCI_USE_LEDS_CLASS
        led_classdev_unregister(&host->led);
@@ -3310,18 +3312,14 @@ void sdhci_remove_host(struct sdhci_host *host, int dead)
 
        tasklet_kill(&host->finish_tasklet);
 
-       if (host->vmmc) {
-               regulator_disable(host->vmmc);
-               regulator_put(host->vmmc);
-       }
+       if (!IS_ERR(mmc->supply.vmmc))
+               regulator_disable(mmc->supply.vmmc);
 
-       if (host->vqmmc) {
-               regulator_disable(host->vqmmc);
-               regulator_put(host->vqmmc);
-       }
+       if (!IS_ERR(mmc->supply.vqmmc))
+               regulator_disable(mmc->supply.vqmmc);
 
        if (host->adma_desc)
-               dma_free_coherent(mmc_dev(host->mmc), ADMA_SIZE,
+               dma_free_coherent(mmc_dev(mmc), ADMA_SIZE,
                                  host->adma_desc, host->adma_addr);
        kfree(host->align_buffer);