mmc: Don't force card to active state when entering suspend/shutdown
authorUlf Hansson <ulf.hansson@linaro.org>
Wed, 2 Oct 2013 15:37:09 +0000 (17:37 +0200)
committerlintao <lintao@rock-chips.com>
Fri, 7 Mar 2014 12:05:12 +0000 (20:05 +0800)
By adding a card state that records if it is suspended or resumed, we
can accept asyncronus suspend/resume requests for the mmc and sd
bus_ops.

MMC_CAP_AGGRESSIVE_PM, will at request inactivity through the runtime
bus_ops callbacks, execute a suspend of the the card. In the state were
this has been done, we can receive a suspend request for the mmc bus,
which for sd and mmc forced the card to active state by a
pm_runtime_get_sync. In other words, the card was resumed and then
immediately suspended again, completely unnecessary.

Since the suspend/resume bus_ops callbacks for sd and mmc are now
capable of handling asynchronous requests, we no longer need to force
the card to active state before executing suspend. Evidently preventing
the above sequence for MMC_CAP_AGGRESSIVE_PM.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Chris Ball <cjb@laptop.org>
Conflicts:
drivers/mmc/core/mmc.c
drivers/mmc/core/sd.c

drivers/mmc/card/block.c
drivers/mmc/core/mmc.c
drivers/mmc/core/sd.c

index e2adbe0216cc868c7d61ef45fdae7070dead097f..65d6c0d566de507144f6ba76e806be04e3a212c1 100644 (file)
@@ -2461,7 +2461,6 @@ static int _mmc_blk_suspend(struct mmc_card *card)
        struct mmc_blk_data *md = mmc_get_drvdata(card);
 
        if (md) {
-               pm_runtime_get_sync(&card->dev);
                mmc_queue_suspend(&md->queue);
                list_for_each_entry(part_md, &md->part, part) {
                        mmc_queue_suspend(&part_md->queue);
@@ -2496,7 +2495,6 @@ static int mmc_blk_resume(struct mmc_card *card)
                list_for_each_entry(part_md, &md->part, part) {
                        mmc_queue_resume(&part_md->queue);
                }
-               pm_runtime_put(&card->dev);
        }
        return 0;
 }
index 98e9eb0f6643149f6b589cb1319b2a0a0905ee1d..be163d65cd2324a66121d58fabaf89e8af344df6 100644 (file)
@@ -1511,18 +1511,12 @@ out:
  */
 static int mmc_suspend(struct mmc_host *host)
 {
-       int err;
-
-       err = _mmc_suspend(host, true);
-       if (!err) {
-               pm_runtime_disable(&host->card->dev);
-               pm_runtime_set_suspended(&host->card->dev);
-       }
-
-       return err;
+       return  _mmc_suspend(host, true);
 }
 
 /*
+ * Resume callback from host.
+ *
  * This function tries to determine if the same card is still present
  * and, if so, restore all state to it.
  */
@@ -1547,6 +1541,21 @@ out:
        return err;
 }
 
+
+/*
+ * Callback for resume.
+ */
+static int mmc_resume(struct mmc_host *host)
+{
+       int err = 0;
+
+       if (!(host->caps & MMC_CAP_RUNTIME_RESUME)) {
+               err = _mmc_resume(host);
+               pm_runtime_set_active(&host->card->dev);
+               pm_runtime_mark_last_busy(&host->card->dev);
+       }
+       pm_runtime_enable(&host->card->dev);
+}
 /*
  * Shutdown callback
  */
@@ -1560,7 +1569,7 @@ static int mmc_shutdown(struct mmc_host *host)
         */
        if (mmc_can_poweroff_notify(host->card) &&
                !(host->caps2 & MMC_CAP2_FULL_PWR_CYCLE))
-               err = _mmc_resume(host);
+               err = mmc_resume(host);
 
        if (!err)
                err = _mmc_suspend(host, false);
@@ -1568,23 +1577,6 @@ static int mmc_shutdown(struct mmc_host *host)
        return err;
 }
 
-/*
- * Callback for resume.
- */
-static int mmc_resume(struct mmc_host *host)
-{
-       int err = 0;
-
-       if (!(host->caps & MMC_CAP_RUNTIME_RESUME)) {
-               err = _mmc_resume(host);
-               pm_runtime_set_active(&host->card->dev);
-               pm_runtime_mark_last_busy(&host->card->dev);
-       }
-       pm_runtime_enable(&host->card->dev);
-
-       return err;
-}
-
 /*
  * Callback for runtime_suspend.
  */
index 8a4dfbbfbb72d3404bed47e4e73f094e2c2f9ea1..f291ad7bf68ba86a359e0f7eaa8e6356d9cef065 100644 (file)
@@ -1116,9 +1116,13 @@ static void mmc_sd_detect(struct mmc_host *host)
        }
 }
 
-static int _mmc_sd_suspend(struct mmc_host *host)
+
+/*
+ * Callback for suspend
+ */
+static int mmc_sd_suspend(struct mmc_host *host)
 {
-       int err = 0;
+       int err;
 
        BUG_ON(!host);
        BUG_ON(!host->card);
@@ -1126,35 +1130,19 @@ static int _mmc_sd_suspend(struct mmc_host *host)
        mmc_claim_host(host);
 
        if (mmc_card_suspended(host->card))
-               goto out;
-
-       if (!mmc_host_is_spi(host))
-               err = mmc_deselect_cards(host);
-       host->card->state &= ~MMC_STATE_HIGHSPEED;
-       if (!err) {
-               mmc_power_off(host);
-               mmc_card_set_suspended(host->card);
-       }
-
+           goto out;
+    if (!mmc_host_is_spi(host))
+        err = mmc_deselect_cards(host);
+
+    host->card->state &= ~MMC_STATE_HIGHSPEED;
+    if (!err) {
+        mmc_power_off(host);
+        mmc_card_set_suspended(host->card);
+    }
 out:
-       mmc_release_host(host);
-       return err;
-}
-
-/*
- * Callback for suspend
- */
-static int mmc_sd_suspend(struct mmc_host *host)
-{
-       int err;
-
-       err = _mmc_sd_suspend(host);
-       if (!err) {
-               pm_runtime_disable(&host->card->dev);
-               pm_runtime_set_suspended(&host->card->dev);
-       }
+    mmc_release_host(host);
+    return err;
 
-       return err;
 }
 
 /*
@@ -1196,6 +1184,8 @@ static int mmc_sd_resume(struct mmc_host *host)
        }
        pm_runtime_enable(&host->card->dev);
 
+out:
+       mmc_release_host(host);
        return err;
 }
 
@@ -1209,7 +1199,7 @@ static int mmc_sd_runtime_suspend(struct mmc_host *host)
        if (!(host->caps & MMC_CAP_AGGRESSIVE_PM))
                return 0;
 
-       err = _mmc_sd_suspend(host);
+       err = mmc_sd_suspend(host);
        if (err)
                pr_err("%s: error %d doing aggessive suspend\n",
                        mmc_hostname(host), err);