Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 164753
b: refs/heads/master
c: 95cdfb7
h: refs/heads/master
i:
  164751: 9b0054b
v: v3
  • Loading branch information
Nicolas Pitre authored and Linus Torvalds committed Sep 23, 2009
1 parent 4231308 commit 23499d2
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 55 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 17d33e14f7ffc05f8c81e4a3bdb9a8003a05dcce
refs/heads/master: 95cdfb72b9bc568803f395c266152c71b034b461
35 changes: 28 additions & 7 deletions trunk/drivers/mmc/core/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1236,6 +1236,8 @@ EXPORT_SYMBOL(mmc_card_can_sleep);
*/
int mmc_suspend_host(struct mmc_host *host, pm_message_t state)
{
int err = 0;

if (host->caps & MMC_CAP_DISABLE)
cancel_delayed_work(&host->disable);
cancel_delayed_work(&host->detect);
Expand All @@ -1244,21 +1246,26 @@ int mmc_suspend_host(struct mmc_host *host, pm_message_t state)
mmc_bus_get(host);
if (host->bus_ops && !host->bus_dead) {
if (host->bus_ops->suspend)
host->bus_ops->suspend(host);
if (!host->bus_ops->resume) {
err = host->bus_ops->suspend(host);
if (err == -ENOSYS || !host->bus_ops->resume) {
/*
* We simply "remove" the card in this case.
* It will be redetected on resume.
*/
if (host->bus_ops->remove)
host->bus_ops->remove(host);

mmc_claim_host(host);
mmc_detach_bus(host);
mmc_release_host(host);
err = 0;
}
}
mmc_bus_put(host);

mmc_power_off(host);
if (!err)
mmc_power_off(host);

return 0;
return err;
}

EXPORT_SYMBOL(mmc_suspend_host);
Expand All @@ -1269,12 +1276,26 @@ EXPORT_SYMBOL(mmc_suspend_host);
*/
int mmc_resume_host(struct mmc_host *host)
{
int err = 0;

mmc_bus_get(host);
if (host->bus_ops && !host->bus_dead) {
mmc_power_up(host);
mmc_select_voltage(host, host->ocr);
BUG_ON(!host->bus_ops->resume);
host->bus_ops->resume(host);
err = host->bus_ops->resume(host);
if (err) {
printk(KERN_WARNING "%s: error %d during resume "
"(card was removed?)\n",
mmc_hostname(host), err);
if (host->bus_ops->remove)
host->bus_ops->remove(host);
mmc_claim_host(host);
mmc_detach_bus(host);
mmc_release_host(host);
/* no need to bother upper layers */
err = 0;
}
}
mmc_bus_put(host);

Expand All @@ -1284,7 +1305,7 @@ int mmc_resume_host(struct mmc_host *host)
*/
mmc_detect_change(host, 1);

return 0;
return err;
}

EXPORT_SYMBOL(mmc_resume_host);
Expand Down
4 changes: 2 additions & 2 deletions trunk/drivers/mmc/core/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ struct mmc_bus_ops {
int (*sleep)(struct mmc_host *);
void (*remove)(struct mmc_host *);
void (*detect)(struct mmc_host *);
void (*suspend)(struct mmc_host *);
void (*resume)(struct mmc_host *);
int (*suspend)(struct mmc_host *);
int (*resume)(struct mmc_host *);
void (*power_save)(struct mmc_host *);
void (*power_restore)(struct mmc_host *);
};
Expand Down
15 changes: 5 additions & 10 deletions trunk/drivers/mmc/core/mmc.c
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,7 @@ static void mmc_detect(struct mmc_host *host)
/*
* Suspend callback from host.
*/
static void mmc_suspend(struct mmc_host *host)
static int mmc_suspend(struct mmc_host *host)
{
BUG_ON(!host);
BUG_ON(!host->card);
Expand All @@ -540,6 +540,8 @@ static void mmc_suspend(struct mmc_host *host)
mmc_deselect_cards(host);
host->card->state &= ~MMC_STATE_HIGHSPEED;
mmc_release_host(host);

return 0;
}

/*
Expand All @@ -548,7 +550,7 @@ static void mmc_suspend(struct mmc_host *host)
* This function tries to determine if the same card is still present
* and, if so, restore all state to it.
*/
static void mmc_resume(struct mmc_host *host)
static int mmc_resume(struct mmc_host *host)
{
int err;

Expand All @@ -559,14 +561,7 @@ static void mmc_resume(struct mmc_host *host)
err = mmc_init_card(host, host->ocr, host->card);
mmc_release_host(host);

if (err) {
mmc_remove(host);

mmc_claim_host(host);
mmc_detach_bus(host);
mmc_release_host(host);
}

return err;
}

static void mmc_power_restore(struct mmc_host *host)
Expand Down
15 changes: 5 additions & 10 deletions trunk/drivers/mmc/core/sd.c
Original file line number Diff line number Diff line change
Expand Up @@ -564,7 +564,7 @@ static void mmc_sd_detect(struct mmc_host *host)
/*
* Suspend callback from host.
*/
static void mmc_sd_suspend(struct mmc_host *host)
static int mmc_sd_suspend(struct mmc_host *host)
{
BUG_ON(!host);
BUG_ON(!host->card);
Expand All @@ -574,6 +574,8 @@ static void mmc_sd_suspend(struct mmc_host *host)
mmc_deselect_cards(host);
host->card->state &= ~MMC_STATE_HIGHSPEED;
mmc_release_host(host);

return 0;
}

/*
Expand All @@ -582,7 +584,7 @@ static void mmc_sd_suspend(struct mmc_host *host)
* This function tries to determine if the same card is still present
* and, if so, restore all state to it.
*/
static void mmc_sd_resume(struct mmc_host *host)
static int mmc_sd_resume(struct mmc_host *host)
{
int err;

Expand All @@ -593,14 +595,7 @@ static void mmc_sd_resume(struct mmc_host *host)
err = mmc_sd_init_card(host, host->ocr, host->card);
mmc_release_host(host);

if (err) {
mmc_sd_remove(host);

mmc_claim_host(host);
mmc_detach_bus(host);
mmc_release_host(host);
}

return err;
}

static void mmc_sd_power_restore(struct mmc_host *host)
Expand Down
54 changes: 29 additions & 25 deletions trunk/drivers/mmc/core/sdio.c
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
goto err;
}
card = oldcard;
return 0;
}

