From patchwork Fri Jul 1 02:27:04 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jun Nie X-Patchwork-Id: 934352 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter2.kernel.org (8.14.4/8.14.4) with ESMTP id p612RICH017707 for ; Fri, 1 Jul 2011 02:27:18 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754587Ab1GAC1S (ORCPT ); Thu, 30 Jun 2011 22:27:18 -0400 Received: from mail-vx0-f174.google.com ([209.85.220.174]:42556 "EHLO mail-vx0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754526Ab1GAC1R (ORCPT ); Thu, 30 Jun 2011 22:27:17 -0400 Received: by vxb39 with SMTP id 39so2067954vxb.19 for ; Thu, 30 Jun 2011 19:27:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=mime-version:date:message-id:subject:from:to:cc:content-type; bh=qK0qVsWCPvyUAQ9RpBTGRQkJNpqDVIRXOI13vf5LVew=; b=LrmlGRbUYgHVm3uyOxChdD4vx4t5kf7zXYrDUcoOsgwFRZ/665bhghKECG2tsSWJyl kv3knRJlM4RIBknNDV10a+dwbuJTN/v4g2TMKBQJjaJxR4qMM8ugi0n5JWag2d47hGlT fHctNm3rG625vyH90zDJEy3v78mKVnZooiU5A= MIME-Version: 1.0 Received: by 10.52.177.36 with SMTP id cn4mr123981vdc.26.1309487224955; Thu, 30 Jun 2011 19:27:04 -0700 (PDT) Received: by 10.52.111.70 with HTTP; Thu, 30 Jun 2011 19:27:04 -0700 (PDT) Date: Fri, 1 Jul 2011 10:27:04 +0800 Message-ID: Subject: [PATCH] mmc: avoid unnecessary rescan in PM_POST_SUSPEND From: Jun Nie To: "linux-mmc@vger.kernel.org" , Chris Ball , zhangfei gao Cc: Jaehoon Chung , Philip Rakity Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter2.kernel.org [140.211.167.43]); Fri, 01 Jul 2011 02:27:19 +0000 (UTC) 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 --- drivers/mmc/core/core.c | 16 ++++++++++++++-- include/linux/mmc/host.h | 1 + 2 files changed, 15 insertions(+), 2 deletions(-) From 8976e67c50fee9eaad742ad097b84fd5523effee Mon Sep 17 00:00:00 2001 From: Jun Nie 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 --- drivers/mmc/core/core.c | 16 ++++++++++++++-- include/linux/mmc/host.h | 1 + 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 7843efe..ded7686 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -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); } diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 1ee4424..f05e619 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -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