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>
This commit is contained in:
parent
810caddba4
commit
7459026338
|
@ -2621,9 +2621,6 @@ int mmc_suspend_host(struct mmc_host *host)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
cancel_delayed_work(&host->detect);
|
|
||||||
mmc_flush_scheduled_work();
|
|
||||||
|
|
||||||
mmc_bus_get(host);
|
mmc_bus_get(host);
|
||||||
if (host->bus_ops && !host->bus_dead) {
|
if (host->bus_ops && !host->bus_dead) {
|
||||||
if (host->bus_ops->suspend)
|
if (host->bus_ops->suspend)
|
||||||
|
@ -2631,9 +2628,6 @@ int mmc_suspend_host(struct mmc_host *host)
|
||||||
}
|
}
|
||||||
mmc_bus_put(host);
|
mmc_bus_put(host);
|
||||||
|
|
||||||
if (!err && !mmc_card_keep_power(host))
|
|
||||||
mmc_power_off(host);
|
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(mmc_suspend_host);
|
EXPORT_SYMBOL(mmc_suspend_host);
|
||||||
|
@ -2644,39 +2638,20 @@ EXPORT_SYMBOL(mmc_suspend_host);
|
||||||
*/
|
*/
|
||||||
int mmc_resume_host(struct mmc_host *host)
|
int mmc_resume_host(struct mmc_host *host)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err;
|
||||||
|
|
||||||
mmc_bus_get(host);
|
mmc_bus_get(host);
|
||||||
if (host->bus_ops && !host->bus_dead) {
|
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);
|
BUG_ON(!host->bus_ops->resume);
|
||||||
err = host->bus_ops->resume(host);
|
err = host->bus_ops->resume(host);
|
||||||
if (err) {
|
if (err)
|
||||||
pr_warning("%s: error %d during resume "
|
pr_warning("%s: error %d during resume "
|
||||||
"(card was removed?)\n",
|
"(card was removed?)\n",
|
||||||
mmc_hostname(host), err);
|
mmc_hostname(host), err);
|
||||||
err = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
host->pm_flags &= ~MMC_PM_KEEP_POWER;
|
|
||||||
mmc_bus_put(host);
|
mmc_bus_put(host);
|
||||||
|
|
||||||
return err;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(mmc_resume_host);
|
EXPORT_SYMBOL(mmc_resume_host);
|
||||||
|
|
||||||
|
|
|
@ -1494,6 +1494,8 @@ static int mmc_suspend(struct mmc_host *host)
|
||||||
err = mmc_deselect_cards(host);
|
err = mmc_deselect_cards(host);
|
||||||
host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200);
|
host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200);
|
||||||
|
|
||||||
|
if (!err)
|
||||||
|
mmc_power_off(host);
|
||||||
out:
|
out:
|
||||||
mmc_release_host(host);
|
mmc_release_host(host);
|
||||||
return err;
|
return err;
|
||||||
|
@ -1513,6 +1515,8 @@ static int mmc_resume(struct mmc_host *host)
|
||||||
BUG_ON(!host->card);
|
BUG_ON(!host->card);
|
||||||
|
|
||||||
mmc_claim_host(host);
|
mmc_claim_host(host);
|
||||||
|
mmc_power_up(host);
|
||||||
|
mmc_select_voltage(host, host->ocr);
|
||||||
err = mmc_init_card(host, host->ocr, host->card);
|
err = mmc_init_card(host, host->ocr, host->card);
|
||||||
mmc_release_host(host);
|
mmc_release_host(host);
|
||||||
|
|
||||||
|
|
|
@ -1075,6 +1075,8 @@ static int mmc_sd_suspend(struct mmc_host *host)
|
||||||
if (!mmc_host_is_spi(host))
|
if (!mmc_host_is_spi(host))
|
||||||
err = mmc_deselect_cards(host);
|
err = mmc_deselect_cards(host);
|
||||||
host->card->state &= ~MMC_STATE_HIGHSPEED;
|
host->card->state &= ~MMC_STATE_HIGHSPEED;
|
||||||
|
if (!err)
|
||||||
|
mmc_power_off(host);
|
||||||
mmc_release_host(host);
|
mmc_release_host(host);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
|
@ -1094,6 +1096,8 @@ static int mmc_sd_resume(struct mmc_host *host)
|
||||||
BUG_ON(!host->card);
|
BUG_ON(!host->card);
|
||||||
|
|
||||||
mmc_claim_host(host);
|
mmc_claim_host(host);
|
||||||
|
mmc_power_up(host);
|
||||||
|
mmc_select_voltage(host, host->ocr);
|
||||||
err = mmc_sd_init_card(host, host->ocr, host->card);
|
err = mmc_sd_init_card(host, host->ocr, host->card);
|
||||||
mmc_release_host(host);
|
mmc_release_host(host);
|
||||||
|
|
||||||
|
|
|
@ -963,6 +963,9 @@ static int mmc_sdio_suspend(struct mmc_host *host)
|
||||||
mmc_release_host(host);
|
mmc_release_host(host);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!err && !mmc_card_keep_power(host))
|
||||||
|
mmc_power_off(host);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -976,6 +979,23 @@ static int mmc_sdio_resume(struct mmc_host *host)
|
||||||
/* Basic card reinitialization. */
|
/* Basic card reinitialization. */
|
||||||
mmc_claim_host(host);
|
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 */
|
/* No need to reinitialize powered-resumed nonremovable cards */
|
||||||
if (mmc_card_is_removable(host) || !mmc_card_keep_power(host)) {
|
if (mmc_card_is_removable(host) || !mmc_card_keep_power(host)) {
|
||||||
sdio_reset(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;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue