From patchwork Thu Oct 3 10:05:59 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ulf Hansson X-Patchwork-Id: 20768 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-ve0-f199.google.com (mail-ve0-f199.google.com [209.85.128.199]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 14DF325CAB for ; Thu, 3 Oct 2013 10:06:06 +0000 (UTC) Received: by mail-ve0-f199.google.com with SMTP id db12sf4920074veb.6 for ; Thu, 03 Oct 2013 03:06:06 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=mime-version:x-gm-message-state:delivered-to:from:to:cc:subject :date:message-id:x-original-sender:x-original-authentication-results :precedence:mailing-list:list-id:list-post:list-help:list-archive :list-unsubscribe; bh=4IsLtYtqUQ0bjL7TsPWJchRnTaBFguZQp4O8SDtDeBY=; b=NwLpF3uKLvEJwy+dD2iIJqPMW+6c7d2IPI/YAiCsi5XhiEBxEGOiSiAGdSVwaBYdLD w+edg+ZmNr1yLaBK6J1pjweBQeNIo01kQQy7dzQhvdNwhDaT79CnUMuYu3VYgvd9EslM lbKrSn0QF11Mx0cYlzskusRVOjI1R/OH15Y0H07Mb6IIEYp9pdfVVSOk/iqslls3ROdI yDXg1rW5KZTR5vh6SLf2LjUEOWhRMyw+4Tx9yCKX3HUjsbcJqbhBAw61M9IEVd/pxard hPUvyuzbInZDu0Dq09+kxnZmPkhU+KFrpPyoJLgQQVGaLa0yxF81u/U+lsZYm9PVLEaT GJNg== X-Received: by 10.236.223.130 with SMTP id v2mr6436841yhp.34.1380794766399; Thu, 03 Oct 2013 03:06:06 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.49.28.10 with SMTP id x10ls881853qeg.20.gmail; Thu, 03 Oct 2013 03:06:06 -0700 (PDT) X-Received: by 10.58.179.104 with SMTP id df8mr64359vec.26.1380794766282; Thu, 03 Oct 2013 03:06:06 -0700 (PDT) Received: from mail-ve0-f181.google.com (mail-ve0-f181.google.com [209.85.128.181]) by mx.google.com with ESMTPS id ug9si1540357vcb.32.1969.12.31.16.00.00 (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 03 Oct 2013 03:06:06 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.128.181 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.128.181; Received: by mail-ve0-f181.google.com with SMTP id oy12so1577704veb.12 for ; Thu, 03 Oct 2013 03:06:06 -0700 (PDT) X-Gm-Message-State: ALoCoQkWJZ7veXSa4R9aZuARdLLnuoWWiq4B06OVrGUvyhOKyR/vJvCFM7SXt4wpKX0RajoD4/p9 X-Received: by 10.58.218.225 with SMTP id pj1mr612574vec.24.1380794766165; Thu, 03 Oct 2013 03:06:06 -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.220.174.196 with SMTP id u4csp165458vcz; Thu, 3 Oct 2013 03:06:05 -0700 (PDT) X-Received: by 10.15.108.202 with SMTP id cd50mr1842875eeb.68.1380794764751; Thu, 03 Oct 2013 03:06:04 -0700 (PDT) Received: from mail-ee0-f43.google.com (mail-ee0-f43.google.com [74.125.83.43]) by mx.google.com with ESMTPS id z8si5215580eee.23.1969.12.31.16.00.00 (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 03 Oct 2013 03:06:04 -0700 (PDT) Received-SPF: neutral (google.com: 74.125.83.43 is neither permitted nor denied by best guess record for domain of ulf.hansson@linaro.org) client-ip=74.125.83.43; Received: by mail-ee0-f43.google.com with SMTP id e52so981988eek.30 for ; Thu, 03 Oct 2013 03:06:04 -0700 (PDT) X-Received: by 10.14.127.2 with SMTP id c2mr1536245eei.77.1380794764144; Thu, 03 Oct 2013 03:06:04 -0700 (PDT) Received: from localhost.localdomain ([85.235.11.236]) by mx.google.com with ESMTPSA id m54sm13915551eex.2.1969.12.31.16.00.00 (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 03 Oct 2013 03:06:02 -0700 (PDT) From: Ulf Hansson To: linux-mmc@vger.kernel.org, Chris Ball Cc: Ulf Hansson Subject: [PATCH] mmc: Don't force card to active state when entering suspend Date: Thu, 3 Oct 2013 12:05:59 +0200 Message-Id: <1380794759-7506-1-git-send-email-ulf.hansson@linaro.org> X-Mailer: git-send-email 1.7.9.5 X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: ulf.hansson@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.128.181 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: , By adding a card state that records if it is suspended or resumed, we can accept asyncronus suspend/resume requests for the mmc and sd bus_ops. MMC_CAP_AGGRESSIVE_PM, will at request inactivity through the runtime bus_ops callbacks, execute a suspend of the the card. In the state were this has been done, we can receive a suspend request for the mmc bus, which for sd and mmc forced the card to active state by a pm_runtime_get_sync. In other words, the card was resumed and then immediately suspended again, completely unnecessary. Since the suspend/resume bus_ops callbacks for sd and mmc are now capable of handling asynchronous requests, we no longer need to force the card to active state before executing suspend. Evidently preventing the above sequence for MMC_CAP_AGGRESSIVE_PM. Signed-off-by: Ulf Hansson --- drivers/mmc/card/block.c | 2 -- drivers/mmc/core/mmc.c | 18 ++++++++++++++---- drivers/mmc/core/sd.c | 21 +++++++++++++++++---- include/linux/mmc/card.h | 4 ++++ 4 files changed, 35 insertions(+), 10 deletions(-) diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 1a3163f..29d5d98 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -2448,7 +2448,6 @@ 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); @@ -2483,7 +2482,6 @@ 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/mmc.c b/drivers/mmc/core/mmc.c index 6d02012..5b236e0 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -1477,6 +1477,9 @@ static int _mmc_suspend(struct mmc_host *host, bool is_suspend) mmc_claim_host(host); + if (mmc_card_suspended(host->card)) + goto out; + if (mmc_card_doing_bkops(host->card)) { err = mmc_stop_bkops(host->card); if (err) @@ -1496,8 +1499,10 @@ static int _mmc_suspend(struct mmc_host *host, bool is_suspend) err = mmc_deselect_cards(host); host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200); - if (!err) + if (!err) { mmc_power_off(host); + mmc_card_set_suspended(host->card); + } out: mmc_release_host(host); return err; @@ -1527,21 +1532,26 @@ static int mmc_shutdown(struct mmc_host *host) */ static int mmc_resume(struct mmc_host *host) { - int err; + int err = 0; BUG_ON(!host); BUG_ON(!host->card); mmc_claim_host(host); + + if (!mmc_card_suspended(host->card)) + goto out; + mmc_power_up(host); mmc_select_voltage(host, host->ocr); err = mmc_init_card(host, host->ocr, host->card); - mmc_release_host(host); + mmc_card_clr_suspended(host->card); +out: + mmc_release_host(host); return err; } - /* * Callback for runtime_suspend. */ diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 5e8823d..ef302f3 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -1075,13 +1075,20 @@ static int mmc_sd_suspend(struct mmc_host *host) BUG_ON(!host->card); mmc_claim_host(host); + + if (mmc_card_suspended(host->card)) + goto out; + if (!mmc_host_is_spi(host)) err = mmc_deselect_cards(host); host->card->state &= ~MMC_STATE_HIGHSPEED; - if (!err) + if (!err) { mmc_power_off(host); - mmc_release_host(host); + mmc_card_set_suspended(host->card); + } +out: + mmc_release_host(host); return err; } @@ -1093,17 +1100,23 @@ static int mmc_sd_suspend(struct mmc_host *host) */ static int mmc_sd_resume(struct mmc_host *host) { - int err; + int err = 0; BUG_ON(!host); BUG_ON(!host->card); mmc_claim_host(host); + + if (!mmc_card_suspended(host->card)) + goto out; + mmc_power_up(host); mmc_select_voltage(host, host->ocr); err = mmc_sd_init_card(host, host->ocr, host->card); - mmc_release_host(host); + mmc_card_clr_suspended(host->card); +out: + mmc_release_host(host); return err; } diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index f42cdbd..111a199 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -257,6 +257,7 @@ struct mmc_card { #define MMC_CARD_REMOVED (1<<7) /* card has been removed */ #define MMC_STATE_HIGHSPEED_200 (1<<8) /* card is in HS200 mode */ #define MMC_STATE_DOING_BKOPS (1<<10) /* card is doing BKOPS */ +#define MMC_STATE_SUSPENDED (1<<11) /* card is suspended */ unsigned int quirks; /* card quirks */ #define MMC_QUIRK_LENIENT_FN0 (1<<0) /* allow SDIO FN0 writes outside of the VS CCCR range */ #define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1) /* use func->cur_blksize */ @@ -423,6 +424,7 @@ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data) #define mmc_card_ext_capacity(c) ((c)->state & MMC_CARD_SDXC) #define mmc_card_removed(c) ((c) && ((c)->state & MMC_CARD_REMOVED)) #define mmc_card_doing_bkops(c) ((c)->state & MMC_STATE_DOING_BKOPS) +#define mmc_card_suspended(c) ((c)->state & MMC_STATE_SUSPENDED) #define mmc_card_set_present(c) ((c)->state |= MMC_STATE_PRESENT) #define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY) @@ -435,6 +437,8 @@ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data) #define mmc_card_set_removed(c) ((c)->state |= MMC_CARD_REMOVED) #define mmc_card_set_doing_bkops(c) ((c)->state |= MMC_STATE_DOING_BKOPS) #define mmc_card_clr_doing_bkops(c) ((c)->state &= ~MMC_STATE_DOING_BKOPS) +#define mmc_card_set_suspended(c) ((c)->state |= MMC_STATE_SUSPENDED) +#define mmc_card_clr_suspended(c) ((c)->state &= ~MMC_STATE_SUSPENDED) /* * Quirk add/remove for MMC products.