diff options
author | Ulf Hansson <ulf.hansson@linaro.org> | 2013-06-10 11:03:38 -0400 |
---|---|---|
committer | Chris Ball <cjb@laptop.org> | 2013-06-27 12:39:16 -0400 |
commit | 74590263384e5d4601de7f0ee2790477578829ea (patch) | |
tree | b6548924c4fdc46244f0663c2adcfd72d22f30c9 | |
parent | 810caddba42a54fe5db4e2664757a9a334ba359c (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.c | 31 | ||||
-rw-r--r-- | drivers/mmc/core/mmc.c | 4 | ||||
-rw-r--r-- | drivers/mmc/core/sd.c | 4 | ||||
-rw-r--r-- | 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 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 | } |
2639 | EXPORT_SYMBOL(mmc_suspend_host); | 2633 | EXPORT_SYMBOL(mmc_suspend_host); |
@@ -2644,39 +2638,20 @@ EXPORT_SYMBOL(mmc_suspend_host); | |||
2644 | */ | 2638 | */ |
2645 | int mmc_resume_host(struct mmc_host *host) | 2639 | int 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 | } |
2681 | EXPORT_SYMBOL(mmc_resume_host); | 2656 | EXPORT_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); | ||
1497 | out: | 1499 | out: |
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 | ||