mmc: core: Push common suspend|resume code into each bus_ops
authorUlf Hansson <ulf.hansson@linaro.org>
Mon, 10 Jun 2013 15:03:38 +0000 (17:03 +0200)
committerlintao <lintao@rock-chips.com>
Fri, 7 Mar 2014 05:03:43 +0000 (13:03 +0800)
By moving code from the mmc_suspend|resume_host down into each
.suspend|resume bus_ops callback, we get a more flexible solution.

Some nice side effects are that we get a better understanding of each
bus_ops suspend|resume sequence and the common code don't have to take
care of specific corner cases, especially for the SDIO case.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Tested-by: Jaehoon Chung <jh80.chung@samsung.com>
Signed-off-by: Chris Ball <cjb@laptop.org>
Conflicts:
drivers/mmc/core/core.c
drivers/mmc/core/sd.c

drivers/mmc/core/core.c
drivers/mmc/core/mmc.c
drivers/mmc/core/sd.c
drivers/mmc/core/sdio.c

index 8ba57a4b2a1c95d13e4a096bc07dd7997015faec..124f521815a0f54483881d47c73140d76f1af297 100644 (file)
@@ -2684,13 +2684,6 @@ int mmc_suspend_host(struct mmc_host *host)
 {
        int err = 0;
 
-       if (mmc_bus_needs_resume(host))
-               return 0;
-
-       if (cancel_delayed_work(&host->detect))
-               wake_unlock(&host->detect_wake_lock);
-       mmc_flush_scheduled_work();
-
        mmc_bus_get(host);
        if (host->bus_ops && !host->bus_dead) {
                if (host->bus_ops->suspend)
@@ -2698,9 +2691,6 @@ int mmc_suspend_host(struct mmc_host *host)
        }
        mmc_bus_put(host);
 
-       if (!err && !mmc_card_keep_power(host))
-               mmc_power_off(host);
-
        return err;
 }
 EXPORT_SYMBOL(mmc_suspend_host);
@@ -2711,7 +2701,7 @@ EXPORT_SYMBOL(mmc_suspend_host);
  */
 int mmc_resume_host(struct mmc_host *host)
 {
-       int err = 0;
+       int err;
 
        mmc_bus_get(host);
        if (mmc_bus_manual_resume(host)) {
@@ -2721,35 +2711,16 @@ int mmc_resume_host(struct mmc_host *host)
        }
 
        if (host->bus_ops && !host->bus_dead) {
-               if (!mmc_card_keep_power(host)) {
-                       mmc_power_up(host);
-                       mmc_select_voltage(host, host->ocr);
-                       /*
-                        * Tell runtime PM core we just powered up the card,
-                        * since it still believes the card is powered off.
-                        * Note that currently runtime PM is only enabled
-                        * for SDIO cards that are MMC_CAP_POWER_OFF_CARD
-                        */
-                       if (mmc_card_sdio(host->card) &&
-                           (host->caps & MMC_CAP_POWER_OFF_CARD)) {
-                               pm_runtime_disable(&host->card->dev);
-                               pm_runtime_set_active(&host->card->dev);
-                               pm_runtime_enable(&host->card->dev);
-                       }
-               }
                BUG_ON(!host->bus_ops->resume);
                err = host->bus_ops->resume(host);
-               if (err) {
+               if (err)
                        pr_warning("%s: error %d during resume "
                                            "(card was removed?)\n",
                                            mmc_hostname(host), err);
-                       err = 0;
-               }
        }
-       host->pm_flags &= ~MMC_PM_KEEP_POWER;
        mmc_bus_put(host);
 
-       return err;
+       return 0;
 }
 EXPORT_SYMBOL(mmc_resume_host);
 
index 913260990829354ce19e35f57044a494ce637f86..c8c7135c84b03c2c263b17682730fa0c289cc564 100644 (file)
@@ -1494,6 +1494,8 @@ static int mmc_suspend(struct mmc_host *host)
                err = mmc_deselect_cards(host);
        host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200);
 
+       if (!err)
+               mmc_power_off(host);
 out:
        mmc_release_host(host);
        return err;
@@ -1513,6 +1515,8 @@ static int mmc_resume(struct mmc_host *host)
        BUG_ON(!host->card);
 
        mmc_claim_host(host);
+       mmc_power_up(host);
+       mmc_select_voltage(host, host->ocr);
        err = mmc_init_card(host, host->ocr, host->card);
        mmc_release_host(host);
 
index 44ac2acf426e691b9fe245166deb99180294633d..3a0027adc4cd595079782e0f3438f22790218912 100644 (file)
@@ -1116,6 +1116,8 @@ static int mmc_sd_suspend(struct mmc_host *host)
        if (!mmc_host_is_spi(host))
                err = mmc_deselect_cards(host);
        host->card->state &= ~MMC_STATE_HIGHSPEED;
+       if (!err)
+               mmc_power_off(host);
        mmc_release_host(host);
 
        return err;
@@ -1130,31 +1132,15 @@ static int mmc_sd_suspend(struct mmc_host *host)
 static int mmc_sd_resume(struct mmc_host *host)
 {
        int err;
-#ifdef CONFIG_MMC_PARANOID_SD_INIT
-       int retries;
-#endif
 
        BUG_ON(!host);
        BUG_ON(!host->card);
 
        mmc_claim_host(host);
-#ifdef CONFIG_MMC_PARANOID_SD_INIT
-       retries = 5;
-       while (retries) {
-               err = mmc_sd_init_card(host, host->ocr, host->card);
+       mmc_power_up(host);
+       mmc_select_voltage(host, host->ocr);
 
-               if (err) {
-                       printk(KERN_ERR "%s: Re-init card rc = %d (retries = %d)\n",
-                              mmc_hostname(host), err, retries);
-                       mdelay(5);
-                       retries--;
-                       continue;
-               }
-               break;
-       }
-#else
        err = mmc_sd_init_card(host, host->ocr, host->card);
-#endif
        mmc_release_host(host);
 
        return err;
index d710ed580f6fe791ef593d996253cd0e83e0b0aa..af9a058fddbbb840d475bc46bb23761f0b569902 100644 (file)
@@ -984,6 +984,9 @@ static int mmc_sdio_suspend(struct mmc_host *host)
                mmc_release_host(host);
        }
 
+       if (!err && !mmc_card_keep_power(host))
+               mmc_power_off(host);
+
        return err;
 }
 
@@ -997,6 +1000,23 @@ static int mmc_sdio_resume(struct mmc_host *host)
        /* Basic card reinitialization. */
        mmc_claim_host(host);
 
+       /* Restore power if needed */
+       if (!mmc_card_keep_power(host)) {
+               mmc_power_up(host);
+               mmc_select_voltage(host, host->ocr);
+               /*
+                * Tell runtime PM core we just powered up the card,
+                * since it still believes the card is powered off.
+                * Note that currently runtime PM is only enabled
+                * for SDIO cards that are MMC_CAP_POWER_OFF_CARD
+                */
+               if (host->caps & MMC_CAP_POWER_OFF_CARD) {
+                       pm_runtime_disable(&host->card->dev);
+                       pm_runtime_set_active(&host->card->dev);
+                       pm_runtime_enable(&host->card->dev);
+               }
+       }
+
        /* No need to reinitialize powered-resumed nonremovable cards */
        if (mmc_card_is_removable(host) || !mmc_card_keep_power(host)) {
                sdio_reset(host);
@@ -1034,6 +1054,7 @@ static int mmc_sdio_resume(struct mmc_host *host)
                }
        }
 
+       host->pm_flags &= ~MMC_PM_KEEP_POWER;
        return err;
 }