summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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;