From 8976e67c50fee9eaad742ad097b84fd5523effee Mon Sep 17 00:00:00 2001
From: Jun Nie <njun@marvell.com>
Date: Fri, 1 Jul 2011 10:01:51 +0800
Subject: [PATCH] mmc: avoid unnecessary rescan in PM_POST_SUSPEND
With this patch, we call rescan only when card insert/remove
happens during rescan_disabled is set to avoid unnecessary mmc
command transaction and realted wakelock holding.
This patch fix below suspend retry issue on Android:
1. System trigger suspend procedure for all wakelock are released
2. A wakelock is hold again and suspend is aborted as a result.
3. pm subsystem post PM_POST_SUSPEND event when exiting suspend.
4. mmc rescan is schedlued on every mmc host when handling the event
5. The wakelock is released just after it block suspend
6. System trigger another suspend retry
7. mmc rescan thread hold wakelock to dectect card
8. System go to state 2 and enter suspend retry loop
Signed-off-by: Jun Nie <njun@marvell.com>
---
drivers/mmc/core/core.c | 16 ++++++++++++++--
include/linux/mmc/host.h | 1 +
2 files changed, 15 insertions(+), 2 deletions(-)
@@ -1568,9 +1568,15 @@ void mmc_rescan(struct work_struct *work)
struct mmc_host *host =
container_of(work, struct mmc_host, detect.work);
int i;
+ unsigned long flags;
- if (host->rescan_disable)
+ spin_lock_irqsave(&host->lock, flags);
+ if (host->rescan_disable) {
+ host->rescan_delayed = 1;
+ spin_unlock_irqrestore(&host->lock, flags);
return;
+ }
+ spin_unlock_irqrestore(&host->lock, flags);
mmc_bus_get(host);
@@ -1836,6 +1842,7 @@ int mmc_pm_notify(struct notifier_block *notify_block,
struct mmc_host *host = container_of(
notify_block, struct mmc_host, pm_notify);
unsigned long flags;
+ unsigned long rescan_needed = 0;
switch (mode) {
@@ -1866,8 +1873,13 @@ int mmc_pm_notify(struct notifier_block *notify_block,
spin_lock_irqsave(&host->lock, flags);
host->rescan_disable = 0;
+ if (host->rescan_delayed) {
+ rescan_needed = 1;
+ host->rescan_delayed = 0;
+ }
spin_unlock_irqrestore(&host->lock, flags);
- mmc_detect_change(host, 0);
+ if (rescan_needed)
+ mmc_detect_change(host, 0);
}
@@ -249,6 +249,7 @@ struct mmc_host {
/* Only used with MMC_CAP_DISABLE */
int enabled; /* host is enabled */
int rescan_disable; /* disable card detection */
+ int rescan_delayed; /* card detection is delayed */
int nesting_cnt; /* "enable" nesting count */
int en_dis_recurs; /* detect recursion */
unsigned int disable_delay; /* disable delay in msecs */
--
1.7.0.4
With this patch, we call rescan only when card insert/remove happens during rescan_disabled is set to avoid unnecessary mmc command transaction and realted wakelock holding. This patch fix below suspend retry issue on Android: 1. System trigger suspend procedure for all wakelock are released 2. A wakelock is hold again and suspend is aborted as a result. 3. pm subsystem post PM_POST_SUSPEND event when exiting suspend. 4. mmc rescan is schedlued on every mmc host when handling the event 5. The wakelock is released just after it block suspend 6. System trigger another suspend retry 7. mmc rescan thread hold wakelock to dectect card 8. System go to state 2 and enter suspend retry loop Signed-off-by: Jun Nie <njun@marvell.com> --- drivers/mmc/core/core.c | 16 ++++++++++++++-- include/linux/mmc/host.h | 1 + 2 files changed, 15 insertions(+), 2 deletions(-)