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>

Conflicts:
	drivers/mmc/core/core.c
	drivers/mmc/core/sd.c
This commit is contained in:
Ulf Hansson
2013-06-10 17:03:38 +02:00
committed by lintao
parent cf46d24117
commit 8acf2c95af
4 changed files with 32 additions and 50 deletions

View 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);

View 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);

View 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;

View 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;
}