mmc: sdhci: Remove SDHCI_QUIRK2_NEED_DELAY_AFTER_INT_CLK_RST
[deliverable/linux.git] / drivers / mmc / host / sdhci.c
index 8670f162dec7452153625f589a3d24aec22e889d..dd1efed09be0e19fd52d648ea42b6aa62b43d532 100644 (file)
@@ -55,28 +55,6 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode);
 static void sdhci_enable_preset_value(struct sdhci_host *host, bool enable);
 static int sdhci_do_get_cd(struct sdhci_host *host);
 
-#ifdef CONFIG_PM
-static int sdhci_runtime_pm_get(struct sdhci_host *host);
-static int sdhci_runtime_pm_put(struct sdhci_host *host);
-static void sdhci_runtime_pm_bus_on(struct sdhci_host *host);
-static void sdhci_runtime_pm_bus_off(struct sdhci_host *host);
-#else
-static inline int sdhci_runtime_pm_get(struct sdhci_host *host)
-{
-       return 0;
-}
-static inline int sdhci_runtime_pm_put(struct sdhci_host *host)
-{
-       return 0;
-}
-static void sdhci_runtime_pm_bus_on(struct sdhci_host *host)
-{
-}
-static void sdhci_runtime_pm_bus_off(struct sdhci_host *host)
-{
-}
-#endif
-
 static void sdhci_dumpregs(struct sdhci_host *host)
 {
        pr_debug(DRIVER_NAME ": =========== REGISTER DUMP (%s)===========\n",
@@ -171,6 +149,22 @@ static void sdhci_disable_card_detection(struct sdhci_host *host)
        sdhci_set_card_detection(host, false);
 }
 
+static void sdhci_runtime_pm_bus_on(struct sdhci_host *host)
+{
+       if (host->bus_on)
+               return;
+       host->bus_on = true;
+       pm_runtime_get_noresume(host->mmc->parent);
+}
+
+static void sdhci_runtime_pm_bus_off(struct sdhci_host *host)
+{
+       if (!host->bus_on)
+               return;
+       host->bus_on = false;
+       pm_runtime_put_noidle(host->mmc->parent);
+}
+
 void sdhci_reset(struct sdhci_host *host, u8 mask)
 {
        unsigned long timeout;
@@ -1091,23 +1085,14 @@ static u16 sdhci_get_preset_value(struct sdhci_host *host)
        return preset;
 }
 
-void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
+u16 sdhci_calc_clk(struct sdhci_host *host, unsigned int clock,
+                  unsigned int *actual_clock)
 {
        int div = 0; /* Initialized for compiler warning */
        int real_div = div, clk_mul = 1;
        u16 clk = 0;
-       unsigned long timeout;
        bool switch_base_clk = false;
 
-       host->mmc->actual_clock = 0;
-
-       sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
-       if (host->quirks2 & SDHCI_QUIRK2_NEED_DELAY_AFTER_INT_CLK_RST)
-               mdelay(1);
-
-       if (clock == 0)
-               return;
-
        if (host->version >= SDHCI_SPEC_300) {
                if (host->preset_enabled) {
                        u16 pre_val;
@@ -1184,10 +1169,29 @@ 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;
+               *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;
+
+       return clk;
+}
+EXPORT_SYMBOL_GPL(sdhci_calc_clk);
+
+void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
+{
+       u16 clk;
+       unsigned long timeout;
+
+       host->mmc->actual_clock = 0;
+
+       sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
+
+       if (clock == 0)
+               return;
+
+       clk = sdhci_calc_clk(host, clock, &host->mmc->actual_clock);
+
        clk |= SDHCI_CLOCK_INT_EN;
        sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
 
@@ -1210,10 +1214,24 @@ clock_set:
 }
 EXPORT_SYMBOL_GPL(sdhci_set_clock);
 
-static void sdhci_set_power(struct sdhci_host *host, unsigned char mode,
-                           unsigned short vdd)
+static void sdhci_set_power_reg(struct sdhci_host *host, unsigned char mode,
+                               unsigned short vdd)
 {
        struct mmc_host *mmc = host->mmc;
+
+       spin_unlock_irq(&host->lock);
+       mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd);
+       spin_lock_irq(&host->lock);
+
+       if (mode != MMC_POWER_OFF)
+               sdhci_writeb(host, SDHCI_POWER_ON, SDHCI_POWER_CONTROL);
+       else
+               sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
+}
+
+void sdhci_set_power(struct sdhci_host *host, unsigned char mode,
+                    unsigned short vdd)
+{
        u8 pwr = 0;
 
        if (mode != MMC_POWER_OFF) {
@@ -1245,7 +1263,6 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned char mode,
                sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
                if (host->quirks2 & SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON)
                        sdhci_runtime_pm_bus_off(host);
-               vdd = 0;
        } else {
                /*
                 * Spec says that we should clear the power reg before setting
@@ -1276,12 +1293,20 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned char mode,
                if (host->quirks & SDHCI_QUIRK_DELAY_AFTER_POWER)
                        mdelay(10);
        }
+}
+EXPORT_SYMBOL_GPL(sdhci_set_power);
 
-       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);
-       }
+static void __sdhci_set_power(struct sdhci_host *host, unsigned char mode,
+                             unsigned short vdd)
+{
+       struct mmc_host *mmc = host->mmc;
+
+       if (host->ops->set_power)
+               host->ops->set_power(host, mode, vdd);
+       else if (!IS_ERR(mmc->supply.vmmc))
+               sdhci_set_power_reg(host, mode, vdd);
+       else
+               sdhci_set_power(host, mode, vdd);
 }
 
 /*****************************************************************************\
@@ -1298,8 +1323,6 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
 
        host = mmc_priv(mmc);
 
-       sdhci_runtime_pm_get(host);
-
        /* Firstly check card presence */
        present = mmc->ops->get_cd(mmc);
 
@@ -1431,7 +1454,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
                }
        }
 
-       sdhci_set_power(host, ios->power_mode, ios->vdd);
+       __sdhci_set_power(host, ios->power_mode, ios->vdd);
 
        if (host->ops->platform_send_init_74_clocks)
                host->ops->platform_send_init_74_clocks(host, ios->power_mode);
@@ -1546,9 +1569,7 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 {
        struct sdhci_host *host = mmc_priv(mmc);
 
-       sdhci_runtime_pm_get(host);
        sdhci_do_set_ios(host, ios);
-       sdhci_runtime_pm_put(host);
 }
 
 static int sdhci_do_get_cd(struct sdhci_host *host)
@@ -1580,12 +1601,8 @@ static int sdhci_do_get_cd(struct sdhci_host *host)
 static int sdhci_get_cd(struct mmc_host *mmc)
 {
        struct sdhci_host *host = mmc_priv(mmc);
-       int ret;
 
-       sdhci_runtime_pm_get(host);
-       ret = sdhci_do_get_cd(host);
-       sdhci_runtime_pm_put(host);
-       return ret;
+       return sdhci_do_get_cd(host);
 }
 
 static int sdhci_check_ro(struct sdhci_host *host)
@@ -1641,12 +1658,8 @@ static void sdhci_hw_reset(struct mmc_host *mmc)
 static int sdhci_get_ro(struct mmc_host *mmc)
 {
        struct sdhci_host *host = mmc_priv(mmc);
-       int ret;
 
-       sdhci_runtime_pm_get(host);
-       ret = sdhci_do_get_ro(host);
-       sdhci_runtime_pm_put(host);
-       return ret;
+       return sdhci_do_get_ro(host);
 }
 
 static void sdhci_enable_sdio_irq_nolock(struct sdhci_host *host, int enable)
@@ -1668,8 +1681,6 @@ static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)
        struct sdhci_host *host = mmc_priv(mmc);
        unsigned long flags;
 
-       sdhci_runtime_pm_get(host);
-
        spin_lock_irqsave(&host->lock, flags);
        if (enable)
                host->flags |= SDHCI_SDIO_IRQ_ENABLED;
@@ -1678,8 +1689,6 @@ static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)
 
        sdhci_enable_sdio_irq_nolock(host, enable);
        spin_unlock_irqrestore(&host->lock, flags);