/*
Expand Down Expand Up @@ -399,62 +400,65 @@ static void mmc_sdio_detect(struct mmc_host *host)
* Therefore all registered functions must have drivers with suspend
* and resume methods. Failing that we simply remove the whole card.
*/
static void mmc_sdio_suspend(struct mmc_host *host)
static int mmc_sdio_suspend(struct mmc_host *host)
{
int i;
int i, err = 0;

/* make sure all registered functions can suspend/resume */
for (i = 0; i < host->card->sdio_funcs; i++) {
struct sdio_func *func = host->card->sdio_func[i];
if (func && sdio_func_present(func) && func->dev.driver) {
const struct dev_pm_ops *pmops = func->dev.driver->pm;
if (!pmops || !pmops->suspend || !pmops->resume) {
/* just remove the entire card in that case */
mmc_sdio_remove(host);
mmc_claim_host(host);
mmc_detach_bus(host);
mmc_release_host(host);
return;
}
/* force removal of entire card in that case */
err = -ENOSYS;
} else
err = pmops->suspend(&func->dev);
if (err)
break;
}
}

/* now suspend them */
for (i = 0; i < host->card->sdio_funcs; i++) {
while (err && --i >= 0) {
struct sdio_func *func = host->card->sdio_func[i];
if (func && sdio_func_present(func) && func->dev.driver) {
const struct dev_pm_ops *pmops = func->dev.driver->pm;
pmops->suspend(&func->dev);
pmops->resume(&func->dev);
}
}

return err;
}

static void mmc_sdio_resume(struct mmc_host *host)
static int mmc_sdio_resume(struct mmc_host *host)
{
int i, err;

BUG_ON(!host);
BUG_ON(!host->card);

/* Basic card reinitialization. */
mmc_claim_host(host);
err = mmc_sdio_init_card(host, host->ocr, host->card);
mmc_release_host(host);
if (err) {
mmc_sdio_remove(host);
mmc_claim_host(host);
mmc_detach_bus(host);
mmc_release_host(host);
return;
}

/* resume all functions */
for (i = 0; i < host->card->sdio_funcs; i++) {
/*
* If the card looked to be the same as before suspending, then
* we proceed to resume all card functions. If one of them returns
* an error then we simply return that error to the core and the
* card will be redetected as new. It is the responsibility of
* the function driver to perform further tests with the extra
* knowledge it has of the card to confirm the card is indeed the
* same as before suspending (same MAC address for network cards,
* etc.) and return an error otherwise.
*/
for (i = 0; !err && i < host->card->sdio_funcs; i++) {
struct sdio_func *func = host->card->sdio_func[i];
if (func && sdio_func_present(func) && func->dev.driver) {
const struct dev_pm_ops *pmops = func->dev.driver->pm;
pmops->resume(&func->dev);
err = pmops->resume(&func->dev);
}
}

return err;
}

static const struct mmc_bus_ops mmc_sdio_ops = {
Expand Down

0 comments on commit 23499d2

Please sign in to comment.