From patchwork Wed Sep 11 09:54:16 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ulf Hansson X-Patchwork-Id: 2871671 Return-Path: X-Original-To: patchwork-linux-mmc@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id C04759F485 for ; Wed, 11 Sep 2013 09:54:45 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 64BAB200DF for ; Wed, 11 Sep 2013 09:54:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 0ED1E200CF for ; Wed, 11 Sep 2013 09:54:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752068Ab3IKJym (ORCPT ); Wed, 11 Sep 2013 05:54:42 -0400 Received: from mail-la0-f44.google.com ([209.85.215.44]:62224 "EHLO mail-la0-f44.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751178Ab3IKJyl (ORCPT ); Wed, 11 Sep 2013 05:54:41 -0400 Received: by mail-la0-f44.google.com with SMTP id eo20so7232501lab.17 for ; Wed, 11 Sep 2013 02:54:40 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=yd1VUe6g4kC7eDH+7bCCoAPsFoD+t0COg50dVq1DekM=; b=Aec8tiS2hyDA/lAVPv4G0fyaTfuMgpce2ljWZP5asheJyfz0xr+2fc9bAtSOuePAUU tOFXcxg5ljcoqTOcte5KOIMYqpBZkZdrKKLEGZ8jDsJtn+LQToQTif8Q+wizbCetWPy8 Xn4T/ROV+F/miMNS/yO5CT0EcBmQS7nqKbFu+nuwPfBApvjN+S1Yq/ffrMdZ3qwjACDO HdVgS9mdAeMrdXoFJJYnJ/RlXutcEdBo5G/iZj18YE5l0cCVLHD5kDwASekWJF1ou1xJ kefibrk7Fs5IEyRGkdzcssrwSqlQhzlkPWXm4jTwKGpBY5UPuo9YIaauKzKDumNmwuty TPdg== X-Gm-Message-State: ALoCoQm6qFdxI+5qtYVR7m4am/hDmKNDTiBSNc+m/IwkdXFtGH3i0HKHEWjJF2Jscah6QpOJQ++e X-Received: by 10.112.128.166 with SMTP id np6mr2045868lbb.7.1378893280125; Wed, 11 Sep 2013 02:54:40 -0700 (PDT) Received: from linaro-ulf.lan (90-231-160-185-no158.tbcn.telia.com. [90.231.160.185]) by mx.google.com with ESMTPSA id b6sm11457543lae.0.1969.12.31.16.00.00 (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 11 Sep 2013 02:54:39 -0700 (PDT) From: Ulf Hansson To: linux-mmc@vger.kernel.org, Chris Ball Cc: Jaehoon Chung , Ulf Hansson Subject: [PATCH] mmc: core: Do not poll for busy with status cmd for all switch cmds Date: Wed, 11 Sep 2013 11:54:16 +0200 Message-Id: <1378893256-27460-1-git-send-email-ulf.hansson@linaro.org> X-Mailer: git-send-email 1.7.9.5 Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org X-Spam-Status: No, score=-7.7 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Some switch operations like poweroff notify, shall according to the spec not be followed by any other new commands. For these cases and when the host does'nt support MMC_CAP_WAIT_WHILE_BUSY, we must not send status commands to poll for busy detection. Instead wait for the stated timeout from the EXT_CSD before completing the request. Signed-off-by: Ulf Hansson Cc: Jaehoon Chung --- drivers/mmc/core/core.c | 2 +- drivers/mmc/core/mmc.c | 6 +++--- drivers/mmc/core/mmc_ops.c | 23 ++++++++++++++++++----- include/linux/mmc/core.h | 3 ++- 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index b9b9fb6..15eba0c 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -301,7 +301,7 @@ void mmc_start_bkops(struct mmc_card *card, bool from_exception) } err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_BKOPS_START, 1, timeout, use_busy_signal); + EXT_CSD_BKOPS_START, 1, timeout, use_busy_signal, true); if (err) { pr_warn("%s: Error %d starting bkops\n", mmc_hostname(card->host), err); diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 6d02012..8f0c516 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -1404,9 +1404,9 @@ static int mmc_poweroff_notify(struct mmc_card *card, unsigned int notify_type) if (notify_type == EXT_CSD_POWER_OFF_LONG) timeout = card->ext_csd.power_off_longtime; - err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_POWER_OFF_NOTIFICATION, - notify_type, timeout); + err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_POWER_OFF_NOTIFICATION, + notify_type, timeout, true, false); if (err) pr_err("%s: Power Off Notification timed out, %u\n", mmc_hostname(card->host), timeout); diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c index ef18348..5ea83b6 100644 --- a/drivers/mmc/core/mmc_ops.c +++ b/drivers/mmc/core/mmc_ops.c @@ -370,11 +370,12 @@ int mmc_spi_set_crc(struct mmc_host *host, int use_crc) * @timeout_ms: timeout (ms) for operation performed by register write, * timeout of zero implies maximum possible timeout * @use_busy_signal: use the busy signal as response type + * @send_status: send status cmd to poll for busy * * Modifies the EXT_CSD register for selected card. */ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, - unsigned int timeout_ms, bool use_busy_signal) + unsigned int timeout_ms, bool use_busy_signal, bool send_status) { int err; struct mmc_command cmd = {0}; @@ -411,14 +412,26 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, /* Must check status to be sure of no errors */ timeout = jiffies + msecs_to_jiffies(MMC_OPS_TIMEOUT_MS); do { - err = mmc_send_status(card, &status); - if (err) - return err; + if (send_status) { + err = mmc_send_status(card, &status); + if (err) + return err; + } if (card->host->caps & MMC_CAP_WAIT_WHILE_BUSY) break; if (mmc_host_is_spi(card->host)) break; + /* + * We are not allowed to issue a status command and the host + * does'nt support MMC_CAP_WAIT_WHILE_BUSY, then we can only + * rely on waiting for the stated timeout to be sufficient. + */ + if (!send_status) { + mmc_delay(timeout_ms); + return 0; + } + /* Timeout if the device never leaves the program state. */ if (time_after(jiffies, timeout)) { pr_err("%s: Card stuck in programming state! %s\n", @@ -445,7 +458,7 @@ EXPORT_SYMBOL_GPL(__mmc_switch); int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, unsigned int timeout_ms) { - return __mmc_switch(card, set, index, value, timeout_ms, true); + return __mmc_switch(card, set, index, value, timeout_ms, true, true); } EXPORT_SYMBOL_GPL(mmc_switch); diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index da51bec..64274ec 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h @@ -151,7 +151,8 @@ extern int mmc_app_cmd(struct mmc_host *, struct mmc_card *); extern int mmc_wait_for_app_cmd(struct mmc_host *, struct mmc_card *, struct mmc_command *, int); extern void mmc_start_bkops(struct mmc_card *card, bool from_exception); -extern int __mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int, bool); +extern int __mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int, bool, + bool); extern int mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int); extern int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd);