summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Cross <ccross@android.com>2011-09-07 17:28:58 -0700
committerArve Hjønnevåg <arve@android.com>2013-07-01 13:40:25 -0700
commitb485d959244fa8460e8a66639dd86328c2c643bc (patch)
tree3a4f6e65020d84b4f70debd1377b2bd79c44cd47
parente33afd7bfd45988b3e354a2ac902183c425ee255 (diff)
downloadolio-linux-3.10-b485d959244fa8460e8a66639dd86328c2c643bc.tar.xz
olio-linux-3.10-b485d959244fa8460e8a66639dd86328c2c643bc.zip
mmc: core: host: only use wakelock for detect work
There is no need to take a wakelock for delayed lazy disable work, it will be cancelled in the suspend handler and force disabled. Only take the wakelock when the detect work is queued, and make sure to drop the wakelock if the work is cancelled. Change-Id: I1e507a5f98848954ea21d45e23b6192c3132a349 Signed-off-by: Colin Cross <ccross@android.com>
-rw-r--r--drivers/mmc/core/core.c26
-rw-r--r--drivers/mmc/core/host.c3
-rw-r--r--include/linux/mmc/host.h2
3 files changed, 18 insertions, 13 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 297367ab548..812f3d98bfc 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -53,7 +53,6 @@
#define MMC_BKOPS_MAX_TIMEOUT (4 * 60 * 1000) /* max time to wait in ms */
static struct workqueue_struct *workqueue;
-static struct wake_lock mmc_delayed_work_wake_lock;
static const unsigned freqs[] = { 400000, 300000, 200000, 100000 };
/*
@@ -87,7 +86,6 @@ 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);
}
@@ -1689,6 +1687,8 @@ void mmc_detect_change(struct mmc_host *host, unsigned long delay)
spin_unlock_irqrestore(&host->lock, flags);
#endif
host->detect_change = 1;
+
+ wake_lock(&host->detect_wake_lock);
mmc_schedule_delayed_work(&host->detect, delay);
}
@@ -2451,11 +2451,13 @@ void mmc_rescan(struct work_struct *work)
out:
if (extend_wakelock)
- wake_lock_timeout(&mmc_delayed_work_wake_lock, HZ / 2);
+ wake_lock_timeout(&host->detect_wake_lock, HZ / 2);
else
- wake_unlock(&mmc_delayed_work_wake_lock);
- if (host->caps & MMC_CAP_NEEDS_POLL)
+ wake_unlock(&host->detect_wake_lock);
+ if (host->caps & MMC_CAP_NEEDS_POLL) {
+ wake_lock(&host->detect_wake_lock);
mmc_schedule_delayed_work(&host->detect, HZ);
+ }
}
void mmc_start_host(struct mmc_host *host)
@@ -2479,7 +2481,8 @@ void mmc_stop_host(struct mmc_host *host)
#endif
host->rescan_disable = 1;
- cancel_delayed_work_sync(&host->detect);
+ if (cancel_delayed_work_sync(&host->detect))
+ wake_unlock(&host->detect_wake_lock);
mmc_flush_scheduled_work();
/* clear pm flags now and let card drivers set them as needed */
@@ -2677,7 +2680,8 @@ int mmc_suspend_host(struct mmc_host *host)
if (mmc_bus_needs_resume(host))
return 0;
- cancel_delayed_work(&host->detect);
+ if (cancel_delayed_work(&host->detect))
+ wake_unlock(&host->detect_wake_lock);
mmc_flush_scheduled_work();
mmc_bus_get(host);
@@ -2800,7 +2804,8 @@ int mmc_pm_notify(struct notifier_block *notify_block,
}
host->rescan_disable = 1;
spin_unlock_irqrestore(&host->lock, flags);
- cancel_delayed_work_sync(&host->detect);
+ if (cancel_delayed_work_sync(&host->detect))
+ wake_unlock(&host->detect_wake_lock);
if (!host->bus_ops || host->bus_ops->suspend)
break;
@@ -2876,9 +2881,6 @@ 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;
@@ -2899,7 +2901,6 @@ unregister_bus:
mmc_unregister_bus();
destroy_workqueue:
destroy_workqueue(workqueue);
- wake_lock_destroy(&mmc_delayed_work_wake_lock);
return ret;
}
@@ -2910,7 +2911,6 @@ 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);
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index f5bb7c769c3..56dadd667ec 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -459,6 +459,8 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
spin_lock_init(&host->lock);
init_waitqueue_head(&host->wq);
+ wake_lock_init(&host->detect_wake_lock, WAKE_LOCK_SUSPEND,
+ kasprintf(GFP_KERNEL, "%s_detect", mmc_hostname(host)));
INIT_DELAYED_WORK(&host->detect, mmc_rescan);
#ifdef CONFIG_PM
host->pm_notify.notifier_call = mmc_pm_notify;
@@ -558,6 +560,7 @@ void mmc_free_host(struct mmc_host *host)
spin_lock(&mmc_host_lock);
idr_remove(&mmc_host_idr, host->index);
spin_unlock(&mmc_host_lock);
+ wake_lock_destroy(&host->detect_wake_lock);
put_device(&host->class_dev);
}
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index d286d7ecaee..66b46592760 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -15,6 +15,7 @@
#include <linux/sched.h>
#include <linux/device.h>
#include <linux/fault-inject.h>
+#include <linux/wakelock.h>
#include <linux/mmc/core.h>
#include <linux/mmc/pm.h>
@@ -329,6 +330,7 @@ struct mmc_host {
int claim_cnt; /* "claim" nesting count */
struct delayed_work detect;
+ struct wake_lock detect_wake_lock;
int detect_change; /* card detect flag */
struct mmc_slot slot;