aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorSan Mehat <san@google.com>2009-07-30 07:55:28 -0700
committerColin Cross <ccross@android.com>2011-06-14 09:08:52 -0700
commit10797cfdbb14c6c1a95775c49a1fd940f216391b (patch)
tree480c4af554d18855e32b68182db6ca058e93d5e3 /drivers/mmc
parentb2afee5fd851ed883ebc36ce3498ed285553c109 (diff)
downloadkernel_samsung_tuna-10797cfdbb14c6c1a95775c49a1fd940f216391b.zip
kernel_samsung_tuna-10797cfdbb14c6c1a95775c49a1fd940f216391b.tar.gz
kernel_samsung_tuna-10797cfdbb14c6c1a95775c49a1fd940f216391b.tar.bz2
mmc: core: Add deferred bus resume policy.
A card driver can now specify that the underlying bus should *not* auto-resume with the rest of the system. This is useful for reducing resume latency as well as saving power when the card driver is not using the bus. In the future, we'll add support for manual suspend Signed-off-by: San Mehat <san@google.com>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/core/core.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index e01daef..14242c5 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -1097,6 +1097,30 @@ static inline void mmc_bus_put(struct mmc_host *host)
spin_unlock_irqrestore(&host->lock, flags);
}
+int mmc_resume_bus(struct mmc_host *host)
+{
+ if (!mmc_bus_needs_resume(host))
+ return -EINVAL;
+
+ printk("%s: Starting deferred resume\n", mmc_hostname(host));
+ host->bus_resume_flags &= ~MMC_BUSRESUME_NEEDS_RESUME;
+ 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);
+ }
+
+ if (host->bus_ops->detect && !host->bus_dead)
+ host->bus_ops->detect(host);
+
+ mmc_bus_put(host);
+ printk("%s: Deferred resume completed\n", mmc_hostname(host));
+ return 0;
+}
+
+EXPORT_SYMBOL(mmc_resume_bus);
+
/*
* Assign a mmc bus handler to a host. Only one bus handler may control a
* host at any given time.
@@ -1761,6 +1785,9 @@ int mmc_suspend_host(struct mmc_host *host)
{
int err = 0;
+ if (mmc_bus_needs_resume(host))
+ return 0;
+
if (host->caps & MMC_CAP_DISABLE)
cancel_delayed_work(&host->disable);
cancel_delayed_work(&host->detect);
@@ -1803,6 +1830,12 @@ int mmc_resume_host(struct mmc_host *host)
int err = 0;
mmc_bus_get(host);
+ if (host->bus_resume_flags & MMC_BUSRESUME_MANUAL_RESUME) {
+ host->bus_resume_flags |= MMC_BUSRESUME_NEEDS_RESUME;
+ mmc_bus_put(host);
+ return 0;
+ }
+
if (host->bus_ops && !host->bus_dead) {
if (!mmc_card_keep_power(host)) {
mmc_power_up(host);