From patchwork Thu May 2 12:02:39 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ulf Hansson X-Patchwork-Id: 16587 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-qe0-f70.google.com (mail-qe0-f70.google.com [209.85.128.70]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 996D1238EC for ; Thu, 2 May 2013 12:03:18 +0000 (UTC) Received: by mail-qe0-f70.google.com with SMTP id b10sf854985qen.5 for ; Thu, 02 May 2013 05:03:11 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:x-beenthere:x-received:received-spf:x-received :x-forwarded-to:x-forwarded-for:delivered-to:x-received:received-spf :from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references :mime-version:x-gm-message-state:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :x-google-group-id:list-post:list-help:list-archive:list-unsubscribe :content-type; bh=mUkTmXlN4+AaAF3W9SG/U5vkfZVxMb3iPldNOSPO2Vs=; b=DMGwfj3ADSYQljA4VEzWUapmjPxS5InFddoJaaWpbttjMSj4ZxazVwzhutYDykaEOZ EP5tM/zZFn01sZ54H3Ow6BcX4NTeowtAJyE0ADzW04NVqzvN2CzXMP2wE2A+P5uVmeaq TWlCvzJW7TPIrCVAdJH5x5u/+fmkpg7cC7sbogLBLgk+ZupWXue56MKOAp8sKF002GFc 9oVnU0k+osqNcv2INtH1RXRJG18KVSEF0Mu5szx2MyXdCUXWEz2nNUi9LOzk/HwBYJbE UmWxP9hrD9LZnambhqvcoldMwrTDyAbjMAa30xr7mzZURbwIU5PfeU9rZA+KnZwFKlBd Htbw== X-Received: by 10.236.161.234 with SMTP id w70mr5219342yhk.22.1367496191228; Thu, 02 May 2013 05:03:11 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.49.96.229 with SMTP id dv5ls1158503qeb.39.gmail; Thu, 02 May 2013 05:03:10 -0700 (PDT) X-Received: by 10.52.24.178 with SMTP id v18mr421080vdf.103.1367496190683; Thu, 02 May 2013 05:03:10 -0700 (PDT) Received: from mail-vc0-f170.google.com (mail-vc0-f170.google.com [209.85.220.170]) by mx.google.com with ESMTPS id lb19si2771768vcb.25.2013.05.02.05.03.10 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 02 May 2013 05:03:10 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.220.170 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.220.170; Received: by mail-vc0-f170.google.com with SMTP id gf12so385866vcb.29 for ; Thu, 02 May 2013 05:03:10 -0700 (PDT) X-Received: by 10.58.144.170 with SMTP id sn10mr2041505veb.7.1367496190490; Thu, 02 May 2013 05:03:10 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.58.127.98 with SMTP id nf2csp198453veb; Thu, 2 May 2013 05:03:09 -0700 (PDT) X-Received: by 10.14.102.9 with SMTP id c9mr18839556eeg.29.1367496189144; Thu, 02 May 2013 05:03:09 -0700 (PDT) Received: from eu1sys200aog103.obsmtp.com (eu1sys200aog103.obsmtp.com [207.126.144.115]) by mx.google.com with SMTP id i41si7589057eev.4.2013.05.02.05.03.04 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Thu, 02 May 2013 05:03:09 -0700 (PDT) Received-SPF: neutral (google.com: 207.126.144.115 is neither permitted nor denied by best guess record for domain of ulf.hansson@stericsson.com) client-ip=207.126.144.115; Received: from beta.dmz-us.st.com ([167.4.1.35]) (using TLSv1) by eu1sys200aob103.postini.com ([207.126.147.11]) with SMTP ID DSNKUYJV8QCynNOgy1g7lbRttA3tC4BwBCOc@postini.com; Thu, 02 May 2013 12:03:08 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 762C658; Thu, 2 May 2013 12:01:58 +0000 (GMT) Received: from relay2.stm.gmessaging.net (unknown [10.230.100.18]) by zeta.dmz-us.st.com (STMicroelectronics) with ESMTP id 5A6A14E; Thu, 2 May 2013 05:03:36 +0000 (GMT) Received: from exdcvycastm003.EQ1STM.local (alteon-source-exch [10.230.100.61]) (using TLSv1 with cipher RC4-MD5 (128/128 bits)) (Client CN "exdcvycastm003", Issuer "exdcvycastm003" (not verified)) by relay2.stm.gmessaging.net (Postfix) with ESMTPS id C0CCAA8065; Thu, 2 May 2013 14:02:48 +0200 (CEST) Received: from steludxu1397.lud.stericsson.com (10.230.100.153) by smtp.stericsson.com (10.230.100.1) with Microsoft SMTP Server (TLS) id 8.3.279.5; Thu, 2 May 2013 14:03:01 +0200 From: Ulf Hansson To: , Chris Ball Cc: Ulf Hansson , Maya Erez , Subhash Jadavani , Arnd Bergmann , Kevin Liu , Adrian Hunter , Daniel Drake , Ohad Ben-Cohen Subject: [PATCH V4 4/4] mmc: core: Support aggressive power management for (e)MMC/SD Date: Thu, 2 May 2013 14:02:39 +0200 Message-ID: <1367496159-7090-5-git-send-email-ulf.hansson@stericsson.com> X-Mailer: git-send-email 1.7.10 In-Reply-To: <1367496159-7090-1-git-send-email-ulf.hansson@stericsson.com> References: <1367496159-7090-1-git-send-email-ulf.hansson@stericsson.com> MIME-Version: 1.0 X-Gm-Message-State: ALoCoQm8zw+cxkvxi2BOETcF3OgXRNi39j0lLAxNtw3IYGElP9YbrQq8UGGqvdWB4CNxYtK03ILz X-Original-Sender: patch@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.220.170 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , From: Ulf Hansson Aggressive power management is suitable when saving power is essential. At request inactivity timeout, aka pm runtime autosuspend timeout, the card will be suspended. Once a new request arrives, the card will be re-initalized and thus the first request will suffer from a latency. This latency is card-specific, experiments has shown in general that SD-cards has quite poor initialization time, around 300ms-1100ms. eMMC is not surprisingly far better but still a couple of hundreds of ms has been observed. Except for the request latency, it is important to know that suspending the card will also prevent the card from executing internal house-keeping operations in idle mode. This could mean degradation in performance. To use this feature make sure the request inactivity timeout is chosen carefully. This has not been done as a part of this patch. Enable this feature by using host cap MMC_CAP_AGGRESSIVE_PM and by setting CONFIG_MMC_UNSAFE_RESUME. Signed-off-by: Ulf Hansson Cc: Maya Erez Cc: Subhash Jadavani Cc: Arnd Bergmann Cc: Kevin Liu Cc: Adrian Hunter Cc: Daniel Drake Cc: Ohad Ben-Cohen --- drivers/mmc/core/mmc.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++ drivers/mmc/core/sd.c | 49 +++++++++++++++++++++++++++++++++++++++++++++ include/linux/mmc/host.h | 2 +- 3 files changed, 100 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 903f381..506f4ee 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -1454,6 +1454,54 @@ static int mmc_resume(struct mmc_host *host) return err; } + +/* + * Callback for runtime_suspend. + */ +static int mmc_runtime_suspend(struct mmc_host *host) +{ + int err; + + if (!(host->caps & MMC_CAP_AGGRESSIVE_PM)) + return 0; + + mmc_claim_host(host); + + err = mmc_suspend(host); + if (err) { + pr_err("%s: error %d doing aggessive suspend\n", + mmc_hostname(host), err); + goto out; + } + mmc_power_off(host); + +out: + mmc_release_host(host); + return err; +} + +/* + * Callback for runtime_resume. + */ +static int mmc_runtime_resume(struct mmc_host *host) +{ + int err; + + if (!(host->caps & MMC_CAP_AGGRESSIVE_PM)) + return 0; + + mmc_claim_host(host); + + mmc_power_up(host); + err = mmc_resume(host); + if (err) + pr_err("%s: error %d doing aggessive resume\n", + mmc_hostname(host), err); + + mmc_release_host(host); + return 0; +} + static int mmc_power_restore(struct mmc_host *host) { int ret; @@ -1514,6 +1562,8 @@ static const struct mmc_bus_ops mmc_ops_unsafe = { .detect = mmc_detect, .suspend = mmc_suspend, .resume = mmc_resume, + .runtime_suspend = mmc_runtime_suspend, + .runtime_resume = mmc_runtime_resume, .power_restore = mmc_power_restore, .alive = mmc_alive, }; diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 30387d6..c197fc7 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -1095,6 +1095,53 @@ static int mmc_sd_resume(struct mmc_host *host) return err; } +/* + * Callback for runtime_suspend. + */ +static int mmc_sd_runtime_suspend(struct mmc_host *host) +{ + int err; + + if (!(host->caps & MMC_CAP_AGGRESSIVE_PM)) + return 0; + + mmc_claim_host(host); + + err = mmc_sd_suspend(host); + if (err) { + pr_err("%s: error %d doing aggessive suspend\n", + mmc_hostname(host), err); + goto out; + } + mmc_power_off(host); + +out: + mmc_release_host(host); + return err; +} + +/* + * Callback for runtime_resume. + */ +static int mmc_sd_runtime_resume(struct mmc_host *host) +{ + int err; + + if (!(host->caps & MMC_CAP_AGGRESSIVE_PM)) + return 0; + + mmc_claim_host(host); + + mmc_power_up(host); + err = mmc_sd_resume(host); + if (err) + pr_err("%s: error %d doing aggessive resume\n", + mmc_hostname(host), err); + + mmc_release_host(host); + return 0; +} + static int mmc_sd_power_restore(struct mmc_host *host) { int ret; @@ -1119,6 +1166,8 @@ static const struct mmc_bus_ops mmc_sd_ops = { static const struct mmc_bus_ops mmc_sd_ops_unsafe = { .remove = mmc_sd_remove, .detect = mmc_sd_detect, + .runtime_suspend = mmc_sd_runtime_suspend, + .runtime_resume = mmc_sd_runtime_resume, .suspend = mmc_sd_suspend, .resume = mmc_sd_resume, .power_restore = mmc_sd_power_restore, diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 8873e83..35f1f7f 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -239,7 +239,7 @@ struct mmc_host { #define MMC_CAP_SPI (1 << 4) /* Talks only SPI protocols */ #define MMC_CAP_NEEDS_POLL (1 << 5) /* Needs polling for card-detection */ #define MMC_CAP_8_BIT_DATA (1 << 6) /* Can the host do 8 bit transfers */ - +#define MMC_CAP_AGGRESSIVE_PM (1 << 7) /* Suspend (e)MMC/SD at idle */ #define MMC_CAP_NONREMOVABLE (1 << 8) /* Nonremovable e.g. eMMC */ #define MMC_CAP_WAIT_WHILE_BUSY (1 << 9) /* Waits while card is busy */ #define MMC_CAP_ERASE (1 << 10) /* Allow erase/trim commands */