aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hansson <ulf.hansson@linaro.org>2013-06-10 11:03:38 -0400
committerChris Ball <cjb@laptop.org>2013-06-27 12:39:16 -0400
commit74590263384e5d4601de7f0ee2790477578829ea (patch)
treeb6548924c4fdc46244f0663c2adcfd72d22f30c9
parent810caddba42a54fe5db4e2664757a9a334ba359c (diff)
mmc: core: Push common suspend|resume code into each bus_ops
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>
-rw-r--r--drivers/mmc/core/core.c31
-rw-r--r--drivers/mmc/core/mmc.c4
-rw-r--r--drivers/mmc/core/sd.c4
-rw-r--r--drivers/mmc/core/sdio.c21
4 files changed, 32 insertions, 28 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 7a8a42d3a039..da3b9078ea65 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)
2621{ 2621{
2622 int err = 0; 2622 int err = 0;
2623 2623
2624 cancel_delayed_work(&host->detect);
2625 mmc_flush_scheduled_work();
2626
2627 mmc_bus_get(host); 2624 mmc_bus_get(host);
2628 if (host->bus_ops && !host->bus_dead) { 2625 if (host->bus_ops && !host->bus_dead) {
2629 if (host->bus_ops->suspend) 2626 if (host->bus_ops->suspend)
@@ -2631,9 +2628,6 @@ int mmc_suspend_host(struct mmc_host *host)
2631 } 2628 }
2632 mmc_bus_put(host); 2629 mmc_bus_put(host);
2633 2630
2634 if (!err && !mmc_card_keep_power(host))
2635 mmc_power_off(host);
2636
2637 return err; 2631 return err;
2638} 2632}
2639EXPORT_SYMBOL(mmc_suspend_host); 2633EXPORT_SYMBOL(mmc_suspend_host);
@@ -2644,39 +2638,20 @@ EXPORT_SYMBOL(mmc_suspend_host);
2644 */ 2638 */
2645int mmc_resume_host(struct mmc_host *host) 2639int mmc_resume_host(struct mmc_host *host)
2646{ 2640{
2647 int err = 0; 2641 int err;
2648 2642
2649 mmc_bus_get(host); 2643 mmc_bus_get(host);
2650 if (host->bus_ops && !host->bus_dead) { 2644 if (host->bus_ops && !host->bus_dead) {
2651 if (!mmc_card_keep_power(host)) {
2652 mmc_power_up(host);
2653 mmc_select_voltage(host, host->ocr);
2654 /*
2655 * Tell runtime PM core we just powered up the card,
2656 * since it still believes the card is powered off.
2657 * Note that currently runtime PM is only enabled
2658 * for SDIO cards that are MMC_CAP_POWER_OFF_CARD
2659 */
2660 if (mmc_card_sdio(host->card) &&
2661 (host->caps & MMC_CAP_POWER_OFF_CARD)) {
2662 pm_runtime_disable(&host->card->dev);
2663 pm_runtime_set_active(&host->card->dev);
2664 pm_runtime_enable(&host->card->dev);
2665 }
2666 }
2667 BUG_ON(!host->bus_ops->resume); 2645 BUG_ON(!host->bus_ops->resume);
2668 err = host->bus_ops->resume(host); 2646 err = host->bus_ops->resume(host);
2669 if (err) { 2647 if (err)
2670 pr_warning("%s: error %d during resume " 2648 pr_warning("%s: error %d during resume "
2671 "(card was removed?)\n", 2649 "(card was removed?)\n",
2672 mmc_hostname(host), err); 2650 mmc_hostname(host), err);
2673 err = 0;
2674 }
2675 } 2651 }
2676 host->pm_flags &= ~MMC_PM_KEEP_POWER;
2677 mmc_bus_put(host); 2652 mmc_bus_put(host);
2678 2653
2679 return err; 2654 return 0;
2680} 2655}
2681EXPORT_SYMBOL(mmc_resume_host); 2656EXPORT_SYMBOL(mmc_resume_host);
2682 2657
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 913260990829..c8c7135c84b0 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)
1494 err = mmc_deselect_cards(host); 1494 err = mmc_deselect_cards(host);
1495 host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200); 1495 host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200);
1496 1496
1497 if (!err)
1498 mmc_power_off(host);
1497out: 1499out:
1498 mmc_release_host(host); 1500 mmc_release_host(host);
1499 return err; 1501 return err;
@@ -1513,6 +1515,8 @@ static int mmc_resume(struct mmc_host *host)
1513 BUG_ON(!host->card); 1515 BUG_ON(!host->card);
1514 1516
1515 mmc_claim_host(host); 1517 mmc_claim_host(host);
1518 mmc_power_up(host);
1519 mmc_select_voltage(host, host->ocr);
1516 err = mmc_init_card(host, host->ocr, host->card); 1520 err = mmc_init_card(host, host->ocr, host->card);
1517 mmc_release_host(host); 1521 mmc_release_host(host);
1518 1522
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index aeaae7c3b22b..cacef27b00d1 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)
1075 if (!mmc_host_is_spi(host)) 1075 if (!mmc_host_is_spi(host))
1076 err = mmc_deselect_cards(host); 1076 err = mmc_deselect_cards(host);
1077 host->card->state &= ~MMC_STATE_HIGHSPEED; 1077 host->card->state &= ~MMC_STATE_HIGHSPEED;
1078 if (!err)
1079 mmc_power_off(host);
1078 mmc_release_host(host); 1080 mmc_release_host(host);
1079 1081
1080 return err; 1082 return err;
@@ -1094,6 +1096,8 @@ static int mmc_sd_resume(struct mmc_host *host)
1094 BUG_ON(!host->card); 1096 BUG_ON(!host->card);
1095 1097
1096 mmc_claim_host(host); 1098 mmc_claim_host(host);
1099 mmc_power_up(host);
1100 mmc_select_voltage(host, host->ocr);
1097 err = mmc_sd_init_card(host, host->ocr, host->card); 1101 err = mmc_sd_init_card(host, host->ocr, host->card);
1098 mmc_release_host(host); 1102 mmc_release_host(host);
1099 1103
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index be8cca8d3024..80d89cff7306 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)
963 mmc_release_host(host); 963 mmc_release_host(host);
964 } 964 }
965 965
966 if (!err && !mmc_card_keep_power(host))
967 mmc_power_off(host);
968
966 return err; 969 return err;
967} 970}
968 971
@@ -976,6 +979,23 @@ static int mmc_sdio_resume(struct mmc_host *host)
976 /* Basic card reinitialization. */ 979 /* Basic card reinitialization. */
977 mmc_claim_host(host); 980 mmc_claim_host(host);
978 981
982 /* Restore power if needed */
983 if (!mmc_card_keep_power(host)) {
984 mmc_power_up(host);
985 mmc_select_voltage(host, host->ocr);
986 /*
987 * Tell runtime PM core we just powered up the card,
988 * since it still believes the card is powered off.
989 * Note that currently runtime PM is only enabled
990 * for SDIO cards that are MMC_CAP_POWER_OFF_CARD
991 */
992 if (host->caps & MMC_CAP_POWER_OFF_CARD) {
993 pm_runtime_disable(&host->card->dev);
994 pm_runtime_set_active(&host->card->dev);
995 pm_runtime_enable(&host->card->dev);
996 }
997 }
998
979 /* No need to reinitialize powered-resumed nonremovable cards */ 999 /* No need to reinitialize powered-resumed nonremovable cards */
980 if (mmc_card_is_removable(host) || !mmc_card_keep_power(host)) { 1000 if (mmc_card_is_removable(host) || !mmc_card_keep_power(host)) {
981 sdio_reset(host); 1001 sdio_reset(host);
@@ -1013,6 +1033,7 @@ static int mmc_sdio_resume(struct mmc_host *host)
1013 } 1033 }
1014 } 1034 }
1015 1035
1036 host->pm_flags &= ~MMC_PM_KEEP_POWER;
1016 return err; 1037 return err;
1017} 1038}
1018 1039