diff options
author | San Mehat <san@android.com> | 2009-03-23 12:20:37 -0700 |
---|---|---|
committer | Colin Cross <ccross@android.com> | 2012-02-14 11:26:15 -0800 |
commit | 5255bb98a04d20d830c640dbf8b5f68bf830eaa0 (patch) | |
tree | 21793b38625e862c93e761a2d8fb1c2dbe69138c /drivers | |
parent | 70d371b3e5836724c8f7aa4f36bcd3653aa42c3b (diff) |
mmc: core: Hold a wake lock accross delayed work + mmc rescan
Signed-off-by: San Mehat <san@android.com>
mmc: core: Rework mmc_delayed_work wakelock so that the wakelock is only extended if a card is added or removed.
Signed-off-by: San Mehat <san@google.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mmc/core/core.c | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index bcee017827e..0813272c77e 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -26,6 +26,7 @@ #include <linux/suspend.h> #include <linux/fault-inject.h> #include <linux/random.h> +#include <linux/wakelock.h> #include <linux/mmc/card.h> #include <linux/mmc/host.h> @@ -42,6 +43,7 @@ #include "sdio_ops.h" static struct workqueue_struct *workqueue; +static struct wake_lock mmc_delayed_work_wake_lock; /* * Enabling software CRCs on the data blocks can be a significant (30%) @@ -74,6 +76,7 @@ MODULE_PARM_DESC( static int mmc_schedule_delayed_work(struct delayed_work *work, unsigned long delay) { + wake_lock(&mmc_delayed_work_wake_lock); return queue_delayed_work(workqueue, work, delay); } @@ -2098,6 +2101,7 @@ void mmc_rescan(struct work_struct *work) struct mmc_host *host = container_of(work, struct mmc_host, detect.work); int i; + bool extend_wakelock = false; if (host->rescan_disable) return; @@ -2138,14 +2142,20 @@ void mmc_rescan(struct work_struct *work) mmc_claim_host(host); for (i = 0; i < ARRAY_SIZE(freqs); i++) { - if (!mmc_rescan_try_freq(host, max(freqs[i], host->f_min))) + if (!mmc_rescan_try_freq(host, max(freqs[i], host->f_min))) { + extend_wakelock = true; break; + } if (freqs[i] <= host->f_min) break; } mmc_release_host(host); out: + if (extend_wakelock) + wake_lock_timeout(&mmc_delayed_work_wake_lock, HZ / 2); + else + wake_unlock(&mmc_delayed_work_wake_lock); if (host->caps & MMC_CAP_NEEDS_POLL) mmc_schedule_delayed_work(&host->detect, HZ); } @@ -2545,6 +2555,9 @@ static int __init mmc_init(void) if (!workqueue) return -ENOMEM; + wake_lock_init(&mmc_delayed_work_wake_lock, WAKE_LOCK_SUSPEND, + "mmc_delayed_work"); + ret = mmc_register_bus(); if (ret) goto destroy_workqueue; @@ -2565,6 +2578,7 @@ unregister_bus: mmc_unregister_bus(); destroy_workqueue: destroy_workqueue(workqueue); + wake_lock_destroy(&mmc_delayed_work_wake_lock); return ret; } @@ -2575,6 +2589,7 @@ static void __exit mmc_exit(void) mmc_unregister_host_class(); mmc_unregister_bus(); destroy_workqueue(workqueue); + wake_lock_destroy(&mmc_delayed_work_wake_lock); } subsys_initcall(mmc_init); |