-
-       sdhci_runtime_pm_put(host);
 }
 
 static int sdhci_do_start_signal_voltage_switch(struct sdhci_host *host,
@@ -1777,14 +1786,11 @@ static int sdhci_start_signal_voltage_switch(struct mmc_host *mmc,
        struct mmc_ios *ios)
 {
        struct sdhci_host *host = mmc_priv(mmc);
-       int err;
 
        if (host->version < SDHCI_SPEC_300)
                return 0;
-       sdhci_runtime_pm_get(host);
-       err = sdhci_do_start_signal_voltage_switch(host, ios);
-       sdhci_runtime_pm_put(host);
-       return err;
+
+       return sdhci_do_start_signal_voltage_switch(host, ios);
 }
 
 static int sdhci_card_busy(struct mmc_host *mmc)
@@ -1792,10 +1798,8 @@ static int sdhci_card_busy(struct mmc_host *mmc)
        struct sdhci_host *host = mmc_priv(mmc);
        u32 present_state;
 
-       sdhci_runtime_pm_get(host);
        /* Check whether DAT[3:0] is 0000 */
        present_state = sdhci_readl(host, SDHCI_PRESENT_STATE);
-       sdhci_runtime_pm_put(host);
 
        return !(present_state & SDHCI_DATA_LVL_MASK);
 }
