aboutsummaryrefslogtreecommitdiff
path: root/drivers/mmc/core/core.c
diff options
context:
space:
mode:
authorPierre Ossman <drzeus@drzeus.cx>2007-05-01 16:00:02 +0200
committerPierre Ossman <drzeus@drzeus.cx>2007-05-01 16:00:02 +0200
commit6abaa0c9fec563538f2a28a682af8c89bb9b125c (patch)
tree1da7fb5a0b37bd57b38ca52c77ccc72b099fcbae /drivers/mmc/core/core.c
parent89a73cf52ba2ae4402c53487b71ec4475544f139 (diff)
mmc: support unsafe resume of cards
Since many have the system root on MMC/SD we must allow some foot shooting when it comes to resume. We cannot detect if a card is removed and reinserted during suspend, so the safe approach would be to assume it was, avoiding potential filesystem corruption. This will of course not work if you cannot release the card before suspend. This commit adds a compile time option that makes the MMC layer assume the card wasn't touched if it is redetected upon resume. Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
Diffstat (limited to 'drivers/mmc/core/core.c')
-rw-r--r--drivers/mmc/core/core.c29
1 files changed, 23 insertions, 6 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 75333a2461d..72c7cf4a9f9 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -677,14 +677,19 @@ 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->remove)
- host->bus_ops->remove(host);
- mmc_detach_bus(host);
+ if (host->bus_ops->suspend)
+ host->bus_ops->suspend(host);
+ if (!host->bus_ops->resume) {
+ if (host->bus_ops->remove)
+ host->bus_ops->remove(host);
+
+ mmc_claim_host(host);
+ mmc_detach_bus(host);
+ mmc_release_host(host);
+ }
}
mmc_bus_put(host);
- BUG_ON(host->card);
-
mmc_power_off(host);
return 0;
@@ -698,7 +703,19 @@ EXPORT_SYMBOL(mmc_suspend_host);
*/
int mmc_resume_host(struct mmc_host *host)
{
- mmc_rescan(&host->detect.work);
+ mmc_bus_get(host);
+ if (host->bus_ops && !host->bus_dead) {
+ mmc_power_up(host);
+ BUG_ON(!host->bus_ops->resume);
+ host->bus_ops->resume(host);
+ }
+ mmc_bus_put(host);
+
+ /*
+ * We add a slight delay here so that resume can progress
+ * in parallel.
+ */
+ mmc_detect_change(host, 1);
return 0;
}