From patchwork Sun Feb 6 18:02:50 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pierre Tardy X-Patchwork-Id: 538401 Received: from smtp1.linux-foundation.org (smtp1.linux-foundation.org [140.211.169.13]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p17Gt8mI009964 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL) for ; Mon, 7 Feb 2011 16:55:28 GMT Received: from daredevil.linux-foundation.org (localhost [127.0.0.1]) by smtp1.linux-foundation.org (8.14.2/8.13.5/Debian-3ubuntu1.1) with ESMTP id p17Grg6B001822; Mon, 7 Feb 2011 08:53:42 -0800 Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by smtp1.linux-foundation.org (8.14.2/8.13.5/Debian-3ubuntu1.1) with ESMTP id p16I3S99001559 for ; Sun, 6 Feb 2011 10:03:29 -0800 Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga102.fm.intel.com with ESMTP; 06 Feb 2011 10:03:28 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.60,434,1291622400"; d="scan'208";a="884836443" Received: from ptardy-mobl3.ger.corp.intel.com (HELO ptardy-VirtualBox.ger.corp.intel.com) ([10.254.185.112]) by fmsmga001.fm.intel.com with ESMTP; 06 Feb 2011 10:03:26 -0800 From: Pierre Tardy To: linux-pm@lists.linux-foundation.org, linux-mmc@vger.kernel.org, linux-kernel@vger.kernel.org Date: Sun, 6 Feb 2011 19:02:50 +0100 Message-Id: <430729a58c5efc725455e1985b1facca8f784c92.1297014479.git.pierre.tardy@intel.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: References: In-Reply-To: References: Received-SPF: pass (localhost is always allowed.) X-Spam-Status: No, hits=-103.72 required=5 tests=AWL, BAYES_00, OSDL_HEADER_SUBJECT_BRACKETED, USER_IN_WHITELIST X-Spam-Checker-Version: SpamAssassin 3.2.4-osdl_revision__1.47__ X-MIMEDefang-Filter: lf$Revision: 1.188 $ X-Scanned-By: MIMEDefang 2.63 on 140.211.169.21 X-Mailman-Approved-At: Mon, 07 Feb 2011 08:48:36 -0800 Cc: Pierre Tardy Subject: [linux-pm] [PATCH v2 3/3] sdhci:v2:use ios->clock to know when sdhci is idle X-BeenThere: linux-pm@lists.linux-foundation.org X-Mailman-Version: 2.1.9 Precedence: list List-Id: Linux power management List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linux-pm-bounces@lists.linux-foundation.org Errors-To: linux-pm-bounces@lists.linux-foundation.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Mon, 07 Feb 2011 16:55:28 +0000 (UTC) diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index 22581a1..9d23f4c 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c @@ -1086,6 +1086,9 @@ static int __devinit sdhci_pci_probe(struct pci_dev *pdev, } pm_runtime_enable(&pdev->dev); pm_runtime_allow(&pdev->dev); + pm_runtime_set_autosuspend_delay(&pdev->dev, 50); + pm_runtime_use_autosuspend(&pdev->dev); + pm_suspend_ignore_children(&pdev->dev, 1); return 0; diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 3e65d94..655617c 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -20,6 +20,7 @@ #include #include #include +#include #include @@ -1161,6 +1162,7 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) { struct sdhci_host *host; unsigned long flags; + unsigned int lastclock; u8 ctrl; host = mmc_priv(mmc); @@ -1171,6 +1173,27 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) goto out; /* + * get/put runtime_pm usage counter at ios->clock transitions + * We need to do it before any other chip access, as sdhci could + * be power gated + */ + lastclock = host->iosclock; + host->iosclock = ios->clock; + if (lastclock == 0 && ios->clock != 0) { + spin_unlock_irqrestore(&host->lock, flags); + pm_runtime_get_sync(host->mmc->parent); + spin_lock_irqsave(&host->lock, flags); + } else if (lastclock != 0 && ios->clock == 0) { + spin_unlock_irqrestore(&host->lock, flags); + pm_runtime_mark_last_busy(host->mmc->parent); + pm_runtime_put_autosuspend(host->mmc->parent); + spin_lock_irqsave(&host->lock, flags); + } + /* no need to configure the rest.. */ + if (host->iosclock == 0) + goto out; + + /* * Reset the chip on each power off. * Should clear out any weird states. */ @@ -1244,6 +1267,8 @@ static int sdhci_get_ro(struct mmc_host *mmc) int is_readonly; host = mmc_priv(mmc); + /* this function is called before set_ios... */ + pm_runtime_get_sync(mmc->parent); spin_lock_irqsave(&host->lock, flags); @@ -1257,6 +1282,7 @@ static int sdhci_get_ro(struct mmc_host *mmc) spin_unlock_irqrestore(&host->lock, flags); + pm_runtime_put_autosuspend(mmc->parent); /* This quirk needs to be replaced by a callback-function later */ return host->quirks & SDHCI_QUIRK_INVERTED_WRITE_PROTECT ? !is_readonly : is_readonly; @@ -1268,6 +1294,7 @@ static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable) unsigned long flags; host = mmc_priv(mmc); + pm_runtime_get_sync(mmc->parent); spin_lock_irqsave(&host->lock, flags); @@ -1282,6 +1309,7 @@ out: mmiowb(); spin_unlock_irqrestore(&host->lock, flags); + pm_runtime_put_autosuspend(mmc->parent); } static const struct mmc_host_ops sdhci_ops = { @@ -1766,6 +1794,7 @@ struct sdhci_host *sdhci_alloc_host(struct device *dev, host = mmc_priv(mmc); host->mmc = mmc; + host->iosclock = 0; return host; } diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h index 83bd9f7..a38d040 100644 --- a/include/linux/mmc/sdhci.h +++ b/include/linux/mmc/sdhci.h @@ -116,6 +116,7 @@ struct sdhci_host { unsigned int timeout_clk; /* Timeout freq (KHz) */ unsigned int clock; /* Current clock (MHz) */ + unsigned int iosclock; /* Last clock asked via set_ios */ u8 pwr; /* Current voltage */ struct mmc_request *mrq; /* Current request */