@@ -1822,7 +1826,6 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
        unsigned int tuning_count = 0;
        bool hs400_tuning;
 
-       sdhci_runtime_pm_get(host);
        spin_lock_irqsave(&host->lock, flags);
 
        hs400_tuning = host->flags & SDHCI_HS400_TUNING;
@@ -1870,7 +1873,6 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
        if (host->ops->platform_execute_tuning) {
                spin_unlock_irqrestore(&host->lock, flags);
                err = host->ops->platform_execute_tuning(host, opcode);
-               sdhci_runtime_pm_put(host);
                return err;
        }
 
@@ -2002,8 +2004,6 @@ out:
        sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
 out_unlock:
        spin_unlock_irqrestore(&host->lock, flags);
-       sdhci_runtime_pm_put(host);
-
        return err;
 }
 
@@ -2201,7 +2201,6 @@ static void sdhci_tasklet_finish(unsigned long param)
        spin_unlock_irqrestore(&host->lock, flags);
 
        mmc_request_done(host->mmc, mrq);
-       sdhci_runtime_pm_put(host);
 }
 
 static void sdhci_timeout_timer(unsigned long data)
@@ -2682,33 +2681,6 @@ int sdhci_resume_host(struct sdhci_host *host)
 
 EXPORT_SYMBOL_GPL(sdhci_resume_host);
 
-static int sdhci_runtime_pm_get(struct sdhci_host *host)
-{
-       return pm_runtime_get_sync(host->mmc->parent);
-}
-
-static int sdhci_runtime_pm_put(struct sdhci_host *host)
-{
-       pm_runtime_mark_last_busy(host->mmc->parent);
-       return pm_runtime_put_autosuspend(host->mmc->parent);
-}
-
-static void sdhci_runtime_pm_bus_on(struct sdhci_host *host)
-{
-       if (host->bus_on)
-               return;
-       host->bus_on = true;
-       pm_runtime_get_noresume(host->mmc->parent);
-}
-
-static void sdhci_runtime_pm_bus_off(struct sdhci_host *host)
-{
-       if (!host->bus_on)
-               return;
-       host->bus_on = false;
-       pm_runtime_put_noidle(host->mmc->parent);
-}
-
 int sdhci_runtime_suspend_host(struct sdhci_host *host)
 {
        unsigned long flags;
This page took 0.034716 seconds and 5 git commands to generate.