From patchwork Tue Mar 1 18:15:32 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pierre Tardy X-Patchwork-Id: 600311 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p21IGkgc024144 for ; Tue, 1 Mar 2011 18:16:46 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756649Ab1CASQ0 (ORCPT ); Tue, 1 Mar 2011 13:16:26 -0500 Received: from mail-bw0-f46.google.com ([209.85.214.46]:59213 "EHLO mail-bw0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756286Ab1CASPw (ORCPT ); Tue, 1 Mar 2011 13:15:52 -0500 Received: by mail-bw0-f46.google.com with SMTP id 15so4832473bwz.19 for ; Tue, 01 Mar 2011 10:15:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:from:to:cc:subject:date:message-id:x-mailer :in-reply-to:references:in-reply-to:references; bh=FwqBLZav/yAfr1YMqGmAGpgWXY3PkJwaTRW12ky31Qo=; b=oh0EYj9AUY39bT3+tjeLL4XX27knSo3CfAWh9UnoiyzusbYzjGoVGckAOQk1PmK9/U uCr4CW5vdhHerRTgL3nghTbkb8ZitzU5BxV4v9lOCny/vC0zUVYLh8kgegCoMkfNFklq o171+qSBp41/lukWp9m9RytPbiCXKMZdnxTM8= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; b=yBbQ7xgFABEtjLb+27xXVU80bK/f7Ix3dIUIRFgDCEXafYUqaz66GabAIzSlIctE2g Lj5yjvIL+Zoj9KstcbRmrJaOSklvDfzWfx09sEsi1KTdE+EgRG/ViNND4j2zstKqklgr 9MwjfHnYn6KNNGLKamGq2Rwgt7VXzHT6gSyrc= Received: by 10.204.22.1 with SMTP id l1mr6325727bkb.22.1299003351763; Tue, 01 Mar 2011 10:15:51 -0800 (PST) Received: from localhost.localdomain ([82.240.198.215]) by mx.google.com with ESMTPS id d17sm1966327bkd.1.2011.03.01.10.15.50 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 01 Mar 2011 10:15:51 -0800 (PST) From: Pierre Tardy To: linux-kernel@vger.kernel.org, linux-pm@lists.linux-foundation.org, linux-mmc@vger.kernel.org Cc: Pierre Tardy Subject: [RFC, PATCHv3 2/3] mmc: sdhci: use ios->clock to know when sdhci is idle Date: Tue, 1 Mar 2011 19:15:32 +0100 Message-Id: <5def72b6b40c10672753fe04a7ad49b394e70706.1298820826.git.tardyp@gmail.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: References: In-Reply-To: References: 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 (demeter1.kernel.org [140.211.167.41]); Tue, 01 Mar 2011 18:16:47 +0000 (UTC) diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index f167a55..1b5e70b 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c @@ -1089,6 +1089,9 @@ static int __devinit sdhci_pci_probe(struct pci_dev *pdev, chip->slots[i] = slot; } + pm_runtime_set_autosuspend_delay(&pdev->dev, 50); + pm_runtime_use_autosuspend(&pdev->dev); + pm_suspend_ignore_children(&pdev->dev, 1); pm_runtime_put_noidle(&pdev->dev); return 0; diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index cd79a28..735c3f7 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 */