From: Ulf Hansson <ulf.hans...@linaro.org>

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.hans...@linaro.org>
Tested-by: Jaehoon Chung <jh80.ch...@samsung.com>
---
 drivers/mmc/core/core.c |   31 +++----------------------------
 drivers/mmc/core/mmc.c  |    4 ++++
 drivers/mmc/core/sd.c   |    4 ++++
 drivers/mmc/core/sdio.c |   21 +++++++++++++++++++++
 4 files changed, 32 insertions(+), 28 deletions(-)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 7a8a42d..da3b907 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -2621,9 +2621,6 @@ int mmc_suspend_host(struct mmc_host *host)
 {
        int err = 0;
 
-       cancel_delayed_work(&host->detect);
-       mmc_flush_scheduled_work();
-
        mmc_bus_get(host);
        if (host->bus_ops && !host->bus_dead) {
                if (host->bus_ops->suspend)
@@ -2631,9 +2628,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);
@@ -2644,39 +2638,20 @@ EXPORT_SYMBOL(mmc_suspend_host);
  */
 int mmc_resume_host(struct mmc_host *host)
 {
-       int err = 0;
+       int err;
 
        mmc_bus_get(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);
 
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 3a69b94..86ca103 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -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);
 
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index aeaae7c..cacef27 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -1075,6 +1075,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;
@@ -1094,6 +1096,8 @@ static int mmc_sd_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_sd_init_card(host, host->ocr, host->card);
        mmc_release_host(host);
 
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index be8cca8..80d89cff 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -963,6 +963,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;
 }
 
@@ -976,6 +979,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);
@@ -1013,6 +1033,7 @@ static int mmc_sdio_resume(struct mmc_host *host)
                }
        }
 
+       host->pm_flags &= ~MMC_PM_KEEP_POWER;
        return err;
 }
 
-- 
1.7.10

--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to