From patchwork Thu May 2 12:02:38 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ulf Hansson X-Patchwork-Id: 16589 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-vb0-f72.google.com (mail-vb0-f72.google.com [209.85.212.72]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id CF943238EC for ; Thu, 2 May 2013 12:03:21 +0000 (UTC) Received: by mail-vb0-f72.google.com with SMTP id q16sf794848vbe.3 for ; Thu, 02 May 2013 05:03:14 -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=IKFUaC2qIGg7xlVVB7Bxy18ShAtiX8Thdtw1VwIvPzc=; b=gWoK9B1cPV3wFHxYXMs33wK3CugI2jPlPRI4GhhZbrw69xM/L54vWYBQWgb18JgfMK mL5M1AWPPLEj1hMpjkJ/bv1rYp2diBYMTTYfTrYWeHor81hWlK2bLLAmBhzTjZ6cke0Z kz3AfkOyoMBlNU3V7UDbdJibPCf8Mgxej/ml5FPFmc39EX4TPlQUjlvMaH0m5+qzk7kq RMLu7gfLsRd03dBUvM1prWF1SAekrURfTdopotpl6unhlSLEoSEvCYOCj7rz3P80vcV0 dZe5CDlOqVZ02m4dauhXEWmkt4XGuCdUNUCETVw934CDwSTmWK7wsYmCdpk2JSqx0r/s SHIw== X-Received: by 10.236.160.1 with SMTP id t1mr5179485yhk.54.1367496194492; Thu, 02 May 2013 05:03:14 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.49.51.69 with SMTP id i5ls1116167qeo.89.gmail; Thu, 02 May 2013 05:03:14 -0700 (PDT) X-Received: by 10.52.66.229 with SMTP id i5mr1691613vdt.131.1367496194130; Thu, 02 May 2013 05:03:14 -0700 (PDT) Received: from mail-vb0-x235.google.com (mail-vb0-x235.google.com [2607:f8b0:400c:c02::235]) by mx.google.com with ESMTPS id ij9si2749703vdb.121.2013.05.02.05.03.14 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 02 May 2013 05:03:14 -0700 (PDT) Received-SPF: neutral (google.com: 2607:f8b0:400c:c02::235 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=2607:f8b0:400c:c02::235; Received: by mail-vb0-f53.google.com with SMTP id i3so360662vbh.26 for ; Thu, 02 May 2013 05:03:14 -0700 (PDT) X-Received: by 10.52.69.109 with SMTP id d13mr1719124vdu.75.1367496193974; Thu, 02 May 2013 05:03:13 -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 nf2csp198458veb; Thu, 2 May 2013 05:03:13 -0700 (PDT) X-Received: by 10.180.198.49 with SMTP id iz17mr7437955wic.19.1367496191953; Thu, 02 May 2013 05:03:11 -0700 (PDT) Received: from eu1sys200aog112.obsmtp.com (eu1sys200aog112.obsmtp.com [207.126.144.133]) by mx.google.com with SMTP id v7si7569433eep.42.2013.05.02.05.03.05 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Thu, 02 May 2013 05:03:11 -0700 (PDT) Received-SPF: neutral (google.com: 207.126.144.133 is neither permitted nor denied by best guess record for domain of ulf.hansson@stericsson.com) client-ip=207.126.144.133; Received: from beta.dmz-ap.st.com ([138.198.100.35]) (using TLSv1) by eu1sys200aob112.postini.com ([207.126.147.11]) with SMTP ID DSNKUYJV8QCynNOgy1g7lbRttA3tC4BwBCOc@postini.com; Thu, 02 May 2013 12:03:11 UTC Received: from zeta.dmz-ap.st.com (ns6.st.com [138.198.234.13]) by beta.dmz-ap.st.com (STMicroelectronics) with ESMTP id 671BDD8; Thu, 2 May 2013 11:54:46 +0000 (GMT) Received: from relay2.stm.gmessaging.net (unknown [10.230.100.18]) by zeta.dmz-ap.st.com (STMicroelectronics) with ESMTP id E32461A6E; Thu, 2 May 2013 12:02:51 +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 2951EA8065; Thu, 2 May 2013 14:02:46 +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:02:58 +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 3/4] mmc: block: Enable runtime pm for mmc blkdevice Date: Thu, 2 May 2013 14:02:38 +0200 Message-ID: <1367496159-7090-4-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: ALoCoQljMfJfUgzT8aQ5hcKWzacHUZIoFe1P2EdDvElPvI4cVL9HhBc5hbfUcIe3gvfXQVx26JjZ X-Original-Sender: patch@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 2607:f8b0:400c:c02::235 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 Once the mmc blkdevice is being probed, runtime pm will be enabled. By using runtime autosuspend, the power save operations can be done when request inactivity occurs for a certain time. Right now the selected timeout value is set to 3 s. Obviously this value will likely need to be configurable somehow since it needs to be trimmed depending on the power save algorithm. For SD-combo cards, we are still leaving the enablement of runtime PM to the SDIO init sequence since it depends on the capabilities of the SDIO func driver. Moreover, when the blk device is being suspended, we make sure the device will be runtime resumed. The reason for doing this is that we want the host suspend sequence to be unaware of any runtime power save operations done for the card in this phase. Thus it can just handle the suspend as the card is fully powered from a runtime perspective. Finally, this patch prepares to make it possible to move BKOPS handling into the runtime callbacks for the mmc bus_ops. Thus IDLE BKOPS can be accomplished. 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/card/block.c | 32 ++++++++++++++++++++++++++------ drivers/mmc/core/core.c | 23 +++++++++++++++++++++++ drivers/mmc/core/debugfs.c | 8 ++++---- drivers/mmc/core/mmc.c | 4 ++-- drivers/mmc/core/sd.c | 4 ++-- include/linux/mmc/core.h | 3 +++ 6 files changed, 60 insertions(+), 14 deletions(-) diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index e12a03c..360a41a 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -222,7 +223,7 @@ static ssize_t power_ro_lock_store(struct device *dev, md = mmc_blk_get(dev_to_disk(dev)); card = md->queue.card; - mmc_claim_host(card->host); + mmc_get_card(card); ret = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_WP, card->ext_csd.boot_ro_lock | @@ -233,7 +234,7 @@ static ssize_t power_ro_lock_store(struct device *dev, else card->ext_csd.boot_ro_lock |= EXT_CSD_BOOT_WP_B_PWR_WP_EN; - mmc_release_host(card->host); + mmc_put_card(card); if (!ret) { pr_info("%s: Locking boot partition ro until next power on\n", @@ -492,7 +493,7 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev, mrq.cmd = &cmd; - mmc_claim_host(card->host); + mmc_get_card(card); err = mmc_blk_part_switch(card, md); if (err) @@ -559,7 +560,7 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev, } cmd_rel_host: - mmc_release_host(card->host); + mmc_put_card(card); cmd_done: mmc_blk_put(md); @@ -1896,7 +1897,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) if (req && !mq->mqrq_prev->req) /* claim host only for the first request */ - mmc_claim_host(card->host); + mmc_get_card(card); ret = mmc_blk_part_switch(card, md); if (ret) { @@ -1940,7 +1941,7 @@ out: * In case sepecial request, there is no reentry to * the 'mmc_blk_issue_rq' with 'mqrq_prev->req'. */ - mmc_release_host(card->host); + mmc_put_card(card); return ret; } @@ -2337,6 +2338,19 @@ static int mmc_blk_probe(struct mmc_card *card) if (mmc_add_disk(part_md)) goto out; } + + pm_runtime_set_autosuspend_delay(&card->dev, 3000); + pm_runtime_use_autosuspend(&card->dev); + + /* + * Don't enable runtime PM for SD-combo cards here. Leave that + * decision to be taken during the SDIO init sequence instead. + */ + if (card->type != MMC_TYPE_SD_COMBO) { + pm_runtime_set_active(&card->dev); + pm_runtime_enable(&card->dev); + } + return 0; out: @@ -2350,9 +2364,13 @@ static void mmc_blk_remove(struct mmc_card *card) struct mmc_blk_data *md = mmc_get_drvdata(card); mmc_blk_remove_parts(card, md); + pm_runtime_get_sync(&card->dev); mmc_claim_host(card->host); mmc_blk_part_switch(card, md); mmc_release_host(card->host); + if (card->type != MMC_TYPE_SD_COMBO) + pm_runtime_disable(&card->dev); + pm_runtime_put_noidle(&card->dev); mmc_blk_remove_req(md); mmc_set_drvdata(card, NULL); } @@ -2364,6 +2382,7 @@ static int mmc_blk_suspend(struct mmc_card *card) struct mmc_blk_data *md = mmc_get_drvdata(card); if (md) { + pm_runtime_get_sync(&card->dev); mmc_queue_suspend(&md->queue); list_for_each_entry(part_md, &md->part, part) { mmc_queue_suspend(&part_md->queue); @@ -2387,6 +2406,7 @@ static int mmc_blk_resume(struct mmc_card *card) list_for_each_entry(part_md, &md->part, part) { mmc_queue_resume(&part_md->queue); } + pm_runtime_put(&card->dev); } return 0; } diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index a6c4dbf..6eb8f9a 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -952,6 +952,29 @@ void mmc_release_host(struct mmc_host *host) EXPORT_SYMBOL(mmc_release_host); /* + * This is a helper function, which fetches a runtime pm reference for the + * card device and also claims the host. + */ +void mmc_get_card(struct mmc_card *card) +{ + pm_runtime_get_sync(&card->dev); + mmc_claim_host(card->host); +} +EXPORT_SYMBOL(mmc_get_card); + +/* + * This is a helper function, which releases the host and drops the runtime + * pm reference for the card device. + */ +void mmc_put_card(struct mmc_card *card) +{ + mmc_release_host(card->host); + pm_runtime_mark_last_busy(&card->dev); + pm_runtime_put_autosuspend(&card->dev); +} +EXPORT_SYMBOL(mmc_put_card); + +/* * Internal function that does the actual ios call to the host driver, * optionally printing some debug output. */ diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c index 35c2f85..54829c0 100644 --- a/drivers/mmc/core/debugfs.c +++ b/drivers/mmc/core/debugfs.c @@ -258,13 +258,13 @@ static int mmc_dbg_card_status_get(void *data, u64 *val) u32 status; int ret; - mmc_claim_host(card->host); + mmc_get_card(card); ret = mmc_send_status(data, &status); if (!ret) *val = status; - mmc_release_host(card->host); + mmc_put_card(card); return ret; } @@ -291,9 +291,9 @@ static int mmc_ext_csd_open(struct inode *inode, struct file *filp) goto out_free; } - mmc_claim_host(card->host); + mmc_get_card(card); err = mmc_send_ext_csd(card, ext_csd); - mmc_release_host(card->host); + mmc_put_card(card); if (err) goto out_free; diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index a0469cf..903f381 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -1380,14 +1380,14 @@ static void mmc_detect(struct mmc_host *host) BUG_ON(!host); BUG_ON(!host->card); - mmc_claim_host(host); + mmc_get_card(host->card); /* * Just check if our card has been removed. */ err = _mmc_detect_card_removed(host); - mmc_release_host(host); + mmc_put_card(host->card); if (err) { mmc_remove(host); diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 9e645e1..30387d6 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -1037,14 +1037,14 @@ static void mmc_sd_detect(struct mmc_host *host) BUG_ON(!host); BUG_ON(!host->card); - mmc_claim_host(host); + mmc_get_card(host->card); /* * Just check if our card has been removed. */ err = _mmc_detect_card_removed(host); - mmc_release_host(host); + mmc_put_card(host->card); if (err) { mmc_sd_remove(host); diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index 39613b9..49fb132 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h @@ -188,6 +188,9 @@ extern int __mmc_claim_host(struct mmc_host *host, atomic_t *abort); extern void mmc_release_host(struct mmc_host *host); extern int mmc_try_claim_host(struct mmc_host *host); +extern void mmc_get_card(struct mmc_card *card); +extern void mmc_put_card(struct mmc_card *card); + extern int mmc_flush_cache(struct mmc_card *); extern int mmc_detect_card_removed(struct mmc_host *host);