From patchwork Tue Jan 17 14:34:22 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ulf Hansson X-Patchwork-Id: 6261 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id BD28C23F03 for ; Tue, 17 Jan 2012 14:34:55 +0000 (UTC) Received: from mail-bk0-f52.google.com (mail-bk0-f52.google.com [209.85.214.52]) by fiordland.canonical.com (Postfix) with ESMTP id AD2B4A1871C for ; Tue, 17 Jan 2012 14:34:55 +0000 (UTC) Received: by mail-bk0-f52.google.com with SMTP id zt4so1750806bkb.11 for ; Tue, 17 Jan 2012 06:34:55 -0800 (PST) Received: by 10.205.26.67 with SMTP id rl3mr6881003bkb.45.1326810895492; Tue, 17 Jan 2012 06:34:55 -0800 (PST) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.205.82.144 with SMTP id ac16cs120328bkc; Tue, 17 Jan 2012 06:34:55 -0800 (PST) Received: by 10.213.31.147 with SMTP id y19mr4236090ebc.80.1326810893087; Tue, 17 Jan 2012 06:34:53 -0800 (PST) Received: from eu1sys200aog107.obsmtp.com (eu1sys200aog107.obsmtp.com. [207.126.144.123]) by mx.google.com with SMTP id a9si15375595eec.214.2012.01.17.06.34.48 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 17 Jan 2012 06:34:53 -0800 (PST) Received-SPF: neutral (google.com: 207.126.144.123 is neither permitted nor denied by best guess record for domain of ulf.hansson@stericsson.com) client-ip=207.126.144.123; Authentication-Results: mx.google.com; spf=neutral (google.com: 207.126.144.123 is neither permitted nor denied by best guess record for domain of ulf.hansson@stericsson.com) smtp.mail=ulf.hansson@stericsson.com Received: from beta.dmz-us.st.com ([167.4.1.35]) (using TLSv1) by eu1sys200aob107.postini.com ([207.126.147.11]) with SMTP ID DSNKTxWHAnVcmbdyetxd/I3guG9UfhNQCg0v@postini.com; Tue, 17 Jan 2012 14:34:52 UTC Received: from zeta.dmz-us.st.com (ns4.st.com [167.4.16.71]) by beta.dmz-us.st.com (STMicroelectronics) with ESMTP id 8EF274E; Tue, 17 Jan 2012 14:34:33 +0000 (GMT) Received: from relay2.stm.gmessaging.net (unknown [10.230.100.18]) by zeta.dmz-us.st.com (STMicroelectronics) with ESMTP id 07F1661; Tue, 17 Jan 2012 13:40:19 +0000 (GMT) Received: from exdcvycastm022.EQ1STM.local (alteon-source-exch [10.230.100.61]) (using TLSv1 with cipher RC4-MD5 (128/128 bits)) (Client CN "exdcvycastm022", Issuer "exdcvycastm022" (not verified)) by relay2.stm.gmessaging.net (Postfix) with ESMTPS id 90C87A8065; Tue, 17 Jan 2012 15:34:34 +0100 (CET) Received: from localhost.localdomain (10.230.100.153) by smtp.stericsson.com (10.230.100.30) with Microsoft SMTP Server (TLS) id 8.3.83.0; Tue, 17 Jan 2012 15:34:39 +0100 From: Ulf Hansson To: , Cc: Russell King , Ulf Hansson , Lee Jones , Per Forlin , Johan Rudholm , Linus Walleij Subject: [PATCH 3/8] mmc: mmci: Implement PM runtime callbacks to save power Date: Tue, 17 Jan 2012 15:34:22 +0100 Message-ID: <1326810867-5346-4-git-send-email-ulf.hansson@stericsson.com> X-Mailer: git-send-email 1.7.5.4 In-Reply-To: <1326810867-5346-1-git-send-email-ulf.hansson@stericsson.com> References: <1326810867-5346-1-git-send-email-ulf.hansson@stericsson.com> MIME-Version: 1.0 In the runtime_suspend callback we make use of mmci_save to disable the VCORE regulator and the MCLK to decrease current consumption. At runtime resume, we use mmci_restore to re-enable the resourses again. >From now on this will mean that especially the mmci_restore function must be fast to execute since otherwise request latency will be introduced. For the ARM Primcell PL180, the MMCIPOWER register is used to control an external power supply to the card. Thus we need to prevent the runtime callbacks from doing save and restore, otherwise the power to card will be cut. This is done by adding a new flag to the variant data. Tested-by: Linus Walleij Signed-off-by: Ulf Hansson Signed-off-by: Linus Walleij --- drivers/mmc/host/mmci.c | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 42 insertions(+), 1 deletions(-) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index cd7e144..a7c8f8f 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -55,6 +55,7 @@ static unsigned int fmax = 515633; * @blksz_datactrl16: true if Block size is at b16..b30 position in datactrl register * @pwrreg_powerup: power up value for MMCIPOWER register * @signal_direction: input/out direction of bus signals can be indicated + * @pwrreg_ctrl_power: bits in MMCIPOWER register controls ext. power supply */ struct variant_data { unsigned int clkreg; @@ -67,6 +68,7 @@ struct variant_data { bool blksz_datactrl16; u32 pwrreg_powerup; bool signal_direction; + bool pwrreg_ctrl_power; }; static struct variant_data variant_arm = { @@ -74,6 +76,7 @@ static struct variant_data variant_arm = { .fifohalfsize = 8 * 4, .datalength_bits = 16, .pwrreg_powerup = MCI_PWR_UP, + .pwrreg_ctrl_power = true, }; static struct variant_data variant_arm_extended_fifo = { @@ -81,6 +84,7 @@ static struct variant_data variant_arm_extended_fifo = { .fifohalfsize = 64 * 4, .datalength_bits = 16, .pwrreg_powerup = MCI_PWR_UP, + .pwrreg_ctrl_power = true, }; static struct variant_data variant_u300 = { @@ -1496,7 +1500,7 @@ static int __devexit mmci_remove(struct amba_device *dev) return 0; } -#ifdef CONFIG_SUSPEND +#if defined(CONFIG_SUSPEND) || defined(CONFIG_PM_RUNTIME) static int mmci_save(struct amba_device *dev) { struct mmc_host *mmc = amba_get_drvdata(dev); @@ -1550,7 +1554,9 @@ static int mmci_restore(struct amba_device *dev) return 0; } +#endif +#ifdef CONFIG_SUSPEND static int mmci_suspend(struct device *dev) { struct amba_device *adev = to_amba_device(dev); @@ -1587,8 +1593,43 @@ static int mmci_resume(struct device *dev) } #endif +#ifdef CONFIG_PM_RUNTIME +static int mmci_runtime_suspend(struct device *dev) +{ + struct amba_device *adev = to_amba_device(dev); + struct mmc_host *mmc = amba_get_drvdata(adev); + int ret = 0; + + if (mmc) { + struct mmci_host *host = mmc_priv(mmc); + struct variant_data *variant = host->variant; + if (!variant->pwrreg_ctrl_power) + ret = mmci_save(adev); + } + + return ret; +} + +static int mmci_runtime_resume(struct device *dev) +{ + struct amba_device *adev = to_amba_device(dev); + struct mmc_host *mmc = amba_get_drvdata(adev); + int ret = 0; + + if (mmc) { + struct mmci_host *host = mmc_priv(mmc); + struct variant_data *variant = host->variant; + if (!variant->pwrreg_ctrl_power) + ret = mmci_restore(adev); + } + + return ret; +} +#endif + static const struct dev_pm_ops mmci_dev_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(mmci_suspend, mmci_resume) + SET_RUNTIME_PM_OPS(mmci_runtime_suspend, mmci_runtime_resume, NULL) }; static struct amba_id mmci_ids[] = {